Fix Jaxb2TypeScanner to scan for @XmlRegistry
Update ClassPathJaxb2TypeScanner to scan for @XmlRegistry classes. Prior to this commit explicitly configured @XmlRegistry annotated classes were not registered with the JAXBContext when using the 'packagesToScan' property of the Jaxb2Unmarshaller. Issue: SPR-10714
This commit is contained in:
parent
5a0e42b76e
commit
4f871d4448
|
@ -19,7 +19,9 @@ package org.springframework.oxm.jaxb;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlEnum;
|
import javax.xml.bind.annotation.XmlEnum;
|
||||||
|
import javax.xml.bind.annotation.XmlRegistry;
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
import javax.xml.bind.annotation.XmlSeeAlso;
|
import javax.xml.bind.annotation.XmlSeeAlso;
|
||||||
import javax.xml.bind.annotation.XmlType;
|
import javax.xml.bind.annotation.XmlType;
|
||||||
|
@ -42,6 +44,7 @@ import org.springframework.util.ClassUtils;
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @author David Harrigan
|
* @author David Harrigan
|
||||||
|
* @author Biju Kunjummen
|
||||||
* @since 3.1.1
|
* @since 3.1.1
|
||||||
* @see #scanPackages()
|
* @see #scanPackages()
|
||||||
*/
|
*/
|
||||||
|
@ -50,8 +53,11 @@ class ClassPathJaxb2TypeScanner {
|
||||||
private static final String RESOURCE_PATTERN = "/**/*.class";
|
private static final String RESOURCE_PATTERN = "/**/*.class";
|
||||||
|
|
||||||
private static final TypeFilter[] JAXB2_TYPE_FILTERS = new TypeFilter[] {
|
private static final TypeFilter[] JAXB2_TYPE_FILTERS = new TypeFilter[] {
|
||||||
new AnnotationTypeFilter(XmlRootElement.class, false), new AnnotationTypeFilter(XmlType.class, false),
|
new AnnotationTypeFilter(XmlRootElement.class, false),
|
||||||
new AnnotationTypeFilter(XmlSeeAlso.class, false), new AnnotationTypeFilter(XmlEnum.class, false)};
|
new AnnotationTypeFilter(XmlType.class, false),
|
||||||
|
new AnnotationTypeFilter(XmlSeeAlso.class, false),
|
||||||
|
new AnnotationTypeFilter(XmlEnum.class, false),
|
||||||
|
new AnnotationTypeFilter(XmlRegistry.class, false)};
|
||||||
|
|
||||||
|
|
||||||
private final ResourcePatternResolver resourcePatternResolver;
|
private final ResourcePatternResolver resourcePatternResolver;
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2013 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.oxm.jaxb;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
@XmlRootElement
|
||||||
|
public class Airplane {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -51,10 +51,15 @@ import org.xml.sax.Attributes;
|
||||||
import org.xml.sax.ContentHandler;
|
import org.xml.sax.ContentHandler;
|
||||||
import org.xml.sax.Locator;
|
import org.xml.sax.Locator;
|
||||||
|
|
||||||
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
|
||||||
import static org.mockito.BDDMockito.*;
|
import static org.mockito.BDDMockito.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Arjen Poutsma
|
||||||
|
* @author Biju Kunjummen
|
||||||
|
*/
|
||||||
public class Jaxb2MarshallerTests extends AbstractMarshallerTests {
|
public class Jaxb2MarshallerTests extends AbstractMarshallerTests {
|
||||||
|
|
||||||
private static final String CONTEXT_PATH = "org.springframework.oxm.jaxb.test";
|
private static final String CONTEXT_PATH = "org.springframework.oxm.jaxb.test";
|
||||||
|
@ -281,6 +286,21 @@ public class Jaxb2MarshallerTests extends AbstractMarshallerTests {
|
||||||
verify(mimeContainer, times(3)).addAttachment(isA(String.class), isA(DataHandler.class));
|
verify(mimeContainer, times(3)).addAttachment(isA(String.class), isA(DataHandler.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void marshalAWrappedObjectHoldingAnXmlElementDeclElement() throws Exception {
|
||||||
|
// SPR-10714
|
||||||
|
marshaller = new Jaxb2Marshaller();
|
||||||
|
marshaller.setPackagesToScan(new String[] { "org.springframework.oxm.jaxb" });
|
||||||
|
marshaller.afterPropertiesSet();
|
||||||
|
Airplane airplane = new Airplane();
|
||||||
|
airplane.setName("test");
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
Result result = new StreamResult(writer);
|
||||||
|
marshaller.marshal(airplane, result);
|
||||||
|
assertXMLEqual("Marshalling should use root Element",
|
||||||
|
writer.toString(), "<airplane><name>test</name></airplane>");
|
||||||
|
}
|
||||||
|
|
||||||
@XmlRootElement
|
@XmlRootElement
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public static class DummyRootElement {
|
public static class DummyRootElement {
|
||||||
|
|
|
@ -39,6 +39,10 @@ import org.springframework.util.xml.StaxUtils;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
import static org.mockito.BDDMockito.*;
|
import static org.mockito.BDDMockito.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Arjen Poutsma
|
||||||
|
* @author Biju Kunjummen
|
||||||
|
*/
|
||||||
public class Jaxb2UnmarshallerTests extends AbstractUnmarshallerTests {
|
public class Jaxb2UnmarshallerTests extends AbstractUnmarshallerTests {
|
||||||
|
|
||||||
private static final String INPUT_STRING = "<tns:flights xmlns:tns=\"http://samples.springframework.org/flight\">" +
|
private static final String INPUT_STRING = "<tns:flights xmlns:tns=\"http://samples.springframework.org/flight\">" +
|
||||||
|
@ -104,6 +108,7 @@ public class Jaxb2UnmarshallerTests extends AbstractUnmarshallerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Override
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public void unmarshalPartialStaxSourceXmlStreamReader() throws Exception {
|
public void unmarshalPartialStaxSourceXmlStreamReader() throws Exception {
|
||||||
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
|
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
|
||||||
XMLStreamReader streamReader = inputFactory.createXMLStreamReader(new StringReader(INPUT_STRING));
|
XMLStreamReader streamReader = inputFactory.createXMLStreamReader(new StringReader(INPUT_STRING));
|
||||||
|
@ -115,5 +120,18 @@ public class Jaxb2UnmarshallerTests extends AbstractUnmarshallerTests {
|
||||||
testFlight(flight);
|
testFlight(flight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void unmarshalAnXmlReferingToAWrappedXmlElementDecl() throws Exception {
|
||||||
|
// SPR-10714
|
||||||
|
unmarshaller = new Jaxb2Marshaller();
|
||||||
|
unmarshaller.setPackagesToScan(new String[] { "org.springframework.oxm.jaxb" });
|
||||||
|
unmarshaller.afterPropertiesSet();
|
||||||
|
Source source = new StreamSource(new StringReader(
|
||||||
|
"<brand-airplane><name>test</name></brand-airplane>"));
|
||||||
|
JAXBElement<Airplane> airplane = (JAXBElement<Airplane>) unmarshaller.unmarshal(source);
|
||||||
|
assertEquals("Unmarshalling via explicit @XmlRegistry tag should return correct type",
|
||||||
|
"test", airplane.getValue().getName());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
package org.springframework.oxm.jaxb;
|
||||||
|
|
||||||
|
import javax.xml.bind.JAXBElement;
|
||||||
|
import javax.xml.bind.annotation.XmlElementDecl;
|
||||||
|
import javax.xml.bind.annotation.XmlRegistry;
|
||||||
|
import javax.xml.namespace.QName;
|
||||||
|
|
||||||
|
@XmlRegistry
|
||||||
|
public class XmlRegObjectFactory {
|
||||||
|
|
||||||
|
@XmlElementDecl(name = "brand-airplane")
|
||||||
|
public JAXBElement<Airplane> createAirplane(Airplane airplane) {
|
||||||
|
return new JAXBElement<Airplane>(new QName("brand-airplane"), Airplane.class, null, airplane);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue