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