2

I'm starting with some Java classes that I would like to be able to unmarshall from XML--I'm determining the schema as I go. I would like to use XML similar to the following:

<Person fname="John" lname="Doe">
  <bio><foo xmlns="http://proprietary.foo">Blah <bar>blah</bar> blah</foo></bio>
</Person>

I'm hoping to annontate my Java classes similar to the following:

public class Person {
  @XmlAttribute
  public String fname;

  @XmlAttribute
  public String lname;

  @XmlElement
  public ProprietaryFoo bio;
}

I'd like to pass the <foo xmlns="http://proprietary.foo"> element and it's descendants to a compiled factory class which works like this:

FooFactory.getFooFromDomNode(myFooElement) // Returns a private ProprietaryFooImpl as an instance of the public ProprietaryFoo Interface

It seems like I need to create a DomHandler for ProprietaryFoo but I'm not quite able to figure it out (I was getting “com.xyz.ProprietaryFooImpl nor any of its super class is known to this context.") I'm also interested in XmlJavaTypeAdapter I can't figure out how to receive the ValueType as an Element.

bdoughan
  • 147,609
  • 23
  • 300
  • 400

1 Answers1

2

Ended up using both an XmlAdapter and a DomHandler along with a simple Wrapper class.

public class FooWrapper {
    @XmlAnyElement(FooDomHandler.class)
    public ProprietaryFoo foo;
}

public class FooXmlAdapter extends XmlAdapter<FooWrapper, ProprietaryFoo> {
    @Override
    public ProprietaryFoo unmarshal(FooWrapper w) throws Exception {
        return w.foo;
    }

    @Override
    public FooWrapper marshal(ProprietaryFoo f) throws Exception {
        FooWrapper fooWrapper = new FooWrapper();
        fooWrapper.foo = f;
        return fooWrapper;
    }
}

/* The vendor also provides a ProprietaryFooResult class that extends SAXResult */
public class FooDomHandler implements DomHandler<ProprietaryFoo, ProprietaryFooResult> {

    @Override
    public ProprietaryFooResult createUnmarshaller(ValidationEventHandler validationEventHandler) {
        return new ProprietaryFooResult();
    }

    @Override
    public ProprietaryFoo getElement(ProprietaryFooResult r) {
        return r.getProprietaryFoo();
    }

    @Override
    public Source marshal(ProprietaryFoo f, ValidationEventHandler validationEventHandler) {
        return f.asSaxSource();
    }
}

For whatever reason, this didn't work with the standard classes from the com.sun namespace but MOXy handles it well.