net.sf.farrago.catalog.codegen
Class ProxyGen

java.lang.Object
  extended by net.sf.farrago.catalog.codegen.ProxyGen

public class ProxyGen
extends Object

ProxyGen generates read-only C++ JNI proxies for MDR-generated Java interfaces (something like a stripped-down JACE). It uses an unholy mix of Java/JMI navel-scrutiny. For an example of its output, see FemGeneratedClasses.h and FemGeneratedMethods.h in //open/fennel/farrago.

To understand this generator, it's important to distinguish among MOF/UML/JMI classes (which are metadata objects), repository-generated Java interfaces, and the C++ proxy classes generated here.

Version:
$Id: //open/dev/farrago/src/net/sf/farrago/catalog/codegen/ProxyGen.java#23 $
Author:
John V. Sichi

Nested Class Summary
private static class ProxyGen.CppTypeInfo
           
 
Field Summary
private  Set<Class> baseInterfaces
          Set containing all base interfaces (represented as Class objects) from which C++ proxies are to inherit.
private  String basePrefix
           
private static Comparator<Class> classNameComparator
           
private  Map<Class,ProxyGen.CppTypeInfo> cppTypeMap
          Map from Class to corresponding C++ type name as String.
private  Set<Class> genEnums
          Set containing all interfaces (represented as Class objects) for which C++ enums are to be generated.
private  Set<Class> genInterfaces
          Set containing all interfaces (represented as Class objects) for which C++ proxies are to be generated.
private  String genPrefix
           
private  Map<Class,RefClass> javaToJmiMap
          Map from Class to RefClass for everything in genInterfaces.
private  Map<Class,String> javaTypeMap
          Map from Class to corresponding Java type String to use in method signatures.
private static Comparator<Method> methodNameComparator
           
private  PrintWriter pw
          PrintWriter used to generate output.
private  Set<Class> undefinedInterfaces
          Set containing interfaces (represented as Class objects) whose proxy definition has not yet been generated.
private  String visitorBaseName
           
private  String visitorClassName
           
 
Constructor Summary
ProxyGen(String genPrefix, String basePrefix)
          Initialize a new ProxyGen.
 
Method Summary
 void addBaseClasses(RefPackage refPackage)
          Adds all classes from a JMI package to the set of interfaces to use as bases.
 void addGenClasses(RefPackage refPackage)
          Adds all classes from a JMI package to the set of interfaces to be generated.
private static RefPackage findPackage(RefPackage rootPackage, String qualifiedName)
           
private  void generateClassDeclaration(Class clazz)
           
 void generateClassDefinition(Class clazz)
          Generates the C++ class definition for one interface.
 void generateClassDefinitions(PrintWriter pw)
          Generates the C++ code for all class definitions.
 void generateClassImplementations(PrintWriter pw)
          Generates the C++ code for all method definitions.
 void generateEnumDefinitions(PrintWriter pw)
          Generates the C++ code for all enumerations.
 void generateMethodDeclaration(Method method)
          Generates the C++ declaration for one (getter) method.
 void generateMethodDefinition(Method method)
          Generates the C++ definition for one (getter) method.
 void generateSetterMethodDeclaration(Method method)
          Generates the C++ declaration for one setter method and its corresponding clear method (if any).
 void generateSetterMethodDefinition(Method method)
          Generates the C++ definition for one setter method and its corresponding clear method (if any).
private  void generateStaticDefinitions(Class clazz)
           
private  void generateStaticInitialization(Class clazz)
           
private  void generateVisitDeclaration(Class clazz)
           
private  String getCppClassName(Class clazz)
          Gets the name of the C++ type for a proxy instance.
private  ProxyGen.CppTypeInfo getCppParameterTypeInfo(Class<?> parameterType)
           
private  String getCppRefName(Class clazz)
          Gets the name of the C++ type used to return a proxy instance by reference.
private  String getCppReturnTypeName(Method method)
           
private  String getJavaTypeSignature(Class clazz)
           
private  boolean isGetter(Method method)
          Decides whether a Java method is a getter for a JMI attribute.
private  boolean isSetter(Method method)
          Decides whether a Java method is setter for a JMI attribute that should be proxied.
static void main(String[] args)
          Main generator entry point invoked by build.xml (target "generateFemCpp").
private  RefClass toJmiClass(Class clazz)
          Finds the JMI class corresponding to a Java interface.
private static Class[] toSortedArray(Collection<Class> collection)
          Converts collection into an array of classes sorted by name.
private static Method[] toSortedArray(Method[] methods)
          Sorts an array of Methods.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

classNameComparator

private static final Comparator<Class> classNameComparator

methodNameComparator

private static final Comparator<Method> methodNameComparator

cppTypeMap

private Map<Class,ProxyGen.CppTypeInfo> cppTypeMap
Map from Class to corresponding C++ type name as String.


javaToJmiMap

private Map<Class,RefClass> javaToJmiMap
Map from Class to RefClass for everything in genInterfaces.


javaTypeMap

private Map<Class,String> javaTypeMap
Map from Class to corresponding Java type String to use in method signatures.


pw

private PrintWriter pw
PrintWriter used to generate output.


genInterfaces

private Set<Class> genInterfaces
Set containing all interfaces (represented as Class objects) for which C++ proxies are to be generated.


baseInterfaces

private Set<Class> baseInterfaces
Set containing all base interfaces (represented as Class objects) from which C++ proxies are to inherit.


undefinedInterfaces

private Set<Class> undefinedInterfaces
Set containing interfaces (represented as Class objects) whose proxy definition has not yet been generated. This is used to induce topological order for the inheritance graph.


genEnums

private Set<Class> genEnums
Set containing all interfaces (represented as Class objects) for which C++ enums are to be generated.


genPrefix

private String genPrefix

basePrefix

private String basePrefix

visitorClassName

private String visitorClassName

visitorBaseName

private String visitorBaseName
Constructor Detail

ProxyGen

public ProxyGen(String genPrefix,
                String basePrefix)
Initialize a new ProxyGen.

Method Detail

addGenClasses

public void addGenClasses(RefPackage refPackage)
                   throws ClassNotFoundException
Adds all classes from a JMI package to the set of interfaces to be generated.

Parameters:
refPackage - the source JMI package
Throws:
ClassNotFoundException

addBaseClasses

public void addBaseClasses(RefPackage refPackage)
                    throws ClassNotFoundException
Adds all classes from a JMI package to the set of interfaces to use as bases.

Parameters:
refPackage - the source JMI package
Throws:
ClassNotFoundException

generateClassDefinition

public void generateClassDefinition(Class clazz)
Generates the C++ class definition for one interface.

Parameters:
clazz - the interface

generateClassDefinitions

public void generateClassDefinitions(PrintWriter pw)
Generates the C++ code for all class definitions.

Parameters:
pw - output

generateEnumDefinitions

public void generateEnumDefinitions(PrintWriter pw)
                             throws Exception
Generates the C++ code for all enumerations.

Parameters:
pw - output
Throws:
Exception

generateClassImplementations

public void generateClassImplementations(PrintWriter pw)
Generates the C++ code for all method definitions.

Parameters:
pw - output

toSortedArray

private static Class[] toSortedArray(Collection<Class> collection)
Converts collection into an array of classes sorted by name. This is necessary in order to make the output deterministic.


toSortedArray

private static Method[] toSortedArray(Method[] methods)
Sorts an array of Methods. This is necessary in order to make output deterministic. Necessary because, for instance, Class.getDeclaredMethods() does not guarantee that it returns methods in any particular order, and in practice the order changes across versions (vendors?) of javac.


generateMethodDeclaration

public void generateMethodDeclaration(Method method)
Generates the C++ declaration for one (getter) method.

Parameters:
method - .

generateSetterMethodDeclaration

public void generateSetterMethodDeclaration(Method method)
Generates the C++ declaration for one setter method and its corresponding clear method (if any). Only setters that take non-primitive types get clear methods.

Parameters:
method - .

generateMethodDefinition

public void generateMethodDefinition(Method method)
Generates the C++ definition for one (getter) method.

Parameters:
method - .

generateSetterMethodDefinition

public void generateSetterMethodDefinition(Method method)
Generates the C++ definition for one setter method and its corresponding clear method (if any).

Parameters:
method - .

main

public static void main(String[] args)
                 throws Exception
Main generator entry point invoked by build.xml (target "generateFemCpp"). The catalog must already exist before running the generator.

Parameters:
args -
  • args[0] = filename for C++ class definition output
  • args[1] = filename for C++ class implementation output
  • args[2] = filename for C++ enumeration output
  • args[3] = qualified name of source model package
  • args[4] = prefix to use for generated objects
  • args[5] = (optional) qualified name of model package to reference as base; if this is not specified, generated objects are base classes
  • args[6] = (optional) prefix to reference for base classes; must be specified together with previous argument
Throws:
Exception

findPackage

private static RefPackage findPackage(RefPackage rootPackage,
                                      String qualifiedName)

getCppClassName

private String getCppClassName(Class clazz)
Gets the name of the C++ type for a proxy instance.

Parameters:
clazz - the source Java interface
Returns:
corresponding C++ type name

getCppRefName

private String getCppRefName(Class clazz)
Gets the name of the C++ type used to return a proxy instance by reference.

Parameters:
clazz - the source Java interface
Returns:
corresponding C++ type name

getCppReturnTypeName

private String getCppReturnTypeName(Method method)

getCppParameterTypeInfo

private ProxyGen.CppTypeInfo getCppParameterTypeInfo(Class<?> parameterType)

isGetter

private boolean isGetter(Method method)
Decides whether a Java method is a getter for a JMI attribute. We ignore all others.

Parameters:
method - the Java method
Returns:
true iff we consider it a getter

isSetter

private boolean isSetter(Method method)
Decides whether a Java method is setter for a JMI attribute that should be proxied. Currently setter support is limited to properties with names that begin with "result" and that are a primitive type, a type that boxes a primitive (e.g. Long), or String. We ignore all methods that don't match.

Parameters:
method - the Java method
Returns:
true iff we consider it a setter

getJavaTypeSignature

private String getJavaTypeSignature(Class clazz)

generateClassDeclaration

private void generateClassDeclaration(Class clazz)

generateStaticDefinitions

private void generateStaticDefinitions(Class clazz)

generateStaticInitialization

private void generateStaticInitialization(Class clazz)

generateVisitDeclaration

private void generateVisitDeclaration(Class clazz)

toJmiClass

private RefClass toJmiClass(Class clazz)
Finds the JMI class corresponding to a Java interface.

Parameters:
clazz - the Java interface
Returns:
the corresponding JMI class, or null if clazz not in set of interfaces to be generated