Welche Rolle spielt ClassOutline / JClass / CClass in CodeModel?

7

Meine Frage betrifft das Schreiben von JAXB-Plugins, insbesondere des JAXB-Codemodells.

Was ist die Rolle von ClassOutline (und es ist Begleiter ) und JClass (und Begleiter ) und CClass (und Begleiter )? Wenn man sich die Liste der Klassen in entsprechenden Paketen ansieht, ist nicht klar, was Huhn ist und was Ei ist.

Meine Interpretation ist, dass CClass ( CPropertyInfo , CEnumConstant , ...) von XJC beim ersten Entwurfsparsing von XSD erstellt werden. Dann passiert etwas Magie und dieses Modell wird in JClass ( JFieldVar , JEnumConstant , ...) umgewandelt und während dieser Transformation werden Anpassungen angewendet. Danach werden Plugins aufgerufen. ClassOutline wird als Brücke zwischen diesen beiden Modellen verwendet. Insgesamt sieht das sehr kompliziert aus.

Mit diesen parallelen Modellen glaube ich, dass die gleiche Information auf verschiedene Arten abgeleitet werden kann. Zum Beispiel Klassenfeldtyp:

  • JClass#fields()JFieldVar#typeJType
  • CClassInfo#getProperties()CPropertyInfo#baseTypeJType

Ich bin auf der Suche nach einer ausführlichen Erklärung des Lebenszyklus der oben genannten Modelle. Danke.

    
dma_k 12.02.2012, 09:26
quelle

2 Antworten

17

Oh, oh, jemand interessiert sich für XJC-Interna. Ich könnte eine Hilfe sein, da ich wahrscheinlich mehr JAXB-Plugins entwickelt habe als irgendjemand sonst (siehe JAXB2 Basics zum Beispiel)

Ok, fangen wir an. In XJC folgt der Schema-Compiler ungefähr

  • Analysiert das Schema
  • Erzeugt das Modell des Schemas (CClass, CPropertyInfo etc.)
  • Erstellt die Gliederung (ClassOutline, FieldOutline etc.)
  • Rendert das Code-Modell (JClass, JDefinedClass, JMethod etc.)
  • Schreibt den physischen Code (zB Java-Dateien auf der Festplatte)

Beginnen wir mit den letzten zwei.

Java-Dateien brauchen keine Erklärung, hoffe ich.

Code-Modell ist auch eine relativ einfache Sache. Es ist eine API, mit der Java-Code programmgesteuert erstellt werden kann. Sie könnten stattdessen auch String Concateination verwenden, aber es ist viel fehleranfälliger. Mit CodeModel erhalten Sie fast garantiert grammatikalisch korrekten Java-Code. Also ich hoffe dieser Teil ist auch klar. (Übrigens gefällt mir CodeModel sehr gut. Ich habe kürzlich JavaScript Code Model basierend auf Ideen aus dem CodeModel geschrieben.)

Sehen wir uns nun das "Modell" und den "Umriss" an. Model ist das Ergebnis der Analyse des eingehenden Schemas. Es modelliert die Konstrukte des eingehenden Schemas, hauptsächlich in Form von "Klassen", die komplexen Typen und "Eigenschaften" entsprechen, die Elementen, Attributen und Werten entsprechen (zB wenn Sie einen komplexen Typ mit einfachem Inhalt haben).

>

Das Modell sollte als logisches Modellierungskonstrukt in der Nähe von XML und Schema verstanden werden. Als solches beschreibt es nur Typen und Eigenschaften, die sie haben. Es ist sicherlich viel komplexer, dass, wie ich es beschreibe, es gibt alle Arten von Ausnahmen und Vorbehalte - beginnend mit Wilcard-Typen (xsd: any), Substitutionsgruppen, Enums, eingebauten Typen und so weiter.

Interessanterweise ist ein Geschwister von Model RuntimeTypeInfoSetImpl , das von JAXB in der Laufzeit verwendet wird. Es ist also auch eine Art von Modell - das jedoch nicht aus dem XML-Schema, sondern aus JAXB-Annotationen in Klassen geparst wird. Das Konzept ist das gleiche. Sowohl Model als auch RuntimeTypeInfoSetImpl implementieren die Schnittstelle TypeInfoSet , die ein Super-Konstrukt ist. Prüfe Schnittstellen wie ClassInfo und PropertyInfo - sie haben eine Implementierung sowohl für die Kompilierzeit ( CClassInfo und CPropertyInfo in XJC) als auch für die Laufzeit ( RuntimeClassInfoImpl etc. für JAXB RI).

Ok, also wenn XJC das Schema analysiert und analysiert hat, hast du Model . Dieser Model kann den Code noch nicht erstellen. Es gibt tatsächlich verschiedene Strategien, um den Code zu produzieren. Sie können nur mit Anmerkungen versehene Klassen erzeugen oder Sie können Schnittstellen- / Implementierungsklassenpaare wie in JAXB 1 erzeugen. Die ganze Codegenerierungs-Sache ist nicht wirklich die Aufgabe des Modells. Darüber hinaus gibt es eine Reihe von Aspekten, die für die physische Natur des Java-Codes relevant sind, aber für das Modell nicht relevant sind. Zum Beispiel müssen Sie Klassen in Pakete gruppieren. Dies wird durch das Packsystem von Java gesteuert, nicht durch die Eigenschaften des Modells selbst.

Und hier kommen Konturen ins Spiel. Sie können Umrisse als Schritt zwischen dem Schemamodell und dem Codemodell sehen. Sie können Outlines als Factory für Code Model-Elemente anzeigen, die für die Organisation des Codes und die Generierung von JDefinedClass es von CClassInfo s verantwortlich sind.

Sie haben also recht, es ist in der Tat sehr kompliziert. Ich bin kein Sun / Oracle-Mitarbeiter, ich habe es nicht entworfen (ich kenne die Person, die es getan hat, und respektiere ihn sehr). Ich kann einige Gründe für bestimmte Designentscheidungen erraten, zum Beispiel:

  • Verwenden Sie die gleichen Schnittstellen für Kompilierungs- und Laufzeitmodelle
  • Erlaube verschiedene Strategien der Code-Generierung
  • Erlaube Plugins, das erstellte Modell zu bearbeiten

Ich stimme zu, dass dieses Design sehr kompliziert ist, aber es hat seine Gründe. Ein Beweis dafür ist, dass es tatsächlich möglich war, einen Mapping-Generator für XML-zu-JavaScript-Mappings zu erstellen - im Wesentlichen auf denselben Modellen. Ich musste nur die Code-Generierung ersetzen und die Schema-Analyse intakt lassen. (Siehe hierzu Jsonix .)

Ok, hoffentlich habe ich ein wenig Klarheit darüber bekommen, warum die Dinge in XJC so sind wie sie sind. Viel Glück mit diesen APIs, sie sind nicht geradlinig. Fühlen Sie sich frei, vorhandenen Open-Source-Code zu überprüfen, es gibt viele Beispiele zur Verfügung.

ps. Ich wollte das wirklich immer schreiben. :)

    
lexicore 22.02.2012, 22:40
quelle
2

(Damit beantworten Sie Ihre weiteren Fragen.)

Ja, es ist möglich, Anpassungen zu überprüfen. Hier ist eine Klasse, die ich verwende, um auf Anpassungen zuzugreifen.

Der Trick besteht darin, dass Referenzeigenschaften keine eigenen Anpassungen haben, Anpassungen werden in den Eigenschaften des referenzierten Elements vorgenommen.

%Vor%

Ich würde sagen, dass [email protected] ein guter Ort für solche Diskussionen ist.

    
lexicore 27.03.2012 23:31
quelle

Tags und Links