Intersult Coder ist ein Werkzeug zur Analyse und zum Generieren von Code.
Wichtige Bestandteile sind:
Da der Reflector die reflektierten Klassen in internen Listen ansammelt, kann es nützlich sein den Reflector nach Gebrauch dem Garbage-Collector zu übergeben. Für diesen Fall kann ein Reflector durch new Reflector() einfach erzeugt werden. Für alle anderen Fälle kann die Default-Instanz Reflector.INSTANCE verwendet werden.
Darüber hinaus liefert der Reflector einige nützliche Informationen über eine Klasse, die über die Java-Reflection nicht zugreifbar sind. Dazu gehören die Namen von Methoden-Parametern und Kommentare von Klassen und Methoden. Dies wird zum Beispiel vom SOAP-Service Abraxas benutzt, um die Service-Aufrufe zu erzeugen.
JavaClass stringClass = Reflector.INSTANCE.reflect(String.class); System.out.println(stringClass.getTypeNameSimple(true)); System.out.println(stringClass.getClassDefinition());
Erklärung: Der Reflector erzeugt aus der String.class-Klasse eine JavaClass, die erweiterte Methoden enthält, wie zum Beispiel getTypeName und getTypeNameSimple. Die Methode getClassDefinition liefert die Definition, wie sie in der Java-Datei steht, für String:
public final class String implements Serializable, Comparable<T>, CharSequence
Folgende Klassen sind bereits enthalten:
WILDCARD, OBJECT, STRING, VOID, ATOMIC_VOID, SHORT, ATOMIC_SHORT, INTEGER, ATOMIC_INTEGER, LONG, ATOMIC_LONG, BOOLEAN, ATOMIC_BOOLEAN, BYTE, ATOMIC_BYTE, DOUBLE, ATOMIC_DOUBLE, FLOAT, ATOMIC_FLOAT, BIG_DECIMAL, CLASS, DATE, URI, URL, QNAME, LIST, SERIALIZABLE, BASE64
Dazu kommen Annotation-Klassen:
OVERRIDE, REQUIRED, DEFAULT, NAME, KEY
Für die Implementierung eigener Maven-Plugins oder anderer Art von Code-Generierung kann die Klasse com.intersult.code.Generator direkt verwendet werden. Die Verwendung ist dabei sehr einfach:
JavaClass javaClass = new JavaClass("com.intersult.test", "Test"); javaClass.generatePath(); Generator.generateClass(Reflector.INSTANCE, javaClass);
Erklärung: Es wird eine neue Klasse com.intersult.test.Test erzeugt. Die Methode generatePath erzeugt den Package-Pfad, der nicht in jedem Fall erwünscht sein kann. Der Generator schreibt dann mit generateClass die Klasse in Dateien. Der Java-Standard ist dabei so definiert, dass Unterklassen (Sub-Classes) in getrennte Dateien geschrieben werden mit dem Namensmuster <Hauptklasse>$<Unterklasse>.
Optional kann eine Liste übergeben werden, in der die generierten Dateien eingetragen werden:
List<File> files = new ArrayList<File>(); Generator.generateClass(Reflector.INSTANCE, javaClass, list);
JavaMethod equals = javaClass.addMethod("equals"); equals.setReturnType(Reflector.INSTANCE.ATOMIC_BOOLEAN); equals.addAnnotation(Reflector.INSTANCE.OVERRIDE.newInstance()); JavaVariable object = new JavaVariable(Reflector.INSTANCE.OBJECT); equals.getParameters().add(object); equals.getCode().add("if (" + object.getVariableName() + " == null || !(" + object.getVariableName() + " instanceof " + javaClass.getTypeNameSimple(false) + "))"); equals.getCode().add("\treturn false;"); equals.getCode().add("if (this == " + object.getVariableName() + ")"); equals.getCode().add("\treturn true;"); JavaVariable field = javaClass.getFields().get("field"); equals.getCode().add("return " + field.getGetter() + "().equals(((" + javaClass.getTypeName(false) + ")" + object.getVariableName() + ")." + field.getGetter() + "());");
Accessor accessor = javaClass.addAccessor(Reflector.INSTANCE.STRING, "name");
Eine JavaClass kann allerdings auch aus dem Code erzeugt werden, also über den Konstruktor new JavaClass("<package>", "<name>"). In diesem Fall kann eine Instance durch die Methode newInstance() der Klasse JavaClass erzeugt werden. Es handelt sich natürlich um keine echte Java-Instanz, sondern um ein Objekt vom Typ com.intersult.code.Instance.