5

I have a class which extends the CompositeConfiguration class from Apache Commons Configuration. I am trying to marshal it to XML using MOXy. I have created an XML adapter that converts the configuration to a list of simple name/value objects.

I have tried using a number of variations on what I have below but am still stymied. I can see my adapter class being loaded and instantiated when I create the JAXB context but it is never called when I marshal the configuration object.

Looking at the MOXy source code, I am beginning to suspect that it is impossible to specify an XML adapter for a Java class that is also a root element. Am I on the right track to getting this working or is there a completely different way to do this?

XML adapter:

public class JAXBConfigurationAdapter extends XmlAdapter<Object, BetterBaseConfiguration>
{

    @Override
    public Object marshal(final BetterBaseConfiguration javaObject) throws Exception
    {
        List<ConfigurationPropertyXmlType> jaxbConfiguration = new ArrayList<>();
        Iterator<String> keys = javaObject.getKeys();
        while (keys.hasNext())
        {
            String key = keys.next();
            ConfigurationPropertyXmlType property = new ConfigurationPropertyXmlType();
            property.setKey(key);
            property.setValue(javaObject.getString(key));
            jaxbConfiguration.add(property);
        }

        return jaxbConfiguration;
    }

    @Override
    public CompositeConfiguration unmarshal(final Object jaxbObject) throws Exception
    {
        BetterBaseConfiguration configuration = new BetterBaseConfiguration();
        for (ConfigurationPropertyXmlType property : (List<ConfigurationPropertyXmlType>) jaxbObject)
        {
            configuration.setProperty(property.getKey(), property.getValue());
        }

        return configuration;
    }

}

Name/value class:

public class ConfigurationPropertyXmlType
{
    private String key;
    private String value;

    public String getKey()
    {
        return key;
    }

    public String getValue()
    {
        return value;
    }

    public void setKey(final String key)
    {
        this.key = key;
    }

    public void setValue(final String value)
    {
        this.value = value;
    }
}

EclipseLink mapping file:

<?xml version="1.0" encoding="UTF-8"?>
<xml-bindings version="2.5" xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
        http://www.eclipse.org/eclipselink/xsds/persistence/oxm http://www.eclipse.org/eclipselink/xsds/eclipselink_oxm_2_5.xsd"
    package-name="myapp.configuration">

    <xml-schema element-form-default="QUALIFIED">
        <xml-ns prefix="mynm" namespace-uri="http://mynamespace" />
    </xml-schema>

    <java-types>
        <java-type name="myapp.configuration.BetterBaseConfiguration" >
            <xml-java-type-adapter value="myapp.configuration.JAXBConfigurationAdapter" type="myapp.configuration.BetterBaseConfiguration" />
            <xml-root-element name="Configuration" />
        </java-type>
    </java-types>

</xml-bindings>

Desired output:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property>
        <name>some name</name>
        <value>some value</value>
    </property>
</configuration>
Jonathan Byrne
  • 193
  • 1
  • 11

1 Answers1

4

EclipseLink MOXy and other JAXB (JSR-222) providers do not apply an XmlAdapter to the root object being marshalled. You can explicitly call the adapter logic before doing a marshal or after doing an unmarshal.

bdoughan
  • 147,609
  • 23
  • 300
  • 400
  • 1
    Thank you very much for verifying that! I was pretty sure that was the case but I could not find documentation of that. – Jonathan Byrne Feb 10 '14 at 16:58
  • I also look for the similar work around. I want to make it marshalled and unmarshalled to the root object only without using any extra dependencies like EclipseLink Moxy other than JAXB, If anything how can explicitly call the adapter logic before doing a marshal or after doing an unmarshal from the root object ? – user3095047 Aug 25 '16 at 09:15