diff --git a/spring-oxm/src/main/java/org/springframework/oxm/castor/CastorMarshaller.java b/spring-oxm/src/main/java/org/springframework/oxm/castor/CastorMarshaller.java index 0405e8272e..131b782c87 100644 --- a/spring-oxm/src/main/java/org/springframework/oxm/castor/CastorMarshaller.java +++ b/spring-oxm/src/main/java/org/springframework/oxm/castor/CastorMarshaller.java @@ -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. @@ -30,16 +30,20 @@ import javax.xml.stream.XMLStreamWriter; import org.exolab.castor.mapping.Mapping; import org.exolab.castor.mapping.MappingException; +import org.exolab.castor.util.ObjectFactory; +import org.exolab.castor.xml.IDResolver; import org.exolab.castor.xml.MarshalException; import org.exolab.castor.xml.Marshaller; import org.exolab.castor.xml.ResolverException; import org.exolab.castor.xml.UnmarshalHandler; import org.exolab.castor.xml.Unmarshaller; import org.exolab.castor.xml.ValidationException; +import org.exolab.castor.xml.XMLClassDescriptorResolver; import org.exolab.castor.xml.XMLContext; import org.exolab.castor.xml.XMLException; import org.w3c.dom.Node; import org.xml.sax.ContentHandler; +import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; @@ -56,30 +60,30 @@ import org.springframework.oxm.XmlMappingException; import org.springframework.oxm.support.AbstractMarshaller; import org.springframework.oxm.support.SaxResourceUtils; import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; import org.springframework.util.xml.DomUtils; import org.springframework.util.xml.StaxUtils; /** - * Implementation of the {@code Marshaller} interface for Castor. By default, Castor does not require any further - * configuration, though setting target classes, target packages or providing a mapping file can be used to have more - * control over the behavior of Castor. + * Implementation of the {@code Marshaller} interface for Castor. By default, Castor does + * not require any further configuration, though setting target classes, target packages or + * providing a mapping file can be used to have more control over the behavior of Castor. * - *

If a target class is specified using {@code setTargetClass}, the {@code CastorMarshaller} can only be - * used to unmarshal XML that represents that specific class. If you want to unmarshal multiple classes, you have to - * provide a mapping file using {@code setMappingLocations}. + *

If a target class is specified using {@code setTargetClass}, the {@code CastorMarshaller} + * can only be used to unmarshal XML that represents that specific class. If you want to unmarshal + * multiple classes, you have to provide a mapping file using {@code setMappingLocations}. * - *

Due to limitations of Castor's API, it is required to set the encoding used for writing to output streams. It - * defaults to {@code UTF-8}. + *

Due to limitations of Castor's API, it is required to set the encoding used for + * writing to output streams. It defaults to {@code UTF-8}. * * @author Arjen Poutsma * @author Jakub Narloch + * @author Juergen Hoeller + * @since 3.0 * @see #setEncoding(String) * @see #setTargetClass(Class) * @see #setTargetPackages(String[]) * @see #setMappingLocation(Resource) * @see #setMappingLocations(Resource[]) - * @since 3.0 */ public class CastorMarshaller extends AbstractMarshaller implements InitializingBean, BeanClassLoaderAware { @@ -88,6 +92,7 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing */ public static final String DEFAULT_ENCODING = "UTF-8"; + private Resource[] mappingLocations; private String encoding = DEFAULT_ENCODING; @@ -98,47 +103,59 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing private boolean validating = false; - private boolean whitespacePreserve = false; - - private boolean ignoreExtraAttributes = true; - - private boolean ignoreExtraElements = false; - - private Map namespaceMappings; - - private XMLContext xmlContext; - private boolean suppressNamespaces = false; private boolean suppressXsiType = false; private boolean marshalAsDocument = true; - private String rootElement; - private boolean marshalExtendedType = true; + private String rootElement; + private String noNamespaceSchemaLocation; private String schemaLocation; private boolean useXSITypeAtRoot = false; - private Map processingInstructions; + private boolean whitespacePreserve = false; - private Map namespaceToPackageMapping; + private boolean ignoreExtraAttributes = true; - private ClassLoader classLoader; + private boolean ignoreExtraElements = false; - private Object root; + private Object rootObject; private boolean reuseObjects = false; private boolean clearCollections = false; + private Map castorProperties; + + private Map doctypes; + + private Map processingInstructions; + + private Map namespaceMappings; + + private Map namespaceToPackageMapping; + + private EntityResolver entityResolver; + + private XMLClassDescriptorResolver classDescriptorResolver; + + private IDResolver idResolver; + + private ObjectFactory objectFactory; + + private ClassLoader beanClassLoader; + + private XMLContext xmlContext; + + /** * Set the encoding to be used for stream access. - * * @see #DEFAULT_ENCODING */ public void setEncoding(String encoding) { @@ -146,7 +163,7 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing } /** - * Set the locations of the Castor XML Mapping files. + * Set the locations of the Castor XML mapping files. */ public void setMappingLocation(Resource mappingLocation) { this.mappingLocations = new Resource[]{mappingLocation}; @@ -190,8 +207,8 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing } /** - * Set whether this marshaller should validate in- and outgoing documents.

Default is {@code false}. - * + * Set whether this marshaller should validate in- and outgoing documents. + *

Default is {@code false}. * @see Marshaller#setValidation(boolean) */ public void setValidating(boolean validating) { @@ -199,55 +216,8 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing } /** - * Set whether the Castor {@link Unmarshaller} should preserve "ignorable" whitespace.

Default is - * {@code false}. - * - * @see org.exolab.castor.xml.Unmarshaller#setWhitespacePreserve(boolean) - */ - public void setWhitespacePreserve(boolean whitespacePreserve) { - this.whitespacePreserve = whitespacePreserve; - } - - /** - * Set whether the Castor {@link Unmarshaller} should ignore attributes that do not match a specific field.

Default - * is {@code true}: extra attributes are ignored. - * - * @see org.exolab.castor.xml.Unmarshaller#setIgnoreExtraAttributes(boolean) - */ - public void setIgnoreExtraAttributes(boolean ignoreExtraAttributes) { - this.ignoreExtraAttributes = ignoreExtraAttributes; - } - - /** - * Set whether the Castor {@link Unmarshaller} should ignore elements that do not match a specific field.

Default - * is - * {@code false}, extra attributes are flagged as an error. - * - * @see org.exolab.castor.xml.Unmarshaller#setIgnoreExtraElements(boolean) - */ - public void setIgnoreExtraElements(boolean ignoreExtraElements) { - this.ignoreExtraElements = ignoreExtraElements; - } - - /** - * Set the namespace mappings. Property names are interpreted as namespace prefixes; values are namespace URIs. - * - * @see org.exolab.castor.xml.Marshaller#setNamespaceMapping(String, String) - */ - public void setNamespaceMappings(Map namespaceMappings) { - this.namespaceMappings = namespaceMappings; - } - - /** - * Returns whether this marshaller should output namespaces. - */ - public boolean isSuppressNamespaces() { - return suppressNamespaces; - } - - /** - * Sets whether this marshaller should output namespaces. The default is {@code false}, i.e. namespaces are written. - * + * Sets whether this marshaller should output namespaces. + *

The default is {@code false}, i.e. namespaces are written. * @see org.exolab.castor.xml.Marshaller#setSuppressNamespaces(boolean) */ public void setSuppressNamespaces(boolean suppressNamespaces) { @@ -255,16 +225,8 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing } /** - * Sets whether this marshaller should output the xsi:type attribute. - */ - public boolean isSuppressXsiType() { - return suppressXsiType; - } - - /** - * Sets whether this marshaller should output the {@code xsi:type} attribute. The default is {@code false}, i.e. the - * {@code xsi:type} is written. - * + * Set whether this marshaller should output the {@code xsi:type} attribute. + *

The default is {@code false}, i.e. the {@code xsi:type} is written. * @see org.exolab.castor.xml.Marshaller#setSuppressXSIType(boolean) */ public void setSuppressXsiType(boolean suppressXsiType) { @@ -272,9 +234,8 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing } /** - * Sets whether this marshaller should output the xml declaration.

The default is {@code true}, the xml - * declaration will be written. - * + * Set whether this marshaller should output the xml declaration. + *

The default is {@code true}, the XML declaration will be written. * @see org.exolab.castor.xml.Marshaller#setMarshalAsDocument(boolean) */ public void setMarshalAsDocument(boolean marshalAsDocument) { @@ -282,18 +243,8 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing } /** - * Sets the name of the root element. - * - * @see org.exolab.castor.xml.Marshaller#setRootElement(String) - */ - public void setRootElement(String rootElement) { - this.rootElement = rootElement; - } - - /** - * Sets whether this marshaller should output for given type the {@code xsi:type} attribute.

The default is {@code - * true}, the {@code xsi:type} attribute will be written. - * + * Set whether this marshaller should output for given type the {@code xsi:type} attribute. + *

The default is {@code true}, the {@code xsi:type} attribute will be written. * @see org.exolab.castor.xml.Marshaller#setMarshalExtendedType(boolean) */ public void setMarshalExtendedType(boolean marshalExtendedType) { @@ -301,9 +252,16 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing } /** - * Sets the value of {@code xsi:noNamespaceSchemaLocation} attribute. When set, the {@code - * xsi:noNamespaceSchemaLocation} attribute will be written for the root element. - * + * Set the name of the root element. + * @see org.exolab.castor.xml.Marshaller#setRootElement(String) + */ + public void setRootElement(String rootElement) { + this.rootElement = rootElement; + } + + /** + * Set the value of {@code xsi:noNamespaceSchemaLocation} attribute. When set, the + * {@code xsi:noNamespaceSchemaLocation} attribute will be written for the root element. * @see org.exolab.castor.xml.Marshaller#setNoNamespaceSchemaLocation(String) */ public void setNoNamespaceSchemaLocation(String noNamespaceSchemaLocation) { @@ -311,9 +269,8 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing } /** - * Sets the value of {@code xsi:schemaLocation} attribute.When set, the {@code xsi:schemaLocation} attribute will be - * written for the root element. - * + * Set the value of {@code xsi:schemaLocation} attribute. When set, the + * {@code xsi:schemaLocation} attribute will be written for the root element. * @see org.exolab.castor.xml.Marshaller#setSchemaLocation(String) */ public void setSchemaLocation(String schemaLocation) { @@ -321,10 +278,9 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing } /** - * Sets whether this marshaller should output the {@code xsi:type} attribute for the root element. This can be useful - * when the type of the element can not be simply determined from the element name.

The default is {@code false}, - * the {@code xsi:type} attribute for the root element won't be written. - * + * Sets whether this marshaller should output the {@code xsi:type} attribute for the root element. + * This can be useful when the type of the element can not be simply determined from the element name. + *

The default is {@code false}: The {@code xsi:type} attribute for the root element won't be written. * @see org.exolab.castor.xml.Marshaller#setUseXSITypeAtRoot(boolean) */ public void setUseXSITypeAtRoot(boolean useXSITypeAtRoot) { @@ -332,38 +288,54 @@ 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 - * contain the processing data. - * - * @see org.exolab.castor.xml.Marshaller#addProcessingInstruction(String, String) + * Set whether the Castor {@link Unmarshaller} should preserve "ignorable" whitespace. + *

Default is {@code false}. + * @see org.exolab.castor.xml.Unmarshaller#setWhitespacePreserve(boolean) */ - public void setProcessingInstructions(Map processingInstructions) { - this.processingInstructions = processingInstructions; + public void setWhitespacePreserve(boolean whitespacePreserve) { + this.whitespacePreserve = whitespacePreserve; } /** - * 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) + * Set whether the Castor {@link Unmarshaller} should ignore attributes that do not match a specific field. + *

Default is {@code true}: Extra attributes are ignored. + * @see org.exolab.castor.xml.Unmarshaller#setIgnoreExtraAttributes(boolean) */ - public void setNamespaceToPackageMapping(Map namespaceToPackageMapping) { - this.namespaceToPackageMapping = namespaceToPackageMapping; + public void setIgnoreExtraAttributes(boolean ignoreExtraAttributes) { + this.ignoreExtraAttributes = ignoreExtraAttributes; } /** - * Sets the expected object for the unmarshaller, into which the source will be unmarshalled. - * + * Set whether the Castor {@link Unmarshaller} should ignore elements that do not match a specific field. + *

Default is {@code false}: Extra elements are flagged as an error. + * @see org.exolab.castor.xml.Unmarshaller#setIgnoreExtraElements(boolean) + */ + public void setIgnoreExtraElements(boolean ignoreExtraElements) { + this.ignoreExtraElements = ignoreExtraElements; + } + + /** + * Set the expected root object for the unmarshaller, into which the source will be unmarshalled. + * @see org.exolab.castor.xml.Unmarshaller#setObject(Object) + * @deprecated in favor of {@link #setRootObject} + */ + @Deprecated + public void setObject(Object root) { + this.rootObject = root; + } + + /** + * Set the expected root 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; + public void setRootObject(Object root) { + this.rootObject = root; } /** - * Sets whether this unmarshaller should re-use objects. This will be only used when unmarshalling to existing - * object.

The default is {@code false}, which means that the objects won't be re-used. - * + * Set whether this unmarshaller should re-use objects. + * This will be only used when unmarshalling to an existing object. + *

The default is {@code false}, which means that the objects won't be re-used. * @see org.exolab.castor.xml.Unmarshaller#setReuseObjects(boolean) */ public void setReuseObjects(boolean reuseObjects) { @@ -371,39 +343,99 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing } /** - * Sets whether this unmarshaller should clear collections upon the first use.

The default is {@code false}, - * which means that marshaller won't clear collections. - * + * Sets whether this unmarshaller should clear collections upon the first use. + *

The default is {@code 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; + /** + * Set Castor-specific properties for marshalling and unmarshalling. + * Each entry key is considered the property name and each value the property value. + * @see org.exolab.castor.xml.Marshaller#setProperty(String, String) + * @see org.exolab.castor.xml.Unmarshaller#setProperty(String, String) + */ + public void setCastorProperties(Map castorProperties) { + this.castorProperties = castorProperties; } - public final void afterPropertiesSet() throws CastorMappingException, IOException { - if (logger.isInfoEnabled()) { - if (!ObjectUtils.isEmpty(this.mappingLocations)) { - logger.info( - "Configured using [" + StringUtils.arrayToCommaDelimitedString(this.mappingLocations) + "]"); - } - if (!ObjectUtils.isEmpty(this.targetClasses)) { - logger.info("Configured for target classes " + StringUtils.arrayToCommaDelimitedString(targetClasses) + - "]"); - } - if (!ObjectUtils.isEmpty(this.targetPackages)) { - logger.info( - "Configured for target packages [" + StringUtils.arrayToCommaDelimitedString(targetPackages) + - "]"); - } - if (ObjectUtils.isEmpty(this.mappingLocations) && ObjectUtils.isEmpty(this.targetClasses) && - ObjectUtils.isEmpty(this.targetPackages)) { - logger.info("Using default configuration"); - } - } + /** + * Set the map containing document type definition for the marshaller. + * Each entry has system id as key and public id as value. + * @see org.exolab.castor.xml.Marshaller#setDoctype(String, String) + */ + public void setDoctypes(Map doctypes) { + this.doctypes = doctypes; + } + + /** + * 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) + */ + public void setProcessingInstructions(Map processingInstructions) { + this.processingInstructions = processingInstructions; + } + + /** + * Set the namespace mappings. + * Property names are interpreted as namespace prefixes; values are namespace URIs. + * @see org.exolab.castor.xml.Marshaller#setNamespaceMapping(String, String) + */ + public void setNamespaceMappings(Map namespaceMappings) { + this.namespaceMappings = namespaceMappings; + } + + /** + * 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; + } + + /** + * Set the {@link EntityResolver} to be used during unmarshalling. + * This resolver will used to resolve system and public ids. + * @see org.exolab.castor.xml.Unmarshaller#setEntityResolver(EntityResolver) + */ + public void setEntityResolver(EntityResolver entityResolver) { + this.entityResolver = entityResolver; + } + + /** + * Set the {@link XMLClassDescriptorResolver} to be used during unmarshalling. + * This resolver will used to resolve class descriptors. + * @see org.exolab.castor.xml.Unmarshaller#setResolver(XMLClassDescriptorResolver) + */ + public void setClassDescriptorResolver(XMLClassDescriptorResolver classDescriptorResolver) { + this.classDescriptorResolver = classDescriptorResolver; + } + + /** + * Set the Castor {@link IDResolver} to be used during unmarshalling. + * @see org.exolab.castor.xml.Unmarshaller#setIDResolver(IDResolver) + */ + public void setIdResolver(IDResolver idResolver) { + this.idResolver = idResolver; + } + + /** + * Set the Castor {@link ObjectFactory} to be used during unmarshalling. + * @see org.exolab.castor.xml.Unmarshaller#setObjectFactory(ObjectFactory) + */ + public void setObjectFactory(ObjectFactory objectFactory) { + this.objectFactory = objectFactory; + } + + public void setBeanClassLoader(ClassLoader classLoader) { + this.beanClassLoader = classLoader; + } + + + public void afterPropertiesSet() throws CastorMappingException, IOException { try { this.xmlContext = createXMLContext(this.mappingLocations, this.targetClasses, this.targetPackages); } @@ -416,9 +448,8 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing } /** - * Create the Castor {@code XMLContext}. Subclasses can override this to create a custom context.

The default - * implementation loads mapping files if defined, or the target class or packages if defined. - * + * Create the Castor {@code XMLContext}. Subclasses can override this to create a custom context. + *

The default implementation loads mapping files if defined, or the target class or packages if defined. * @return the created resolver * @throws MappingException when the mapping file cannot be loaded * @throws IOException in case of I/O errors @@ -442,9 +473,15 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing if (!ObjectUtils.isEmpty(targetPackages)) { context.addPackages(targetPackages); } + if (this.castorProperties != null) { + for (Map.Entry property : this.castorProperties.entrySet()) { + context.setProperty(property.getKey(), property.getValue()); + } + } return context; } + /** * Returns {@code true} for all classes, i.e. Castor supports arbitrary classes. */ @@ -462,6 +499,7 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing @Override protected final void marshalSaxHandlers(Object graph, ContentHandler contentHandler, LexicalHandler lexicalHandler) throws XmlMappingException { + Marshaller marshaller = xmlContext.createMarshaller(); marshaller.setContentHandler(contentHandler); marshal(graph, marshaller); @@ -470,6 +508,7 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing @Override protected final void marshalOutputStream(Object graph, OutputStream outputStream) throws XmlMappingException, IOException { + marshalWriter(graph, new OutputStreamWriter(outputStream, encoding)); } @@ -502,42 +541,29 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing /** * 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); - marshaller.setSuppressNamespaces(isSuppressNamespaces()); - marshaller.setSuppressXSIType(isSuppressXsiType()); - marshaller.setMarshalAsDocument(marshalAsDocument); - marshaller.setRootElement(rootElement); - marshaller.setMarshalExtendedType(marshalExtendedType); - marshaller.setNoNamespaceSchemaLocation(noNamespaceSchemaLocation); - marshaller.setSchemaLocation(schemaLocation); - marshaller.setUseXSITypeAtRoot(useXSITypeAtRoot); - if (processingInstructions != null) { - for (Map.Entry processingInstruction : processingInstructions.entrySet()) { + marshaller.setSuppressNamespaces(this.suppressNamespaces); + marshaller.setSuppressXSIType(this.suppressXsiType); + marshaller.setMarshalAsDocument(this.marshalAsDocument); + marshaller.setMarshalExtendedType(this.marshalExtendedType); + marshaller.setRootElement(this.rootElement); + marshaller.setNoNamespaceSchemaLocation(this.noNamespaceSchemaLocation); + marshaller.setSchemaLocation(this.schemaLocation); + marshaller.setUseXSITypeAtRoot(this.useXSITypeAtRoot); + if (this.doctypes != null) { + for (Map.Entry doctype : this.doctypes.entrySet()) { + marshaller.setDoctype(doctype.getKey(), doctype.getValue()); + } + } + if (this.processingInstructions != null) { + for (Map.Entry processingInstruction : this.processingInstructions.entrySet()) { marshaller.addProcessingInstruction(processingInstruction.getKey(), processingInstruction.getValue()); } } if (this.namespaceMappings != null) { - for (Map.Entry entry : namespaceMappings.entrySet()) { + for (Map.Entry entry : this.namespaceMappings.entrySet()) { marshaller.setNamespaceMapping(entry.getKey(), entry.getValue()); } } @@ -619,48 +645,45 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing /** * 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) { unmarshaller.setValidation(this.validating); 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.setObject(this.rootObject); + unmarshaller.setReuseObjects(this.reuseObjects); + unmarshaller.setClearCollections(this.clearCollections); + if (this.namespaceToPackageMapping != null) { + for (Map.Entry mapping : this.namespaceToPackageMapping.entrySet()) { unmarshaller.addNamespaceToPackageMapping(mapping.getKey(), mapping.getValue()); } } - + if (this.entityResolver != null) { + unmarshaller.setEntityResolver(this.entityResolver); + } + if (this.classDescriptorResolver != null) { + unmarshaller.setResolver(this.classDescriptorResolver); + } + if (this.idResolver != null) { + unmarshaller.setIDResolver(this.idResolver); + } + if (this.objectFactory != null) { + unmarshaller.setObjectFactory(this.objectFactory); + } + if (this.beanClassLoader != null) { + unmarshaller.setClassLoader(this.beanClassLoader); + } } /** * Convert the given {@code XMLException} to an appropriate exception from the - * {@code 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. - * + * {@code 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 {@code XMLException} that occurred - * @param marshalling indicates whether the exception occurs during marshalling ({@code true}), or unmarshalling - * ({@code false}) + * @param marshalling indicates whether the exception occurs during marshalling ({@code true}), + * or unmarshalling ({@code false}) * @return the corresponding {@code XmlMappingException} */ protected XmlMappingException convertCastorException(XMLException ex, boolean marshalling) { diff --git a/spring-oxm/src/test/java/org/springframework/oxm/castor/CastorUnmarshallerTests.java b/spring-oxm/src/test/java/org/springframework/oxm/castor/CastorUnmarshallerTests.java index 367b4aa5c1..585640893b 100644 --- a/spring-oxm/src/test/java/org/springframework/oxm/castor/CastorUnmarshallerTests.java +++ b/spring-oxm/src/test/java/org/springframework/oxm/castor/CastorUnmarshallerTests.java @@ -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. @@ -30,12 +30,9 @@ import org.springframework.oxm.MarshallingException; import org.springframework.oxm.Unmarshaller; import static org.hamcrest.CoreMatchers.*; - import static org.junit.Assert.*; /** - * Tests the {@link CastorMarshaller} class. - * * @author Arjen Poutsma * @author Jakub Narloch */ @@ -114,7 +111,6 @@ public class CastorUnmarshallerTests extends AbstractUnmarshallerTests { @Test public void testWhitespacePreserveTrue() throws Exception { - getCastorUnmarshaller().setWhitespacePreserve(true); Object result = unmarshalFlights(); testFlights(result); @@ -122,7 +118,6 @@ public class CastorUnmarshallerTests extends AbstractUnmarshallerTests { @Test public void testWhitespacePreserveFalse() throws Exception { - getCastorUnmarshaller().setWhitespacePreserve(false); Object result = unmarshalFlights(); testFlights(result); @@ -130,7 +125,6 @@ public class CastorUnmarshallerTests extends AbstractUnmarshallerTests { @Test public void testIgnoreExtraAttributesTrue() throws Exception { - getCastorUnmarshaller().setIgnoreExtraAttributes(true); Object result = unmarshal(EXTRA_ATTRIBUTES_STRING); testFlights(result); @@ -146,7 +140,6 @@ public class CastorUnmarshallerTests extends AbstractUnmarshallerTests { @Test @Ignore("Not working yet") public void testIgnoreExtraElementsTrue() throws Exception { - getCastorUnmarshaller().setIgnoreExtraElements(true); getCastorUnmarshaller().setValidating(false); Object result = unmarshal(EXTRA_ELEMENTS_STRING); @@ -161,22 +154,19 @@ public class CastorUnmarshallerTests extends AbstractUnmarshallerTests { } @Test - public void testObject() throws Exception { - + public void testRootObject() throws Exception { Flights flights = new Flights(); - getCastorUnmarshaller().setObject(flights); + getCastorUnmarshaller().setRootObject(flights); Object result = unmarshalFlights(); - testFlights(result); assertSame("Result Flights is different object.", flights, result); } @Test public void testClearCollectionsTrue() throws Exception { - Flights flights = new Flights(); flights.setFlight(new Flight[]{new Flight()}); - getCastorUnmarshaller().setObject(flights); + getCastorUnmarshaller().setRootObject(flights); getCastorUnmarshaller().setClearCollections(true); Object result = unmarshalFlights(); @@ -188,10 +178,9 @@ public class CastorUnmarshallerTests extends AbstractUnmarshallerTests { @Test @Ignore("Fails on the builder server for some reason") public void testClearCollectionsFalse() throws Exception { - Flights flights = new Flights(); flights.setFlight(new Flight[]{new Flight(), null}); - getCastorUnmarshaller().setObject(flights); + getCastorUnmarshaller().setRootObject(flights); getCastorUnmarshaller().setClearCollections(false); Object result = unmarshalFlights();