Browse Source

Backported recent Jaxb2Marshaller changes

Issue: SPR-9152
3.1.x
Juergen Hoeller 14 years ago
parent
commit
3f48c71c77
  1. 92
      org.springframework.oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java

92
org.springframework.oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java

@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
package org.springframework.oxm.jaxb;
import java.awt.*;
import java.awt.Image;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@ -76,6 +76,7 @@ import org.xml.sax.helpers.XMLReaderFactory; @@ -76,6 +76,7 @@ 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;
import org.springframework.core.io.ResourceLoader;
@ -105,6 +106,7 @@ import org.springframework.util.xml.StaxUtils; @@ -105,6 +106,7 @@ import org.springframework.util.xml.StaxUtils;
* listeners, and to refer to it.
*
* @author Arjen Poutsma
* @since 3.0
* @see #setContextPath(String)
* @see #setClassesToBeBound(Class[])
* @see #setJaxbContextProperties(Map)
@ -115,7 +117,6 @@ import org.springframework.util.xml.StaxUtils; @@ -115,7 +117,6 @@ import org.springframework.util.xml.StaxUtils;
* @see #setMarshallerListener(javax.xml.bind.Marshaller.Listener)
* @see #setUnmarshallerListener(javax.xml.bind.Unmarshaller.Listener)
* @see #setAdapters(XmlAdapter[])
* @since 3.0
*/
public class Jaxb2Marshaller
implements MimeMarshaller, MimeUnmarshaller, GenericMarshaller, GenericUnmarshaller, BeanClassLoaderAware,
@ -224,10 +225,10 @@ public class Jaxb2Marshaller @@ -224,10 +225,10 @@ public class Jaxb2Marshaller
}
/**
* Returns the packages to search for JAXB2 annotations.
* Return the packages to search for JAXB2 annotations.
*/
public String[] getPackagesToScan() {
return packagesToScan;
return this.packagesToScan;
}
/**
@ -316,8 +317,7 @@ public class Jaxb2Marshaller @@ -316,8 +317,7 @@ public class Jaxb2Marshaller
}
/**
* Sets the resource resolver, as used to load the schema resources.
*
* Set the resource resolver, as used to load the schema resources.
* @see SchemaFactory#setResourceResolver(org.w3c.dom.ls.LSResourceResolver)
* @see #setSchema(Resource)
* @see #setSchemas(Resource[])
@ -351,7 +351,6 @@ public class Jaxb2Marshaller @@ -351,7 +351,6 @@ public class Jaxb2Marshaller
* <p>This property is typically enabled in combination with usage of classes like
* {@link org.springframework.web.servlet.view.xml.MarshallingView MarshallingView}, since the {@code ModelAndView}
* does not offer type parameter information at runtime.
*
* @see #supports(Class)
* @see #supports(Type)
*/
@ -368,9 +367,9 @@ public class Jaxb2Marshaller @@ -368,9 +367,9 @@ public class Jaxb2Marshaller
}
public final void afterPropertiesSet() throws Exception {
boolean hasContextPath = StringUtils.hasLength(getContextPath());
boolean hasClassesToBeBound = !ObjectUtils.isEmpty(getClassesToBeBound());
boolean hasPackagesToScan = !ObjectUtils.isEmpty(getPackagesToScan());
boolean hasContextPath = StringUtils.hasLength(this.contextPath);
boolean hasClassesToBeBound = !ObjectUtils.isEmpty(this.classesToBeBound);
boolean hasPackagesToScan = !ObjectUtils.isEmpty(this.packagesToScan);
if (hasContextPath && (hasClassesToBeBound || hasPackagesToScan) ||
(hasClassesToBeBound && hasPackagesToScan)) {
@ -392,13 +391,13 @@ public class Jaxb2Marshaller @@ -392,13 +391,13 @@ public class Jaxb2Marshaller
protected synchronized JAXBContext getJaxbContext() {
if (this.jaxbContext == null) {
try {
if (StringUtils.hasLength(getContextPath())) {
if (StringUtils.hasLength(this.contextPath)) {
this.jaxbContext = createJaxbContextFromContextPath();
}
else if (!ObjectUtils.isEmpty(getClassesToBeBound())) {
else if (!ObjectUtils.isEmpty(this.classesToBeBound)) {
this.jaxbContext = createJaxbContextFromClasses();
}
else if (!ObjectUtils.isEmpty(getPackagesToScan())) {
else if (!ObjectUtils.isEmpty(this.packagesToScan)) {
this.jaxbContext = createJaxbContextFromPackages();
}
}
@ -406,27 +405,27 @@ public class Jaxb2Marshaller @@ -406,27 +405,27 @@ public class Jaxb2Marshaller
throw convertJaxbException(ex);
}
}
return jaxbContext;
return this.jaxbContext;
}
private JAXBContext createJaxbContextFromContextPath() throws JAXBException {
if (logger.isInfoEnabled()) {
logger.info("Creating JAXBContext with context path [" + getContextPath() + "]");
logger.info("Creating JAXBContext with context path [" + this.contextPath + "]");
}
if (this.jaxbContextProperties != null) {
if (this.beanClassLoader != null) {
return JAXBContext.newInstance(getContextPath(), this.beanClassLoader, this.jaxbContextProperties);
return JAXBContext.newInstance(this.contextPath, this.beanClassLoader, this.jaxbContextProperties);
}
else {
return JAXBContext.newInstance(getContextPath(), ClassUtils.getDefaultClassLoader(), this.jaxbContextProperties);
return JAXBContext.newInstance(this.contextPath, ClassUtils.getDefaultClassLoader(), this.jaxbContextProperties);
}
}
else {
if (this.beanClassLoader != null) {
return JAXBContext.newInstance(getContextPath(), this.beanClassLoader);
return JAXBContext.newInstance(this.contextPath, this.beanClassLoader);
}
else {
return JAXBContext.newInstance(getContextPath());
return JAXBContext.newInstance(this.contextPath);
}
}
}
@ -434,28 +433,29 @@ public class Jaxb2Marshaller @@ -434,28 +433,29 @@ public class Jaxb2Marshaller
private JAXBContext createJaxbContextFromClasses() throws JAXBException {
if (logger.isInfoEnabled()) {
logger.info("Creating JAXBContext with classes to be bound [" +
StringUtils.arrayToCommaDelimitedString(getClassesToBeBound()) + "]");
StringUtils.arrayToCommaDelimitedString(this.classesToBeBound) + "]");
}
if (this.jaxbContextProperties != null) {
return JAXBContext.newInstance(getClassesToBeBound(), this.jaxbContextProperties);
return JAXBContext.newInstance(this.classesToBeBound, this.jaxbContextProperties);
}
else {
return JAXBContext.newInstance(getClassesToBeBound());
return JAXBContext.newInstance(this.classesToBeBound);
}
}
private JAXBContext createJaxbContextFromPackages() throws JAXBException {
if (logger.isInfoEnabled()) {
logger.info("Creating JAXBContext by scanning packages [" +
StringUtils.arrayToCommaDelimitedString(getPackagesToScan()) + "]");
StringUtils.arrayToCommaDelimitedString(this.packagesToScan) + "]");
}
ClassPathJaxb2TypeScanner scanner = new ClassPathJaxb2TypeScanner(getPackagesToScan());
ClassPathJaxb2TypeScanner scanner = new ClassPathJaxb2TypeScanner(this.packagesToScan);
scanner.setResourceLoader(this.resourceLoader);
scanner.scanPackages();
Class<?>[] jaxb2Classes = scanner.getJaxb2Classes();
if (logger.isDebugEnabled()) {
logger.debug("Found JAXB2 classes: [" + StringUtils.arrayToCommaDelimitedString(jaxb2Classes) + "]");
}
this.classesToBeBound = jaxb2Classes;
if (this.jaxbContextProperties != null) {
return JAXBContext.newInstance(jaxb2Classes, this.jaxbContextProperties);
}
@ -466,7 +466,8 @@ public class Jaxb2Marshaller @@ -466,7 +466,8 @@ public class Jaxb2Marshaller
private Schema loadSchema(Resource[] resources, String schemaLanguage) throws IOException, SAXException {
if (logger.isDebugEnabled()) {
logger.debug("Setting validation schema to " + StringUtils.arrayToCommaDelimitedString(this.schemaResources));
logger.debug("Setting validation schema to " +
StringUtils.arrayToCommaDelimitedString(this.schemaResources));
}
Assert.notEmpty(resources, "No resources given");
Assert.hasLength(schemaLanguage, "No schema language provided");
@ -480,15 +481,15 @@ public class Jaxb2Marshaller @@ -480,15 +481,15 @@ public class Jaxb2Marshaller
schemaSources[i] = new SAXSource(xmlReader, inputSource);
}
SchemaFactory schemaFactory = SchemaFactory.newInstance(schemaLanguage);
if (schemaResourceResolver != null) {
schemaFactory.setResourceResolver(schemaResourceResolver);
if (this.schemaResourceResolver != null) {
schemaFactory.setResourceResolver(this.schemaResourceResolver);
}
return schemaFactory.newSchema(schemaSources);
}
public boolean supports(Class<?> clazz) {
if (supportJaxbElementClass && JAXBElement.class.isAssignableFrom(clazz)) {
if (this.supportJaxbElementClass && JAXBElement.class.isAssignableFrom(clazz)) {
return true;
}
return supportsInternal(clazz, true);
@ -502,10 +503,17 @@ public class Jaxb2Marshaller @@ -502,10 +503,17 @@ public class Jaxb2Marshaller
Type typeArgument = parameterizedType.getActualTypeArguments()[0];
if (typeArgument instanceof Class) {
Class<?> classArgument = (Class<?>) typeArgument;
return (isPrimitiveWrapper(classArgument) || isStandardClass(classArgument) ||
supportsInternal(classArgument, false));
if (JdkVersion.getMajorJavaVersion() >= JdkVersion.JAVA_17 && classArgument.isArray()) {
return classArgument.getComponentType().equals(Byte.TYPE);
}
else {
return (isPrimitiveWrapper(classArgument) || isStandardClass(classArgument) ||
supportsInternal(classArgument, false));
}
}
else if (typeArgument instanceof GenericArrayType) {
else if (JdkVersion.getMajorJavaVersion() <= JdkVersion.JAVA_16 &&
typeArgument instanceof GenericArrayType) {
// see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5041784
GenericArrayType arrayType = (GenericArrayType) typeArgument;
return arrayType.getGenericComponentType().equals(Byte.TYPE);
}
@ -522,9 +530,9 @@ public class Jaxb2Marshaller @@ -522,9 +530,9 @@ public class Jaxb2Marshaller
if (checkForXmlRootElement && AnnotationUtils.findAnnotation(clazz, XmlRootElement.class) == null) {
return false;
}
if (StringUtils.hasLength(getContextPath())) {
if (StringUtils.hasLength(this.contextPath)) {
String packageName = ClassUtils.getPackageName(clazz);
String[] contextPaths = StringUtils.tokenizeToStringArray(getContextPath(), ":");
String[] contextPaths = StringUtils.tokenizeToStringArray(this.contextPath, ":");
for (String contextPath : contextPaths) {
if (contextPath.equals(packageName)) {
return true;
@ -532,8 +540,8 @@ public class Jaxb2Marshaller @@ -532,8 +540,8 @@ public class Jaxb2Marshaller
}
return false;
}
else if (!ObjectUtils.isEmpty(getClassesToBeBound())) {
return Arrays.asList(getClassesToBeBound()).contains(clazz);
else if (!ObjectUtils.isEmpty(this.classesToBeBound)) {
return Arrays.asList(this.classesToBeBound).contains(clazz);
}
return false;
}
@ -700,7 +708,8 @@ public class Jaxb2Marshaller @@ -700,7 +708,8 @@ public class Jaxb2Marshaller
}
/**
* Return a newly created JAXB unmarshaller. JAXB unmarshallers are not necessarily thread safe.
* Return a newly created JAXB unmarshaller.
* Note: JAXB unmarshallers are not necessarily thread-safe.
*/
protected Unmarshaller createUnmarshaller() {
try {
@ -743,7 +752,6 @@ public class Jaxb2Marshaller @@ -743,7 +752,6 @@ public class Jaxb2Marshaller
}
}
/**
* Convert the given <code>JAXBException</code> to an appropriate exception from the
* <code>org.springframework.oxm</code> hierarchy.
@ -810,7 +818,7 @@ public class Jaxb2Marshaller @@ -810,7 +818,7 @@ public class Jaxb2Marshaller
@Override
public String addSwaRefAttachment(DataHandler dataHandler) {
String contentId = UUID.randomUUID() + "@" + dataHandler.getName();
mimeContainer.addAttachment(contentId, dataHandler);
this.mimeContainer.addAttachment(contentId, dataHandler);
return contentId;
}
@ -867,13 +875,13 @@ public class Jaxb2Marshaller @@ -867,13 +875,13 @@ public class Jaxb2Marshaller
*/
private static class ByteArrayDataSource implements DataSource {
private byte[] data;
private final byte[] data;
private String contentType;
private final String contentType;
private int offset;
private final int offset;
private int length;
private final int length;
private ByteArrayDataSource(String contentType, byte[] data, int offset, int length) {
this.contentType = contentType;

Loading…
Cancel
Save