Jaxb2Marshaller doesn't need to depend on ResourceLoaderAware
Issue: SPR-10512
This commit is contained in:
parent
2a53a2de0e
commit
255eab5bed
|
|
@ -88,7 +88,7 @@ configure(allprojects) { project ->
|
|||
"http://aopalliance.sourceforge.net/doc/",
|
||||
"http://glassfish.java.net/nonav/docs/v3/api/",
|
||||
"http://docs.oracle.com/cd/E13222_01/wls/docs90/javadocs/", // commonj
|
||||
"http://quartz-scheduler.org/api/2.1.5/",
|
||||
"http://quartz-scheduler.org/api/2.1.7/",
|
||||
"http://www.eclipse.org/aspectj/doc/released/aspectj5rt-api/",
|
||||
"http://fasterxml.github.com/jackson-core/javadoc/2.2.0/",
|
||||
"http://jackson.codehaus.org/1.9.12/javadoc/",
|
||||
|
|
@ -340,7 +340,7 @@ project("spring-oxm") {
|
|||
dependencies {
|
||||
compile(project(":spring-beans"))
|
||||
compile(project(":spring-core"))
|
||||
optional(project(":spring-context")) // for Jaxb2Marshaller
|
||||
testCompile(project(":spring-context"))
|
||||
optional("com.thoughtworks.xstream:xstream:1.4.4")
|
||||
optional("org.jibx:jibx-run:1.2.5")
|
||||
optional("org.apache.xmlbeans:xmlbeans:2.6.0")
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* 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.
|
||||
|
|
@ -25,10 +25,8 @@ import javax.xml.bind.annotation.XmlSeeAlso;
|
|||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
import org.springframework.core.io.support.ResourcePatternUtils;
|
||||
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
|
||||
import org.springframework.core.type.classreading.MetadataReader;
|
||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||
|
|
@ -42,62 +40,54 @@ import org.springframework.util.ClassUtils;
|
|||
* Helper class for {@link Jaxb2Marshaller} that scans given packages for classes marked with JAXB2 annotations.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Juergen Hoeller
|
||||
* @author David Harrigan
|
||||
* @since 3.1.1
|
||||
* @see #scanPackages()
|
||||
*/
|
||||
class ClassPathJaxb2TypeScanner {
|
||||
|
||||
private static final String RESOURCE_PATTERN = "/**/*.class";
|
||||
|
||||
private final TypeFilter[] jaxb2TypeFilters =
|
||||
new TypeFilter[]{new AnnotationTypeFilter(XmlRootElement.class, false),
|
||||
new AnnotationTypeFilter(XmlType.class, false), new AnnotationTypeFilter(XmlSeeAlso.class, false),
|
||||
new AnnotationTypeFilter(XmlEnum.class, false)};
|
||||
private static final TypeFilter[] JAXB2_TYPE_FILTERS = new TypeFilter[] {
|
||||
new AnnotationTypeFilter(XmlRootElement.class, false), new AnnotationTypeFilter(XmlType.class, false),
|
||||
new AnnotationTypeFilter(XmlSeeAlso.class, false), new AnnotationTypeFilter(XmlEnum.class, false)};
|
||||
|
||||
|
||||
private final ResourcePatternResolver resourcePatternResolver;
|
||||
|
||||
private final String[] packagesToScan;
|
||||
|
||||
private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
|
||||
|
||||
private List<Class<?>> jaxb2Classes = new ArrayList<Class<?>>();
|
||||
|
||||
/** Constructs a new {@code ClassPathJaxb2TypeScanner} for the given packages. */
|
||||
ClassPathJaxb2TypeScanner(String[] packagesToScan) {
|
||||
public ClassPathJaxb2TypeScanner(ClassLoader classLoader, String... packagesToScan) {
|
||||
Assert.notEmpty(packagesToScan, "'packagesToScan' must not be empty");
|
||||
this.resourcePatternResolver = new PathMatchingResourcePatternResolver(classLoader);
|
||||
this.packagesToScan = packagesToScan;
|
||||
}
|
||||
|
||||
void setResourceLoader(ResourceLoader resourceLoader) {
|
||||
if (resourceLoader != null) {
|
||||
this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the JAXB2 classes found in the specified packages. */
|
||||
Class<?>[] getJaxb2Classes() {
|
||||
return jaxb2Classes.toArray(new Class<?>[jaxb2Classes.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans the packages for classes marked with JAXB2 annotations.
|
||||
*
|
||||
* Scan the packages for classes marked with JAXB2 annotations.
|
||||
* @throws UncategorizedMappingException in case of errors
|
||||
*/
|
||||
void scanPackages() throws UncategorizedMappingException {
|
||||
public Class<?>[] scanPackages() throws UncategorizedMappingException {
|
||||
try {
|
||||
for (String packageToScan : packagesToScan) {
|
||||
List<Class<?>> jaxb2Classes = new ArrayList<Class<?>>();
|
||||
for (String packageToScan : this.packagesToScan) {
|
||||
String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
|
||||
ClassUtils.convertClassNameToResourcePath(packageToScan) + RESOURCE_PATTERN;
|
||||
Resource[] resources = resourcePatternResolver.getResources(pattern);
|
||||
MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resourcePatternResolver);
|
||||
Resource[] resources = this.resourcePatternResolver.getResources(pattern);
|
||||
MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(this.resourcePatternResolver);
|
||||
for (Resource resource : resources) {
|
||||
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
|
||||
if (isJaxb2Class(metadataReader, metadataReaderFactory)) {
|
||||
String className = metadataReader.getClassMetadata().getClassName();
|
||||
Class<?> jaxb2AnnotatedClass = resourcePatternResolver.getClassLoader().loadClass(className);
|
||||
Class<?> jaxb2AnnotatedClass = this.resourcePatternResolver.getClassLoader().loadClass(className);
|
||||
jaxb2Classes.add(jaxb2AnnotatedClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
return jaxb2Classes.toArray(new Class<?>[jaxb2Classes.size()]);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new UncategorizedMappingException("Failed to scan classpath for unlisted classes", ex);
|
||||
|
|
@ -107,8 +97,8 @@ class ClassPathJaxb2TypeScanner {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean isJaxb2Class(MetadataReader reader, MetadataReaderFactory factory) throws IOException {
|
||||
for (TypeFilter filter : jaxb2TypeFilters) {
|
||||
protected boolean isJaxb2Class(MetadataReader reader, MetadataReaderFactory factory) throws IOException {
|
||||
for (TypeFilter filter : JAXB2_TYPE_FILTERS) {
|
||||
if (filter.match(reader, factory)) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -116,5 +106,4 @@ class ClassPathJaxb2TypeScanner {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,7 +75,6 @@ import org.xml.sax.helpers.XMLReaderFactory;
|
|||
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.ResourceLoaderAware;
|
||||
import org.springframework.core.JdkVersion;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
|
@ -119,9 +118,8 @@ import org.springframework.util.xml.StaxUtils;
|
|||
* @see #setUnmarshallerListener(javax.xml.bind.Unmarshaller.Listener)
|
||||
* @see #setAdapters(XmlAdapter[])
|
||||
*/
|
||||
public class Jaxb2Marshaller
|
||||
implements MimeMarshaller, MimeUnmarshaller, GenericMarshaller, GenericUnmarshaller, BeanClassLoaderAware,
|
||||
ResourceLoaderAware, InitializingBean {
|
||||
public class Jaxb2Marshaller implements MimeMarshaller, MimeUnmarshaller, GenericMarshaller, GenericUnmarshaller,
|
||||
BeanClassLoaderAware, InitializingBean {
|
||||
|
||||
private static final String CID = "cid:";
|
||||
|
||||
|
|
@ -177,8 +175,8 @@ public class Jaxb2Marshaller
|
|||
|
||||
|
||||
/**
|
||||
* Set multiple JAXB context paths. The given array of context paths is converted to a
|
||||
* colon-delimited string, as supported by JAXB.
|
||||
* Set multiple JAXB context paths. The given array of context paths gets
|
||||
* converted to a colon-delimited string, as supported by JAXB.
|
||||
*/
|
||||
public void setContextPaths(String... contextPaths) {
|
||||
Assert.notEmpty(contextPaths, "'contextPaths' must not be empty");
|
||||
|
|
@ -187,8 +185,8 @@ public class Jaxb2Marshaller
|
|||
|
||||
/**
|
||||
* Set a JAXB context path.
|
||||
* <p>Setting this property, {@link #setClassesToBeBound "classesToBeBound"}, or
|
||||
* {@link #setPackagesToScan "packagesToScan"} is required.
|
||||
* <p>Setting either this property, {@link #setClassesToBeBound "classesToBeBound"}
|
||||
* or {@link #setPackagesToScan "packagesToScan"} is required.
|
||||
*/
|
||||
public void setContextPath(String contextPath) {
|
||||
Assert.hasText(contextPath, "'contextPath' must not be null");
|
||||
|
|
@ -204,8 +202,8 @@ public class Jaxb2Marshaller
|
|||
|
||||
/**
|
||||
* Set the list of Java classes to be recognized by a newly created JAXBContext.
|
||||
* <p>Setting this property, {@link #setContextPath "contextPath"}, or
|
||||
* {@link #setPackagesToScan "packagesToScan"} is required.
|
||||
* <p>Setting either this property, {@link #setContextPath "contextPath"}
|
||||
* or {@link #setPackagesToScan "packagesToScan"} is required.
|
||||
*/
|
||||
public void setClassesToBeBound(Class<?>... classesToBeBound) {
|
||||
Assert.notEmpty(classesToBeBound, "'classesToBeBound' must not be empty");
|
||||
|
|
@ -220,10 +218,11 @@ public class Jaxb2Marshaller
|
|||
}
|
||||
|
||||
/**
|
||||
* Set the packages to search using Spring-based scanning for classes with JAXB2 annotations in the classpath.
|
||||
* <p>Setting this property, {@link #setContextPath "contextPath"}, or
|
||||
* {@link #setClassesToBeBound "classesToBeBound"} is required. This is analogous to Spring's component-scan feature
|
||||
* ({@link org.springframework.context.annotation.ClassPathBeanDefinitionScanner}).
|
||||
* Set the packages to search for classes with JAXB2 annotations in the classpath.
|
||||
* This is using a Spring-bases search and therefore analogous to Spring's component-scan
|
||||
* feature ({@link org.springframework.context.annotation.ClassPathBeanDefinitionScanner}).
|
||||
* <p>Setting either this property, {@link #setContextPath "contextPath"}
|
||||
* or {@link #setClassesToBeBound "classesToBeBound"} is required.
|
||||
*/
|
||||
public void setPackagesToScan(String[] packagesToScan) {
|
||||
this.packagesToScan = packagesToScan;
|
||||
|
|
@ -390,12 +389,8 @@ public class Jaxb2Marshaller
|
|||
this.beanClassLoader = classLoader;
|
||||
}
|
||||
|
||||
public void setResourceLoader(ResourceLoader resourceLoader) {
|
||||
this.resourceLoader = resourceLoader;
|
||||
}
|
||||
|
||||
|
||||
public final void afterPropertiesSet() throws Exception {
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
boolean hasContextPath = StringUtils.hasLength(this.contextPath);
|
||||
boolean hasClassesToBeBound = !ObjectUtils.isEmpty(this.classesToBeBound);
|
||||
boolean hasPackagesToScan = !ObjectUtils.isEmpty(this.packagesToScan);
|
||||
|
|
@ -487,10 +482,8 @@ public class Jaxb2Marshaller
|
|||
logger.info("Creating JAXBContext by scanning packages [" +
|
||||
StringUtils.arrayToCommaDelimitedString(this.packagesToScan) + "]");
|
||||
}
|
||||
ClassPathJaxb2TypeScanner scanner = new ClassPathJaxb2TypeScanner(this.packagesToScan);
|
||||
scanner.setResourceLoader(this.resourceLoader);
|
||||
scanner.scanPackages();
|
||||
Class<?>[] jaxb2Classes = scanner.getJaxb2Classes();
|
||||
ClassPathJaxb2TypeScanner scanner = new ClassPathJaxb2TypeScanner(this.beanClassLoader, this.packagesToScan);
|
||||
Class<?>[] jaxb2Classes = scanner.scanPackages();
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Found JAXB2 classes: [" + StringUtils.arrayToCommaDelimitedString(jaxb2Classes) + "]");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue