From bd4a08df62d3d47bde6d1d1d1358265036e9335b Mon Sep 17 00:00:00 2001
From: Arjen Poutsma
Date: Thu, 19 May 2011 14:01:35 +0000
Subject: [PATCH] SPR-8296 - Extension for CastorMarshaller - additional
unmarshaller properties
git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@4330 50f2f4bb-b051-0410-bef5-90022cba6387
---
.../oxm/castor/CastorMarshaller.java | 123 +++++++++++++++---
1 file changed, 104 insertions(+), 19 deletions(-)
diff --git a/org.springframework.oxm/src/main/java/org/springframework/oxm/castor/CastorMarshaller.java b/org.springframework.oxm/src/main/java/org/springframework/oxm/castor/CastorMarshaller.java
index 10a83faee5b..218d158147e 100644
--- a/org.springframework.oxm/src/main/java/org/springframework/oxm/castor/CastorMarshaller.java
+++ b/org.springframework.oxm/src/main/java/org/springframework/oxm/castor/CastorMarshaller.java
@@ -45,6 +45,7 @@ import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.ext.LexicalHandler;
+import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import org.springframework.oxm.MarshallingFailureException;
@@ -80,7 +81,7 @@ import org.springframework.util.xml.StaxUtils;
* @see #setMappingLocations(Resource[])
* @since 3.0
*/
-public class CastorMarshaller extends AbstractMarshaller implements InitializingBean {
+public class CastorMarshaller extends AbstractMarshaller implements InitializingBean, BeanClassLoaderAware {
/**
* The default encoding used for stream access: UTF-8.
@@ -125,6 +126,16 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing
private Map processingInstructions;
+ private Map namespaceToPackageMapping;
+
+ private ClassLoader classLoader;
+
+ private Object root;
+
+ private boolean reuseObjects = false;
+
+ private boolean clearCollections = false;
+
/**
* Set the encoding to be used for stream access.
*
@@ -201,7 +212,8 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing
}
/**
- * Set whether the Castor {@link Unmarshaller} should ignore elements that do not match a specific field. Default is
+ * Set whether the Castor {@link Unmarshaller} should ignore elements that do not match a specific field.
Default
+ * is
* false, extra attributes are flagged as an error.
*
* @see org.exolab.castor.xml.Unmarshaller#setIgnoreExtraElements(boolean)
@@ -313,7 +325,8 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing
}
/**
- * Sets the processing instructions that will be used by during marshalling. Keys are the processing targets and values
+ * Sets the processing instructions that will be used by during marshalling. Keys are the processing targets and
+ * values
* contain the processing data.
*
* @see org.exolab.castor.xml.Marshaller#addProcessingInstruction(String, String)
@@ -322,6 +335,48 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing
this.processingInstructions = processingInstructions;
}
+ /**
+ * Set the namespace to package mappings. Property names are represents the namespaces URI, values are packages.
+ *
+ * @see org.exolab.castor.xml.Marshaller#setNamespaceMapping(String, String)
+ */
+ public void setNamespaceToPackageMapping(Map namespaceToPackageMapping) {
+ this.namespaceToPackageMapping = namespaceToPackageMapping;
+ }
+
+ /**
+ * Sets the expected object for the unmarshaller, into which the source will be unmarshalled.
+ *
+ * @see org.exolab.castor.xml.Unmarshaller#setObject(Object)
+ */
+ public void setObject(Object root) {
+ this.root = root;
+ }
+
+ /**
+ * Sets whether this unmarshaller should re-use objects. This will be only used when unmarshalling to existing
+ * object.
The default is {@link false}, which means that the objects won't be re-used.
+ *
+ * @see org.exolab.castor.xml.Unmarshaller#setReuseObjects(boolean)
+ */
+ public void setReuseObjects(boolean reuseObjects) {
+ this.reuseObjects = reuseObjects;
+ }
+
+ /**
+ * Sets whether this unmarshaller should clear collections upon the first use.
The default is {@link false},
+ * which means that marshaller won't clear collections.
+ *
+ * @see org.exolab.castor.xml.Unmarshaller#setClearCollections(boolean)
+ */
+ public void setClearCollections(boolean clearCollections) {
+ this.clearCollections = clearCollections;
+ }
+
+ public void setBeanClassLoader(ClassLoader classLoader) {
+ this.classLoader = classLoader;
+ }
+
public final void afterPropertiesSet() throws CastorMappingException, IOException {
if (logger.isInfoEnabled()) {
if (!ObjectUtils.isEmpty(this.mappingLocations)) {
@@ -439,15 +494,25 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing
}
/**
- * Template method that allows for customizing of the given Castor {@link Marshaller}. The default implementation
- * invokes {@link Marshaller#setValidation(boolean)}, {@link Marshaller#setSuppressNamespaces(boolean)}, {@link
- * Marshaller#setSuppressXSIType(boolean)}, {@link Marshaller#setMarshalAsDocument(boolean)}, {@link
- * Marshaller#setRootElement(String)}, {@link Marshaller#setMarshalExtendedType(boolean)}, {@link
- * Marshaller#setNoNamespaceSchemaLocation(String)}, {@link Marshaller#setSchemaLocation(String)} and {@link
- * Marshaller#setUseXSITypeAtRoot(boolean)}, with the property set on this marshaller, it also calls {@link
- * Marshaller#setNamespaceMapping(String, String)} with the {@linkplain #setNamespaceMappings(java.util.Map) namespace
- * mappings} and {@link Marshaller#addProcessingInstruction(String, String)} with the {@linkplain
- * #setProcessingInstructions(java.util.Map) processing instructions}.
+ * Template method that allows for customizing of the given Castor {@link Marshaller}.
+ *
+ * The default implementation invokes
+ *
+ * - {@link Marshaller#setValidation(boolean)},
+ * - {@link Marshaller#setSuppressNamespaces(boolean)},
+ * - {@link Marshaller#setSuppressXSIType(boolean)},
+ * - {@link Marshaller#setMarshalAsDocument(boolean)},
+ * - {@link Marshaller#setRootElement(String)},
+ * - {@link Marshaller#setMarshalExtendedType(boolean)},
+ * - {@link Marshaller#setNoNamespaceSchemaLocation(String)},
+ * - {@link Marshaller#setSchemaLocation(String)} and
+ * - {@link Marshaller#setUseXSITypeAtRoot(boolean)}.
+ *
+ * with the property set on this marshaller.
+ * It also calls {@link Marshaller#setNamespaceMapping(String, String)}
+ * with the {@linkplain #setNamespaceMappings(java.util.Map) namespace mappings} and
+ * {@link Marshaller#addProcessingInstruction(String, String)} with the
+ * {@linkplain #setProcessingInstructions(java.util.Map) processing instructions}.
*/
protected void customizeMarshaller(Marshaller marshaller) {
marshaller.setValidation(this.validating);
@@ -548,12 +613,21 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing
}
/**
- * Template method that allows for customizing of the given Castor {@link Unmarshaller}. The default
- * implementation invokes {@link Unmarshaller#setValidation(boolean)}, {@link Unmarshaller#setWhitespacePreserve(boolean)},
- * {@link Unmarshaller#setIgnoreExtraAttributes(boolean)}, {@link Unmarshaller#setIgnoreExtraElements(boolean)}, {@link
- * Unmarshaller#setClassLoader(ClassLoader)}, {@link Unmarshaller#setObject(Object)}, {@link
- * Unmarshaller#setReuseObjects(boolean)} and {@link Unmarshaller#setClearCollections(boolean)} with the properties set
- * on this marshaller, it also calls {@link Unmarshaller#addNamespaceToPackageMapping(String, String)} with the
+ * Template method that allows for customizing of the given Castor {@link Unmarshaller}.
+ *
+ * The default implementation invokes
+ *
+ * - {@link Unmarshaller#setValidation(boolean)},
+ *
- {@link Unmarshaller#setWhitespacePreserve(boolean)},
+ *
- {@link Unmarshaller#setIgnoreExtraAttributes(boolean)},
+ *
- {@link Unmarshaller#setIgnoreExtraElements(boolean)},
+ *
- {@link Unmarshaller#setClassLoader(ClassLoader)},
+ *
- {@link Unmarshaller#setObject(Object)},
+ *
- {@link Unmarshaller#setReuseObjects(boolean)} and
+ *
- {@link Unmarshaller#setClearCollections(boolean)}
+ *
+ * with the properties set on this marshaller.
+ * It also calls {@link Unmarshaller#addNamespaceToPackageMapping(String, String)} with the
* {@linkplain #setNamespaceMappings(java.util.Map) namespace to package mapping}.
*/
protected void customizeUnmarshaller(Unmarshaller unmarshaller) {
@@ -561,11 +635,22 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing
unmarshaller.setWhitespacePreserve(this.whitespacePreserve);
unmarshaller.setIgnoreExtraAttributes(this.ignoreExtraAttributes);
unmarshaller.setIgnoreExtraElements(this.ignoreExtraElements);
+ unmarshaller.setClassLoader(classLoader);
+ unmarshaller.setObject(root);
+ unmarshaller.setReuseObjects(reuseObjects);
+ unmarshaller.setClearCollections(clearCollections);
+ if (namespaceToPackageMapping != null) {
+ for (Map.Entry mapping : namespaceToPackageMapping.entrySet()) {
+ unmarshaller.addNamespaceToPackageMapping(mapping.getKey(), mapping.getValue());
+ }
+ }
+
}
/**
* Convert the given XMLException to an appropriate exception from the
- * org.springframework.oxm hierarchy. A boolean flag is used to indicate whether this exception occurs
+ * org.springframework.oxm hierarchy.
A boolean flag is used to indicate whether this exception
+ * occurs
* during marshalling or unmarshalling, since Castor itself does not make this distinction in its exception hierarchy.
*
* @param ex Castor XMLException that occured