/*
 * Copyright 2002-2018 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.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.oxm.castor;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.Map;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLStreamReader;
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;
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.lang.Nullable;
import org.springframework.oxm.MarshallingFailureException;
import org.springframework.oxm.UncategorizedMappingException;
import org.springframework.oxm.UnmarshallingFailureException;
import org.springframework.oxm.ValidationFailureException;
import org.springframework.oxm.XmlMappingException;
import org.springframework.oxm.support.AbstractMarshaller;
import org.springframework.oxm.support.SaxResourceUtils;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.xml.DomUtils;
import org.springframework.util.xml.StaxUtils;

Implementation of the 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 setTargetClass, the 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 setMappingLocations.

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

Author:Arjen Poutsma, Jakub Narloch, Juergen Hoeller
See Also:
Since:3.0
Deprecated:as of Spring Framework 4.3.13, due to the lack of activity on the Castor project
/** * 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. * * <p>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}. * * <p>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[]) * @deprecated as of Spring Framework 4.3.13, due to the lack of activity on the Castor project */
@Deprecated public class CastorMarshaller extends AbstractMarshaller implements InitializingBean, BeanClassLoaderAware {
The default encoding used for stream access: UTF-8.
/** * The default encoding used for stream access: UTF-8. */
public static final String DEFAULT_ENCODING = "UTF-8"; @Nullable private Resource[] mappingLocations; private String encoding = DEFAULT_ENCODING; @Nullable private Class<?>[] targetClasses; @Nullable private String[] targetPackages; private boolean validating = false; private boolean suppressNamespaces = false; private boolean suppressXsiType = false; private boolean marshalAsDocument = true; private boolean marshalExtendedType = true; @Nullable private String rootElement; @Nullable private String noNamespaceSchemaLocation; @Nullable private String schemaLocation; private boolean useXSITypeAtRoot = false; private boolean whitespacePreserve = false; private boolean ignoreExtraAttributes = true; private boolean ignoreExtraElements = false; @Nullable private Object rootObject; private boolean reuseObjects = false; private boolean clearCollections = false; @Nullable private Map<String, String> castorProperties; @Nullable private Map<String, String> doctypes; @Nullable private Map<String, String> processingInstructions; @Nullable private Map<String, String> namespaceMappings; @Nullable private Map<String, String> namespaceToPackageMapping; @Nullable private EntityResolver entityResolver; @Nullable private XMLClassDescriptorResolver classDescriptorResolver; @Nullable private IDResolver idResolver; @Nullable private ObjectFactory objectFactory; @Nullable private ClassLoader beanClassLoader; @Nullable private XMLContext xmlContext;
Set the encoding to be used for stream access.
See Also:
  • DEFAULT_ENCODING
/** * Set the encoding to be used for stream access. * @see #DEFAULT_ENCODING */
public void setEncoding(String encoding) { this.encoding = encoding; } @Override protected String getDefaultEncoding() { return this.encoding; }
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}; }
Set the locations of the Castor XML mapping files.
/** * Set the locations of the Castor XML mapping files. */
public void setMappingLocations(Resource... mappingLocations) { this.mappingLocations = mappingLocations; }
Set the Castor target class.
See Also:
/** * Set the Castor target class. * @see #setTargetPackage * @see #setMappingLocation */
public void setTargetClass(Class<?> targetClass) { this.targetClasses = new Class<?>[] {targetClass}; }
Set the Castor target classes.
See Also:
/** * Set the Castor target classes. * @see #setTargetPackages * @see #setMappingLocations */
public void setTargetClasses(Class<?>... targetClasses) { this.targetClasses = targetClasses; }
Set the name of a package with the Castor descriptor classes.
/** * Set the name of a package with the Castor descriptor classes. */
public void setTargetPackage(String targetPackage) { this.targetPackages = new String[] {targetPackage}; }
Set the names of packages with the Castor descriptor classes.
/** * Set the names of packages with the Castor descriptor classes. */
public void setTargetPackages(String... targetPackages) { this.targetPackages = targetPackages; }
Set whether this marshaller should validate in- and outgoing documents.

Default is false.

See Also:
/** * Set whether this marshaller should validate in- and outgoing documents. * <p>Default is {@code false}. * @see Marshaller#setValidation(boolean) */
public void setValidating(boolean validating) { this.validating = validating; }
Sets whether this marshaller should output namespaces.

The default is false, i.e. namespaces are written.

See Also:
/** * Sets whether this marshaller should output namespaces. * <p>The default is {@code false}, i.e. namespaces are written. * @see org.exolab.castor.xml.Marshaller#setSuppressNamespaces(boolean) */
public void setSuppressNamespaces(boolean suppressNamespaces) { this.suppressNamespaces = suppressNamespaces; }
Set whether this marshaller should output the xsi:type attribute.

The default is false, i.e. the xsi:type is written.

See Also:
/** * Set whether this marshaller should output the {@code xsi:type} attribute. * <p>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) { this.suppressXsiType = suppressXsiType; }
Set whether this marshaller should output the xml declaration.

The default is true, the XML declaration will be written.

See Also:
/** * Set whether this marshaller should output the xml declaration. * <p>The default is {@code true}, the XML declaration will be written. * @see org.exolab.castor.xml.Marshaller#setMarshalAsDocument(boolean) */
public void setMarshalAsDocument(boolean marshalAsDocument) { this.marshalAsDocument = marshalAsDocument; }
Set whether this marshaller should output for given type the xsi:type attribute.

The default is true, the xsi:type attribute will be written.

See Also:
/** * Set whether this marshaller should output for given type the {@code xsi:type} attribute. * <p>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) { this.marshalExtendedType = marshalExtendedType; }
Set the name of the root element.
See Also:
  • setRootElement.setRootElement(String)
/** * 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 xsi:noNamespaceSchemaLocation attribute. When set, the xsi:noNamespaceSchemaLocation attribute will be written for the root element.
See Also:
/** * 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) { this.noNamespaceSchemaLocation = noNamespaceSchemaLocation; }
Set the value of xsi:schemaLocation attribute. When set, the xsi:schemaLocation attribute will be written for the root element.
See Also:
/** * 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) { this.schemaLocation = schemaLocation; }
Sets whether this marshaller should output the 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 false: The xsi:type attribute for the root element won't be written.

See Also:
/** * 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. * <p>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) { this.useXSITypeAtRoot = useXSITypeAtRoot; }
Set whether the Castor Unmarshaller should preserve "ignorable" whitespace.

Default is false.

See Also:
/** * Set whether the Castor {@link Unmarshaller} should preserve "ignorable" whitespace. * <p>Default is {@code false}. * @see org.exolab.castor.xml.Unmarshaller#setWhitespacePreserve(boolean) */
public void setWhitespacePreserve(boolean whitespacePreserve) { this.whitespacePreserve = whitespacePreserve; }
Set whether the Castor Unmarshaller should ignore attributes that do not match a specific field.

Default is true: Extra attributes are ignored.

See Also:
/** * Set whether the Castor {@link Unmarshaller} should ignore attributes that do not match a specific field. * <p>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 Unmarshaller should ignore elements that do not match a specific field.

Default is false: Extra elements are flagged as an error.

See Also:
/** * Set whether the Castor {@link Unmarshaller} should ignore elements that do not match a specific field. * <p>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 Also:
  • setObject.setObject(Object)
/** * 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 setRootObject(Object root) { this.rootObject = root; }
Set whether this unmarshaller should re-use objects. This will be only used when unmarshalling to an existing object.

The default is false, which means that the objects won't be re-used.

See Also:
/** * Set whether this unmarshaller should re-use objects. * This will be only used when unmarshalling to an existing object. * <p>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) { this.reuseObjects = reuseObjects; }
Sets whether this unmarshaller should clear collections upon the first use.

The default is false which means that marshaller won't clear collections.

See Also:
/** * Sets whether this unmarshaller should clear collections upon the first use. * <p>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; }
Set Castor-specific properties for marshalling and unmarshalling. Each entry key is considered the property name and each value the property value.
See Also:
/** * 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<String, String> castorProperties) { this.castorProperties = castorProperties; }
Set the map containing document type definition for the marshaller. Each entry has system id as key and public id as value.
See Also:
  • setDoctype.setDoctype(String, String)
/** * 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<String, String> 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 Also:
  • addProcessingInstruction.addProcessingInstruction(String, String)
/** * 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<String, String> processingInstructions) { this.processingInstructions = processingInstructions; }
Set the namespace mappings. Property names are interpreted as namespace prefixes; values are namespace URIs.
See Also:
  • setNamespaceMapping.setNamespaceMapping(String, String)
/** * 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<String, String> namespaceMappings) { this.namespaceMappings = namespaceMappings; }
Set the namespace to package mappings. Property names are represents the namespaces URI, values are packages.
See Also:
  • setNamespaceMapping.setNamespaceMapping(String, String)
/** * 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<String, String> namespaceToPackageMapping) { this.namespaceToPackageMapping = namespaceToPackageMapping; }
Set the EntityResolver to be used during unmarshalling. This resolver will used to resolve system and public ids.
See Also:
/** * 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 XMLClassDescriptorResolver to be used during unmarshalling. This resolver will used to resolve class descriptors.
See Also:
/** * 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 IDResolver to be used during unmarshalling.
See Also:
/** * 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 ObjectFactory to be used during unmarshalling.
See Also:
/** * 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; } @Override public void setBeanClassLoader(ClassLoader classLoader) { this.beanClassLoader = classLoader; } @Override public void afterPropertiesSet() throws CastorMappingException, IOException { try { this.xmlContext = createXMLContext(this.mappingLocations, this.targetClasses, this.targetPackages); } catch (MappingException ex) { throw new CastorMappingException("Could not load Castor mapping", ex); } catch (ResolverException ex) { throw new CastorMappingException("Could not resolve Castor mapping", ex); } }
Create the Castor 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.

Throws:
See Also:
Returns:the created resolver
/** * Create the Castor {@code XMLContext}. Subclasses can override this to create a custom context. * <p>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 * @see XMLContext#addMapping(org.exolab.castor.mapping.Mapping) * @see XMLContext#addClass(Class) */
protected XMLContext createXMLContext(@Nullable Resource[] mappingLocations, @Nullable Class<?>[] targetClasses, @Nullable String[] targetPackages) throws MappingException, ResolverException, IOException { XMLContext context = new XMLContext(); if (!ObjectUtils.isEmpty(mappingLocations)) { Mapping mapping = new Mapping(); for (Resource mappingLocation : mappingLocations) { mapping.loadMapping(SaxResourceUtils.createInputSource(mappingLocation)); } context.addMapping(mapping); } if (!ObjectUtils.isEmpty(targetClasses)) { context.addClasses(targetClasses); } if (!ObjectUtils.isEmpty(targetPackages)) { context.addPackages(targetPackages); } if (this.castorProperties != null) { this.castorProperties.forEach(context::setProperty); } return context; }
Returns true for all classes, i.e. Castor supports arbitrary classes.
/** * Returns {@code true} for all classes, i.e. Castor supports arbitrary classes. */
@Override public boolean supports(Class<?> clazz) { return true; } // Marshalling @Override protected void marshalDomNode(Object graph, Node node) throws XmlMappingException { marshalSaxHandlers(graph, DomUtils.createContentHandler(node), null); } @Override protected void marshalXmlEventWriter(Object graph, XMLEventWriter eventWriter) throws XmlMappingException { ContentHandler contentHandler = StaxUtils.createContentHandler(eventWriter); LexicalHandler lexicalHandler = null; if (contentHandler instanceof LexicalHandler) { lexicalHandler = (LexicalHandler) contentHandler; } marshalSaxHandlers(graph, contentHandler, lexicalHandler); } @Override protected void marshalXmlStreamWriter(Object graph, XMLStreamWriter streamWriter) throws XmlMappingException { ContentHandler contentHandler = StaxUtils.createContentHandler(streamWriter); LexicalHandler lexicalHandler = null; if (contentHandler instanceof LexicalHandler) { lexicalHandler = (LexicalHandler) contentHandler; } marshalSaxHandlers(graph, StaxUtils.createContentHandler(streamWriter), lexicalHandler); } @Override protected void marshalSaxHandlers(Object graph, ContentHandler contentHandler, @Nullable LexicalHandler lexicalHandler) throws XmlMappingException { Assert.state(this.xmlContext != null, "CastorMarshaller not initialized"); Marshaller marshaller = this.xmlContext.createMarshaller(); marshaller.setContentHandler(contentHandler); doMarshal(graph, marshaller); } @Override protected void marshalOutputStream(Object graph, OutputStream outputStream) throws XmlMappingException, IOException { marshalWriter(graph, new OutputStreamWriter(outputStream, this.encoding)); } @Override protected void marshalWriter(Object graph, Writer writer) throws XmlMappingException, IOException { Assert.state(this.xmlContext != null, "CastorMarshaller not initialized"); Marshaller marshaller = this.xmlContext.createMarshaller(); marshaller.setWriter(writer); doMarshal(graph, marshaller); } private void doMarshal(Object graph, Marshaller marshaller) { try { customizeMarshaller(marshaller); marshaller.marshal(graph); } catch (XMLException ex) { throw convertCastorException(ex, true); } }
Template method that allows for customizing of the given Castor Marshaller.
/** * Template method that allows for customizing of the given Castor {@link Marshaller}. */
protected void customizeMarshaller(Marshaller marshaller) { marshaller.setValidation(this.validating); 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) { this.doctypes.forEach(marshaller::setDoctype); } if (this.processingInstructions != null) { this.processingInstructions.forEach(marshaller::addProcessingInstruction); } if (this.namespaceMappings != null) { this.namespaceMappings.forEach(marshaller::setNamespaceMapping); } } // Unmarshalling @Override protected Object unmarshalDomNode(Node node) throws XmlMappingException { try { return createUnmarshaller().unmarshal(node); } catch (XMLException ex) { throw convertCastorException(ex, false); } } @Override protected Object unmarshalXmlEventReader(XMLEventReader eventReader) { try { return createUnmarshaller().unmarshal(eventReader); } catch (XMLException ex) { throw convertCastorException(ex, false); } } @Override protected Object unmarshalXmlStreamReader(XMLStreamReader streamReader) { try { return createUnmarshaller().unmarshal(streamReader); } catch (XMLException ex) { throw convertCastorException(ex, false); } } @Override protected Object unmarshalSaxReader(XMLReader xmlReader, InputSource inputSource) throws XmlMappingException, IOException { UnmarshalHandler unmarshalHandler = createUnmarshaller().createHandler(); try { ContentHandler contentHandler = Unmarshaller.getContentHandler(unmarshalHandler); xmlReader.setContentHandler(contentHandler); xmlReader.parse(inputSource); return unmarshalHandler.getObject(); } catch (SAXException ex) { throw new UnmarshallingFailureException("SAX reader exception", ex); } } @Override protected Object unmarshalInputStream(InputStream inputStream) throws XmlMappingException, IOException { try { return createUnmarshaller().unmarshal(new InputSource(inputStream)); } catch (XMLException ex) { throw convertCastorException(ex, false); } } @Override protected Object unmarshalReader(Reader reader) throws XmlMappingException, IOException { try { return createUnmarshaller().unmarshal(new InputSource(reader)); } catch (XMLException ex) { throw convertCastorException(ex, false); } } private Unmarshaller createUnmarshaller() { Assert.state(this.xmlContext != null, "CastorMarshaller not initialized"); Unmarshaller unmarshaller = this.xmlContext.createUnmarshaller(); customizeUnmarshaller(unmarshaller); return unmarshaller; }
Template method that allows for customizing of the given Castor Unmarshaller.
/** * Template method that allows for customizing of the given Castor {@link Unmarshaller}. */
protected void customizeUnmarshaller(Unmarshaller unmarshaller) { unmarshaller.setValidation(this.validating); unmarshaller.setWhitespacePreserve(this.whitespacePreserve); unmarshaller.setIgnoreExtraAttributes(this.ignoreExtraAttributes); unmarshaller.setIgnoreExtraElements(this.ignoreExtraElements); unmarshaller.setObject(this.rootObject); unmarshaller.setReuseObjects(this.reuseObjects); unmarshaller.setClearCollections(this.clearCollections); if (this.namespaceToPackageMapping != null) { this.namespaceToPackageMapping.forEach(unmarshaller::addNamespaceToPackageMapping); } 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 XMLException to an appropriate exception from the 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.

Params:
  • ex – the Castor XMLException that occurred
  • marshalling – indicates whether the exception occurs during marshalling (true), or unmarshalling (false)
Returns:the corresponding XmlMappingException
/** * Convert the given {@code XMLException} to an appropriate exception from the * {@code org.springframework.oxm} hierarchy. * <p>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 the Castor {@code XMLException} that occurred * @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) { if (ex instanceof ValidationException) { return new ValidationFailureException("Castor validation exception", ex); } else if (ex instanceof MarshalException) { if (marshalling) { return new MarshallingFailureException("Castor marshalling exception", ex); } else { return new UnmarshallingFailureException("Castor unmarshalling exception", ex); } } else { // fallback return new UncategorizedMappingException("Unknown Castor exception", ex); } } }