I think a xml to object mapper that doesn't need any config filoes like Digester is worthwile, and I would love to try it out. I like Digester and JAXB, JAXme, etc, but I still think these are not the end of the story.
If had known about Digester, I probably have never written Alchemy. I wanted a way to load object structures easily without the hassle of writing a serialization tool and have something that lets me tweak values easily. Maybe it will help if I describe what my engine does and then you can contrast it with Digester. The two could certainly be considered complementary. You register the tags that serve as the start of an object mapping. You can do this either programmatically by calling addMapping() in the engine or via a set of directives you embed in your XML document. This is the only configuration information the engine needs. You can do other things (such as add constant redefines and method name prefixes, but out of the box the engine is functional with minimal config). The embedded configuration is my preferred method. Once you register the object mappings, you set an object listener on the engine. This listener is where the engine will send the instantiated objects. Once registered, you call transmuteXML() with the path to the XML file or an InputStream to read the XML from. The engine does the rest and broadcasts the objects it creates to the listener. It is up to you to react to the incoming objects. The XML itself defines the methods that get called and the parameters to use. The names of the tags correspond to the names of the methods in the object you want to call. Attributes and tag values become arguments to the method. The engine uses bean patterns to determine the method name. Several default method name prefixes are provided. For example, if the tag <amount>15</amount> appears in the XML, the engine will look for a method that takes a single argument with one of the following names: setAmount, addAmount, putAmount, isAmount, amount. It takes the first match it finds in name and number of arguments. Once it has the method, it asks the method for the number and type of arguments and translates all the arguments into their appropriate types. An internal parameter factory constructs the argument list and the method gets called. For methods that take objects as arguments, you provide a mapping for the object type and nest the XML that defines it under its parent tag. This is kind of a high level view. An example here helps illustrate: Here is an XML document you can use to create a Java Properties object. <sample> <twgp:alchemy xmlns:twgp="http://www.wargameproject.org/transmuteml"> <twgp:mapping parentTag="*" tag="myprops" class="java.util.Properties"/> </twgp:alchemy> <myprops> <property key="prop1" value="value1"/> <property key="prop2" value="value2"/> <put key="prop3" value="value3"/> </myprops> </sample> >From a code perspective, you would do this: ... public void objectExtracted(Object obj) { // Objects created by the engine from XML get // broadcast here. } AlchemyEngine engine = AlchemyEngine.getInstance(); engine.addListener(this); engine.transmuteXML("/path/to/sample.xml"); That's it. If you were to run this sample, a Properties object would be set to objectExtracted() with the values prop1=value1, prop2=value2, prop3=value3. You add additional property sets with the myprops tag or add new objects. Tags that don't have mappings are simply ignored. Admittedly, this is a simple example, but serves to illustrate how the engine resolves method names and parameter types automatically. I don't want to chew up list space with too much chatter. The engine can handle very deep object hierarchies. Bascially, the structure of your code determines the engine's behavior. I've been writing up a user's guide for it for those that might be interested. The difference I see between my work and Digester is I only need to tell Alchemy what tag serves as the start of an object. That's what the mapping does. From there, Alchemy instantiates the object (default and multiargument constructors are supported) and then uses the tag names, attributes and values to interrogate the object and determine the best method to call. It operates in both strict and open modes. Strict mode (the default) fails any XML document that doesn't conform to the object's structure. Open mode broadcasts warnings, will do partial initialization and ignore very broken object mappings. I do not need to tell the engine about parameter names or types. It figures it out via reflection and constructs the appropriate parameter lists itself. Consider my work "Digester Lite" or "Digester + self writing mapping rules". I could probably use my work to build an extension to Digester that writes its own mapping rules on the fly for an arbitrary XML document. I see them as complementary. XML used by Alchemy maps directly onto method names. Digester lets you alias tags to methods. Alchemy support constant definition (i.e. define a human value like 'Yes' for a tag value and have it map to the value 1 when the method is actually called) and the ability to add your own method name prefixes. Using Digester as inspiration, I could easily add tag name aliasing to allow tag A to map to a specific method with a different name than the tag, but that crosses into what Digester does with a rules file. My goal was to have little to no rules. Alchemy is more interactive and looser than Digester. Alchemy even runs standalone to let you play with the XML and see what comes out without having to write a separate program. If Alchemy interests anyone, I'll happily make the code available. My work can at least serve as yet another approach to the problem of mapping XML onto Java. Matt Pickering __________________________________________________ Do you Yahoo!? HotJobs - Search new jobs daily now http://hotjobs.yahoo.com/ --------------------------------------------------------------------- In case of troubles, e-mail: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
