Oh, oh, someone is interested in the internal environment of XJC. I could help, since I probably developed more JAXB plugins than anyone else (see JAXB2 Basics )
Ok, let it begin. In XJC, the schema compiler does something like this
- Parses the circuit
- Creates a schema model (CClass, CPropertyInfo, etc.)
- Creates a path (ClassOutline, FieldOutline, etc.).
- Displays the code model (JClass, JDefinedClass, JMethod, etc.).
- Writes physical code (e.g. Java files to disk)
Let's start with the last two.
Java files do not need explanation, I hope.
A code model is also a very simple task. This is an API that you can use to programmatically develop Java code. Instead, you can just use string concatenation, but it is much more error prone. With CodeModel, you are almost guaranteed to get at least grammatically correct Java code. Therefore, I hope this part is also clear. (By the way, I really like CodeModel. I recently wrote JavaScript code based on the ideas of CodeModel.)
Now let's look at the "model" and the "outline". The model is the result of parsing the incoming circuit. It models the designs of the input circuit, mainly in terms of “classes” that correspond to complex types and “properties” that correspond to elements, attributes and values (for example, when you have a complex type with simple content).
A model should be understood as a logical modeling construct close to XML and schema. Thus, it simply describes the types and properties that they have. Of course, it’s much more complicated that I describe it, there are all kinds of exceptions and caveats - starting with wilcard (xsd: any) types, permutation groups, enumerations, built-in types, etc.
Interestingly enough, the sibling Model is a RuntimeTypeInfoSetImpl that is used by JAXB at runtime. Thus, it is also a type of model that, however, is not parsed from an XML schema, but rather from JAXB annotations in classes. The concept is the same. Both models and RuntimeTypeInfoSetImpl implement the TypeInfoSet interface, which is a superconstruction. Check interfaces such as ClassInfo and PropertyInfo - they have an implementation for both compile time ( CClassInfo and CPropertyInfo in XJC) and runtime ( RuntimeClassInfoImpl , etc. For JAXB RI).
So, when the XJC parsed and parsed the schema, you have a Model . This Model cannot yet create code. There are different strategies for creating code. You can only generate annotated classes, or you can create an interface / implementation of a pair of classes, as in JAXB 1. All code generation is not really the task of the model. Moreover, there are a number of aspects that are relevant to the physical nature of Java code, but not very relevant to the model. For example, you need to group classes into packages. This is due to the Java packaging system, not the properties of the model itself.
And here the contours come into play. You can see the contours as a step between the circuit model and the code model. You can view contours as factories for code model elements responsible for organizing code and generating JDefinedClass es from CClassInfo s.
So you are right, it is really very difficult. I am not a Sun / Oracle employee, I did not design it (I know the person who did this, although I respected him very much). I can guess a few reasons for some design decisions, for example:
- Use the same interfaces for compile time and runtime models.
- Allow various code generation strategies
- Allow plugins to manage the created model
I agree that this design is very complex, but it has its own reasons. One of the proofs of this is that it was actually possible to build a mapping generator for XML-to-JavaScript mappings - basically on the same models. I just had to replace the code generation, leaving the circuit analysis intact. (See Jsonix for this.)
Well, I hope I shed some light on why things in XJC are like them. Good luck with these APIs, they are not scary. Feel free to check your existing open source code, there are many examples available.
ps. Actually always wanted to write this. :)