19 changed files with 14 additions and 1686 deletions
@ -1 +0,0 @@
@@ -1 +0,0 @@
|
||||
org.exolab.castor.builder.primitivetowrapper=true |
||||
@ -1,42 +0,0 @@
@@ -1,42 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2017 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 org.springframework.oxm.XmlMappingException; |
||||
|
||||
/** |
||||
* Exception thrown by {@link CastorMarshaller} whenever it encounters a mapping problem. |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 3.0 |
||||
* @deprecated as of Spring Framework 4.3.13, due to the lack of activity on the Castor project |
||||
*/ |
||||
@Deprecated |
||||
@SuppressWarnings("serial") |
||||
public class CastorMappingException extends XmlMappingException { |
||||
|
||||
/** |
||||
* Construct a {@code CastorMappingException} with the specified detail message |
||||
* and nested exception. |
||||
* @param msg the detail message |
||||
* @param cause the nested exception |
||||
*/ |
||||
public CastorMappingException(String msg, Throwable cause) { |
||||
super(msg, cause); |
||||
} |
||||
|
||||
} |
||||
@ -1,734 +0,0 @@
@@ -1,734 +0,0 @@
|
||||
/* |
||||
* 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 {@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. |
||||
*/ |
||||
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 #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. |
||||
*/ |
||||
public void setMappingLocation(Resource mappingLocation) { |
||||
this.mappingLocations = new Resource[]{mappingLocation}; |
||||
} |
||||
|
||||
/** |
||||
* Set the locations of the Castor XML mapping files. |
||||
*/ |
||||
public void setMappingLocations(Resource... mappingLocations) { |
||||
this.mappingLocations = mappingLocations; |
||||
} |
||||
|
||||
/** |
||||
* 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 #setTargetPackages |
||||
* @see #setMappingLocations |
||||
*/ |
||||
public void setTargetClasses(Class<?>... targetClasses) { |
||||
this.targetClasses = targetClasses; |
||||
} |
||||
|
||||
/** |
||||
* 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. |
||||
*/ |
||||
public void setTargetPackages(String... targetPackages) { |
||||
this.targetPackages = targetPackages; |
||||
} |
||||
|
||||
/** |
||||
* 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. |
||||
* <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 {@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. |
||||
* <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 {@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 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) { |
||||
this.noNamespaceSchemaLocation = noNamespaceSchemaLocation; |
||||
} |
||||
|
||||
/** |
||||
* 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 {@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 {@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 {@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 {@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 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. |
||||
* <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. |
||||
* <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 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 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 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 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 org.exolab.castor.xml.Marshaller#setNamespaceMapping(String, String) |
||||
*/ |
||||
public void setNamespaceToPackageMapping(Map<String, String> 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; |
||||
} |
||||
|
||||
@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 {@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 {@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 {@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 {@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 {@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); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -1,10 +0,0 @@
@@ -1,10 +0,0 @@
|
||||
/** |
||||
* Package providing integration of <a href="http://castor-data-binding.github.io/castor/reference-guides/1.3.3/html-single/index.html#xml.mapping">Castor</a> |
||||
* within Spring's O/X Mapping support. |
||||
*/ |
||||
@NonNullApi |
||||
@NonNullFields |
||||
package org.springframework.oxm.castor; |
||||
|
||||
import org.springframework.lang.NonNullApi; |
||||
import org.springframework.lang.NonNullFields; |
||||
@ -1,38 +0,0 @@
@@ -1,38 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2017 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.config; |
||||
|
||||
import org.w3c.dom.Element; |
||||
|
||||
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser; |
||||
|
||||
/** |
||||
* Parser for the {@code <oxm:castor-marshaller/>} element. |
||||
* |
||||
* @author Jakub Narloch |
||||
* @since 3.1 |
||||
* @deprecated as of Spring Framework 4.3.13, due to the lack of activity on the Castor project |
||||
*/ |
||||
@Deprecated |
||||
class CastorMarshallerBeanDefinitionParser extends AbstractSimpleBeanDefinitionParser { |
||||
|
||||
@Override |
||||
protected String getBeanClassName(Element element) { |
||||
return "org.springframework.oxm.castor.CastorMarshaller"; |
||||
} |
||||
|
||||
} |
||||
@ -1,300 +0,0 @@
@@ -1,300 +0,0 @@
|
||||
/* |
||||
* 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.StringWriter; |
||||
import java.util.Arrays; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
import javax.xml.transform.Source; |
||||
import javax.xml.transform.sax.SAXResult; |
||||
import javax.xml.transform.stream.StreamResult; |
||||
|
||||
import org.castor.xml.XMLProperties; |
||||
import org.exolab.castor.xml.XercesXMLSerializerFactory; |
||||
import org.junit.Test; |
||||
import org.mockito.InOrder; |
||||
import org.w3c.dom.Node; |
||||
import org.xml.sax.Attributes; |
||||
import org.xml.sax.ContentHandler; |
||||
import org.xmlunit.builder.Input; |
||||
import org.xmlunit.xpath.JAXPXPathEngine; |
||||
|
||||
import org.springframework.core.io.ClassPathResource; |
||||
import org.springframework.oxm.AbstractMarshallerTests; |
||||
|
||||
import static org.junit.Assert.*; |
||||
import static org.mockito.Mockito.*; |
||||
import static org.xmlunit.matchers.CompareMatcher.*; |
||||
|
||||
/** |
||||
* Tests the {@link CastorMarshaller} class. |
||||
* |
||||
* @author Arjen Poutsma |
||||
* @author Jakub Narloch |
||||
* @author Sam Brannen |
||||
*/ |
||||
@Deprecated |
||||
public class CastorMarshallerTests extends AbstractMarshallerTests<CastorMarshaller> { |
||||
|
||||
/** |
||||
* Represents the expected result that doesn't contain the xml declaration. |
||||
*/ |
||||
private static final String DOCUMENT_EXPECTED_STRING = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + |
||||
"<tns:flights xmlns:tns=\"http://samples.springframework.org/flight\">" + |
||||
"<tns:flight><tns:number>42</tns:number></tns:flight></tns:flights>"; |
||||
|
||||
/** |
||||
* Represents the expected result that doesn't contain the xml namespaces. |
||||
*/ |
||||
private static final String SUPPRESSED_NAMESPACE_EXPECTED_STRING = |
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><flights><flight><number>42</number></flight></flights>"; |
||||
|
||||
/** |
||||
* Represents the expected result with modified root element name. |
||||
*/ |
||||
private static final String ROOT_ELEMENT_EXPECTED_STRING = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + |
||||
"<tns:canceledFlights xmlns:tns=\"http://samples.springframework.org/flight\">" + |
||||
"<tns:flight><tns:number>42</tns:number></tns:flight></tns:canceledFlights>"; |
||||
|
||||
/** |
||||
* Represents the expected result with 'xsi:type' attribute. |
||||
*/ |
||||
private static final String XSI_EXPECTED_STRING = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + |
||||
"<objects><castor-object xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" + |
||||
" xmlns:java=\"http://java.sun.com\"" + |
||||
" xsi:type=\"java:org.springframework.oxm.castor.CastorObject\">" + |
||||
"<name>test</name><value>8</value></castor-object></objects>"; |
||||
|
||||
/** |
||||
* Represents the expected result with suppressed 'xsi:type' attribute. |
||||
*/ |
||||
private static final String SUPPRESSED_XSI_EXPECTED_STRING = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + |
||||
"<objects><castor-object><name>test</name><value>8</value></castor-object></objects>"; |
||||
|
||||
/** |
||||
* Represents the expected result with 'xsi:type' attribute for root element. |
||||
*/ |
||||
private static final String ROOT_WITH_XSI_EXPECTED_STRING = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + |
||||
"<objects xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" + |
||||
" xmlns:java=\"http://java.sun.com\"" + |
||||
" xsi:type=\"java:java.util.Arrays$ArrayList\">" + |
||||
"<castor-object xsi:type=\"java:org.springframework.oxm.castor.CastorObject\">" + |
||||
"<name>test</name><value>8</value></castor-object></objects>"; |
||||
|
||||
/** |
||||
* Represents the expected result without 'xsi:type' attribute for root element. |
||||
*/ |
||||
private static final String ROOT_WITHOUT_XSI_EXPECTED_STRING = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + |
||||
"<objects><castor-object xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" + |
||||
" xmlns:java=\"http://java.sun.com\"" + |
||||
" xsi:type=\"java:org.springframework.oxm.castor.CastorObject\">" + |
||||
"<name>test</name><value>8</value></castor-object></objects>"; |
||||
|
||||
|
||||
@Override |
||||
protected CastorMarshaller createMarshaller() throws Exception { |
||||
CastorMarshaller marshaller = new CastorMarshaller(); |
||||
ClassPathResource mappingLocation = new ClassPathResource("mapping.xml", CastorMarshaller.class); |
||||
marshaller.setMappingLocation(mappingLocation); |
||||
Map<String, String> props = new HashMap<>(1); |
||||
props.put(XMLProperties.SERIALIZER_FACTORY, XercesXMLSerializerFactory.class.getName()); |
||||
marshaller.setCastorProperties(props); |
||||
marshaller.afterPropertiesSet(); |
||||
return marshaller; |
||||
} |
||||
|
||||
@Override |
||||
protected Object createFlights() { |
||||
Flight flight = new Flight(); |
||||
flight.setNumber(42L); |
||||
Flights flights = new Flights(); |
||||
flights.addFlight(flight); |
||||
return flights; |
||||
} |
||||
|
||||
|
||||
@Test |
||||
public void marshalSaxResult() throws Exception { |
||||
ContentHandler contentHandler = mock(ContentHandler.class); |
||||
SAXResult result = new SAXResult(contentHandler); |
||||
marshaller.marshal(flights, result); |
||||
InOrder ordered = inOrder(contentHandler); |
||||
ordered.verify(contentHandler).startDocument(); |
||||
ordered.verify(contentHandler).startPrefixMapping("tns", "http://samples.springframework.org/flight"); |
||||
ordered.verify(contentHandler).startElement(eq("http://samples.springframework.org/flight"), |
||||
eq("flights"), eq("tns:flights"), isA(Attributes.class)); |
||||
ordered.verify(contentHandler).startElement(eq("http://samples.springframework.org/flight"), |
||||
eq("flight"), eq("tns:flight"), isA(Attributes.class)); |
||||
ordered.verify(contentHandler).startElement(eq("http://samples.springframework.org/flight"), |
||||
eq("number"), eq("tns:number"), isA(Attributes.class)); |
||||
ordered.verify(contentHandler).characters(eq(new char[]{'4', '2'}), eq(0), eq(2)); |
||||
ordered.verify(contentHandler).endElement("http://samples.springframework.org/flight", "number", "tns:number"); |
||||
ordered.verify(contentHandler).endElement("http://samples.springframework.org/flight", "flight", "tns:flight"); |
||||
ordered.verify(contentHandler).endElement("http://samples.springframework.org/flight", "flights", "tns:flights"); |
||||
ordered.verify(contentHandler).endPrefixMapping("tns"); |
||||
ordered.verify(contentHandler).endDocument(); |
||||
} |
||||
|
||||
@Test |
||||
public void supports() throws Exception { |
||||
assertTrue("CastorMarshaller does not support Flights", marshaller.supports(Flights.class)); |
||||
assertTrue("CastorMarshaller does not support Flight", marshaller.supports(Flight.class)); |
||||
} |
||||
|
||||
@Test |
||||
public void suppressNamespacesTrue() throws Exception { |
||||
marshaller.setSuppressNamespaces(true); |
||||
String result = marshalFlights(); |
||||
assertThat("Marshaller wrote invalid result", result, isSimilarTo(SUPPRESSED_NAMESPACE_EXPECTED_STRING)); |
||||
} |
||||
|
||||
@Test |
||||
public void suppressNamespacesFalse() throws Exception { |
||||
marshaller.setSuppressNamespaces(false); |
||||
String result = marshalFlights(); |
||||
assertThat("Marshaller wrote invalid result", result, isSimilarTo(EXPECTED_STRING)); |
||||
} |
||||
|
||||
@Test |
||||
public void suppressXsiTypeTrue() throws Exception { |
||||
CastorObject castorObject = createCastorObject(); |
||||
marshaller.setSuppressXsiType(true); |
||||
marshaller.setRootElement("objects"); |
||||
String result = marshal(Arrays.asList(castorObject)); |
||||
assertThat("Marshaller wrote invalid result", result, isSimilarTo(SUPPRESSED_XSI_EXPECTED_STRING)); |
||||
} |
||||
|
||||
@Test |
||||
public void suppressXsiTypeFalse() throws Exception { |
||||
CastorObject castorObject = createCastorObject(); |
||||
marshaller.setSuppressXsiType(false); |
||||
marshaller.setRootElement("objects"); |
||||
String result = marshal(Arrays.asList(castorObject)); |
||||
assertThat("Marshaller wrote invalid result", result, isSimilarTo(XSI_EXPECTED_STRING)); |
||||
} |
||||
|
||||
@Test |
||||
public void marshalAsDocumentTrue() throws Exception { |
||||
marshaller.setMarshalAsDocument(true); |
||||
String result = marshalFlights(); |
||||
assertThat("Marshaller wrote invalid result", result, isSimilarTo(DOCUMENT_EXPECTED_STRING)); |
||||
assertTrue("Result doesn't contain xml declaration.", |
||||
result.contains("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")); |
||||
} |
||||
|
||||
@Test |
||||
public void marshalAsDocumentFalse() throws Exception { |
||||
marshaller.setMarshalAsDocument(true); |
||||
String result = marshalFlights(); |
||||
assertThat("Marshaller wrote invalid result", result, isSimilarTo(EXPECTED_STRING)); |
||||
assertFalse("Result contains xml declaration.", result.matches("<\\?\\s*xml")); |
||||
} |
||||
|
||||
@Test |
||||
public void rootElement() throws Exception { |
||||
marshaller.setRootElement("canceledFlights"); |
||||
String result = marshalFlights(); |
||||
assertThat("Marshaller wrote invalid result", result, isSimilarTo(ROOT_ELEMENT_EXPECTED_STRING)); |
||||
} |
||||
|
||||
@Test |
||||
public void noNamespaceSchemaLocation() throws Exception { |
||||
String noNamespaceSchemaLocation = "flights.xsd"; |
||||
marshaller.setNoNamespaceSchemaLocation(noNamespaceSchemaLocation); |
||||
String result = marshalFlights(); |
||||
assertXpathEvaluatesTo("The xsi:noNamespaceSchemaLocation hasn't been written or has invalid value.", |
||||
noNamespaceSchemaLocation, "/tns:flights/@xsi:noNamespaceSchemaLocation", result); |
||||
assertThat("Marshaller wrote invalid result", result, isSimilarTo(EXPECTED_STRING)); |
||||
} |
||||
|
||||
@Test |
||||
public void schemaLocation() throws Exception { |
||||
String schemaLocation = "flights.xsd"; |
||||
marshaller.setSchemaLocation(schemaLocation); |
||||
String result = marshalFlights(); |
||||
assertXpathEvaluatesTo("The xsi:noNamespaceSchemaLocation hasn't been written or has invalid value.", |
||||
schemaLocation, "/tns:flights/@xsi:schemaLocation", result); |
||||
assertThat("Marshaller wrote invalid result", result, isSimilarTo(EXPECTED_STRING)); |
||||
} |
||||
|
||||
@Test |
||||
public void useXsiTypeAsRootTrue() throws Exception { |
||||
CastorObject castorObject = createCastorObject(); |
||||
marshaller.setSuppressXsiType(false); |
||||
marshaller.setUseXSITypeAtRoot(true); |
||||
marshaller.setRootElement("objects"); |
||||
String result = marshal(Arrays.asList(castorObject)); |
||||
assertThat("Marshaller wrote invalid result", result, isSimilarTo(ROOT_WITH_XSI_EXPECTED_STRING)); |
||||
} |
||||
|
||||
@Test |
||||
public void useXsiTypeAsRootFalse() throws Exception { |
||||
CastorObject castorObject = createCastorObject(); |
||||
marshaller.setSuppressXsiType(false); |
||||
marshaller.setUseXSITypeAtRoot(false); |
||||
marshaller.setRootElement("objects"); |
||||
String result = marshal(Arrays.asList(castorObject)); |
||||
assertThat("Marshaller wrote invalid result", result, isSimilarTo(ROOT_WITHOUT_XSI_EXPECTED_STRING)); |
||||
} |
||||
|
||||
|
||||
private String marshal(Object object) throws Exception { |
||||
StringWriter writer = new StringWriter(); |
||||
StreamResult result = new StreamResult(writer); |
||||
marshaller.marshal(object, result); |
||||
return writer.toString(); |
||||
} |
||||
|
||||
private String marshalFlights() throws Exception { |
||||
return marshal(flights); |
||||
} |
||||
|
||||
/** |
||||
* Assert the values of xpath expression evaluation is exactly the same as expected value. |
||||
* <p>The xpath may contain the xml namespace prefixes, since namespaces from flight example |
||||
* are being registered. |
||||
* @param msg the error message that will be used in case of test failure |
||||
* @param expected the expected value |
||||
* @param xpath the xpath to evaluate |
||||
* @param xmlDoc the xml to use |
||||
* @throws Exception if any error occurs during xpath evaluation |
||||
*/ |
||||
private void assertXpathEvaluatesTo(String msg, String expected, String xpath, String xmlDoc) throws Exception { |
||||
Map<String, String> namespaces = new HashMap<>(); |
||||
namespaces.put("tns", "http://samples.springframework.org/flight"); |
||||
namespaces.put("xsi", "http://www.w3.org/2001/XMLSchema-instance"); |
||||
|
||||
JAXPXPathEngine engine = new JAXPXPathEngine(); |
||||
engine.setNamespaceContext(namespaces); |
||||
|
||||
Source source = Input.fromString(xmlDoc).build(); |
||||
Iterable<Node> nodeList = engine.selectNodes(xpath, source); |
||||
assertEquals(msg, expected, nodeList.iterator().next().getNodeValue()); |
||||
} |
||||
|
||||
/** |
||||
* Create an instance of {@link CastorObject} for testing. |
||||
*/ |
||||
private CastorObject createCastorObject() { |
||||
CastorObject castorObject = new CastorObject(); |
||||
castorObject.setName("test"); |
||||
castorObject.setValue(8); |
||||
return castorObject; |
||||
} |
||||
|
||||
} |
||||
@ -1,45 +0,0 @@
@@ -1,45 +0,0 @@
|
||||
/* |
||||
* 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; |
||||
|
||||
/** |
||||
* Represents a POJO used by {@link CastorMarshallerTests} for testing the marshaller output. |
||||
* |
||||
* @author Jakub Narloch |
||||
*/ |
||||
public class CastorObject { |
||||
|
||||
private String name; |
||||
|
||||
private Integer value; |
||||
|
||||
public String getName() { |
||||
return name; |
||||
} |
||||
|
||||
public void setName(String name) { |
||||
this.name = name; |
||||
} |
||||
|
||||
public Integer getValue() { |
||||
return value; |
||||
} |
||||
|
||||
public void setValue(Integer value) { |
||||
this.value = value; |
||||
} |
||||
} |
||||
@ -1,260 +0,0 @@
@@ -1,260 +0,0 @@
|
||||
/* |
||||
* 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.ByteArrayInputStream; |
||||
import java.io.IOException; |
||||
import java.io.StringReader; |
||||
import java.util.concurrent.atomic.AtomicReference; |
||||
import javax.xml.transform.sax.SAXSource; |
||||
import javax.xml.transform.stream.StreamSource; |
||||
|
||||
import org.junit.Ignore; |
||||
import org.junit.Test; |
||||
import org.xml.sax.InputSource; |
||||
import org.xml.sax.XMLReader; |
||||
|
||||
import org.springframework.core.io.ClassPathResource; |
||||
import org.springframework.oxm.AbstractUnmarshallerTests; |
||||
import org.springframework.oxm.MarshallingException; |
||||
|
||||
import static org.hamcrest.CoreMatchers.*; |
||||
import static org.junit.Assert.*; |
||||
|
||||
/** |
||||
* @author Arjen Poutsma |
||||
* @author Jakub Narloch |
||||
* @author Sam Brannen |
||||
*/ |
||||
@Deprecated |
||||
public class CastorUnmarshallerTests extends AbstractUnmarshallerTests<CastorMarshaller> { |
||||
|
||||
/** |
||||
* Represents the xml with additional attribute that is not mapped in Castor config. |
||||
*/ |
||||
protected static final String EXTRA_ATTRIBUTES_STRING = |
||||
"<tns:flights xmlns:tns=\"http://samples.springframework.org/flight\">" + |
||||
"<tns:flight status=\"canceled\"><tns:number>42</tns:number></tns:flight></tns:flights>"; |
||||
|
||||
/** |
||||
* Represents the xml with additional element that is not mapped in Castor config. |
||||
*/ |
||||
protected static final String EXTRA_ELEMENTS_STRING = |
||||
"<tns:flights xmlns:tns=\"http://samples.springframework.org/flight\">" + |
||||
"<tns:flight><tns:number>42</tns:number><tns:date>2011-06-14</tns:date>" + |
||||
"</tns:flight></tns:flights>"; |
||||
|
||||
|
||||
@Override |
||||
protected CastorMarshaller createUnmarshaller() throws Exception { |
||||
CastorMarshaller marshaller = new CastorMarshaller(); |
||||
ClassPathResource mappingLocation = new ClassPathResource("mapping.xml", CastorMarshaller.class); |
||||
marshaller.setMappingLocation(mappingLocation); |
||||
marshaller.afterPropertiesSet(); |
||||
return marshaller; |
||||
} |
||||
|
||||
@Override |
||||
protected void testFlights(Object o) { |
||||
Flights flights = (Flights) o; |
||||
assertNotNull("Flights is null", flights); |
||||
assertEquals("Invalid amount of flight elements", 1, flights.getFlightCount()); |
||||
testFlight(flights.getFlight()[0]); |
||||
} |
||||
|
||||
@Override |
||||
protected void testFlight(Object o) { |
||||
Flight flight = (Flight) o; |
||||
assertNotNull("Flight is null", flight); |
||||
assertThat("Number is invalid", flight.getNumber(), equalTo(42L)); |
||||
} |
||||
|
||||
|
||||
@Test |
||||
public void unmarshalTargetClass() throws Exception { |
||||
CastorMarshaller unmarshaller = new CastorMarshaller(); |
||||
unmarshaller.setTargetClasses(Flights.class); |
||||
unmarshaller.afterPropertiesSet(); |
||||
StreamSource source = new StreamSource(new ByteArrayInputStream(INPUT_STRING.getBytes("UTF-8"))); |
||||
Object flights = unmarshaller.unmarshal(source); |
||||
testFlights(flights); |
||||
} |
||||
|
||||
@Test |
||||
public void setBothTargetClassesAndMapping() throws IOException { |
||||
CastorMarshaller unmarshaller = new CastorMarshaller(); |
||||
unmarshaller.setMappingLocation(new ClassPathResource("order-mapping.xml", CastorMarshaller.class)); |
||||
unmarshaller.setTargetClasses(Order.class); |
||||
unmarshaller.afterPropertiesSet(); |
||||
|
||||
String xml = "<order>" + |
||||
"<order-item id=\"1\" quantity=\"15\"/>" + |
||||
"<order-item id=\"3\" quantity=\"20\"/>" + |
||||
"</order>"; |
||||
|
||||
Order order = (Order) unmarshaller.unmarshal(new StreamSource(new StringReader(xml))); |
||||
assertEquals("Invalid amount of items", 2, order.getOrderItemCount()); |
||||
OrderItem item = order.getOrderItem(0); |
||||
assertEquals("Invalid items", "1", item.getId()); |
||||
assertThat("Invalid items", item.getQuantity(), equalTo(15)); |
||||
item = order.getOrderItem(1); |
||||
assertEquals("Invalid items", "3", item.getId()); |
||||
assertThat("Invalid items", item.getQuantity(), equalTo(20)); |
||||
} |
||||
|
||||
@Test |
||||
public void whitespacePreserveTrue() throws Exception { |
||||
unmarshaller.setWhitespacePreserve(true); |
||||
Object result = unmarshalFlights(); |
||||
testFlights(result); |
||||
} |
||||
|
||||
@Test |
||||
public void whitespacePreserveFalse() throws Exception { |
||||
unmarshaller.setWhitespacePreserve(false); |
||||
Object result = unmarshalFlights(); |
||||
testFlights(result); |
||||
} |
||||
|
||||
@Test |
||||
public void ignoreExtraAttributesTrue() throws Exception { |
||||
unmarshaller.setIgnoreExtraAttributes(true); |
||||
Object result = unmarshal(EXTRA_ATTRIBUTES_STRING); |
||||
testFlights(result); |
||||
} |
||||
|
||||
@Test(expected = MarshallingException.class) |
||||
public void ignoreExtraAttributesFalse() throws Exception { |
||||
unmarshaller.setIgnoreExtraAttributes(false); |
||||
unmarshal(EXTRA_ATTRIBUTES_STRING); |
||||
} |
||||
|
||||
@Test |
||||
@Ignore("Not working yet") |
||||
public void ignoreExtraElementsTrue() throws Exception { |
||||
unmarshaller.setIgnoreExtraElements(true); |
||||
unmarshaller.setValidating(false); |
||||
Object result = unmarshal(EXTRA_ELEMENTS_STRING); |
||||
testFlights(result); |
||||
} |
||||
|
||||
@Test(expected = MarshallingException.class) |
||||
public void ignoreExtraElementsFalse() throws Exception { |
||||
unmarshaller.setIgnoreExtraElements(false); |
||||
unmarshal(EXTRA_ELEMENTS_STRING); |
||||
} |
||||
|
||||
@Test |
||||
public void rootObject() throws Exception { |
||||
Flights flights = new Flights(); |
||||
unmarshaller.setRootObject(flights); |
||||
Object result = unmarshalFlights(); |
||||
testFlights(result); |
||||
assertSame("Result Flights is different object.", flights, result); |
||||
} |
||||
|
||||
@Test |
||||
public void clearCollectionsTrue() throws Exception { |
||||
Flights flights = new Flights(); |
||||
flights.setFlight(new Flight[]{new Flight()}); |
||||
unmarshaller.setRootObject(flights); |
||||
unmarshaller.setClearCollections(true); |
||||
Object result = unmarshalFlights(); |
||||
|
||||
assertSame("Result Flights is different object.", flights, result); |
||||
assertEquals("Result Flights has incorrect number of Flight.", 1, ((Flights) result).getFlightCount()); |
||||
testFlights(result); |
||||
} |
||||
|
||||
@Test |
||||
public void clearCollectionsFalse() throws Exception { |
||||
Flights flights = new Flights(); |
||||
flights.setFlight(new Flight[] {new Flight(), null}); |
||||
unmarshaller.setRootObject(flights); |
||||
unmarshaller.setClearCollections(false); |
||||
Object result = unmarshalFlights(); |
||||
|
||||
assertSame("Result Flights is different object.", flights, result); |
||||
assertEquals("Result Flights has incorrect number of Flights.", 3, ((Flights) result).getFlightCount()); |
||||
assertNull("Null Flight was expected.", flights.getFlight()[1]); |
||||
testFlight(flights.getFlight()[2]); |
||||
} |
||||
|
||||
@Test |
||||
public void unmarshalStreamSourceWithXmlOptions() throws Exception { |
||||
final AtomicReference<XMLReader> result = new AtomicReference<>(); |
||||
CastorMarshaller marshaller = new CastorMarshaller() { |
||||
@Override |
||||
protected Object unmarshalSaxReader(XMLReader xmlReader, InputSource inputSource) { |
||||
result.set(xmlReader); |
||||
return null; |
||||
} |
||||
}; |
||||
|
||||
// 1. external-general-entities and dtd support disabled (default)
|
||||
marshaller.unmarshal(new StreamSource("1")); |
||||
assertNotNull(result.get()); |
||||
assertEquals(true, result.get().getFeature("http://apache.org/xml/features/disallow-doctype-decl")); |
||||
assertEquals(false, result.get().getFeature("http://xml.org/sax/features/external-general-entities")); |
||||
|
||||
// 2. external-general-entities and dtd support enabled
|
||||
result.set(null); |
||||
marshaller.setSupportDtd(true); |
||||
marshaller.setProcessExternalEntities(true); |
||||
marshaller.unmarshal(new StreamSource("1")); |
||||
assertNotNull(result.get()); |
||||
assertEquals(false, result.get().getFeature("http://apache.org/xml/features/disallow-doctype-decl")); |
||||
assertEquals(true, result.get().getFeature("http://xml.org/sax/features/external-general-entities")); |
||||
} |
||||
|
||||
@Test |
||||
public void unmarshalSaxSourceWithXmlOptions() throws Exception { |
||||
final AtomicReference<XMLReader> result = new AtomicReference<>(); |
||||
CastorMarshaller marshaller = new CastorMarshaller() { |
||||
@Override |
||||
protected Object unmarshalSaxReader(XMLReader xmlReader, InputSource inputSource) { |
||||
result.set(xmlReader); |
||||
return null; |
||||
} |
||||
}; |
||||
|
||||
// 1. external-general-entities and dtd support disabled (default)
|
||||
marshaller.unmarshal(new SAXSource(new InputSource("1"))); |
||||
assertNotNull(result.get()); |
||||
assertEquals(true, result.get().getFeature("http://apache.org/xml/features/disallow-doctype-decl")); |
||||
assertEquals(false, result.get().getFeature("http://xml.org/sax/features/external-general-entities")); |
||||
|
||||
// 2. external-general-entities and dtd support enabled
|
||||
result.set(null); |
||||
marshaller.setSupportDtd(true); |
||||
marshaller.setProcessExternalEntities(true); |
||||
marshaller.unmarshal(new SAXSource(new InputSource("1"))); |
||||
assertNotNull(result.get()); |
||||
assertEquals(false, result.get().getFeature("http://apache.org/xml/features/disallow-doctype-decl")); |
||||
assertEquals(true, result.get().getFeature("http://xml.org/sax/features/external-general-entities")); |
||||
} |
||||
|
||||
private Object unmarshalFlights() throws Exception { |
||||
return unmarshal(INPUT_STRING); |
||||
} |
||||
|
||||
private Object unmarshal(String xml) throws Exception { |
||||
StreamSource source = new StreamSource(new StringReader(xml)); |
||||
return unmarshaller.unmarshal(source); |
||||
} |
||||
|
||||
} |
||||
@ -1,31 +0,0 @@
@@ -1,31 +0,0 @@
|
||||
<?xml version="1.0"?> |
||||
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN" "http://castor.org/mapping.dtd"> |
||||
<mapping> |
||||
<description>Castor generated mapping file</description> |
||||
<class name="org.springframework.oxm.castor.Flights"> |
||||
<description> |
||||
Default mapping for class |
||||
org.springframework.oxm.castor.Flights |
||||
</description> |
||||
<map-to xml="flights" |
||||
ns-uri="http://samples.springframework.org/flight" ns-prefix="tns"/> |
||||
<field name="flight" |
||||
type="org.springframework.oxm.castor.Flight" |
||||
required="true" collection="array"> |
||||
<bind-xml name="tns:flight" node="element" QName-prefix="tns" |
||||
xmlns:tns="http://samples.springframework.org/flight"/> |
||||
</field> |
||||
</class> |
||||
<class name="org.springframework.oxm.castor.Flight"> |
||||
<description> |
||||
Default mapping for class |
||||
org.springframework.oxm.castor.Flight |
||||
</description> |
||||
<map-to xml="flight" |
||||
ns-uri="http://samples.springframework.org/flight" ns-prefix="tns"/> |
||||
<field name="number" type="long" required="true"> |
||||
<bind-xml name="tns:number" node="element" |
||||
xmlns:tns="http://samples.springframework.org/flight"/> |
||||
</field> |
||||
</class> |
||||
</mapping> |
||||
@ -1,11 +0,0 @@
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> |
||||
<mapping> |
||||
<class name="org.springframework.oxm.castor.OrderItem"> |
||||
<field name="Id" type="java.lang.String"> |
||||
<bind-xml name="id" node="attribute" /> |
||||
</field> |
||||
<field name="Quantity" type="java.lang.Integer"> |
||||
<bind-xml name="quantity" node="attribute" /> |
||||
</field> |
||||
</class> |
||||
</mapping> |
||||
Loading…
Reference in new issue