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
[email protected]
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
[email protected]
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/jibx-users

Reply via email to