users@jaxb.java.net

Re: runtime (or per-instance) custom unmarshaling

From: arghman <jmsachs_at_gmail.com>
Date: Tue, 7 Jul 2009 08:38:08 -0700 (PDT)

clarifications:

On 7/7/09, arghman <jmsachs_at_gmail.com> wrote:
>> This works fine, but it relies on parseMethod and printMethod being
>> static
>> methods. I would like to use a marshaller/unmarshaller that is a class
>> instance, that I pass into the Unmarshaller or Marshaller.
>
>Pass an (Un)marshaller into itself? Please clarify.

argh, my error... I meant "use a marshal/unmarshal helper object that is a
class instance"

>> Is there a way to
>> do this? (I hope so :-( otherwise I'm stuck) I have read up on XMLAdapter
>> and it looks OK, only it seems to require that the type conversion has
>> already occurred.
>
>It relies on some conversion JAXB knows about, but this could be from a
>string to java.lang.String, and therefore you'd lose nothing.

conundrum... see below.

>>What I want is for my someElement class in Java to have a method:
>>
>> Tag getTag()
>>
>> where Tag is an interface, and I want to install a hook object (an
>> instance
>> of class TagManager in this case) so that the hook object gets to do the
>> unmarshaling from String to Tag, and marshaling from Tag back into
>> String.
>
>Where should this "hook object" be installed? It can't very well be in a
>someElement object, since this is the one being created while the
conversion
>of its attribute "tag" takes place.

"install" was perhaps the wrong word. I want to pass it in as a parameter to
the unmarshaler, or set it as a helper object like Unmarshaller.setListener.

So here's my dilemma.

someElement's tag attribute gets configured in the .xjb file to have a
<jaxb:javaType> of Tag:

<jaxb:javaType name="{mypackage}.Tag"
  parseMethod="{darnit, it needs a static method}"
  printMethod="{darnit, it needs a static method}"
/>

When the .xjb file gets compiled. JAXB creates an Adapter class that uses
the parseMethod and printMethod to create instances of a Tag object from the
attribute string. Ideally I would like to override this behavior with an
object instance that can do the creation of Tag objects from a String.
(Primarily because I have an object that contains a lookup table from String
-> Tag and would like to use the lookup table to instantiate the Tag
objects.)

Right now I have a kludged-together solution. I created a DummyTag class
which implements the Tag interface, but does nothing but return garbage from
Tag's methods and store the String that was contained in the Tag attribute
of the xml file. Then later, after the unmarshalling is all done, I go in
and fixup the "someElement"s to give them a proper Tag field, by doing
something like this:

   for (SomeElement someElement : elements)
   {
     Tag dummyTag = someElement.getTag();
     if (dummyTag instanceof DummyTag)
     {
       String tagAttributeString = ((DummyTag)dummyTag).getString();
       Tag realTag =
myHelperObject.createTagFromAttributeString(tagAttributeString);
       someElement.setTag(realTag);
     }
   }

This appears to work, but it feels kludgey (I don't like mutating the XML
object tree) and I would rather have the "createTagFromAttributeString"
method get called during the unmarshalling process itself, only I can't seem
to figure out how to do this, since there seems to be no way to provide
"myHelperObject" to JAXB.
-- 
View this message in context: http://www.nabble.com/runtime-%28or-per-instance%29-custom-unmarshaling-tp24373874p24375735.html
Sent from the java.net - jaxb users mailing list archive at Nabble.com.