Hi Luc, Sorry I've been slow in responding to your original query on this. In regard to that, there are several approaches you can use for unmarshalling immutable objects. One of the easiest is the use a factory method (see http://jibx.sourceforge.net/tutorial/binding-extend.html#extmeths). Although this part is not well documented, the factory method will always be called when positioned on the start tag for the element matching the object being unmarshalled. You can have the unmarshalling context passed to your method (by giving the factory method a parameter of type org.jibx.runtime.IUnmarshallingContext) and then extract the attribute values directly in your own code.
As for why the abstract mapping approach won't work for your IAliasable custom marshaller/unmarshaller, this is logically an error in the JiBX code but probably one that won't get fixed since it's a rather uncommon requirement (and the fix would probably get pretty nasty). But if you're only doing unmarshalling you should be able to simplify your binding and code by specifying direction="input" on the <binding> element - that way you should be able to use an unmarshaller="..." attribute without a corresponding marshaller="..." attribute. I'm guessing you didn't realize that bindings could be one-way, or that this would make a different in the use of custom marshaller/unmarshallers, even though you've obviously dug into the documentation pretty deeply. Where should this be mentioned in the documentation to save other new users trouble? - Dennis Dennis M. Sosnoski SOA and Web Services in Java Training and Consulting http://www.sosnoski.com - http://www.sosnoski.co.nz Seattle, WA +1-425-939-0576 - Wellington, NZ +64-4-298-6117 Luc Maisonobe wrote: > [Partly answering to myself, in case somebody else has the same problem, > and going further with an extended question] > > My use case was to build a 3D vector from the apache commons math > library, using the constructor with 3 double parameters for the vector > coordinates: Vector3D(double, double, double). > <http://commons.apache.org/math/apidocs/org/apache/commons/math/geometry/Vector3D.html#Vector3D%28double,%20double,%20double%29> > > This class is immutable (the coordinates are stored in final fields). > > The only way I found was to implement complete marshaller/unmarshaller, > has described in the Custom marshallers and unmarshallers > <http://jibx.sourceforge.net/tutorial/binding-custom.html#marunmar> > section of the documentation. Implementing only the unmarshller is > impossible, if you use "unmarshaller=some.class.you.wrote", you must > also provide the marshaller otherwise JiBX will complain. > > The main unmarshal method from the IUnmarshaller interface is called > with an object as its first parameter, but it seems to be always null (I > found no hint about this in the documentation). This was pretty good for > me as I wanted to build the vector myself after having unmarshalled the > three coordinates. I ended up with something close to this (showing only > the unmarshal part): > > public class Vector3DBinder implements IMarshaller, IUnmarshaller, > IAliasable { > > private final String uri; > private final int index; > private final String name; > > public Vector3DBinder() { > uri = null; > index = 0; > name = "vector"; > } > > public Vector3DBinder(final String uri, final int index, final > String name) { > this.uri = uri; > this.index = index; > this.name = name; > } > > // skipping the isExtension, marshall and isPresent method > > public Object unmarshal(final Object object, final > IUnmarshallingContext context) > throws JiBXException { > try { > > final UnmarshallingContext ctx = (UnmarshallingContext) context; > > // extract coordinates > ctx.parseToStartTag(uri, name); > final double x = Double.parseDouble(ctx.attributeText(uri, > "x", null)); > final double y = Double.parseDouble(ctx.attributeText(uri, > "y", null)); > final double z = Double.parseDouble(ctx.attributeText(uri, > "z", null)); > ctx.parsePastStartTag(uri, name); > ctx.parsePastEndTag(uri, name); > > // return a new vector > return new Vector3D(x, y, z); > > } catch (ClassCastException cce) { > throw new JiBXException(cce.getMessage(), cce); > } > } > } > > > This method is in a custom Vector3DBinder class. One interesting > property of this approach is that JiBX does not attempt to modify the > Vector3D class itself, which is simpler as it allows to simply put the > commons-math jar as an already built dependency and not to change the > build process. > > I still have a problem, though. I want to extract data from an XML > document containing several vectors instances, similar to this reduced > exemple: > > <root> > <vector-1 x="1.0" y="0.0" z="0.0"/> > <vector-2 x="0.0" y="1.0" z="0.0"/> > </root> > > I was able to do this only with the following binding: > > <mapping name="root" class="Root"> > <structure name="vector-1" > field="v1" > marshaller="some.package.path.Vector3DBinder" > unmarshaller="some.package.path.Vector3DBinder"/> > <structure name="vector-2" > field="v2" > marshaller="some.package.path.Vector3DBinder" > unmarshaller="some.package.path.Vector3DBinder"/> > </mapping> > > Since I have lots of vectors in the real file, I would have prefered to > use something like: > > <mapping name="root" class="Root"> > <structure name="vector-1" field="v1" /> > <structure name="vector-2" field="v2" /> > </mapping> > > <mapping class="org.apache.commons.math.geometry.Vector3D" > abstract="true" > marshaller="some.package.path.Vector3DBinder" > unmarshaller="some.package.path.Vector3DBinder"/> > </mapping> > > Despite the abstract="true" attribute, and the fact the class implements > IAliasable, in the second case I get an error while unmarshalling > because JiBX expects a "vector" element and not the "vector-1" and > "vector-2" elements. The reason for this seems to be that the > unmarshaller is built for the no-argument constructor instead of the > constructor providing the current name. > > If I use the first binding, repeating myself the marshaller="..." and > unmarshaller="..." everywhere, all works as expected. > > I don't understand what I do wrong. I guess I misunderstood the > abstract="true" attribute and IAliasable interface, but need help to > understand them correctly. > > Thanks, > Luc > > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Microsoft > Defy all challenges. Microsoft(R) Visual Studio 2008. > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > _______________________________________________ > jibx-users mailing list > jibx-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/jibx-users > > ------------------------------------------------------------------------- Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://sourceforge.net/services/buy/index.php _______________________________________________ jibx-users mailing list jibx-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jibx-users