[CXF-6074] Add the ability to configure (statefull) XmlAdapters on the JAXB Un-/Marshaller. Commits from Maarten Winkels applied This closes #28 Update DataWriterImpl.java Update JAXBDataBinding.java Update DataReaderImpl.java Update DataReaderImpl.java Update DataWriterImpl.java Update JAXBDataBinding.java Update DataReaderImpl.java Fixed whitespace.
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/4494f4ee Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/4494f4ee Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/4494f4ee Branch: refs/heads/3.0.x-fixes Commit: 4494f4ee6c2391212aecc857cd06e2dcfeabfcb7 Parents: 25f0eb7 Author: Maarten Winkels <[email protected]> Authored: Fri Oct 31 13:31:32 2014 +0100 Committer: Daniel Kulp <[email protected]> Committed: Wed Nov 26 13:53:20 2014 -0500 ---------------------------------------------------------------------- .../org/apache/cxf/jaxb/JAXBDataBinding.java | 12 ++- .../org/apache/cxf/jaxb/io/DataReaderImpl.java | 4 + .../org/apache/cxf/jaxb/io/DataWriterImpl.java | 4 + .../apache/cxf/jaxb/JAXBDataBindingTest.java | 87 +++++++++++++++++++- 4 files changed, 102 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/4494f4ee/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBDataBinding.java ---------------------------------------------------------------------- diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBDataBinding.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBDataBinding.java index cbca739..bae0752 100644 --- a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBDataBinding.java +++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBDataBinding.java @@ -47,6 +47,7 @@ import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import javax.xml.bind.ValidationEventHandler; import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.adapters.XmlAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import javax.xml.namespace.QName; import javax.xml.stream.XMLEventReader; @@ -58,9 +59,7 @@ import javax.xml.transform.dom.DOMSource; import org.w3c.dom.Document; import org.w3c.dom.Node; - import org.xml.sax.InputSource; - import org.apache.cxf.common.injection.NoJSR250Annotations; import org.apache.cxf.common.jaxb.JAXBBeanInfo; import org.apache.cxf.common.jaxb.JAXBContextCache; @@ -192,6 +191,7 @@ public class JAXBDataBinding extends AbstractInterceptorProvidingDataBinding Class<?> cls; private Map<String, Object> contextProperties = Collections.emptyMap(); + private List<XmlAdapter<?, ?>> adapters = Collections.emptyList(); private Map<String, Object> marshallerProperties = Collections.emptyMap(); private Map<String, Object> unmarshallerProperties = Collections.emptyMap(); private Unmarshaller.Listener unmarshallerListener; @@ -514,6 +514,14 @@ public class JAXBDataBinding extends AbstractInterceptorProvidingDataBinding this.contextProperties = contextProperties; } + public List<XmlAdapter<?, ?>> getConfiguredXmlAdapters() { + return adapters; + } + + public void setConfiguredXmlAdapters(List<XmlAdapter<?, ?>> adpters) { + this.adapters = adpters; + } + /** * Return a map of properties. These properties are set into the JAXB * Marshaller (via Marshaller.setProperty(...) when the marshaller is http://git-wip-us.apache.org/repos/asf/cxf/blob/4494f4ee/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/io/DataReaderImpl.java ---------------------------------------------------------------------- diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/io/DataReaderImpl.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/io/DataReaderImpl.java index 31676a3..b08a8b7 100644 --- a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/io/DataReaderImpl.java +++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/io/DataReaderImpl.java @@ -29,6 +29,7 @@ import javax.xml.bind.PropertyException; import javax.xml.bind.Unmarshaller; import javax.xml.bind.ValidationEvent; import javax.xml.bind.ValidationEventHandler; +import javax.xml.bind.annotation.adapters.XmlAdapter; import javax.xml.namespace.QName; import org.apache.cxf.common.i18n.Message; @@ -125,6 +126,9 @@ public class DataReaderImpl<T> extends JAXBDataBase implements DataReader<T> { } um.setSchema(schema); um.setAttachmentUnmarshaller(getAttachmentUnmarshaller()); + for (XmlAdapter<?, ?> adapter : databinding.getConfiguredXmlAdapters()) { + um.setAdapter(adapter); + } return um; } catch (JAXBException ex) { if (ex instanceof javax.xml.bind.UnmarshalException) { http://git-wip-us.apache.org/repos/asf/cxf/blob/4494f4ee/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/io/DataWriterImpl.java ---------------------------------------------------------------------- diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/io/DataWriterImpl.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/io/DataWriterImpl.java index 3479108..d45f664 100644 --- a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/io/DataWriterImpl.java +++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/io/DataWriterImpl.java @@ -34,6 +34,7 @@ import javax.xml.bind.Marshaller; import javax.xml.bind.PropertyException; import javax.xml.bind.ValidationEvent; import javax.xml.bind.ValidationEventHandler; +import javax.xml.bind.annotation.adapters.XmlAdapter; import javax.xml.bind.attachment.AttachmentMarshaller; import org.apache.cxf.common.i18n.Message; @@ -179,6 +180,9 @@ public class DataWriterImpl<T> extends JAXBDataBase implements DataWriter<T> { throw new Fault(new Message("MARSHAL_ERROR", LOG, ex.getMessage()), ex); } } + for (XmlAdapter<?, ?> adapter : databinding.getConfiguredXmlAdapters()) { + marshaller.setAdapter(adapter); + } return marshaller; } http://git-wip-us.apache.org/repos/asf/cxf/blob/4494f4ee/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBDataBindingTest.java ---------------------------------------------------------------------- diff --git a/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBDataBindingTest.java b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBDataBindingTest.java index 791525f..5aeb192 100644 --- a/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBDataBindingTest.java +++ b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBDataBindingTest.java @@ -20,7 +20,9 @@ package org.apache.cxf.jaxb; +import java.io.ByteArrayOutputStream; import java.io.OutputStream; +import java.io.StringReader; import java.io.StringWriter; import java.util.ArrayList; import java.util.Arrays; @@ -36,14 +38,18 @@ import javax.wsdl.Definition; import javax.wsdl.Service; import javax.wsdl.factory.WSDLFactory; import javax.wsdl.xml.WSDLReader; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.adapters.XmlAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLEventWriter; +import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; import org.w3c.dom.Node; - import org.apache.cxf.Bus; import org.apache.cxf.binding.BindingFactoryManager; import org.apache.cxf.common.logging.LogUtils; @@ -60,7 +66,6 @@ import org.apache.hello_world_soap_http.types.GreetMe; import org.apache.hello_world_soap_http.types.GreetMeOneWay; import org.easymock.EasyMock; import org.easymock.IMocksControl; - import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -241,5 +246,81 @@ public class JAXBDataBindingTest extends Assert { } public interface Addressable<T extends AddressEntity<T>> { - } + } + + @Test + public void testConfiguredXmlAdapter() throws Exception { + Language dutch = new Language("nl_NL", "Dutch"); + Language americanEnglish = new Language("en_US", "Americanish"); + + Person person = new Person(dutch); + JAXBDataBinding binding = new JAXBDataBinding(Person.class, Language.class); + binding.setConfiguredXmlAdapters(Arrays.<XmlAdapter<?, ?>>asList(new LanguageAdapter(dutch, americanEnglish))); + DataWriter<OutputStream> writer = binding.createWriter(OutputStream.class); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + writer.write(person, baos); + String output = baos.toString(); + String xml = "<person motherTongue=\"nl_NL\"/>"; + + assertEquals(xml, output); + + DataReader<XMLStreamReader> reader = binding.createReader(XMLStreamReader.class); + Person read = (Person) reader.read(XMLInputFactory.newFactory().createXMLStreamReader(new StringReader(xml))); + + assertEquals(dutch, read.getMotherTongue()); + + } + + @XmlRootElement + public static class Person { + @XmlAttribute + @XmlJavaTypeAdapter(LanguageAdapter.class) + private final Language motherTongue; + public Person() { + this(null); + } + public Person(Language motherTongue) { + this.motherTongue = motherTongue; + } + public Language getMotherTongue() { + return motherTongue; + } + } + + public static class Language { + private final String code; + private final String name; + public Language(String code, String name) { + this.code = code; + this.name = name; + } + public String getCode() { + return code; + } + public String getName() { + return name; + } + } + + public static class LanguageAdapter extends XmlAdapter<String, Language> { + + private Map<String, Language> knownLanguages = new HashMap<String, Language>(); + + public LanguageAdapter(Language... languages) { + for (Language language : languages) { + knownLanguages.put(language.getCode(), language); + } + } + + @Override + public String marshal(Language language) throws Exception { + return language.getCode(); + } + + @Override + public Language unmarshal(String code) throws Exception { + return knownLanguages.get(code); + } + + } }
