Some months ago a sort of Aegis subcommittee of Dan K, Dan D, Dain S and myself laid out a plan to clean up some modularity in Aegis. I just committed a large piece of it. There is some possibility, I guess, that some of the rest of you will wake up this morning, read this, and spit out your coffee. Just in case, I made a snapshot tag so that this could be pushed past 2.1 without throwing it out.
The following probably deserves a more permanent home than the email archive. However, here goes. Aegis came, of course, from XFire. In XFire, the design allowed for many services to share a 'type mapping registry'. The TypeMappingRegistry is a mapping from strings (labelled 'encoding URI') to TypeMapping objects. TypeMapping object, in turn, store bidirectional mappings between classes and binding information objects. There is only one type of TypeMapping (called, in XFire and CXF 2.0.x, CustomTypeMapping). TypeMapping objects have a delegation model: if a mapping lacks knowledge of a type, it can pass the problem to the next mapping in a chain. Alternatively, a type mapping object can have a type creator object. Type creator objects create new mappings. Type creator objects also have a delegation model, and there are three of them. - The default type creator uses ordinary introspection. - The java5 type creator looks at annotations and generics. - The xml type creator looks at .aegis.xml files. (XFire supported Java 1.4, and so it was important for the java5 creator to be a separate module.) This entire structure came over from CXF. It was still theoretically possible for an application to: - explicitly create a shared type mapping registry - explicitly push it into AegisDatabinding objects so that multiple services would share it. However, no one could think of a good reason for anyone to want to do this. While the registry served as a factory of type mappings, and it was hypothetically possible to thus subclass the registry and customize the factory, the same customization was at about the same difficulty level without the registry. The meat of any customization would be in the type mapping object, not the registry. By default, CXF created a new type mapping registry for each AegisDatabinding. All in all, the registry was appendicinal. It was also quite confusing. Thus, the new, simpler structure: - No more TypeMappingRegistry - CustomTypeMapping renamed to DefaultTypeMapping - AegisContext creates the type mappings. A little more detail. In the normal, 'inside CXF' case, the application creates an AegisDatabinding. This, in turn, creates and AegisContext. It passed the namespace URI derived from the service into the context, and initializes the context. The context, in turn, creates two type mappings. First, it creates a base type mapping containing the default mappings. Then it creates an empty type mapping labelled with the service namespace URI, and gives it the standard type creator chain, and sets it to delegate to the default mapping. Note that the default mappings are not shared, because they respect the 'defaultNillable' flag in the Configuration object, if any. >From then on, the context passes the 'front' type mapping to the readers and writers, and it accumulates mappings as it goes. Note that Dain's code to set up Soap 1.1 encoded types is still there, but moved to the DefaultTypeMapping. Nothing uses it except for the encoded unit tests. As a side-effect, this change clarifies the role of the once-called 'encoding URI'. Every type mapping has an associated URI. It serves two purposes, period: - If the AbstractTypeCreator has no other URI at hand to qualify a type, it uses that one. - The XMLTypeCreator will use that URI to select the best mapping from the .aegis.xml file. I guess my next mission is to start pushing confluence to reflect 2.1instead of 2.0, both for this change and for the previous round of Aegis cleanups. On the horizon is to rationalize the type creator chain.
