This page (revision-11) was last changed on 23-Oct-2013 10:34 by Dieter Käppel

This page was created on 26-Apr-2012 12:34 by Dieter Käppel

Only authorized users are allowed to rename pages.

Only authorized users are allowed to delete pages.

Page revision history

Version Date Modified Size Author Changes ... Change note
11 23-Oct-2013 10:34 6 KB Dieter Käppel to previous
10 23-Oct-2013 10:34 6 KB Dieter Käppel to previous | to last
9 26-Apr-2012 13:37 6 KB Dieter Käppel to previous | to last
8 26-Apr-2012 13:37 6 KB Dieter Käppel to previous | to last
7 26-Apr-2012 13:36 6 KB Dieter Käppel to previous | to last
6 26-Apr-2012 13:35 3 KB Dieter Käppel to previous | to last
5 26-Apr-2012 12:56 3 KB Dieter Käppel to previous | to last
4 26-Apr-2012 12:50 3 KB Dieter Käppel to previous | to last
3 26-Apr-2012 12:50 2 KB Dieter Käppel to previous | to last
2 26-Apr-2012 12:39 2 KB Dieter Käppel to previous | to last
1 26-Apr-2012 12:34 1 KB Dieter Käppel to last

Page References

Incoming links Outgoing links

Version management

Difference between version and

At line 1 changed one line
[Intersult] [Coder] ist ein Werkzeug zur Analyse und zum Generieren von Code. Wichtige Bestandteile sind:
[Intersult] [Coder] ist ein Werkzeug zur Analyse und zum Generieren von Java-Code. Das Projekt wird von [Abraxas] verwendet, um die Konvertierung von XML nach [Java] und umgekehrt durchzuführen. Ziel des Projekts ist die einfache Nutzbarkeit durch [Convention over Configuration].
At line 3 changed 2 lines
* __Reflector:__ Stellt ein erweitertes Reflection für Java-Klassen zur Verfügung mit der Unterstüzung von Argumentnamen (bei Methoden), Generics, Annotations und Kommentaren.
* __Generator:__ Generiert Code aus erstellten JavaClass-Dateien und schreibt diesen in Dateien.
!!!Übersicht
Das Projekt enthält im Wesentlichen folgende Klassen, die für den Einstieg wichtig sind:
At line 6 added 45 lines
* __Reflector:__ Diese Klasse stellt eine erweiterte Reflection für Java-Klassen dar. Features sind Unterstüzung von Argumentnamen (bei Methoden), Generics, Annotations und Kommentare.
* __Generator:__ Generiert den Code für Java-Klassen aus JavaClass-Instanzen. JavaClass-Objekte können durch den Reflector aus bestehenden Code erzeugt werden oder komplett dynamisch angelegt werden. Der Generator schreibt das Ergebnis dann in Java-Dateien, die gut formatiert und compilierbar sind.
* __Instance:__ Es können Instanzen von Klassen erzeugt werden, die nicht vom ClassLoader geladen wurden. Dabei handelt es sich natürlich nicht um "echte" Instanzen, sondern Objekte vom Typ com.intersult.code.Instance.
!!!Reflector
Der com.intersult.code.Reflector kann genutzt werden, um Informationen über Java-Klassen zu gewinnen.
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.
!!Anwendung
Beim Generieren von neuen Klassen mit dem Generator werden häufig bestehende Klassen und Systemklassen gebraucht. Diese brauchen nicht "per Hand" gebaut werden, sondern können vom Reflector erzeugt 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.
!!Beispiel
{{{
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
}}}
!!Basis-Typen
Die String-Klasse aus dem oberen Beispiel hätte nicht reflektiert werden müssen, da sie zur Grundausstattung des Reflector gehört (tatsächlich wird auch in diesem Fall dieselbe JavaClass zurück geliefert, da jede JavaClass nur einmal existiert).
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
}}}
At line 7 changed one line
Code-Generierung aus XML-Schema (XSD) oder WSDL können mit Plugins, wie dem [Abraxas Maven Plugin|Abraxas] abgedekt werden. Für die Implementierung eigener [Maven-Plugins] oder anderer Art von Code-Generierung kann der Generator direkt verwendet werden.
Viele Fälle der Code-Generierung, z.B. aus XML-Schema (XSD) oder WSDL können mit Plugins abgedeckt werden, wie dem [Abraxas Maven Plugin|Abraxas].
At line 54 added 2 lines
Für die Implementierung eigener [Maven-Plugins|Maven] oder anderer Art von Code-Generierung kann die Klasse com.intersult.code.Generator direkt verwendet werden. Die Verwendung ist dabei sehr einfach:
At line 70 added 34 lines
!!Methods
Das Hinzufügen einer Methode inklusive Code kann zum Beispiel so aussehen:
{{{
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() + "());");
}}}
!!Beans und Properties
In Java werden Felder mit Gettern und Settern zugegriffen. Die Methoden dazu heißen Accessors und können mit einer Methode hinzugefügt werden:
{{{
Accessor accessor = javaClass.addAccessor(Reflector.INSTANCE.STRING, "name");
}}}
!!!Instance
Hat man eine JavaClass vorliegen, bekommt man über die Methode getType() das Java-Class-Objekt zurück. Mit newInstance() bekommt man eine neue Instanz. Dieser Fall liegt immer vor, wenn die JavaClass vom Reflector bezogen wurde.
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.
!!!Annotations
Instance wird auch bei der Verwendung von Annotations benutzt. Die Code-Generierung arbeitet ja mit JavaClass-Objekten, da diese aus dem Code heraus gebaut werden können. Instanzen werden benötigt, da eine Annotation-Klasse instantiiert wird, sobald sie an einer Stelle im Code mit dem @-Operator angebracht wird.