Hi Phil, In reference to your first issue, that mappings usable by AnyXmlable must not be used as base mappings for any concrete mappings, this is by-design in the current code. It may be possible to relax this restriction in 1.2, so if you enter a Jira issue on the topic I'll see what I can do.
The second issue is probably more difficult to correct, since it really does concern the state expected when using an unmarshaller. It's worth adding a Jira on this point, too, but it probably won't get addressed until the 2.0 code generation rewrite. In the meantime, your idea of a phony attribute is probably best. You might try using a constant="whatever" usage="optional" attribute for this purpose, since that won't require you to have a field or get/set methods on your object. - Dennis Dennis M. Sosnoski SOA, Web Services, and XML Training and Consulting http://www.sosnoski.com - http://www.sosnoski.co.nz Seattle, WA +1-425-296-6194 - Wellington, NZ +64-4-298-6117 Phil McGee wrote: > Hi Dennis, > > Based on your suggestions I got the implementation of the AnyXmlable > marshaller/unmarshaller fundamentally working. Thank you. > > I now have two additional obstacles to overcome. One issue is that > apparently mappings usable by AnyXmlable must not be used as base > mappings for any concrete mappings, if I do, then I lose access to the > "aliasable" marshaller for the abstract mapping. So apparently, I can > bind class Foo to element <Foo> or to <AnyXmlable javaClass="Foo"> but > I can't do both in the same binding.xml. I haven't been able to > discover any means of resolving this dilemma short of modifying the > code generation. I am not anxious to take that step (or confident > that I could) and was wondering if I may have missed some other > possibility. > > My second difficulty is dealing with using AnyXmlable mapping for an > abstract mapping which defines attributes. The following (modified) > XML snippet demonstrates the desired behavior. > <XmlableList> > <Foo> > <fooStuff>42<fooStuff/> > </Foo> > <Bar units="radians"> > <barStuff>3.14<barStuff/> > </Bar> > <FooBar> > <AnyXmlable javaClass="Foo" > > <fooStuff>60<fooStuff/> > </AnyXmlable> > </FooBar> > <FooBar> > <AnyXmlable javaClass="Bar" units="radians"> > <barStuff>2.72<barStuff/> > </AnyXmlable> > </FooBar> > </XmlableList> > > Note how the tag <AnyXmlable javaClass="Bar" units="radians"> > includes the attributes defined by Bar as well as the javaClass > attribute required by the AnyXmlable marshaller/unmarshaller. It > seems that when unmarshalling <AnyXmlable javaClass="Foo"> the > unmarshaller for AnyXmlable needs to call > UnmarshallingContext.parsePastStartTag() before calling the > unmarshaller for Foo, whereas when unmarshalling <AnyXmlable > javaClass="Bar" units="radians"> the unmarshaller for AnyXmlable must > not have parsed past the start tag or the units attribute is not > accessible to the Bar unmarshaller. If the unmarshaller for > AnyXmlable could determine if the specific abstract mapping defined > attributes it could do the right thing, but there is no obvious way to > determine this. > I was wondering about the possibility of defining an optional dummy > attribute of some kind that would never actually exist in the XML but > might force the non-attribute unmarshallers to expect the parser in > the same state as those marshallers which do support attributes. > Might that work? And if so, could I define an attribute in such a way > that it would never show up in the XML but would not require the > modification of all the Java data classes to support an always null > dummy field (or set/get pair) to which it would be mapped? > > As always, thank you for your help. > > Phil > > Dennis Sosnoski wrote: >> Hi Phil, >> >> I think you could make this work, though it's going to be pushing >> into dusty corners of the code and you may run into some unpleasant >> surprises. The basic approach would be to use abstract <mapping>s for >> all your classes, then have your <AnyXmlable> unmarshaller access the >> appropriate abstract mapping information at runtime. To do this you >> need to use the <binding force-classes="true"> attribute and then >> find the abstract mapping class for each data class via the >> IBindingFactory.getTypeIndex() method. Once you've got the index you >> can get the marshaller/unmarshaller instance from the context. Note >> that if you do this, your concrete <mapping>s can just add a name >> while referencing the abstract ones for all the content. >> >> - Dennis >> >> Phil McGee wrote: >> >>> Great work on JiBX. It is the most flexible XML-Java binding >>> framework I've >>> ever seen AND the fastest. I hope to eliminate lots of homegrown >>> code and run >>> three to four times faster. >>> >>> That said, I have one tricky problem I can't seem to solve. >>> Consider the >>> following hypothetical classes >>> >>> interface Xmlable { >>> } >>> >>> class Foo implements Xmlable { >>> int fooStuff; >>> } >>> >>> class Bar implements Xmlable { >>> float barStuff; >>> } >>> >>> class FooBar implements Xmlable { >>> Xmlable xmlable; >>> } >>> >>> class XmlableList implements Xmlable { >>> ArrayList xmlables; >>> } >>> >>> and the related XML document below >>> >>> <XmlableList> >>> <Foo> >>> <fooStuff>42<fooStuff/> >>> </Foo> >>> <Bar> >>> <barStuff>3.14<barStuff/> >>> </Bar> >>> <FooBar> >>> <AnyXmlable javaClass="Foo" > >>> <fooStuff>60<fooStuff/> >>> </AnyXmlable> >>> </FooBar> >>> <FooBar> >>> <AnyXmlable javaClass="Bar" > >>> <barStuff>2.72<barStuff/> >>> </AnyXmlable> >>> </FooBar> >>> </XmlableList> >>> >>> which illustrate my problem. Although each class which is marshalled >>> to/from XML is typically associated with >>> a uniquely named XML element, there are a few unfortunate instances >>> of element >>> AnyXmlable each of which corresponds to a Java object of the class >>> identified by >>> its javaClass attribute. The content of each AnyXmlable element >>> depends on its >>> actual type as determined by the javaClass attribute -- AnyXmlable >>> elements with >>> javaClass="Foo" contain fooStuff and AnyXmlable elements with >>> javaClass="Bar" >>> contain barStuff. >>> >>> I can create a custom Unmarshaller for FooBar that creates an instance >>> of class Foo when it encounters <AnyXmlable javaClass="Foo" >, and I >>> can retrieve >>> the Unmarshaller for class Foo which knows how to deal with the >>> fooStuff contained by AnyXmlable. The problem is that the >>> Unmarshaller for class Foo relies on the fact that it is dealing with >>> a Foo element. When it sees that it is an AnyXmlable element it >>> throws an >>> exception. I was hoping that some mechanism akin to IAliasable used >>> for custom >>> marshallers could be invoked, but the element names seem to be hard >>> coded into >>> the marshallers. >>> >>> In reality, Foo and Bar correspond to hundreds Java classes and the >>> fooStuff and >>> barStuff can be quite complex and often highly recursive content. >>> We have tens >>> of thousands of historical documents containing a very small >>> fraction of >>> AnyXmlable type elements which unfortunately we must support. >>> >>> Can anyone suggest a means of patching over the AnyXmlable elements >>> and tying >>> back into the marshallers defined for all the Foo and Bar type classes? >>> >>> Any suggestions are greatly appreciated. >>> >>> Phil McGee >>> XFI Corp >>> >>> >>> >>> >>> ------------------------------------------------------- >>> Using Tomcat but need to do more? Need to support web services, >>> security? >>> Get stuff done quickly with pre-integrated technology to make your >>> job easier >>> Download IBM WebSphere Application Server v.1.0.1 based on Apache >>> Geronimo >>> http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 >>> >>> _______________________________________________ >>> jibx-users mailing list >>> jibx-users@lists.sourceforge.net >>> https://lists.sourceforge.net/lists/listinfo/jibx-users >>> >> >> >> ------------------------------------------------------- >> Using Tomcat but need to do more? Need to support web services, >> security? >> Get stuff done quickly with pre-integrated technology to make your >> job easier >> Download IBM WebSphere Application Server v.1.0.1 based on Apache >> Geronimo >> http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 >> _______________________________________________ >> jibx-users mailing list >> jibx-users@lists.sourceforge.net >> https://lists.sourceforge.net/lists/listinfo/jibx-users >> >> > > > > > ------------------------------------------------------- > Using Tomcat but need to do more? Need to support web services, security? > Get stuff done quickly with pre-integrated technology to make your job > easier > Download IBM WebSphere Application Server v.1.0.1 based on Apache > Geronimo > http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 > _______________________________________________ > jibx-users mailing list > jibx-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/jibx-users > _______________________________________________ jibx-users mailing list jibx-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jibx-users