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