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 + *
    + *
  1. {@link Marshaller#setValidation(boolean)},
  2. + *
  3. {@link Marshaller#setSuppressNamespaces(boolean)},
  4. + *
  5. {@link Marshaller#setSuppressXSIType(boolean)},
  6. + *
  7. {@link Marshaller#setMarshalAsDocument(boolean)},
  8. + *
  9. {@link Marshaller#setRootElement(String)},
  10. + *
  11. {@link Marshaller#setMarshalExtendedType(boolean)},
  12. + *
  13. {@link Marshaller#setNoNamespaceSchemaLocation(String)},
  14. + *
  15. {@link Marshaller#setSchemaLocation(String)} and
  16. + *
  17. {@link Marshaller#setUseXSITypeAtRoot(boolean)}.
  18. + *
+ * 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 + *
    + *
  1. {@link Unmarshaller#setValidation(boolean)}, + *
  2. {@link Unmarshaller#setWhitespacePreserve(boolean)}, + *
  3. {@link Unmarshaller#setIgnoreExtraAttributes(boolean)}, + *
  4. {@link Unmarshaller#setIgnoreExtraElements(boolean)}, + *
  5. {@link Unmarshaller#setClassLoader(ClassLoader)}, + *
  6. {@link Unmarshaller#setObject(Object)}, + *
  7. {@link Unmarshaller#setReuseObjects(boolean)} and + *
  8. {@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