OXM is nearing completion

This commit is contained in:
Arjen Poutsma
2009-01-09 12:48:19 +00:00
parent f2329cf426
commit fc06f9ba72
99 changed files with 6343 additions and 5359 deletions

View File

@@ -49,8 +49,7 @@ import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.XMLReaderFactory;
import org.springframework.util.Assert;
import org.springframework.xml.transform.StaxSource;
import org.springframework.xml.transform.TraxUtils;
import org.springframework.util.xml.StaxUtils;
/**
* Abstract implementation of the <code>Marshaller</code> and <code>Unmarshaller</code> interface. This implementation
@@ -58,439 +57,434 @@ import org.springframework.xml.transform.TraxUtils;
* methods.
*
* @author Arjen Poutsma
* @since 1.0.0
* @since 3.0
*/
public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
/** Logger available to subclasses. */
protected final Log logger = LogFactory.getLog(getClass());
/** Logger available to subclasses. */
protected final Log logger = LogFactory.getLog(getClass());
private DocumentBuilderFactory documentBuilderFactory;
private DocumentBuilderFactory documentBuilderFactory;
/**
* Marshals the object graph with the given root into the provided <code>javax.xml.transform.Result</code>.
* <p/>
* This implementation inspects the given result, and calls <code>marshalDomResult</code>,
* <code>marshalSaxResult</code>, or <code>marshalStreamResult</code>.
*
* @param graph the root of the object graph to marshal
* @param result the result to marshal to
* @throws XmlMappingException if the given object cannot be marshalled to the result
* @throws IOException if an I/O exception occurs
* @throws IllegalArgumentException if <code>result</code> if neither a <code>DOMResult</code>,
* <code>SAXResult</code>, <code>StreamResult</code>
* @see #marshalDomResult(Object,javax.xml.transform.dom.DOMResult)
* @see #marshalSaxResult(Object,javax.xml.transform.sax.SAXResult)
* @see #marshalStreamResult(Object,javax.xml.transform.stream.StreamResult)
*/
public final void marshal(Object graph, Result result) throws XmlMappingException, IOException {
if (result instanceof DOMResult) {
marshalDomResult(graph, (DOMResult) result);
}
else if (TraxUtils.isStaxResult(result)) {
marshalStaxResult(graph, result);
}
else if (result instanceof SAXResult) {
marshalSaxResult(graph, (SAXResult) result);
}
else if (result instanceof StreamResult) {
marshalStreamResult(graph, (StreamResult) result);
}
else {
throw new IllegalArgumentException("Unknown Result type: " + result.getClass());
}
}
/**
* Marshals the object graph with the given root into the provided <code>javax.xml.transform.Result</code>. <p/> This
* implementation inspects the given result, and calls <code>marshalDomResult</code>, <code>marshalSaxResult</code>, or
* <code>marshalStreamResult</code>.
*
* @param graph the root of the object graph to marshal
* @param result the result to marshal to
* @throws XmlMappingException if the given object cannot be marshalled to the result
* @throws IOException if an I/O exception occurs
* @throws IllegalArgumentException if <code>result</code> if neither a <code>DOMResult</code>, <code>SAXResult</code>,
* <code>StreamResult</code>
* @see #marshalDomResult(Object,javax.xml.transform.dom.DOMResult)
* @see #marshalSaxResult(Object,javax.xml.transform.sax.SAXResult)
* @see #marshalStreamResult(Object,javax.xml.transform.stream.StreamResult)
*/
public final void marshal(Object graph, Result result) throws XmlMappingException, IOException {
if (result instanceof DOMResult) {
marshalDomResult(graph, (DOMResult) result);
}
else if (StaxUtils.isStaxResult(result)) {
marshalStaxResult(graph, result);
}
else if (result instanceof SAXResult) {
marshalSaxResult(graph, (SAXResult) result);
}
else if (result instanceof StreamResult) {
marshalStreamResult(graph, (StreamResult) result);
}
else {
throw new IllegalArgumentException("Unknown Result type: " + result.getClass());
}
}
/**
* Unmarshals the given provided <code>javax.xml.transform.Source</code> into an object graph.
* <p/>
* This implementation inspects the given result, and calls <code>unmarshalDomSource</code>,
* <code>unmarshalSaxSource</code>, or <code>unmarshalStreamSource</code>.
*
* @param source the source to marshal from
* @return the object graph
* @throws XmlMappingException if the given source cannot be mapped to an object
* @throws IOException if an I/O Exception occurs
* @throws IllegalArgumentException if <code>source</code> is neither a <code>DOMSource</code>, a
* <code>SAXSource</code>, nor a <code>StreamSource</code>
* @see #unmarshalDomSource(javax.xml.transform.dom.DOMSource)
* @see #unmarshalSaxSource(javax.xml.transform.sax.SAXSource)
* @see #unmarshalStreamSource(javax.xml.transform.stream.StreamSource)
*/
public final Object unmarshal(Source source) throws XmlMappingException, IOException {
if (source instanceof DOMSource) {
return unmarshalDomSource((DOMSource) source);
}
else if (TraxUtils.isStaxSource(source)) {
return unmarshalStaxSource(source);
}
else if (source instanceof SAXSource) {
return unmarshalSaxSource((SAXSource) source);
}
else if (source instanceof StreamSource) {
return unmarshalStreamSource((StreamSource) source);
}
else {
throw new IllegalArgumentException("Unknown Source type: " + source.getClass());
}
}
/**
* Unmarshals the given provided <code>javax.xml.transform.Source</code> into an object graph. <p/> This implementation
* inspects the given result, and calls <code>unmarshalDomSource</code>, <code>unmarshalSaxSource</code>, or
* <code>unmarshalStreamSource</code>.
*
* @param source the source to marshal from
* @return the object graph
* @throws XmlMappingException if the given source cannot be mapped to an object
* @throws IOException if an I/O Exception occurs
* @throws IllegalArgumentException if <code>source</code> is neither a <code>DOMSource</code>, a
* <code>SAXSource</code>, nor a <code>StreamSource</code>
* @see #unmarshalDomSource(javax.xml.transform.dom.DOMSource)
* @see #unmarshalSaxSource(javax.xml.transform.sax.SAXSource)
* @see #unmarshalStreamSource(javax.xml.transform.stream.StreamSource)
*/
public final Object unmarshal(Source source) throws XmlMappingException, IOException {
if (source instanceof DOMSource) {
return unmarshalDomSource((DOMSource) source);
}
else if (StaxUtils.isStaxSource(source)) {
return unmarshalStaxSource(source);
}
else if (source instanceof SAXSource) {
return unmarshalSaxSource((SAXSource) source);
}
else if (source instanceof StreamSource) {
return unmarshalStreamSource((StreamSource) source);
}
else {
throw new IllegalArgumentException("Unknown Source type: " + source.getClass());
}
}
/**
* Create a <code>DocumentBuilder</code> that this marshaller will use for creating DOM documents when passed an
* empty <code>DOMSource</code>. Can be overridden in subclasses, adding further initialization of the builder.
*
* @param factory the <code>DocumentBuilderFactory</code> that the DocumentBuilder should be created with
* @return the <code>DocumentBuilder</code>
* @throws javax.xml.parsers.ParserConfigurationException
* if thrown by JAXP methods
*/
protected DocumentBuilder createDocumentBuilder(DocumentBuilderFactory factory)
throws ParserConfigurationException {
return factory.newDocumentBuilder();
}
/**
* Create a <code>DocumentBuilder</code> that this marshaller will use for creating DOM documents when passed an empty
* <code>DOMSource</code>. Can be overridden in subclasses, adding further initialization of the builder.
*
* @param factory the <code>DocumentBuilderFactory</code> that the DocumentBuilder should be created with
* @return the <code>DocumentBuilder</code>
* @throws javax.xml.parsers.ParserConfigurationException
* if thrown by JAXP methods
*/
protected DocumentBuilder createDocumentBuilder(DocumentBuilderFactory factory)
throws ParserConfigurationException {
return factory.newDocumentBuilder();
}
/**
* Create a <code>DocumentBuilder</code> that this marshaller will use for creating DOM documents when passed an
* empty <code>DOMSource</code>. The resulting <code>DocumentBuilderFactory</code> is cached, so this method will
* only be called once.
*
* @return the DocumentBuilderFactory
* @throws ParserConfigurationException if thrown by JAXP methods
*/
protected DocumentBuilderFactory createDocumentBuilderFactory() throws ParserConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(false);
factory.setNamespaceAware(true);
return factory;
}
/**
* Create a <code>DocumentBuilder</code> that this marshaller will use for creating DOM documents when passed an empty
* <code>DOMSource</code>. The resulting <code>DocumentBuilderFactory</code> is cached, so this method will only be
* called once.
*
* @return the DocumentBuilderFactory
* @throws ParserConfigurationException if thrown by JAXP methods
*/
protected DocumentBuilderFactory createDocumentBuilderFactory() throws ParserConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(false);
factory.setNamespaceAware(true);
return factory;
}
/**
* Create a <code>XMLReader</code> that this marshaller will when passed an empty <code>SAXSource</code>.
*
* @return the XMLReader
* @throws SAXException if thrown by JAXP methods
*/
protected XMLReader createXmlReader() throws SAXException {
return XMLReaderFactory.createXMLReader();
}
/**
* Create a <code>XMLReader</code> that this marshaller will when passed an empty <code>SAXSource</code>.
*
* @return the XMLReader
* @throws SAXException if thrown by JAXP methods
*/
protected XMLReader createXmlReader() throws SAXException {
return XMLReaderFactory.createXMLReader();
}
//
// Marshalling
//
//
// Marshalling
//
/**
* Template method for handling <code>DOMResult</code>s. This implementation defers to <code>marshalDomNode</code>.
*
* @param graph the root of the object graph to marshal
* @param domResult the <code>DOMResult</code>
* @throws XmlMappingException if the given object cannot be marshalled to the result
* @throws IllegalArgumentException if the <code>domResult</code> is empty
* @see #marshalDomNode(Object,org.w3c.dom.Node)
*/
protected void marshalDomResult(Object graph, DOMResult domResult) throws XmlMappingException {
Assert.notNull(domResult.getNode(), "DOMResult does not contain Node");
marshalDomNode(graph, domResult.getNode());
}
/**
* Template method for handling <code>DOMResult</code>s. This implementation defers to <code>marshalDomNode</code>.
*
* @param graph the root of the object graph to marshal
* @param domResult the <code>DOMResult</code>
* @throws XmlMappingException if the given object cannot be marshalled to the result
* @throws IllegalArgumentException if the <code>domResult</code> is empty
* @see #marshalDomNode(Object,org.w3c.dom.Node)
*/
protected void marshalDomResult(Object graph, DOMResult domResult) throws XmlMappingException {
Assert.notNull(domResult.getNode(), "DOMResult does not contain Node");
marshalDomNode(graph, domResult.getNode());
}
/**
* Template method for handling <code>StaxResult</code>s. This implementation defers to
* <code>marshalXMLSteamWriter</code>, or <code>marshalXMLEventConsumer</code>, depending on what is contained in
* the <code>StaxResult</code>.
*
* @param graph the root of the object graph to marshal
* @param staxResult a Spring-WS {@link StaxSource} or JAXP 1.4 {@link StAXSource}
* @throws XmlMappingException if the given object cannot be marshalled to the result
* @throws IllegalArgumentException if the <code>domResult</code> is empty
* @see #marshalDomNode(Object,org.w3c.dom.Node)
*/
protected void marshalStaxResult(Object graph, Result staxResult) throws XmlMappingException {
XMLStreamWriter streamWriter = TraxUtils.getXMLStreamWriter(staxResult);
if (streamWriter != null) {
marshalXmlStreamWriter(graph, streamWriter);
}
else {
XMLEventWriter eventWriter = TraxUtils.getXMLEventWriter(staxResult);
if (eventWriter != null) {
marshalXmlEventWriter(graph, eventWriter);
}
else {
throw new IllegalArgumentException("StaxResult contains neither XMLStreamWriter nor XMLEventConsumer");
}
}
}
/**
* Template method for handling <code>StaxResult</code>s. This implementation defers to
* <code>marshalXMLSteamWriter</code>, or <code>marshalXMLEventConsumer</code>, depending on what is contained in the
* <code>StaxResult</code>.
*
* @param graph the root of the object graph to marshal
* @param staxResult a Spring {@link org.springframework.util.xml.StaxSource} or JAXP 1.4 {@link StAXSource}
* @throws XmlMappingException if the given object cannot be marshalled to the result
* @throws IllegalArgumentException if the <code>domResult</code> is empty
* @see #marshalDomNode(Object,org.w3c.dom.Node)
*/
protected void marshalStaxResult(Object graph, Result staxResult) throws XmlMappingException {
XMLStreamWriter streamWriter = StaxUtils.getXMLStreamWriter(staxResult);
if (streamWriter != null) {
marshalXmlStreamWriter(graph, streamWriter);
}
else {
XMLEventWriter eventWriter = StaxUtils.getXMLEventWriter(staxResult);
if (eventWriter != null) {
marshalXmlEventWriter(graph, eventWriter);
}
else {
throw new IllegalArgumentException("StaxResult contains neither XMLStreamWriter nor XMLEventConsumer");
}
}
}
/**
* Template method for handling <code>SAXResult</code>s. This implementation defers to
* <code>marshalSaxHandlers</code>.
*
* @param graph the root of the object graph to marshal
* @param saxResult the <code>SAXResult</code>
* @throws XmlMappingException if the given object cannot be marshalled to the result
* @see #marshalSaxHandlers(Object,org.xml.sax.ContentHandler,org.xml.sax.ext.LexicalHandler)
*/
protected void marshalSaxResult(Object graph, SAXResult saxResult) throws XmlMappingException {
ContentHandler contentHandler = saxResult.getHandler();
Assert.notNull(contentHandler, "ContentHandler not set on SAXResult");
LexicalHandler lexicalHandler = saxResult.getLexicalHandler();
marshalSaxHandlers(graph, contentHandler, lexicalHandler);
}
/**
* Template method for handling <code>SAXResult</code>s. This implementation defers to
* <code>marshalSaxHandlers</code>.
*
* @param graph the root of the object graph to marshal
* @param saxResult the <code>SAXResult</code>
* @throws XmlMappingException if the given object cannot be marshalled to the result
* @see #marshalSaxHandlers(Object,org.xml.sax.ContentHandler,org.xml.sax.ext.LexicalHandler)
*/
protected void marshalSaxResult(Object graph, SAXResult saxResult) throws XmlMappingException {
ContentHandler contentHandler = saxResult.getHandler();
Assert.notNull(contentHandler, "ContentHandler not set on SAXResult");
LexicalHandler lexicalHandler = saxResult.getLexicalHandler();
marshalSaxHandlers(graph, contentHandler, lexicalHandler);
}
/**
* Template method for handling <code>StreamResult</code>s. This implementation defers to
* <code>marshalOutputStream</code>, or <code>marshalWriter</code>, depending on what is contained in the
* <code>StreamResult</code>
*
* @param graph the root of the object graph to marshal
* @param streamResult the <code>StreamResult</code>
* @throws IOException if an I/O Exception occurs
* @throws XmlMappingException if the given object cannot be marshalled to the result
* @throws IllegalArgumentException if <code>streamResult</code> contains neither <code>OutputStream</code> nor
* <code>Writer</code>.
*/
protected void marshalStreamResult(Object graph, StreamResult streamResult)
throws XmlMappingException, IOException {
if (streamResult.getOutputStream() != null) {
marshalOutputStream(graph, streamResult.getOutputStream());
}
else if (streamResult.getWriter() != null) {
marshalWriter(graph, streamResult.getWriter());
}
else {
throw new IllegalArgumentException("StreamResult contains neither OutputStream nor Writer");
}
}
/**
* Template method for handling <code>StreamResult</code>s. This implementation defers to
* <code>marshalOutputStream</code>, or <code>marshalWriter</code>, depending on what is contained in the
* <code>StreamResult</code>
*
* @param graph the root of the object graph to marshal
* @param streamResult the <code>StreamResult</code>
* @throws IOException if an I/O Exception occurs
* @throws XmlMappingException if the given object cannot be marshalled to the result
* @throws IllegalArgumentException if <code>streamResult</code> contains neither <code>OutputStream</code> nor
* <code>Writer</code>.
*/
protected void marshalStreamResult(Object graph, StreamResult streamResult)
throws XmlMappingException, IOException {
if (streamResult.getOutputStream() != null) {
marshalOutputStream(graph, streamResult.getOutputStream());
}
else if (streamResult.getWriter() != null) {
marshalWriter(graph, streamResult.getWriter());
}
else {
throw new IllegalArgumentException("StreamResult contains neither OutputStream nor Writer");
}
}
//
// Unmarshalling
//
//
// Unmarshalling
//
/**
* Template method for handling <code>DOMSource</code>s. This implementation defers to
* <code>unmarshalDomNode</code>. If the given source is empty, an empty source <code>Document</code> will be
* created as a placeholder.
*
* @param domSource the <code>DOMSource</code>
* @return the object graph
* @throws IllegalArgumentException if the <code>domSource</code> is empty
* @throws XmlMappingException if the given source cannot be mapped to an object
* @see #unmarshalDomNode(org.w3c.dom.Node)
*/
protected Object unmarshalDomSource(DOMSource domSource) throws XmlMappingException {
if (domSource.getNode() == null) {
try {
if (documentBuilderFactory == null) {
documentBuilderFactory = createDocumentBuilderFactory();
}
DocumentBuilder documentBuilder = createDocumentBuilder(documentBuilderFactory);
domSource.setNode(documentBuilder.newDocument());
}
catch (ParserConfigurationException ex) {
throw new UnmarshallingFailureException(
"Could not create document placeholder for DOMSource: " + ex.getMessage(), ex);
}
}
return unmarshalDomNode(domSource.getNode());
}
/**
* Template method for handling <code>DOMSource</code>s. This implementation defers to <code>unmarshalDomNode</code>.
* If the given source is empty, an empty source <code>Document</code> will be created as a placeholder.
*
* @param domSource the <code>DOMSource</code>
* @return the object graph
* @throws IllegalArgumentException if the <code>domSource</code> is empty
* @throws XmlMappingException if the given source cannot be mapped to an object
* @see #unmarshalDomNode(org.w3c.dom.Node)
*/
protected Object unmarshalDomSource(DOMSource domSource) throws XmlMappingException {
if (domSource.getNode() == null) {
try {
if (documentBuilderFactory == null) {
documentBuilderFactory = createDocumentBuilderFactory();
}
DocumentBuilder documentBuilder = createDocumentBuilder(documentBuilderFactory);
domSource.setNode(documentBuilder.newDocument());
}
catch (ParserConfigurationException ex) {
throw new UnmarshallingFailureException(
"Could not create document placeholder for DOMSource: " + ex.getMessage(), ex);
}
}
return unmarshalDomNode(domSource.getNode());
}
/**
* Template method for handling <code>StaxSource</code>s. This implementation defers to
* <code>unmarshalXmlStreamReader</code>, or <code>unmarshalXmlEventReader</code>.
*
* @param staxSource the <code>StaxSource</code>
* @return the object graph
* @throws XmlMappingException if the given source cannot be mapped to an object
*/
protected Object unmarshalStaxSource(Source staxSource) throws XmlMappingException {
XMLStreamReader streamReader = TraxUtils.getXMLStreamReader(staxSource);
if (streamReader != null) {
return unmarshalXmlStreamReader(streamReader);
}
else {
XMLEventReader eventReader = TraxUtils.getXMLEventReader(staxSource);
if (eventReader != null) {
return unmarshalXmlEventReader(eventReader);
}
else {
throw new IllegalArgumentException("StaxSource contains neither XMLStreamReader nor XMLEventReader");
}
}
}
/**
* Template method for handling <code>StaxSource</code>s. This implementation defers to
* <code>unmarshalXmlStreamReader</code>, or <code>unmarshalXmlEventReader</code>.
*
* @param staxSource the <code>StaxSource</code>
* @return the object graph
* @throws XmlMappingException if the given source cannot be mapped to an object
*/
protected Object unmarshalStaxSource(Source staxSource) throws XmlMappingException {
XMLStreamReader streamReader = StaxUtils.getXMLStreamReader(staxSource);
if (streamReader != null) {
return unmarshalXmlStreamReader(streamReader);
}
else {
XMLEventReader eventReader = StaxUtils.getXMLEventReader(staxSource);
if (eventReader != null) {
return unmarshalXmlEventReader(eventReader);
}
else {
throw new IllegalArgumentException("StaxSource contains neither XMLStreamReader nor XMLEventReader");
}
}
}
/**
* Template method for handling <code>SAXSource</code>s. This implementation defers to
* <code>unmarshalSaxReader</code>.
*
* @param saxSource the <code>SAXSource</code>
* @return the object graph
* @throws XmlMappingException if the given source cannot be mapped to an object
* @throws IOException if an I/O Exception occurs
* @see #unmarshalSaxReader(org.xml.sax.XMLReader,org.xml.sax.InputSource)
*/
protected Object unmarshalSaxSource(SAXSource saxSource) throws XmlMappingException, IOException {
if (saxSource.getXMLReader() == null) {
try {
saxSource.setXMLReader(createXmlReader());
}
catch (SAXException ex) {
throw new UnmarshallingFailureException("Could not create XMLReader for SAXSource: " + ex.getMessage(),
ex);
}
}
if (saxSource.getInputSource() == null) {
saxSource.setInputSource(new InputSource());
}
return unmarshalSaxReader(saxSource.getXMLReader(), saxSource.getInputSource());
}
/**
* Template method for handling <code>SAXSource</code>s. This implementation defers to
* <code>unmarshalSaxReader</code>.
*
* @param saxSource the <code>SAXSource</code>
* @return the object graph
* @throws XmlMappingException if the given source cannot be mapped to an object
* @throws IOException if an I/O Exception occurs
* @see #unmarshalSaxReader(org.xml.sax.XMLReader,org.xml.sax.InputSource)
*/
protected Object unmarshalSaxSource(SAXSource saxSource) throws XmlMappingException, IOException {
if (saxSource.getXMLReader() == null) {
try {
saxSource.setXMLReader(createXmlReader());
}
catch (SAXException ex) {
throw new UnmarshallingFailureException("Could not create XMLReader for SAXSource: " + ex.getMessage(),
ex);
}
}
if (saxSource.getInputSource() == null) {
saxSource.setInputSource(new InputSource());
}
return unmarshalSaxReader(saxSource.getXMLReader(), saxSource.getInputSource());
}
/**
* Template method for handling <code>StreamSource</code>s. This implementation defers to
* <code>unmarshalInputStream</code>, or <code>unmarshalReader</code>.
*
* @param streamSource the <code>StreamSource</code>
* @return the object graph
* @throws IOException if an I/O exception occurs
* @throws XmlMappingException if the given source cannot be mapped to an object
*/
protected Object unmarshalStreamSource(StreamSource streamSource) throws XmlMappingException, IOException {
if (streamSource.getInputStream() != null) {
return unmarshalInputStream(streamSource.getInputStream());
}
else if (streamSource.getReader() != null) {
return unmarshalReader(streamSource.getReader());
}
else {
throw new IllegalArgumentException("StreamSource contains neither InputStream nor Reader");
}
}
/**
* Template method for handling <code>StreamSource</code>s. This implementation defers to
* <code>unmarshalInputStream</code>, or <code>unmarshalReader</code>.
*
* @param streamSource the <code>StreamSource</code>
* @return the object graph
* @throws IOException if an I/O exception occurs
* @throws XmlMappingException if the given source cannot be mapped to an object
*/
protected Object unmarshalStreamSource(StreamSource streamSource) throws XmlMappingException, IOException {
if (streamSource.getInputStream() != null) {
return unmarshalInputStream(streamSource.getInputStream());
}
else if (streamSource.getReader() != null) {
return unmarshalReader(streamSource.getReader());
}
else {
throw new IllegalArgumentException("StreamSource contains neither InputStream nor Reader");
}
}
//
// Abstract template methods
//
//
// Abstract template methods
//
/**
* Abstract template method for marshalling the given object graph to a DOM <code>Node</code>.
* <p/>
* In practice, node is be a <code>Document</code> node, a <code>DocumentFragment</code> node, or a
* <code>Element</code> node. In other words, a node that accepts children.
*
* @param graph the root of the object graph to marshal
* @param node The DOM node that will contain the result tree
* @throws XmlMappingException if the given object cannot be marshalled to the DOM node
* @see org.w3c.dom.Document
* @see org.w3c.dom.DocumentFragment
* @see org.w3c.dom.Element
*/
protected abstract void marshalDomNode(Object graph, Node node) throws XmlMappingException;
/**
* Abstract template method for marshalling the given object graph to a DOM <code>Node</code>. <p/> In practice, node
* is be a <code>Document</code> node, a <code>DocumentFragment</code> node, or a <code>Element</code> node. In other
* words, a node that accepts children.
*
* @param graph the root of the object graph to marshal
* @param node The DOM node that will contain the result tree
* @throws XmlMappingException if the given object cannot be marshalled to the DOM node
* @see org.w3c.dom.Document
* @see org.w3c.dom.DocumentFragment
* @see org.w3c.dom.Element
*/
protected abstract void marshalDomNode(Object graph, Node node) throws XmlMappingException;
/**
* Abstract template method for marshalling the given object to a StAX <code>XMLEventWriter</code>.
*
* @param graph the root of the object graph to marshal
* @param eventWriter the <code>XMLEventWriter</code> to write to
* @throws XmlMappingException if the given object cannot be marshalled to the DOM node
*/
protected abstract void marshalXmlEventWriter(Object graph, XMLEventWriter eventWriter) throws XmlMappingException;
/**
* Abstract template method for marshalling the given object to a StAX <code>XMLEventWriter</code>.
*
* @param graph the root of the object graph to marshal
* @param eventWriter the <code>XMLEventWriter</code> to write to
* @throws XmlMappingException if the given object cannot be marshalled to the DOM node
*/
protected abstract void marshalXmlEventWriter(Object graph, XMLEventWriter eventWriter) throws XmlMappingException;
/**
* Abstract template method for marshalling the given object to a StAX <code>XMLStreamWriter</code>.
*
* @param graph the root of the object graph to marshal
* @param streamWriter the <code>XMLStreamWriter</code> to write to
* @throws XmlMappingException if the given object cannot be marshalled to the DOM node
*/
protected abstract void marshalXmlStreamWriter(Object graph, XMLStreamWriter streamWriter)
throws XmlMappingException;
/**
* Abstract template method for marshalling the given object to a StAX <code>XMLStreamWriter</code>.
*
* @param graph the root of the object graph to marshal
* @param streamWriter the <code>XMLStreamWriter</code> to write to
* @throws XmlMappingException if the given object cannot be marshalled to the DOM node
*/
protected abstract void marshalXmlStreamWriter(Object graph, XMLStreamWriter streamWriter)
throws XmlMappingException;
/**
* Abstract template method for marshalling the given object graph to a <code>OutputStream</code>.
*
* @param graph the root of the object graph to marshal
* @param outputStream the <code>OutputStream</code> to write to
* @throws XmlMappingException if the given object cannot be marshalled to the writer
* @throws IOException if an I/O exception occurs
*/
protected abstract void marshalOutputStream(Object graph, OutputStream outputStream)
throws XmlMappingException, IOException;
/**
* Abstract template method for marshalling the given object graph to a <code>OutputStream</code>.
*
* @param graph the root of the object graph to marshal
* @param outputStream the <code>OutputStream</code> to write to
* @throws XmlMappingException if the given object cannot be marshalled to the writer
* @throws IOException if an I/O exception occurs
*/
protected abstract void marshalOutputStream(Object graph, OutputStream outputStream)
throws XmlMappingException, IOException;
/**
* Abstract template method for marshalling the given object graph to a SAX <code>ContentHandler</code>.
*
* @param graph the root of the object graph to marshal
* @param contentHandler the SAX <code>ContentHandler</code>
* @param lexicalHandler the SAX2 <code>LexicalHandler</code>. Can be <code>null</code>.
* @throws XmlMappingException if the given object cannot be marshalled to the handlers
*/
protected abstract void marshalSaxHandlers(Object graph,
ContentHandler contentHandler,
LexicalHandler lexicalHandler) throws XmlMappingException;
/**
* Abstract template method for marshalling the given object graph to a SAX <code>ContentHandler</code>.
*
* @param graph the root of the object graph to marshal
* @param contentHandler the SAX <code>ContentHandler</code>
* @param lexicalHandler the SAX2 <code>LexicalHandler</code>. Can be <code>null</code>.
* @throws XmlMappingException if the given object cannot be marshalled to the handlers
*/
protected abstract void marshalSaxHandlers(Object graph,
ContentHandler contentHandler,
LexicalHandler lexicalHandler) throws XmlMappingException;
/**
* Abstract template method for marshalling the given object graph to a <code>Writer</code>.
*
* @param graph the root of the object graph to marshal
* @param writer the <code>Writer</code> to write to
* @throws XmlMappingException if the given object cannot be marshalled to the writer
* @throws IOException if an I/O exception occurs
*/
protected abstract void marshalWriter(Object graph, Writer writer) throws XmlMappingException, IOException;
/**
* Abstract template method for marshalling the given object graph to a <code>Writer</code>.
*
* @param graph the root of the object graph to marshal
* @param writer the <code>Writer</code> to write to
* @throws XmlMappingException if the given object cannot be marshalled to the writer
* @throws IOException if an I/O exception occurs
*/
protected abstract void marshalWriter(Object graph, Writer writer) throws XmlMappingException, IOException;
/**
* Abstract template method for unmarshalling from a given DOM <code>Node</code>.
*
* @param node The DOM node that contains the objects to be unmarshalled
* @return the object graph
* @throws XmlMappingException if the given DOM node cannot be mapped to an object
*/
protected abstract Object unmarshalDomNode(Node node) throws XmlMappingException;
/**
* Abstract template method for unmarshalling from a given DOM <code>Node</code>.
*
* @param node The DOM node that contains the objects to be unmarshalled
* @return the object graph
* @throws XmlMappingException if the given DOM node cannot be mapped to an object
*/
protected abstract Object unmarshalDomNode(Node node) throws XmlMappingException;
/**
* Abstract template method for unmarshalling from a given Stax <code>XMLEventReader</code>.
*
* @param eventReader The <code>XMLEventReader</code> to read from
* @return the object graph
* @throws XmlMappingException if the given event reader cannot be converted to an object
*/
protected abstract Object unmarshalXmlEventReader(XMLEventReader eventReader) throws XmlMappingException;
/**
* Abstract template method for unmarshalling from a given Stax <code>XMLEventReader</code>.
*
* @param eventReader The <code>XMLEventReader</code> to read from
* @return the object graph
* @throws XmlMappingException if the given event reader cannot be converted to an object
*/
protected abstract Object unmarshalXmlEventReader(XMLEventReader eventReader) throws XmlMappingException;
/**
* Abstract template method for unmarshalling from a given Stax <code>XMLStreamReader</code>.
*
* @param streamReader The <code>XMLStreamReader</code> to read from
* @return the object graph
* @throws XmlMappingException if the given stream reader cannot be converted to an object
*/
protected abstract Object unmarshalXmlStreamReader(XMLStreamReader streamReader) throws XmlMappingException;
/**
* Abstract template method for unmarshalling from a given Stax <code>XMLStreamReader</code>.
*
* @param streamReader The <code>XMLStreamReader</code> to read from
* @return the object graph
* @throws XmlMappingException if the given stream reader cannot be converted to an object
*/
protected abstract Object unmarshalXmlStreamReader(XMLStreamReader streamReader) throws XmlMappingException;
/**
* Abstract template method for unmarshalling from a given <code>InputStream</code>.
*
* @param inputStream the <code>InputStreamStream</code> to read from
* @return the object graph
* @throws XmlMappingException if the given stream cannot be converted to an object
* @throws IOException if an I/O exception occurs
*/
protected abstract Object unmarshalInputStream(InputStream inputStream) throws XmlMappingException, IOException;
/**
* Abstract template method for unmarshalling from a given <code>InputStream</code>.
*
* @param inputStream the <code>InputStreamStream</code> to read from
* @return the object graph
* @throws XmlMappingException if the given stream cannot be converted to an object
* @throws IOException if an I/O exception occurs
*/
protected abstract Object unmarshalInputStream(InputStream inputStream) throws XmlMappingException, IOException;
/**
* Abstract template method for unmarshalling from a given <code>Reader</code>.
*
* @param reader the <code>Reader</code> to read from
* @return the object graph
* @throws XmlMappingException if the given reader cannot be converted to an object
* @throws IOException if an I/O exception occurs
*/
protected abstract Object unmarshalReader(Reader reader) throws XmlMappingException, IOException;
/**
* Abstract template method for unmarshalling from a given <code>Reader</code>.
*
* @param reader the <code>Reader</code> to read from
* @return the object graph
* @throws XmlMappingException if the given reader cannot be converted to an object
* @throws IOException if an I/O exception occurs
*/
protected abstract Object unmarshalReader(Reader reader) throws XmlMappingException, IOException;
/**
* Abstract template method for unmarshalling using a given SAX <code>XMLReader</code> and
* <code>InputSource</code>.
*
* @param xmlReader the SAX <code>XMLReader</code> to parse with
* @param inputSource the input source to parse from
* @return the object graph
* @throws XmlMappingException if the given reader and input source cannot be converted to an object
* @throws java.io.IOException if an I/O exception occurs
*/
protected abstract Object unmarshalSaxReader(XMLReader xmlReader, InputSource inputSource)
throws XmlMappingException, IOException;
/**
* Abstract template method for unmarshalling using a given SAX <code>XMLReader</code> and <code>InputSource</code>.
*
* @param xmlReader the SAX <code>XMLReader</code> to parse with
* @param inputSource the input source to parse from
* @return the object graph
* @throws XmlMappingException if the given reader and input source cannot be converted to an object
* @throws java.io.IOException if an I/O exception occurs
*/
protected abstract Object unmarshalSaxReader(XMLReader xmlReader, InputSource inputSource)
throws XmlMappingException, IOException;
}

View File

@@ -25,16 +25,16 @@ import java.lang.reflect.Type;
* {@link Method#getGenericReturnType()}.
*
* @author Arjen Poutsma
* @since 1.0.2
* @since 3.0
*/
public interface GenericMarshaller extends Marshaller {
/**
* Indicates whether this marshaller can marshal instances of the supplied type.
*
* @param type the type that this marshaller is being asked if it can marshal
* @return <code>true</code> if this marshaller can indeed marshal instances of the supplied type;
* <code>false</code> otherwise
*/
boolean supports(Type type);
/**
* Indicates whether this marshaller can marshal instances of the supplied type.
*
* @param type the type that this marshaller is being asked if it can marshal
* @return <code>true</code> if this marshaller can indeed marshal instances of the supplied type; <code>false</code>
* otherwise
*/
boolean supports(Type type);
}

View File

@@ -21,18 +21,18 @@ package org.springframework.oxm;
* @author Arjen Poutsma
* @see MarshallingFailureException
* @see UnmarshallingFailureException
* @since 1.0.0
* @since 3.0
*/
public abstract class GenericMarshallingFailureException extends XmlMappingException {
/** Constructor for <code>GenericMarshallingFailureException</code>. */
public GenericMarshallingFailureException(String msg) {
super(msg);
}
/** Constructor for <code>GenericMarshallingFailureException</code>. */
public GenericMarshallingFailureException(String msg) {
super(msg);
}
/** Constructor for <code>GenericMarshallingFailureException</code>. */
public GenericMarshallingFailureException(String msg, Throwable ex) {
super(msg, ex);
}
/** Constructor for <code>GenericMarshallingFailureException</code>. */
public GenericMarshallingFailureException(String msg, Throwable ex) {
super(msg, ex);
}
}

View File

@@ -25,16 +25,16 @@ import java.lang.reflect.Type;
* Method#getGenericParameterTypes()} and {@link Method#getGenericReturnType()}.
*
* @author Arjen Poutsma
* @since 1.0.2
* @since 3.0
*/
public interface GenericUnmarshaller extends Unmarshaller {
/**
* Indicates whether this unmarshaller can unmarshal instances of the supplied type.
*
* @param type the type that this unmarshaller is being asked if it can marshal
* @return <code>true</code> if this unmarshaller can indeed unmarshal to the supplied type; <code>false</code>
* otherwise
*/
boolean supports(Type type);
/**
* Indicates whether this unmarshaller can unmarshal instances of the supplied type.
*
* @param type the type that this unmarshaller is being asked if it can marshal
* @return <code>true</code> if this unmarshaller can indeed unmarshal to the supplied type; <code>false</code>
* otherwise
*/
boolean supports(Type type);
}

View File

@@ -20,34 +20,32 @@ import javax.xml.transform.Result;
/**
* Defines the contract for Object XML Mapping Marshallers. Implementations of this interface can serialize a given
* Object to an XML Stream.
* <p/>
* Although the <code>marshal</code> method accepts a <code>java.lang.Object</code> as its first parameter, most
* <code>Marshaller</code> implementations cannot handle arbitrary <code>java.lang.Object</code>. Instead, a object
* class must be registered with the marshaller, or have a common base class.
* Object to an XML Stream. <p/> Although the <code>marshal</code> method accepts a <code>java.lang.Object</code> as its
* first parameter, most <code>Marshaller</code> implementations cannot handle arbitrary <code>java.lang.Object</code>.
* Instead, a object class must be registered with the marshaller, or have a common base class.
*
* @author Arjen Poutsma
* @since 1.0.0
* @since 3.0
*/
public interface Marshaller {
/**
* Marshals the object graph with the given root into the provided {@link Result}.
*
* @param graph the root of the object graph to marshal
* @param result the result to marshal to
* @throws XmlMappingException if the given object cannot be marshalled to the result
* @throws IOException if an I/O exception occurs
*/
void marshal(Object graph, Result result) throws XmlMappingException, IOException;
/**
* Marshals the object graph with the given root into the provided {@link Result}.
*
* @param graph the root of the object graph to marshal
* @param result the result to marshal to
* @throws XmlMappingException if the given object cannot be marshalled to the result
* @throws IOException if an I/O exception occurs
*/
void marshal(Object graph, Result result) throws XmlMappingException, IOException;
/**
* Indicates whether this marshaller can marshal instances of the supplied type.
*
* @param clazz the class that this marshaller is being asked if it can marshal
* @return <code>true</code> if this marshaller can indeed marshal instances of the supplied class;
* <code>false</code> otherwise
*/
boolean supports(Class clazz);
/**
* Indicates whether this marshaller can marshal instances of the supplied type.
*
* @param clazz the class that this marshaller is being asked if it can marshal
* @return <code>true</code> if this marshaller can indeed marshal instances of the supplied class; <code>false</code>
* otherwise
*/
boolean supports(Class clazz);
}

View File

@@ -19,26 +19,26 @@ package org.springframework.oxm;
* Exception thrown on marshalling failure.
*
* @author Arjen Poutsma
* @since 1.0.0
* @since 3.0
*/
public class MarshallingFailureException extends GenericMarshallingFailureException {
/**
* Construct a <code>MarshallingFailureException</code> with the specified detail message.
*
* @param msg the detail message
*/
public MarshallingFailureException(String msg) {
super(msg);
}
/**
* Construct a <code>MarshallingFailureException</code> with the specified detail message.
*
* @param msg the detail message
*/
public MarshallingFailureException(String msg) {
super(msg);
}
/**
* Construct a <code>MarshallingFailureException</code> with the specified detail message and nested exception.
*
* @param msg the detail message
* @param ex the nested exception
*/
public MarshallingFailureException(String msg, Throwable ex) {
super(msg, ex);
}
/**
* Construct a <code>MarshallingFailureException</code> with the specified detail message and nested exception.
*
* @param msg the detail message
* @param ex the nested exception
*/
public MarshallingFailureException(String msg, Throwable ex) {
super(msg, ex);
}
}

View File

@@ -19,12 +19,12 @@ package org.springframework.oxm;
* Superclass for exceptions that cannot be distinguished further.
*
* @author Arjen Poutsma
* @since 1.0.0
* @since 3.0
*/
public abstract class UncategorizedXmlMappingException extends XmlMappingException {
/** Constructor for <code>UncategorizedXmlMappingException</code>. */
protected UncategorizedXmlMappingException(String msg, Throwable ex) {
super(msg, ex);
}
/** Constructor for <code>UncategorizedXmlMappingException</code>. */
protected UncategorizedXmlMappingException(String msg, Throwable ex) {
super(msg, ex);
}
}

View File

@@ -19,32 +19,31 @@ import java.io.IOException;
import javax.xml.transform.Source;
/**
* Defines the contract for Object XML Mapping unmarshallers.
* <p/>
* <p>Implementations of this interface can deserialize a given XML Stream to an Object graph.
* Defines the contract for Object XML Mapping unmarshallers. <p/> <p>Implementations of this interface can deserialize
* a given XML Stream to an Object graph.
*
* @author Arjen Poutsma
* @since 1.0.0
* @since 3.0
*/
public interface Unmarshaller {
/**
* Unmarshals the given {@link Source} into an object graph.
*
* @param source the source to marshal from
* @return the object graph
* @throws XmlMappingException if the given source cannot be mapped to an object
* @throws IOException if an I/O Exception occurs
*/
Object unmarshal(Source source) throws XmlMappingException, IOException;
/**
* Unmarshals the given {@link Source} into an object graph.
*
* @param source the source to marshal from
* @return the object graph
* @throws XmlMappingException if the given source cannot be mapped to an object
* @throws IOException if an I/O Exception occurs
*/
Object unmarshal(Source source) throws XmlMappingException, IOException;
/**
* Indicates whether this unmarshaller can unmarshal instances of the supplied type.
*
* @param clazz the class that this unmarshaller is being asked if it can marshal
* @return <code>true</code> if this unmarshaller can indeed unmarshal to the supplied class; <code>false</code>
* otherwise
*/
boolean supports(Class clazz);
/**
* Indicates whether this unmarshaller can unmarshal instances of the supplied type.
*
* @param clazz the class that this unmarshaller is being asked if it can marshal
* @return <code>true</code> if this unmarshaller can indeed unmarshal to the supplied class; <code>false</code>
* otherwise
*/
boolean supports(Class clazz);
}

View File

@@ -19,17 +19,17 @@ package org.springframework.oxm;
* Exception thrown on unmarshalling failure.
*
* @author Arjen Poutsma
* @since 1.0.0
* @since 3.0
*/
public class UnmarshallingFailureException extends GenericMarshallingFailureException {
/** Constructor for <code>UnmarshallingFailureException</code>. */
public UnmarshallingFailureException(String msg) {
super(msg);
}
/** Constructor for <code>UnmarshallingFailureException</code>. */
public UnmarshallingFailureException(String msg) {
super(msg);
}
/** Constructor for <code>UnmarshallingFailureException</code>. */
public UnmarshallingFailureException(String msg, Throwable ex) {
super(msg, ex);
}
/** Constructor for <code>UnmarshallingFailureException</code>. */
public UnmarshallingFailureException(String msg, Throwable ex) {
super(msg, ex);
}
}

View File

@@ -19,17 +19,17 @@ package org.springframework.oxm;
* Exception thrown on marshalling validation failure.
*
* @author Arjen Poutsma
* @since 1.0.0
* @since 3.0
*/
public class ValidationFailureException extends XmlMappingException {
/** Constructor for <code>ValidationFailureException</code>. */
public ValidationFailureException(String msg) {
super(msg);
}
/** Constructor for <code>ValidationFailureException</code>. */
public ValidationFailureException(String msg) {
super(msg);
}
/** Constructor for <code>ValidationFailureException</code>. */
public ValidationFailureException(String msg, Throwable ex) {
super(msg, ex);
}
/** Constructor for <code>ValidationFailureException</code>. */
public ValidationFailureException(String msg, Throwable ex) {
super(msg, ex);
}
}

View File

@@ -50,396 +50,386 @@ import org.springframework.oxm.AbstractMarshaller;
import org.springframework.oxm.XmlMappingException;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.xml.dom.DomContentHandler;
import org.springframework.xml.sax.SaxUtils;
import org.springframework.xml.stream.StaxEventContentHandler;
import org.springframework.xml.stream.StaxEventXmlReader;
import org.springframework.xml.stream.StaxStreamContentHandler;
import org.springframework.xml.stream.StaxStreamXmlReader;
import org.springframework.util.xml.DomUtils;
import org.springframework.util.xml.SaxUtils;
import org.springframework.util.xml.StaxUtils;
/**
* Implementation of the <code>Marshaller</code> interface for Castor. By default, Castor does not require any further
* configuration, though setting a target class 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</code>, the <code>CastorMarshaller</code> can only be used
* to unmarshall XML that represents that specific class. If you want to unmarshall multiple classes, you have to
*
* <p>If a target class is specified using <code>setTargetClass</code>, the <code>CastorMarshaller</code> can only be
* used to unmarshall XML that represents that specific class. If you want to unmarshall multiple classes, you have to
* provide a mapping file using <code>setMappingLocations</code>.
* <p/>
* Due to Castor's API, it is required to set the encoding used for writing to output streams. It defaults to
* <code>UTF-8</code>.
*
* <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</code>.
*
* @author Arjen Poutsma
* @see #setEncoding(String)
* @see #setTargetClass(Class)
* @see #setMappingLocation(org.springframework.core.io.Resource)
* @see #setMappingLocations(org.springframework.core.io.Resource[])
* @since 1.0.0
* @see #setMappingLocation(Resource)
* @see #setMappingLocations(Resource[])
* @since 3.0
*/
public class CastorMarshaller extends AbstractMarshaller implements InitializingBean {
/** The default encoding used for stream access. */
public static final String DEFAULT_ENCODING = "UTF-8";
/** The default encoding used for stream access. */
public static final String DEFAULT_ENCODING = "UTF-8";
private Resource[] mappingLocations;
private Resource[] mappingLocations;
private String encoding = DEFAULT_ENCODING;
private String encoding = DEFAULT_ENCODING;
private Class targetClass;
private Class targetClass;
private XMLContext xmlContext;
private XMLContext xmlContext;
private boolean validating = false;
private boolean validating = false;
private boolean whitespacePreserve = false;
private boolean whitespacePreserve = false;
private boolean ignoreExtraAttributes = true;
private boolean ignoreExtraAttributes = true;
private boolean ignoreExtraElements = false;
private boolean ignoreExtraElements = false;
private Properties namespaceMappings;
private Properties namespaceMappings;
/** Returns whether the Castor {@link Unmarshaller} should ignore attributes that do not match a specific field. */
public boolean getIgnoreExtraAttributes() {
return ignoreExtraAttributes;
}
/** Returns whether the Castor {@link Unmarshaller} should ignore attributes that do not match a specific field. */
public boolean getIgnoreExtraAttributes() {
return ignoreExtraAttributes;
}
/**
* Sets whether the Castor {@link Unmarshaller} should ignore attributes that do not match a specific field.
* Default is <code>true</code>: extra attributes are ignored.
*
* @see org.exolab.castor.xml.Unmarshaller#setIgnoreExtraAttributes(boolean)
*/
public void setIgnoreExtraAttributes(boolean ignoreExtraAttributes) {
this.ignoreExtraAttributes = ignoreExtraAttributes;
}
/**
* Sets whether the Castor {@link Unmarshaller} should ignore attributes that do not match a specific field. Default
* is <code>true</code>: extra attributes are ignored.
*
* @see org.exolab.castor.xml.Unmarshaller#setIgnoreExtraAttributes(boolean)
*/
public void setIgnoreExtraAttributes(boolean ignoreExtraAttributes) {
this.ignoreExtraAttributes = ignoreExtraAttributes;
}
/** Returns whether the Castor {@link Unmarshaller} should ignore elements that do not match a specific field. */
public boolean getIgnoreExtraElements() {
return ignoreExtraElements;
}
/** Returns whether the Castor {@link Unmarshaller} should ignore elements that do not match a specific field. */
public boolean getIgnoreExtraElements() {
return ignoreExtraElements;
}
/**
* Sets whether the Castor {@link Unmarshaller} should ignore elements that do not match a specific field. Default
* is <code>false</code>, extra attributes are flagged as an error.
*
* @see org.exolab.castor.xml.Unmarshaller#setIgnoreExtraElements(boolean)
*/
public void setIgnoreExtraElements(boolean ignoreExtraElements) {
this.ignoreExtraElements = ignoreExtraElements;
}
/**
* Sets whether the Castor {@link Unmarshaller} should ignore elements that do not match a specific field. Default is
* <code>false</code>, extra attributes are flagged as an error.
*
* @see org.exolab.castor.xml.Unmarshaller#setIgnoreExtraElements(boolean)
*/
public void setIgnoreExtraElements(boolean ignoreExtraElements) {
this.ignoreExtraElements = ignoreExtraElements;
}
/** Returns whether the Castor {@link Unmarshaller} should preserve "ignorable" whitespace. */
public boolean getWhitespacePreserve() {
return whitespacePreserve;
}
/** Returns whether the Castor {@link Unmarshaller} should preserve "ignorable" whitespace. */
public boolean getWhitespacePreserve() {
return whitespacePreserve;
}
/**
* Sets whether the Castor {@link Unmarshaller} should preserve "ignorable" whitespace. Default is
* <code>false</code>.
*
* @see org.exolab.castor.xml.Unmarshaller#setWhitespacePreserve(boolean)
*/
public void setWhitespacePreserve(boolean whitespacePreserve) {
this.whitespacePreserve = whitespacePreserve;
}
/**
* Sets whether the Castor {@link Unmarshaller} should preserve "ignorable" whitespace. Default is <code>false</code>.
*
* @see org.exolab.castor.xml.Unmarshaller#setWhitespacePreserve(boolean)
*/
public void setWhitespacePreserve(boolean whitespacePreserve) {
this.whitespacePreserve = whitespacePreserve;
}
/** Returns whether this marshaller should validate in- and outgoing documents. */
public boolean isValidating() {
return validating;
}
/** Returns whether this marshaller should validate in- and outgoing documents. */
public boolean isValidating() {
return validating;
}
/**
* Sets whether this marshaller should validate in- and outgoing documents. Default is <code>false</code>.
*
* @see Marshaller#setValidation(boolean)
*/
public void setValidating(boolean validating) {
this.validating = validating;
}
/**
* Sets whether this marshaller should validate in- and outgoing documents. Default is <code>false</code>.
*
* @see Marshaller#setValidation(boolean)
*/
public void setValidating(boolean validating) {
this.validating = validating;
}
/** Returns the namespace mappings. Property names are interpreted as namespace prefixes; values are namespace URIs. */
public Properties getNamespaceMappings() {
return namespaceMappings;
}
/** Returns the namespace mappings. Property names are interpreted as namespace prefixes; values are namespace URIs. */
public Properties getNamespaceMappings() {
return namespaceMappings;
}
/**
* Sets 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(Properties namespaceMappings) {
this.namespaceMappings = namespaceMappings;
}
/**
* Sets 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(Properties namespaceMappings) {
this.namespaceMappings = namespaceMappings;
}
/**
* Sets the encoding to be used for stream access. If this property is not set, the default encoding is used.
*
* @see #DEFAULT_ENCODING
*/
public void setEncoding(String encoding) {
this.encoding = encoding;
}
/**
* Sets the encoding to be used for stream access. If this property is not set, the default encoding is used.
*
* @see #DEFAULT_ENCODING
*/
public void setEncoding(String encoding) {
this.encoding = encoding;
}
/** Sets the locations of the Castor XML Mapping files. */
public void setMappingLocation(Resource mappingLocation) {
mappingLocations = new Resource[]{mappingLocation};
}
/** Sets the locations of the Castor XML Mapping files. */
public void setMappingLocation(Resource mappingLocation) {
mappingLocations = new Resource[]{mappingLocation};
}
/** Sets the locations of the Castor XML Mapping files. */
public void setMappingLocations(Resource[] mappingLocations) {
this.mappingLocations = mappingLocations;
}
/** Sets the locations of the Castor XML Mapping files. */
public void setMappingLocations(Resource[] mappingLocations) {
this.mappingLocations = mappingLocations;
}
/**
* Sets the Castor target class. If this property is set, this <code>CastorMarshaller</code> is tied to this one
* specific class. Use a mapping file for unmarshalling multiple classes.
* <p/>
* You cannot set both this property and the mapping (location).
*/
public void setTargetClass(Class targetClass) {
this.targetClass = targetClass;
}
/**
* Sets the Castor target class. If this property is set, this <code>CastorMarshaller</code> is tied to this one
* specific class. Use a mapping file for unmarshalling multiple classes. <p/> You cannot set both this property and
* the mapping (location).
*/
public void setTargetClass(Class targetClass) {
this.targetClass = targetClass;
}
public final void afterPropertiesSet() throws IOException {
if (mappingLocations != null && targetClass != null) {
throw new IllegalArgumentException("Cannot set both the 'mappingLocations' and 'targetClass' property. " +
"Set targetClass for unmarshalling a single class, and 'mappingLocations' for multiple classes'");
}
if (logger.isInfoEnabled()) {
if (mappingLocations != null) {
logger.info("Configured using " + StringUtils.arrayToCommaDelimitedString(mappingLocations));
}
else if (targetClass != null) {
logger.info("Configured for target class [" + targetClass.getName() + "]");
}
else {
logger.info("Using default configuration");
}
}
try {
xmlContext = createXMLContext(mappingLocations, targetClass);
}
catch (MappingException ex) {
throw new CastorSystemException("Could not load Castor mapping: " + ex.getMessage(), ex);
}
catch (ResolverException rex) {
throw new CastorSystemException("Could not load Castor mapping: " + rex.getMessage(), rex);
}
}
public final void afterPropertiesSet() throws IOException {
if (mappingLocations != null && targetClass != null) {
throw new IllegalArgumentException("Cannot set both the 'mappingLocations' and 'targetClass' property. " +
"Set targetClass for unmarshalling a single class, and 'mappingLocations' for multiple classes'");
}
if (logger.isInfoEnabled()) {
if (mappingLocations != null) {
logger.info("Configured using " + StringUtils.arrayToCommaDelimitedString(mappingLocations));
}
else if (targetClass != null) {
logger.info("Configured for target class [" + targetClass.getName() + "]");
}
else {
logger.info("Using default configuration");
}
}
try {
xmlContext = createXMLContext(mappingLocations, targetClass);
}
catch (MappingException ex) {
throw new CastorSystemException("Could not load Castor mapping: " + ex.getMessage(), ex);
}
catch (ResolverException rex) {
throw new CastorSystemException("Could not load Castor mapping: " + rex.getMessage(), rex);
}
}
/** Returns <code>true</code> for all classes, i.e. Castor supports arbitrary classes. */
public boolean supports(Class clazz) {
return true;
}
/** Returns <code>true</code> for all classes, i.e. Castor supports arbitrary classes. */
public boolean supports(Class clazz) {
return true;
}
/**
* Creates the Castor <code>XMLContext</code>. Subclasses can override this to create a custom context.
* <p/>
* The default implementation loads mapping files if defined, and the target class if not 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(Resource[] mappingLocations, Class targetClass)
throws MappingException, IOException, ResolverException {
XMLContext context = new XMLContext();
if (!ObjectUtils.isEmpty(mappingLocations)) {
Mapping mapping = new Mapping();
for (int i = 0; i < mappingLocations.length; i++) {
mapping.loadMapping(SaxUtils.createInputSource(mappingLocations[i]));
}
context.addMapping(mapping);
}
if (targetClass != null) {
context.addClass(targetClass);
}
return context;
}
/**
* Creates the Castor <code>XMLContext</code>. Subclasses can override this to create a custom context. <p/> The
* default implementation loads mapping files if defined, and the target class if not 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(Resource[] mappingLocations, Class targetClass)
throws MappingException, IOException, ResolverException {
XMLContext context = new XMLContext();
if (!ObjectUtils.isEmpty(mappingLocations)) {
Mapping mapping = new Mapping();
for (Resource mappingLocation : mappingLocations) {
mapping.loadMapping(SaxUtils.createInputSource(mappingLocation));
}
context.addMapping(mapping);
}
if (targetClass != null) {
context.addClass(targetClass);
}
return context;
}
//
// Marshalling
//
//
// Marshalling
//
@Override
@Override
protected final void marshalDomNode(Object graph, Node node) throws XmlMappingException {
marshalSaxHandlers(graph, new DomContentHandler(node), null);
}
marshalSaxHandlers(graph, DomUtils.createContentHandler(node), null);
}
@Override
@Override
protected final void marshalSaxHandlers(Object graph, ContentHandler contentHandler, LexicalHandler lexicalHandler)
throws XmlMappingException {
Marshaller marshaller = xmlContext.createMarshaller();
marshaller.setContentHandler(contentHandler);
marshal(graph, marshaller);
}
throws XmlMappingException {
Marshaller marshaller = xmlContext.createMarshaller();
marshaller.setContentHandler(contentHandler);
marshal(graph, marshaller);
}
@Override
@Override
protected final void marshalOutputStream(Object graph, OutputStream outputStream)
throws XmlMappingException, IOException {
marshalWriter(graph, new OutputStreamWriter(outputStream, encoding));
}
throws XmlMappingException, IOException {
marshalWriter(graph, new OutputStreamWriter(outputStream, encoding));
}
@Override
@Override
protected final void marshalWriter(Object graph, Writer writer) throws XmlMappingException, IOException {
Marshaller marshaller = xmlContext.createMarshaller();
marshaller.setWriter(writer);
marshal(graph, marshaller);
}
Marshaller marshaller = xmlContext.createMarshaller();
marshaller.setWriter(writer);
marshal(graph, marshaller);
}
@Override
@Override
protected final void marshalXmlEventWriter(Object graph, XMLEventWriter eventWriter) throws XmlMappingException {
marshalSaxHandlers(graph, new StaxEventContentHandler(eventWriter), null);
}
marshalSaxHandlers(graph, StaxUtils.createContentHandler(eventWriter), null);
}
@Override
@Override
protected final void marshalXmlStreamWriter(Object graph, XMLStreamWriter streamWriter) throws XmlMappingException {
marshalSaxHandlers(graph, new StaxStreamContentHandler(streamWriter), null);
}
marshalSaxHandlers(graph, StaxUtils.createContentHandler(streamWriter), null);
}
private void marshal(Object graph, Marshaller marshaller) {
try {
customizeMarshaller(marshaller);
marshaller.marshal(graph);
}
catch (XMLException ex) {
throw convertCastorException(ex, true);
}
}
private void marshal(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}.
* <p/>
* Default implementation invokes {@link Marshaller#setValidation(boolean)} with the property set on this
* marshaller, and calls {@link Marshaller#setNamespaceMapping(String, String)} with the {@linkplain
* #setNamespaceMappings(java.util.Properties) namespace mappings}.
*/
protected void customizeMarshaller(Marshaller marshaller) {
marshaller.setValidation(isValidating());
Properties namespaceMappings = getNamespaceMappings();
if (namespaceMappings != null) {
for (Iterator iterator = namespaceMappings.keySet().iterator(); iterator.hasNext();) {
String prefix = (String) iterator.next();
String uri = namespaceMappings.getProperty(prefix);
marshaller.setNamespaceMapping(prefix, uri);
}
}
}
/**
* Template method that allows for customizing of the given Castor {@link Marshaller}. <p/> Default implementation
* invokes {@link Marshaller#setValidation(boolean)} with the property set on this marshaller, and calls {@link
* Marshaller#setNamespaceMapping(String, String)} with the {@linkplain #setNamespaceMappings(java.util.Properties)
* namespace mappings}.
*/
protected void customizeMarshaller(Marshaller marshaller) {
marshaller.setValidation(isValidating());
Properties namespaceMappings = getNamespaceMappings();
if (namespaceMappings != null) {
for (Iterator iterator = namespaceMappings.keySet().iterator(); iterator.hasNext();) {
String prefix = (String) iterator.next();
String uri = namespaceMappings.getProperty(prefix);
marshaller.setNamespaceMapping(prefix, uri);
}
}
}
//
// Unmarshalling
//
//
// Unmarshalling
//
@Override
@Override
protected final Object unmarshalDomNode(Node node) throws XmlMappingException {
try {
return createUnmarshaller().unmarshal(node);
}
catch (XMLException ex) {
throw convertCastorException(ex, false);
}
}
try {
return createUnmarshaller().unmarshal(node);
}
catch (XMLException ex) {
throw convertCastorException(ex, false);
}
}
@Override
@Override
protected final Object unmarshalInputStream(InputStream inputStream) throws XmlMappingException, IOException {
try {
return createUnmarshaller().unmarshal(new InputSource(inputStream));
}
catch (XMLException ex) {
throw convertCastorException(ex, false);
}
}
try {
return createUnmarshaller().unmarshal(new InputSource(inputStream));
}
catch (XMLException ex) {
throw convertCastorException(ex, false);
}
}
@Override
@Override
protected final Object unmarshalReader(Reader reader) throws XmlMappingException, IOException {
try {
return createUnmarshaller().unmarshal(new InputSource(reader));
}
catch (XMLException ex) {
throw convertCastorException(ex, false);
}
}
try {
return createUnmarshaller().unmarshal(new InputSource(reader));
}
catch (XMLException ex) {
throw convertCastorException(ex, false);
}
}
@Override
@Override
protected final Object unmarshalXmlEventReader(XMLEventReader eventReader) {
XMLReader reader = new StaxEventXmlReader(eventReader);
try {
return unmarshalSaxReader(reader, new InputSource());
}
catch (IOException ex) {
throw new CastorUnmarshallingFailureException(new MarshalException(ex));
}
}
XMLReader reader = StaxUtils.createXMLReader(eventReader);
try {
return unmarshalSaxReader(reader, new InputSource());
}
catch (IOException ex) {
throw new CastorUnmarshallingFailureException(new MarshalException(ex));
}
}
@Override
@Override
protected final 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 CastorUnmarshallingFailureException(ex);
}
}
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 CastorUnmarshallingFailureException(ex);
}
}
@Override
@Override
protected final Object unmarshalXmlStreamReader(XMLStreamReader streamReader) {
XMLReader reader = new StaxStreamXmlReader(streamReader);
try {
return unmarshalSaxReader(reader, new InputSource());
}
catch (IOException ex) {
throw new CastorUnmarshallingFailureException(new MarshalException(ex));
}
}
XMLReader reader = StaxUtils.createXMLReader(streamReader);
try {
return unmarshalSaxReader(reader, new InputSource());
}
catch (IOException ex) {
throw new CastorUnmarshallingFailureException(new MarshalException(ex));
}
}
private Unmarshaller createUnmarshaller() {
Unmarshaller unmarshaller = xmlContext.createUnmarshaller();
if (targetClass != null) {
unmarshaller.setClass(targetClass);
unmarshaller.setClassLoader(targetClass.getClassLoader());
}
customizeUnmarshaller(unmarshaller);
return unmarshaller;
}
private Unmarshaller createUnmarshaller() {
Unmarshaller unmarshaller = xmlContext.createUnmarshaller();
if (targetClass != null) {
unmarshaller.setClass(targetClass);
unmarshaller.setClassLoader(targetClass.getClassLoader());
}
customizeUnmarshaller(unmarshaller);
return unmarshaller;
}
/**
* Template method that allows for customizing of the given Castor {@link Unmarshaller}.
* <p/>
* Default implementation invokes {@link Unmarshaller#setValidation(boolean)}, {@link
* Unmarshaller#setWhitespacePreserve(boolean)}, {@link Unmarshaller#setIgnoreExtraAttributes(boolean)}, and {@link
* Unmarshaller#setIgnoreExtraElements(boolean)} with the properties set on this marshaller.
*/
protected void customizeUnmarshaller(Unmarshaller unmarshaller) {
unmarshaller.setValidation(isValidating());
unmarshaller.setWhitespacePreserve(getWhitespacePreserve());
unmarshaller.setIgnoreExtraAttributes(getIgnoreExtraAttributes());
unmarshaller.setIgnoreExtraElements(getIgnoreExtraElements());
}
/**
* Template method that allows for customizing of the given Castor {@link Unmarshaller}. <p/> Default implementation
* invokes {@link Unmarshaller#setValidation(boolean)}, {@link Unmarshaller#setWhitespacePreserve(boolean)}, {@link
* Unmarshaller#setIgnoreExtraAttributes(boolean)}, and {@link Unmarshaller#setIgnoreExtraElements(boolean)} with the
* properties set on this marshaller.
*/
protected void customizeUnmarshaller(Unmarshaller unmarshaller) {
unmarshaller.setValidation(isValidating());
unmarshaller.setWhitespacePreserve(getWhitespacePreserve());
unmarshaller.setIgnoreExtraAttributes(getIgnoreExtraAttributes());
unmarshaller.setIgnoreExtraElements(getIgnoreExtraElements());
}
/**
* Converts the given <code>CastorException</code> to an appropriate exception from the
* <code>org.springframework.oxm</code> hierarchy.
* <p/>
* The default implementation delegates to <code>CastorUtils</code>. Can be overridden in subclasses.
* <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 Castor <code>XMLException</code> that occured
* @param marshalling indicates whether the exception occurs during marshalling (<code>true</code>), or
* unmarshalling (<code>false</code>)
* @return the corresponding <code>XmlMappingException</code>
* @see CastorUtils#convertXmlException
*/
public XmlMappingException convertCastorException(XMLException ex, boolean marshalling) {
return CastorUtils.convertXmlException(ex, marshalling);
}
/**
* Converts the given <code>CastorException</code> to an appropriate exception from the
* <code>org.springframework.oxm</code> hierarchy. <p/> The default implementation delegates to
* <code>CastorUtils</code>. Can be overridden in subclasses. <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 Castor <code>XMLException</code> that occured
* @param marshalling indicates whether the exception occurs during marshalling (<code>true</code>), or unmarshalling
* (<code>false</code>)
* @return the corresponding <code>XmlMappingException</code>
* @see CastorUtils#convertXmlException
*/
public XmlMappingException convertCastorException(XMLException ex, boolean marshalling) {
return CastorUtils.convertXmlException(ex, marshalling);
}
}

View File

@@ -16,6 +16,7 @@
package org.springframework.oxm.castor;
import org.exolab.castor.xml.MarshalException;
import org.springframework.oxm.MarshallingFailureException;
/**
@@ -23,12 +24,12 @@ import org.springframework.oxm.MarshallingFailureException;
*
* @author Arjen Poutsma
* @see CastorUtils#convertXmlException
* @since 1.0.0
* @since 3.0
*/
public class CastorMarshallingFailureException extends MarshallingFailureException {
public CastorMarshallingFailureException(MarshalException ex) {
super("Castor marshalling exception: " + ex.getMessage(), ex);
}
public CastorMarshallingFailureException(MarshalException ex) {
super("Castor marshalling exception: " + ex.getMessage(), ex);
}
}

View File

@@ -22,11 +22,11 @@ import org.springframework.oxm.UncategorizedXmlMappingException;
* distinguished further.
*
* @author Arjen Poutsma
* @since 1.0.0
* @since 3.0
*/
public class CastorSystemException extends UncategorizedXmlMappingException {
public CastorSystemException(String msg, Throwable ex) {
super(msg, ex);
}
public CastorSystemException(String msg, Throwable ex) {
super(msg, ex);
}
}

View File

@@ -16,23 +16,24 @@
package org.springframework.oxm.castor;
import org.exolab.castor.xml.MarshalException;
import org.springframework.oxm.UnmarshallingFailureException;
import org.xml.sax.SAXException;
import org.springframework.oxm.UnmarshallingFailureException;
/**
* Castor-specific subclass of <code>UnmarshallingFailureException</code>.
*
* @author Arjen Poutsma
* @see CastorUtils#convertXmlException
* @since 1.0.0
* @since 3.0
*/
public class CastorUnmarshallingFailureException extends UnmarshallingFailureException {
public CastorUnmarshallingFailureException(MarshalException ex) {
super("Castor unmarshalling exception: " + ex.getMessage(), ex);
}
public CastorUnmarshallingFailureException(MarshalException ex) {
super("Castor unmarshalling exception: " + ex.getMessage(), ex);
}
public CastorUnmarshallingFailureException(SAXException ex) {
super("Castor unmarshalling exception: " + ex.getMessage(), ex);
}
public CastorUnmarshallingFailureException(SAXException ex) {
super("Castor unmarshalling exception: " + ex.getMessage(), ex);
}
}

View File

@@ -18,43 +18,43 @@ package org.springframework.oxm.castor;
import org.exolab.castor.xml.MarshalException;
import org.exolab.castor.xml.ValidationException;
import org.exolab.castor.xml.XMLException;
import org.springframework.oxm.XmlMappingException;
/**
* Generic utility methods for working with Castor. Mainly for internal use within the framework.
*
* @author Arjen Poutsma
* @since 1.0.0
* @since 3.0
*/
public class CastorUtils {
/**
* Converts the given <code>XMLException</code> to an appropriate exception from the
* <code>org.springframework.oxm</code> 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 Castor <code>XMLException</code> that occured
* @param marshalling indicates whether the exception occurs during marshalling (<code>true</code>), or
* unmarshalling (<code>false</code>)
* @return the corresponding <code>XmlMappingException</code>
*/
public static XmlMappingException convertXmlException(XMLException ex, boolean marshalling) {
if (ex instanceof MarshalException) {
MarshalException marshalException = (MarshalException) ex;
if (marshalling) {
return new CastorMarshallingFailureException(marshalException);
}
else {
return new CastorUnmarshallingFailureException(marshalException);
}
}
else if (ex instanceof ValidationException) {
return new CastorValidationFailureException((ValidationException) ex);
}
// fallback
return new CastorSystemException("Unknown Castor exception: " + ex.getMessage(), ex);
}
/**
* Converts the given <code>XMLException</code> to an appropriate exception from the
* <code>org.springframework.oxm</code> 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 Castor <code>XMLException</code> that occured
* @param marshalling indicates whether the exception occurs during marshalling (<code>true</code>), or unmarshalling
* (<code>false</code>)
* @return the corresponding <code>XmlMappingException</code>
*/
public static XmlMappingException convertXmlException(XMLException ex, boolean marshalling) {
if (ex instanceof MarshalException) {
MarshalException marshalException = (MarshalException) ex;
if (marshalling) {
return new CastorMarshallingFailureException(marshalException);
}
else {
return new CastorUnmarshallingFailureException(marshalException);
}
}
else if (ex instanceof ValidationException) {
return new CastorValidationFailureException((ValidationException) ex);
}
// fallback
return new CastorSystemException("Unknown Castor exception: " + ex.getMessage(), ex);
}
}

View File

@@ -16,6 +16,7 @@
package org.springframework.oxm.castor;
import org.exolab.castor.xml.ValidationException;
import org.springframework.oxm.ValidationFailureException;
/**
@@ -23,11 +24,11 @@ import org.springframework.oxm.ValidationFailureException;
*
* @author Arjen Poutsma
* @see CastorUtils#convertXmlException
* @since 1.0.0
* @since 3.0
*/
public class CastorValidationFailureException extends ValidationFailureException {
public CastorValidationFailureException(ValidationException ex) {
super("Castor validation exception: " + ex.getMessage(), ex);
}
public CastorValidationFailureException(ValidationException ex) {
super("Castor validation exception: " + ex.getMessage(), ex);
}
}

View File

@@ -1,37 +0,0 @@
/*
* Copyright 2008 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>&lt;oxm:jaxb1-marshaller/&gt; element.
*
* @author Arjen Poutsma
* @since 1.5.0
*/
class Jaxb1MarshallerBeanDefinitionParser extends AbstractSimpleBeanDefinitionParser {
public static final String JAXB1_MARSHALLER_CLASS_NAME = "org.springframework.oxm.jaxb.Jaxb1Marshaller";
@Override
protected String getBeanClassName(Element element) {
return JAXB1_MARSHALLER_CLASS_NAME;
}
}

View File

@@ -19,45 +19,46 @@ package org.springframework.oxm.config;
import java.util.Iterator;
import java.util.List;
import org.w3c.dom.Element;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
/**
* Parser for the <code>&lt;oxm:jaxb2-marshaller/&gt; element.
*
* @author Arjen Poutsma
* @since 1.5.0
* @since 3.0
*/
class Jaxb2MarshallerBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
private static final String JAXB2_MARSHALLER_CLASS_NAME = "org.springframework.oxm.jaxb.Jaxb2Marshaller";
private static final String JAXB2_MARSHALLER_CLASS_NAME = "org.springframework.oxm.jaxb.Jaxb2Marshaller";
@Override
@Override
protected String getBeanClassName(Element element) {
return JAXB2_MARSHALLER_CLASS_NAME;
}
return JAXB2_MARSHALLER_CLASS_NAME;
}
@Override
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder beanDefinitionBuilder) {
String contextPath = element.getAttribute("contextPath");
if (StringUtils.hasText(contextPath)) {
beanDefinitionBuilder.addPropertyValue("contextPath", contextPath);
}
List classes = DomUtils.getChildElementsByTagName(element, "class-to-be-bound");
if (!classes.isEmpty()) {
ManagedList classesToBeBound = new ManagedList(classes.size());
for (Iterator iterator = classes.iterator(); iterator.hasNext();) {
Element classToBeBound = (Element) iterator.next();
String className = classToBeBound.getAttribute("name");
classesToBeBound.add(className);
}
beanDefinitionBuilder.addPropertyValue("classesToBeBound", classesToBeBound);
}
}
String contextPath = element.getAttribute("contextPath");
if (StringUtils.hasText(contextPath)) {
beanDefinitionBuilder.addPropertyValue("contextPath", contextPath);
}
List classes = DomUtils.getChildElementsByTagName(element, "class-to-be-bound");
if (!classes.isEmpty()) {
ManagedList classesToBeBound = new ManagedList(classes.size());
for (Iterator iterator = classes.iterator(); iterator.hasNext();) {
Element classToBeBound = (Element) iterator.next();
String className = classToBeBound.getAttribute("name");
classesToBeBound.add(className);
}
beanDefinitionBuilder.addPropertyValue("classesToBeBound", classesToBeBound);
}
}
}

View File

@@ -24,15 +24,15 @@ import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
* Parser for the <code>&lt;oxm:jibx-marshaller/&gt; element.
*
* @author Arjen Poutsma
* @since 1.5.0
* @since 3.0
*/
class JibxMarshallerBeanDefinitionParser extends AbstractSimpleBeanDefinitionParser {
private static final String JIBX_MARSHALLER_CLASS_NAME = "org.springframework.oxm.jibx.JibxMarshaller";
private static final String JIBX_MARSHALLER_CLASS_NAME = "org.springframework.oxm.jibx.JibxMarshaller";
@Override
@Override
protected String getBeanClassName(Element element) {
return JIBX_MARSHALLER_CLASS_NAME;
}
return JIBX_MARSHALLER_CLASS_NAME;
}
}

View File

@@ -23,14 +23,13 @@ import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
* {@link NamespaceHandler} for the '<code>oxm</code>' namespace.
*
* @author Arjen Poutsma
* @since 1.5.0
* @since 3.0
*/
public class OxmNamespaceHandler extends NamespaceHandlerSupport {
public void init() {
registerBeanDefinitionParser("jaxb1-marshaller", new Jaxb1MarshallerBeanDefinitionParser());
registerBeanDefinitionParser("jaxb2-marshaller", new Jaxb2MarshallerBeanDefinitionParser());
registerBeanDefinitionParser("jibx-marshaller", new JibxMarshallerBeanDefinitionParser());
registerBeanDefinitionParser("xmlbeans-marshaller", new XmlBeansMarshallerBeanDefinitionParser());
}
public void init() {
registerBeanDefinitionParser("jaxb2-marshaller", new Jaxb2MarshallerBeanDefinitionParser());
registerBeanDefinitionParser("jibx-marshaller", new JibxMarshallerBeanDefinitionParser());
registerBeanDefinitionParser("xmlbeans-marshaller", new XmlBeansMarshallerBeanDefinitionParser());
}
}

View File

@@ -27,22 +27,22 @@ import org.springframework.util.StringUtils;
* Parser for the <code>&lt;oxm:xmlbeans-marshaller/&gt; element.
*
* @author Arjen Poutsma
* @since 1.5.0
* @since 3.0
*/
class XmlBeansMarshallerBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
public static final String XML_BEANS_MARSHALLER_CLASS_NAME = "org.springframework.oxm.xmlbeans.XmlBeansMarshaller";
public static final String XML_BEANS_MARSHALLER_CLASS_NAME = "org.springframework.oxm.xmlbeans.XmlBeansMarshaller";
@Override
@Override
protected String getBeanClassName(Element element) {
return XML_BEANS_MARSHALLER_CLASS_NAME;
}
return XML_BEANS_MARSHALLER_CLASS_NAME;
}
@Override
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder beanDefinitionBuilder) {
String optionsName = element.getAttribute("options");
if (StringUtils.hasText(optionsName)) {
beanDefinitionBuilder.addPropertyReference("xmlOptions", optionsName);
}
}
String optionsName = element.getAttribute("options");
if (StringUtils.hasText(optionsName)) {
beanDefinitionBuilder.addPropertyReference("xmlOptions", optionsName);
}
}
}

View File

@@ -26,6 +26,7 @@ import javax.xml.bind.ValidationEventHandler;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.oxm.XmlMappingException;
import org.springframework.util.Assert;
@@ -33,176 +34,171 @@ import org.springframework.util.StringUtils;
/**
* Abstract base class for implementations of the <code>Marshaller</code> and <code>Unmarshaller</code> interfaces that
* use JAXB. This base class is responsible for creating JAXB marshallers from a <code>JAXBContext</code>.
* <p/>
* JAXB 2.0 added breaking API changes, so specific subclasses must be used for JAXB 1.0 and 2.0
* (<code>Jaxb1Marshaller</code> and <code>Jaxb2Marshaller</code> respectivaly).
* use JAXB. This base class is responsible for creating JAXB marshallers from a <code>JAXBContext</code>. <p/> JAXB 2.0
* added breaking API changes, so specific subclasses must be used for JAXB 1.0 and 2.0 (<code>Jaxb1Marshaller</code>
* and <code>Jaxb2Marshaller</code> respectivaly).
*
* @author Arjen Poutsma
* @see Jaxb1Marshaller
* @see Jaxb2Marshaller
* @since 1.0.0
* @since 3.0
*/
public abstract class AbstractJaxbMarshaller
implements org.springframework.oxm.Marshaller, org.springframework.oxm.Unmarshaller, InitializingBean {
implements org.springframework.oxm.Marshaller, org.springframework.oxm.Unmarshaller, InitializingBean {
/** Logger available to subclasses. */
protected final Log logger = LogFactory.getLog(getClass());
/** Logger available to subclasses. */
protected final Log logger = LogFactory.getLog(getClass());
private String contextPath;
private String contextPath;
private Map marshallerProperties;
private Map marshallerProperties;
private Map unmarshallerProperties;
private Map unmarshallerProperties;
private JAXBContext jaxbContext;
private JAXBContext jaxbContext;
private ValidationEventHandler validationEventHandler;
private ValidationEventHandler validationEventHandler;
/** Returns the JAXB Context path. */
protected String getContextPath() {
return contextPath;
}
/** Returns the JAXB Context path. */
protected String getContextPath() {
return contextPath;
}
/** Sets the JAXB Context path. */
public void setContextPath(String contextPath) {
Assert.notNull(contextPath, "'contextPath' must not be null");
this.contextPath = contextPath;
}
/** Sets the JAXB Context path. */
public void setContextPath(String contextPath) {
Assert.notNull(contextPath, "'contextPath' must not be null");
this.contextPath = contextPath;
}
/**
* Sets multiple JAXB Context paths. The given array of context paths is converted to a colon-delimited string, as
* supported by JAXB.
*/
public void setContextPaths(String[] contextPaths) {
Assert.notEmpty(contextPaths, "'contextPaths' must not be empty");
this.contextPath = StringUtils.arrayToDelimitedString(contextPaths, ":");
}
/**
* Sets multiple JAXB Context paths. The given array of context paths is converted to a colon-delimited string, as
* supported by JAXB.
*/
public void setContextPaths(String[] contextPaths) {
Assert.notEmpty(contextPaths, "'contextPaths' must not be empty");
this.contextPath = StringUtils.arrayToDelimitedString(contextPaths, ":");
}
/**
* Sets the JAXB <code>Marshaller</code> properties. These properties will be set on the underlying JAXB
* <code>Marshaller</code>, and allow for features such as indentation.
*
* @param properties the properties
* @see javax.xml.bind.Marshaller#setProperty(String,Object)
* @see javax.xml.bind.Marshaller#JAXB_ENCODING
* @see javax.xml.bind.Marshaller#JAXB_FORMATTED_OUTPUT
* @see javax.xml.bind.Marshaller#JAXB_NO_NAMESPACE_SCHEMA_LOCATION
* @see javax.xml.bind.Marshaller#JAXB_SCHEMA_LOCATION
*/
public void setMarshallerProperties(Map properties) {
this.marshallerProperties = properties;
}
/**
* Sets the JAXB <code>Marshaller</code> properties. These properties will be set on the underlying JAXB
* <code>Marshaller</code>, and allow for features such as indentation.
*
* @param properties the properties
* @see javax.xml.bind.Marshaller#setProperty(String,Object)
* @see javax.xml.bind.Marshaller#JAXB_ENCODING
* @see javax.xml.bind.Marshaller#JAXB_FORMATTED_OUTPUT
* @see javax.xml.bind.Marshaller#JAXB_NO_NAMESPACE_SCHEMA_LOCATION
* @see javax.xml.bind.Marshaller#JAXB_SCHEMA_LOCATION
*/
public void setMarshallerProperties(Map properties) {
this.marshallerProperties = properties;
}
/**
* Sets the JAXB <code>Unmarshaller</code> properties. These properties will be set on the underlying JAXB
* <code>Unmarshaller</code>.
*
* @param properties the properties
* @see javax.xml.bind.Unmarshaller#setProperty(String,Object)
*/
public void setUnmarshallerProperties(Map properties) {
this.unmarshallerProperties = properties;
}
/**
* Sets the JAXB <code>Unmarshaller</code> properties. These properties will be set on the underlying JAXB
* <code>Unmarshaller</code>.
*
* @param properties the properties
* @see javax.xml.bind.Unmarshaller#setProperty(String,Object)
*/
public void setUnmarshallerProperties(Map properties) {
this.unmarshallerProperties = properties;
}
/**
* Sets the JAXB validation event handler. This event handler will be called by JAXB if any validation errors are
* encountered during calls to any of the marshal API's.
*
* @param validationEventHandler the event handler
*/
public void setValidationEventHandler(ValidationEventHandler validationEventHandler) {
this.validationEventHandler = validationEventHandler;
}
/**
* Sets the JAXB validation event handler. This event handler will be called by JAXB if any validation errors are
* encountered during calls to any of the marshal API's.
*
* @param validationEventHandler the event handler
*/
public void setValidationEventHandler(ValidationEventHandler validationEventHandler) {
this.validationEventHandler = validationEventHandler;
}
/** Returns the {@link JAXBContext} created in {@link #afterPropertiesSet()}. */
public JAXBContext getJaxbContext() {
return jaxbContext;
}
/** Returns the {@link JAXBContext} created in {@link #afterPropertiesSet()}. */
public JAXBContext getJaxbContext() {
return jaxbContext;
}
public final void afterPropertiesSet() throws Exception {
try {
jaxbContext = createJaxbContext();
}
catch (JAXBException ex) {
throw convertJaxbException(ex);
}
}
public final void afterPropertiesSet() throws Exception {
try {
jaxbContext = createJaxbContext();
}
catch (JAXBException ex) {
throw convertJaxbException(ex);
}
}
/**
* Convert the given <code>JAXBException</code> to an appropriate exception from the
* <code>org.springframework.oxm</code> hierarchy.
* <p/>
* The default implementation delegates to <code>JaxbUtils</code>. Can be overridden in subclasses.
*
* @param ex <code>JAXBException</code> that occured
* @return the corresponding <code>XmlMappingException</code> instance
* @see JaxbUtils#convertJaxbException
*/
protected XmlMappingException convertJaxbException(JAXBException ex) {
return JaxbUtils.convertJaxbException(ex);
}
/**
* Convert the given <code>JAXBException</code> to an appropriate exception from the
* <code>org.springframework.oxm</code> hierarchy. <p/> The default implementation delegates to <code>JaxbUtils</code>.
* Can be overridden in subclasses.
*
* @param ex <code>JAXBException</code> that occured
* @return the corresponding <code>XmlMappingException</code> instance
* @see JaxbUtils#convertJaxbException
*/
protected XmlMappingException convertJaxbException(JAXBException ex) {
return JaxbUtils.convertJaxbException(ex);
}
/** Returns a newly created JAXB marshaller. JAXB marshallers are not necessarily thread safe. */
protected Marshaller createMarshaller() {
try {
Marshaller marshaller = jaxbContext.createMarshaller();
if (marshallerProperties != null) {
for (Iterator iterator = marshallerProperties.keySet().iterator(); iterator.hasNext();) {
String name = (String) iterator.next();
marshaller.setProperty(name, marshallerProperties.get(name));
}
}
if (validationEventHandler != null) {
marshaller.setEventHandler(validationEventHandler);
}
initJaxbMarshaller(marshaller);
return marshaller;
}
catch (JAXBException ex) {
throw convertJaxbException(ex);
}
}
/** Returns a newly created JAXB marshaller. JAXB marshallers are not necessarily thread safe. */
protected Marshaller createMarshaller() {
try {
Marshaller marshaller = jaxbContext.createMarshaller();
if (marshallerProperties != null) {
for (Iterator iterator = marshallerProperties.keySet().iterator(); iterator.hasNext();) {
String name = (String) iterator.next();
marshaller.setProperty(name, marshallerProperties.get(name));
}
}
if (validationEventHandler != null) {
marshaller.setEventHandler(validationEventHandler);
}
initJaxbMarshaller(marshaller);
return marshaller;
}
catch (JAXBException ex) {
throw convertJaxbException(ex);
}
}
/** Returns a newly created JAXB unmarshaller. JAXB unmarshallers are not necessarily thread safe. */
protected Unmarshaller createUnmarshaller() {
try {
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
if (unmarshallerProperties != null) {
for (Iterator iterator = unmarshallerProperties.keySet().iterator(); iterator.hasNext();) {
String name = (String) iterator.next();
unmarshaller.setProperty(name, unmarshallerProperties.get(name));
}
}
if (validationEventHandler != null) {
unmarshaller.setEventHandler(validationEventHandler);
}
initJaxbUnmarshaller(unmarshaller);
return unmarshaller;
}
catch (JAXBException ex) {
throw convertJaxbException(ex);
}
}
/** Returns a newly created JAXB unmarshaller. JAXB unmarshallers are not necessarily thread safe. */
protected Unmarshaller createUnmarshaller() {
try {
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
if (unmarshallerProperties != null) {
for (Iterator iterator = unmarshallerProperties.keySet().iterator(); iterator.hasNext();) {
String name = (String) iterator.next();
unmarshaller.setProperty(name, unmarshallerProperties.get(name));
}
}
if (validationEventHandler != null) {
unmarshaller.setEventHandler(validationEventHandler);
}
initJaxbUnmarshaller(unmarshaller);
return unmarshaller;
}
catch (JAXBException ex) {
throw convertJaxbException(ex);
}
}
/**
* Template method that can be overridden by concrete JAXB marshallers for custom initialization behavior. Gets
* called after creation of JAXB <code>Marshaller</code>, and after the respective properties have been set.
* <p/>
* Default implementation does nothing.
*/
protected void initJaxbMarshaller(Marshaller marshaller) throws JAXBException {
}
/**
* Template method that can be overridden by concrete JAXB marshallers for custom initialization behavior. Gets called
* after creation of JAXB <code>Marshaller</code>, and after the respective properties have been set. <p/> Default
* implementation does nothing.
*/
protected void initJaxbMarshaller(Marshaller marshaller) throws JAXBException {
}
/**
* Template method that can overridden by concrete JAXB marshallers for custom initialization behavior. Gets called
* after creation of JAXB <code>Unmarshaller</code>, and after the respective properties have been set.
* <p/>
* Default implementation does nothing.
*/
protected void initJaxbUnmarshaller(Unmarshaller unmarshaller) throws JAXBException {
}
/**
* Template method that can overridden by concrete JAXB marshallers for custom initialization behavior. Gets called
* after creation of JAXB <code>Unmarshaller</code>, and after the respective properties have been set. <p/> Default
* implementation does nothing.
*/
protected void initJaxbUnmarshaller(Unmarshaller unmarshaller) throws JAXBException {
}
/** Template method that returns a newly created JAXB context. Called from <code>afterPropertiesSet()</code>. */
protected abstract JAXBContext createJaxbContext() throws Exception;
/** Template method that returns a newly created JAXB context. Called from <code>afterPropertiesSet()</code>. */
protected abstract JAXBContext createJaxbContext() throws Exception;
}

View File

@@ -1,154 +0,0 @@
/*
* Copyright 2005 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.jaxb;
import javax.xml.bind.Element;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import org.springframework.xml.transform.StaxResult;
import org.springframework.xml.transform.StaxSource;
import org.springframework.xml.transform.TraxUtils;
/**
* Implementation of the <code>Marshaller</code> interface for JAXB 1.0.
* <p/>
* The typical usage will be to set the <code>contextPath</code> property on this bean, possibly customize the
* marshaller and unmarshaller by setting properties, and validations, and to refer to it.
*
* @author Arjen Poutsma
* @see #setContextPath(String)
* @see #setMarshallerProperties(java.util.Map)
* @see #setUnmarshallerProperties(java.util.Map)
* @see #setValidating(boolean)
* @since 1.0.0
*/
public class Jaxb1Marshaller extends AbstractJaxbMarshaller implements BeanClassLoaderAware {
private boolean validating = false;
private ClassLoader classLoader;
public void setBeanClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
/** Set if the JAXB <code>Unmarshaller</code> should validate the incoming document. Default is <code>false</code>. */
public void setValidating(boolean validating) {
this.validating = validating;
}
public boolean supports(Class clazz) {
if (!Element.class.isAssignableFrom(clazz)) {
return false;
}
if (StringUtils.hasLength(getContextPath())) {
String className = ClassUtils.getQualifiedName(clazz);
int lastDotIndex = className.lastIndexOf('.');
if (lastDotIndex == -1) {
return false;
}
String packageName = className.substring(0, lastDotIndex);
String[] contextPaths = StringUtils.tokenizeToStringArray(getContextPath(), ":");
for (int i = 0; i < contextPaths.length; i++) {
if (contextPaths[i].equals(packageName)) {
return true;
}
}
return false;
}
return false;
}
@Override
protected final JAXBContext createJaxbContext() throws JAXBException {
if (!StringUtils.hasLength(getContextPath())) {
throw new IllegalArgumentException("contextPath is required");
}
if (logger.isInfoEnabled()) {
logger.info("Creating JAXBContext with context path [" + getContextPath() + "]");
}
return classLoader != null ? JAXBContext.newInstance(getContextPath(), classLoader) :
JAXBContext.newInstance(getContextPath());
}
@Override
protected void initJaxbUnmarshaller(Unmarshaller unmarshaller) throws JAXBException {
unmarshaller.setValidating(validating);
}
public void marshal(Object graph, Result result) {
if (TraxUtils.isStaxResult(result)) {
XMLStreamWriter streamWriter = TraxUtils.getXMLStreamWriter(result);
if (streamWriter != null) {
result = new StaxResult(streamWriter);
}
else {
XMLEventWriter eventWriter = TraxUtils.getXMLEventWriter(result);
if (eventWriter != null) {
result = new StaxResult(eventWriter);
}
else {
throw new IllegalArgumentException(
"StAXResult contains neither XMLStreamWriter nor XMLEventWriter");
}
}
}
try {
createMarshaller().marshal(graph, result);
}
catch (JAXBException ex) {
throw convertJaxbException(ex);
}
}
public Object unmarshal(Source source) {
if (TraxUtils.isStaxSource(source)) {
XMLStreamReader streamReader = TraxUtils.getXMLStreamReader(source);
if (streamReader != null) {
source = new StaxSource(streamReader);
}
else {
XMLEventReader eventReader = TraxUtils.getXMLEventReader(source);
if (eventReader != null) {
source = new StaxSource(eventReader);
}
else {
throw new IllegalArgumentException(
"StAXSource contains neither XMLStreamReader nor XMLEventReader");
}
}
}
try {
return createUnmarshaller().unmarshal(source);
}
catch (JAXBException ex) {
throw convertJaxbException(ex);
}
}
}

View File

@@ -58,7 +58,14 @@ import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.sax.SAXSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.core.io.Resource;
@@ -73,15 +80,13 @@ import org.springframework.util.ClassUtils;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.xml.transform.TraxUtils;
import org.springframework.xml.validation.SchemaLoaderUtils;
import org.springframework.util.xml.SaxUtils;
import org.springframework.util.xml.StaxUtils;
/**
* Implementation of the <code>Marshaller</code> interface for JAXB 2.0.
* <p/>
* The typical usage will be to set either the <code>contextPath</code> or the <code>classesToBeBound</code> property on
* this bean, possibly customize the marshaller and unmarshaller by setting properties, schemas, adapters, and
* listeners, and to refer to it.
* Implementation of the <code>Marshaller</code> interface for JAXB 2.0. <p/> The typical usage will be to set either
* the <code>contextPath</code> or the <code>classesToBeBound</code> property on this bean, possibly customize the
* marshaller and unmarshaller by setting properties, schemas, adapters, and listeners, and to refer to it.
*
* @author Arjen Poutsma
* @see #setContextPath(String)
@@ -94,494 +99,509 @@ import org.springframework.xml.validation.SchemaLoaderUtils;
* @see #setMarshallerListener(javax.xml.bind.Marshaller.Listener)
* @see #setUnmarshallerListener(javax.xml.bind.Unmarshaller.Listener)
* @see #setAdapters(javax.xml.bind.annotation.adapters.XmlAdapter[])
* @since 1.0.0
* @since 3.0
*/
public class Jaxb2Marshaller extends AbstractJaxbMarshaller
implements MimeMarshaller, MimeUnmarshaller, GenericMarshaller, GenericUnmarshaller, BeanClassLoaderAware {
implements MimeMarshaller, MimeUnmarshaller, GenericMarshaller, GenericUnmarshaller, BeanClassLoaderAware {
private ClassLoader classLoader;
private ClassLoader classLoader;
private Resource[] schemaResources;
private Resource[] schemaResources;
private String schemaLanguage = XMLConstants.W3C_XML_SCHEMA_NS_URI;
private String schemaLanguage = XMLConstants.W3C_XML_SCHEMA_NS_URI;
private Marshaller.Listener marshallerListener;
private Marshaller.Listener marshallerListener;
private Unmarshaller.Listener unmarshallerListener;
private Unmarshaller.Listener unmarshallerListener;
private XmlAdapter[] adapters;
private XmlAdapter[] adapters;
private Schema schema;
private Schema schema;
private Class[] classesToBeBound;
private Class[] classesToBeBound;
private Map<String, ?> jaxbContextProperties;
private Map<String, ?> jaxbContextProperties;
private boolean mtomEnabled = false;
private boolean mtomEnabled = false;
public void setBeanClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
public void setBeanClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
/**
* Sets the <code>XmlAdapter</code>s to be registered with the JAXB <code>Marshaller</code> and
* <code>Unmarshaller</code>
*/
public void setAdapters(XmlAdapter[] adapters) {
this.adapters = adapters;
}
/**
* Sets the <code>XmlAdapter</code>s to be registered with the JAXB <code>Marshaller</code> and
* <code>Unmarshaller</code>
*/
public void setAdapters(XmlAdapter[] adapters) {
this.adapters = adapters;
}
/**
* Sets the list of java classes to be recognized by a newly created JAXBContext. Setting this property or
* <code>contextPath</code> is required.
*
* @see #setContextPath(String)
*/
public void setClassesToBeBound(Class[] classesToBeBound) {
this.classesToBeBound = classesToBeBound;
}
/**
* Sets the list of java classes to be recognized by a newly created JAXBContext. Setting this property or
* <code>contextPath</code> is required.
*
* @see #setContextPath(String)
*/
public void setClassesToBeBound(Class[] classesToBeBound) {
this.classesToBeBound = classesToBeBound;
}
/**
* Sets the <code>JAXBContext</code> properties. These implementation-specific properties will be set on the
* <code>JAXBContext</code>.
*/
public void setJaxbContextProperties(Map<String, ?> jaxbContextProperties) {
this.jaxbContextProperties = jaxbContextProperties;
}
/**
* Sets the <code>JAXBContext</code> properties. These implementation-specific properties will be set on the
* <code>JAXBContext</code>.
*/
public void setJaxbContextProperties(Map<String, ?> jaxbContextProperties) {
this.jaxbContextProperties = jaxbContextProperties;
}
/** Sets the <code>Marshaller.Listener</code> to be registered with the JAXB <code>Marshaller</code>. */
public void setMarshallerListener(Marshaller.Listener marshallerListener) {
this.marshallerListener = marshallerListener;
}
/** Sets the <code>Marshaller.Listener</code> to be registered with the JAXB <code>Marshaller</code>. */
public void setMarshallerListener(Marshaller.Listener marshallerListener) {
this.marshallerListener = marshallerListener;
}
/**
* Indicates whether MTOM support should be enabled or not. Default is <code>false</code>, marshalling using
* XOP/MTOM is not enabled.
*/
public void setMtomEnabled(boolean mtomEnabled) {
this.mtomEnabled = mtomEnabled;
}
/**
* Indicates whether MTOM support should be enabled or not. Default is <code>false</code>, marshalling using XOP/MTOM
* is not enabled.
*/
public void setMtomEnabled(boolean mtomEnabled) {
this.mtomEnabled = mtomEnabled;
}
/**
* Sets the schema language. Default is the W3C XML Schema: <code>http://www.w3.org/2001/XMLSchema"</code>.
*
* @see XMLConstants#W3C_XML_SCHEMA_NS_URI
* @see XMLConstants#RELAXNG_NS_URI
*/
public void setSchemaLanguage(String schemaLanguage) {
this.schemaLanguage = schemaLanguage;
}
/**
* Sets the schema language. Default is the W3C XML Schema: <code>http://www.w3.org/2001/XMLSchema"</code>.
*
* @see XMLConstants#W3C_XML_SCHEMA_NS_URI
* @see XMLConstants#RELAXNG_NS_URI
*/
public void setSchemaLanguage(String schemaLanguage) {
this.schemaLanguage = schemaLanguage;
}
/** Sets the schema resource to use for validation. */
public void setSchema(Resource schemaResource) {
schemaResources = new Resource[]{schemaResource};
}
/** Sets the schema resource to use for validation. */
public void setSchema(Resource schemaResource) {
schemaResources = new Resource[]{schemaResource};
}
/** Sets the schema resources to use for validation. */
public void setSchemas(Resource[] schemaResources) {
this.schemaResources = schemaResources;
}
/** Sets the schema resources to use for validation. */
public void setSchemas(Resource[] schemaResources) {
this.schemaResources = schemaResources;
}
/** Sets the <code>Unmarshaller.Listener</code> to be registered with the JAXB <code>Unmarshaller</code>. */
public void setUnmarshallerListener(Unmarshaller.Listener unmarshallerListener) {
this.unmarshallerListener = unmarshallerListener;
}
/** Sets the <code>Unmarshaller.Listener</code> to be registered with the JAXB <code>Unmarshaller</code>. */
public void setUnmarshallerListener(Unmarshaller.Listener unmarshallerListener) {
this.unmarshallerListener = unmarshallerListener;
}
public boolean supports(Type type) {
if (type instanceof Class) {
return supportsInternal((Class) type, true);
}
else if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
if (JAXBElement.class.equals(parameterizedType.getRawType())) {
Assert.isTrue(parameterizedType.getActualTypeArguments().length == 1,
"Invalid amount of parameterized types in JAXBElement");
Type typeArgument = parameterizedType.getActualTypeArguments()[0];
if (typeArgument instanceof Class) {
Class clazz = (Class) typeArgument;
if (!isPrimitiveType(clazz) && !isStandardType(clazz) && !supportsInternal(clazz, false)) {
return false;
}
}
else if (typeArgument instanceof GenericArrayType) {
GenericArrayType genericArrayType = (GenericArrayType) typeArgument;
return genericArrayType.getGenericComponentType().equals(Byte.TYPE);
}
else if (!supports(typeArgument)) {
return false;
}
return true;
}
}
return false;
}
public boolean supports(Type type) {
if (type instanceof Class) {
return supportsInternal((Class) type, true);
}
else if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
if (JAXBElement.class.equals(parameterizedType.getRawType())) {
Assert.isTrue(parameterizedType.getActualTypeArguments().length == 1,
"Invalid amount of parameterized types in JAXBElement");
Type typeArgument = parameterizedType.getActualTypeArguments()[0];
if (typeArgument instanceof Class) {
Class clazz = (Class) typeArgument;
if (!isPrimitiveType(clazz) && !isStandardType(clazz) && !supportsInternal(clazz, false)) {
return false;
}
}
else if (typeArgument instanceof GenericArrayType) {
GenericArrayType genericArrayType = (GenericArrayType) typeArgument;
return genericArrayType.getGenericComponentType().equals(Byte.TYPE);
}
else if (!supports(typeArgument)) {
return false;
}
return true;
}
}
return false;
}
private boolean isPrimitiveType(Class clazz) {
return (Boolean.class.equals(clazz) || Byte.class.equals(clazz) || Short.class.equals(clazz) ||
Integer.class.equals(clazz) || Long.class.equals(clazz) || Float.class.equals(clazz) ||
Double.class.equals(clazz) || byte[].class.equals(clazz));
}
private boolean isPrimitiveType(Class clazz) {
return (Boolean.class.equals(clazz) || Byte.class.equals(clazz) || Short.class.equals(clazz) ||
Integer.class.equals(clazz) || Long.class.equals(clazz) || Float.class.equals(clazz) ||
Double.class.equals(clazz) || byte[].class.equals(clazz));
}
private boolean isStandardType(Class clazz) {
return (String.class.equals(clazz) || BigInteger.class.equals(clazz) || BigDecimal.class.equals(clazz) ||
Calendar.class.isAssignableFrom(clazz) || Date.class.isAssignableFrom(clazz) ||
QName.class.equals(clazz) || URI.class.equals(clazz) ||
XMLGregorianCalendar.class.isAssignableFrom(clazz) || Duration.class.isAssignableFrom(clazz) ||
Object.class.equals(clazz) || Image.class.isAssignableFrom(clazz) || DataHandler.class.equals(clazz) ||
Source.class.isAssignableFrom(clazz) || UUID.class.equals(clazz));
}
private boolean isStandardType(Class clazz) {
return (String.class.equals(clazz) || BigInteger.class.equals(clazz) || BigDecimal.class.equals(clazz) ||
Calendar.class.isAssignableFrom(clazz) || Date.class.isAssignableFrom(clazz) ||
QName.class.equals(clazz) || URI.class.equals(clazz) ||
XMLGregorianCalendar.class.isAssignableFrom(clazz) || Duration.class.isAssignableFrom(clazz) ||
Object.class.equals(clazz) || Image.class.isAssignableFrom(clazz) || DataHandler.class.equals(clazz) ||
Source.class.isAssignableFrom(clazz) || UUID.class.equals(clazz));
}
public boolean supports(Class clazz) {
return supportsInternal(clazz, true);
}
public boolean supports(Class clazz) {
return supportsInternal(clazz, true);
}
private boolean supportsInternal(Class<?> clazz, boolean checkForXmlRootElement) {
if (checkForXmlRootElement && clazz.getAnnotation(XmlRootElement.class) == null) {
return false;
}
if (clazz.getAnnotation(XmlType.class) == null) {
return false;
}
if (StringUtils.hasLength(getContextPath())) {
String className = ClassUtils.getQualifiedName(clazz);
int lastDotIndex = className.lastIndexOf('.');
if (lastDotIndex == -1) {
return false;
}
String packageName = className.substring(0, lastDotIndex);
String[] contextPaths = StringUtils.tokenizeToStringArray(getContextPath(), ":");
for (int i = 0; i < contextPaths.length; i++) {
if (contextPaths[i].equals(packageName)) {
return true;
}
}
return false;
}
else if (!ObjectUtils.isEmpty(classesToBeBound)) {
return Arrays.asList(classesToBeBound).contains(clazz);
}
return false;
}
private boolean supportsInternal(Class<?> clazz, boolean checkForXmlRootElement) {
if (checkForXmlRootElement && clazz.getAnnotation(XmlRootElement.class) == null) {
return false;
}
if (clazz.getAnnotation(XmlType.class) == null) {
return false;
}
if (StringUtils.hasLength(getContextPath())) {
String className = ClassUtils.getQualifiedName(clazz);
int lastDotIndex = className.lastIndexOf('.');
if (lastDotIndex == -1) {
return false;
}
String packageName = className.substring(0, lastDotIndex);
String[] contextPaths = StringUtils.tokenizeToStringArray(getContextPath(), ":");
for (String contextPath : contextPaths) {
if (contextPath.equals(packageName)) {
return true;
}
}
return false;
}
else if (!ObjectUtils.isEmpty(classesToBeBound)) {
return Arrays.asList(classesToBeBound).contains(clazz);
}
return false;
}
/*
* JAXBContext
*/
/*
* JAXBContext
*/
@Override
@Override
protected JAXBContext createJaxbContext() throws Exception {
if (JaxbUtils.getJaxbVersion() < JaxbUtils.JAXB_2) {
throw new IllegalStateException(
"Cannot use Jaxb2Marshaller in combination with JAXB 1.0. Use Jaxb1Marshaller instead.");
}
if (StringUtils.hasLength(getContextPath()) && !ObjectUtils.isEmpty(classesToBeBound)) {
throw new IllegalArgumentException("specify either contextPath or classesToBeBound property; not both");
}
if (!ObjectUtils.isEmpty(schemaResources)) {
if (logger.isDebugEnabled()) {
logger.debug(
"Setting validation schema to " + StringUtils.arrayToCommaDelimitedString(schemaResources));
}
schema = SchemaLoaderUtils.loadSchema(schemaResources, schemaLanguage);
}
if (StringUtils.hasLength(getContextPath())) {
return createJaxbContextFromContextPath();
}
else if (!ObjectUtils.isEmpty(classesToBeBound)) {
return createJaxbContextFromClasses();
}
else {
throw new IllegalArgumentException("setting either contextPath or classesToBeBound is required");
}
}
if (JaxbUtils.getJaxbVersion() < JaxbUtils.JAXB_2) {
throw new IllegalStateException(
"Cannot use Jaxb2Marshaller in combination with JAXB 1.0. Use Jaxb1Marshaller instead.");
}
if (StringUtils.hasLength(getContextPath()) && !ObjectUtils.isEmpty(classesToBeBound)) {
throw new IllegalArgumentException("specify either contextPath or classesToBeBound property; not both");
}
if (!ObjectUtils.isEmpty(schemaResources)) {
if (logger.isDebugEnabled()) {
logger.debug(
"Setting validation schema to " + StringUtils.arrayToCommaDelimitedString(schemaResources));
}
schema = loadSchema(schemaResources, schemaLanguage);
}
if (StringUtils.hasLength(getContextPath())) {
return createJaxbContextFromContextPath();
}
else if (!ObjectUtils.isEmpty(classesToBeBound)) {
return createJaxbContextFromClasses();
}
else {
throw new IllegalArgumentException("setting either contextPath or classesToBeBound is required");
}
}
private JAXBContext createJaxbContextFromContextPath() throws JAXBException {
if (logger.isInfoEnabled()) {
logger.info("Creating JAXBContext with context path [" + getContextPath() + "]");
}
if (jaxbContextProperties != null) {
if (classLoader != null) {
return JAXBContext
.newInstance(getContextPath(), classLoader, jaxbContextProperties);
}
else {
return JAXBContext
.newInstance(getContextPath(), ClassUtils.getDefaultClassLoader(), jaxbContextProperties);
}
}
else {
return classLoader != null ? JAXBContext.newInstance(getContextPath(), classLoader) :
JAXBContext.newInstance(getContextPath());
}
}
private Schema loadSchema(Resource[] resources, String schemaLanguage) throws IOException, SAXException {
Assert.notEmpty(resources, "No resources given");
Assert.hasLength(schemaLanguage, "No schema language provided");
Source[] schemaSources = new Source[resources.length];
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
xmlReader.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
for (int i = 0; i < resources.length; i++) {
Assert.notNull(resources[i], "Resource is null");
Assert.isTrue(resources[i].exists(), "Resource " + resources[i] + " does not exist");
InputSource inputSource = SaxUtils.createInputSource(resources[i]);
schemaSources[i] = new SAXSource(xmlReader, inputSource);
}
SchemaFactory schemaFactory = SchemaFactory.newInstance(schemaLanguage);
return schemaFactory.newSchema(schemaSources);
}
private JAXBContext createJaxbContextFromClasses() throws JAXBException {
if (logger.isInfoEnabled()) {
logger.info("Creating JAXBContext with classes to be bound [" +
StringUtils.arrayToCommaDelimitedString(classesToBeBound) + "]");
}
if (jaxbContextProperties != null) {
return JAXBContext.newInstance(classesToBeBound, jaxbContextProperties);
}
else {
return JAXBContext.newInstance(classesToBeBound);
}
}
private JAXBContext createJaxbContextFromContextPath() throws JAXBException {
if (logger.isInfoEnabled()) {
logger.info("Creating JAXBContext with context path [" + getContextPath() + "]");
}
if (jaxbContextProperties != null) {
if (classLoader != null) {
return JAXBContext.newInstance(getContextPath(), classLoader, jaxbContextProperties);
}
else {
return JAXBContext
.newInstance(getContextPath(), ClassUtils.getDefaultClassLoader(), jaxbContextProperties);
}
}
else {
return classLoader != null ? JAXBContext.newInstance(getContextPath(), classLoader) :
JAXBContext.newInstance(getContextPath());
}
}
/*
* Marshaller/Unmarshaller
*/
private JAXBContext createJaxbContextFromClasses() throws JAXBException {
if (logger.isInfoEnabled()) {
logger.info("Creating JAXBContext with classes to be bound [" +
StringUtils.arrayToCommaDelimitedString(classesToBeBound) + "]");
}
if (jaxbContextProperties != null) {
return JAXBContext.newInstance(classesToBeBound, jaxbContextProperties);
}
else {
return JAXBContext.newInstance(classesToBeBound);
}
}
@Override
/*
* Marshaller/Unmarshaller
*/
@Override
protected void initJaxbMarshaller(Marshaller marshaller) throws JAXBException {
if (schema != null) {
marshaller.setSchema(schema);
}
if (marshallerListener != null) {
marshaller.setListener(marshallerListener);
}
if (adapters != null) {
for (int i = 0; i < adapters.length; i++) {
marshaller.setAdapter(adapters[i]);
}
}
}
if (schema != null) {
marshaller.setSchema(schema);
}
if (marshallerListener != null) {
marshaller.setListener(marshallerListener);
}
if (adapters != null) {
for (XmlAdapter adapter : adapters) {
marshaller.setAdapter(adapter);
}
}
}
@Override
@Override
protected void initJaxbUnmarshaller(Unmarshaller unmarshaller) throws JAXBException {
if (schema != null) {
unmarshaller.setSchema(schema);
}
if (unmarshallerListener != null) {
unmarshaller.setListener(unmarshallerListener);
}
if (adapters != null) {
for (int i = 0; i < adapters.length; i++) {
unmarshaller.setAdapter(adapters[i]);
}
}
}
if (schema != null) {
unmarshaller.setSchema(schema);
}
if (unmarshallerListener != null) {
unmarshaller.setListener(unmarshallerListener);
}
if (adapters != null) {
for (XmlAdapter adapter : adapters) {
unmarshaller.setAdapter(adapter);
}
}
}
/*
* Marshalling
*/
/*
* Marshalling
*/
public void marshal(Object graph, Result result) throws XmlMappingException {
marshal(graph, result, null);
}
public void marshal(Object graph, Result result) throws XmlMappingException {
marshal(graph, result, null);
}
public void marshal(Object graph, Result result, MimeContainer mimeContainer) throws XmlMappingException {
try {
Marshaller marshaller = createMarshaller();
if (mtomEnabled && mimeContainer != null) {
marshaller.setAttachmentMarshaller(new Jaxb2AttachmentMarshaller(mimeContainer));
}
if (TraxUtils.isStaxResult(result)) {
marshalStaxResult(marshaller, graph, result);
}
else {
marshaller.marshal(graph, result);
}
}
catch (JAXBException ex) {
throw convertJaxbException(ex);
}
}
public void marshal(Object graph, Result result, MimeContainer mimeContainer) throws XmlMappingException {
try {
Marshaller marshaller = createMarshaller();
if (mtomEnabled && mimeContainer != null) {
marshaller.setAttachmentMarshaller(new Jaxb2AttachmentMarshaller(mimeContainer));
}
if (StaxUtils.isStaxResult(result)) {
marshalStaxResult(marshaller, graph, result);
}
else {
marshaller.marshal(graph, result);
}
}
catch (JAXBException ex) {
throw convertJaxbException(ex);
}
}
private void marshalStaxResult(Marshaller jaxbMarshaller, Object graph, Result staxResult) throws JAXBException {
XMLStreamWriter streamWriter = TraxUtils.getXMLStreamWriter(staxResult);
if (streamWriter != null) {
jaxbMarshaller.marshal(graph, streamWriter);
}
else {
XMLEventWriter eventWriter = TraxUtils.getXMLEventWriter(staxResult);
if (eventWriter != null) {
jaxbMarshaller.marshal(graph, eventWriter);
}
else {
throw new IllegalArgumentException("StAX Result contains neither XMLStreamWriter nor XMLEventConsumer");
}
}
}
private void marshalStaxResult(Marshaller jaxbMarshaller, Object graph, Result staxResult) throws JAXBException {
XMLStreamWriter streamWriter = StaxUtils.getXMLStreamWriter(staxResult);
if (streamWriter != null) {
jaxbMarshaller.marshal(graph, streamWriter);
}
else {
XMLEventWriter eventWriter = StaxUtils.getXMLEventWriter(staxResult);
if (eventWriter != null) {
jaxbMarshaller.marshal(graph, eventWriter);
}
else {
throw new IllegalArgumentException("StAX Result contains neither XMLStreamWriter nor XMLEventConsumer");
}
}
}
/*
* Unmarshalling
*/
/*
* Unmarshalling
*/
public Object unmarshal(Source source) throws XmlMappingException {
return unmarshal(source, null);
}
public Object unmarshal(Source source) throws XmlMappingException {
return unmarshal(source, null);
}
public Object unmarshal(Source source, MimeContainer mimeContainer) throws XmlMappingException {
try {
Unmarshaller unmarshaller = createUnmarshaller();
if (mtomEnabled && mimeContainer != null) {
unmarshaller.setAttachmentUnmarshaller(new Jaxb2AttachmentUnmarshaller(mimeContainer));
}
if (TraxUtils.isStaxSource(source)) {
return unmarshalStaxSource(unmarshaller, source);
}
else {
return unmarshaller.unmarshal(source);
}
}
catch (JAXBException ex) {
throw convertJaxbException(ex);
}
}
public Object unmarshal(Source source, MimeContainer mimeContainer) throws XmlMappingException {
try {
Unmarshaller unmarshaller = createUnmarshaller();
if (mtomEnabled && mimeContainer != null) {
unmarshaller.setAttachmentUnmarshaller(new Jaxb2AttachmentUnmarshaller(mimeContainer));
}
if (StaxUtils.isStaxSource(source)) {
return unmarshalStaxSource(unmarshaller, source);
}
else {
return unmarshaller.unmarshal(source);
}
}
catch (JAXBException ex) {
throw convertJaxbException(ex);
}
}
private Object unmarshalStaxSource(Unmarshaller jaxbUnmarshaller, Source staxSource) throws JAXBException {
XMLStreamReader streamReader = TraxUtils.getXMLStreamReader(staxSource);
if (streamReader != null) {
return jaxbUnmarshaller.unmarshal(streamReader);
}
else {
XMLEventReader eventReader = TraxUtils.getXMLEventReader(staxSource);
if (eventReader != null) {
return jaxbUnmarshaller.unmarshal(eventReader);
}
else {
throw new IllegalArgumentException("StaxSource contains neither XMLStreamReader nor XMLEventReader");
}
}
}
private Object unmarshalStaxSource(Unmarshaller jaxbUnmarshaller, Source staxSource) throws JAXBException {
XMLStreamReader streamReader = StaxUtils.getXMLStreamReader(staxSource);
if (streamReader != null) {
return jaxbUnmarshaller.unmarshal(streamReader);
}
else {
XMLEventReader eventReader = StaxUtils.getXMLEventReader(staxSource);
if (eventReader != null) {
return jaxbUnmarshaller.unmarshal(eventReader);
}
else {
throw new IllegalArgumentException("StaxSource contains neither XMLStreamReader nor XMLEventReader");
}
}
}
/*
* Inner classes
*/
/*
* Inner classes
*/
private static class Jaxb2AttachmentMarshaller extends AttachmentMarshaller {
private static class Jaxb2AttachmentMarshaller extends AttachmentMarshaller {
private final MimeContainer mimeContainer;
private final MimeContainer mimeContainer;
public Jaxb2AttachmentMarshaller(MimeContainer mimeContainer) {
this.mimeContainer = mimeContainer;
}
private Jaxb2AttachmentMarshaller(MimeContainer mimeContainer) {
this.mimeContainer = mimeContainer;
}
@Override
@Override
public String addMtomAttachment(byte[] data,
int offset,
int length,
String mimeType,
String elementNamespace,
String elementLocalName) {
ByteArrayDataSource dataSource = new ByteArrayDataSource(mimeType, data, offset, length);
return addMtomAttachment(new DataHandler(dataSource), elementNamespace, elementLocalName);
}
int offset,
int length,
String mimeType,
String elementNamespace,
String elementLocalName) {
ByteArrayDataSource dataSource = new ByteArrayDataSource(mimeType, data, offset, length);
return addMtomAttachment(new DataHandler(dataSource), elementNamespace, elementLocalName);
}
@Override
@Override
public String addMtomAttachment(DataHandler dataHandler, String elementNamespace, String elementLocalName) {
String host = getHost(elementNamespace, dataHandler);
String contentId = UUID.randomUUID() + "@" + host;
mimeContainer.addAttachment("<" + contentId + ">", dataHandler);
try {
contentId = URLEncoder.encode(contentId, "UTF-8");
}
catch (UnsupportedEncodingException e) {
// ignore
}
return "cid:" + contentId;
}
String host = getHost(elementNamespace, dataHandler);
String contentId = UUID.randomUUID() + "@" + host;
mimeContainer.addAttachment("<" + contentId + ">", dataHandler);
try {
contentId = URLEncoder.encode(contentId, "UTF-8");
}
catch (UnsupportedEncodingException e) {
// ignore
}
return "cid:" + contentId;
}
private String getHost(String elementNamespace, DataHandler dataHandler) {
try {
URI uri = new URI(elementNamespace);
return uri.getHost();
}
catch (URISyntaxException e) {
// ignore
}
return dataHandler.getName();
}
private String getHost(String elementNamespace, DataHandler dataHandler) {
try {
URI uri = new URI(elementNamespace);
return uri.getHost();
}
catch (URISyntaxException e) {
// ignore
}
return dataHandler.getName();
}
@Override
@Override
public String addSwaRefAttachment(DataHandler dataHandler) {
String contentId = UUID.randomUUID() + "@" + dataHandler.getName();
mimeContainer.addAttachment(contentId, dataHandler);
return contentId;
}
String contentId = UUID.randomUUID() + "@" + dataHandler.getName();
mimeContainer.addAttachment(contentId, dataHandler);
return contentId;
}
@Override
public boolean isXOPPackage() {
return mimeContainer.convertToXopPackage();
}
}
@Override
public boolean isXOPPackage() {
return mimeContainer.convertToXopPackage();
}
}
private static class Jaxb2AttachmentUnmarshaller extends AttachmentUnmarshaller {
private static class Jaxb2AttachmentUnmarshaller extends AttachmentUnmarshaller {
private final MimeContainer mimeContainer;
private final MimeContainer mimeContainer;
public Jaxb2AttachmentUnmarshaller(MimeContainer mimeContainer) {
this.mimeContainer = mimeContainer;
}
private Jaxb2AttachmentUnmarshaller(MimeContainer mimeContainer) {
this.mimeContainer = mimeContainer;
}
@Override
@Override
public byte[] getAttachmentAsByteArray(String cid) {
try {
DataHandler dataHandler = getAttachmentAsDataHandler(cid);
return FileCopyUtils.copyToByteArray(dataHandler.getInputStream());
}
catch (IOException ex) {
throw new JaxbUnmarshallingFailureException(ex);
}
}
try {
DataHandler dataHandler = getAttachmentAsDataHandler(cid);
return FileCopyUtils.copyToByteArray(dataHandler.getInputStream());
}
catch (IOException ex) {
throw new JaxbUnmarshallingFailureException(ex);
}
}
@Override
@Override
public DataHandler getAttachmentAsDataHandler(String contentId) {
if (contentId.startsWith("cid:")) {
contentId = contentId.substring("cid:".length());
try {
contentId = URLDecoder.decode(contentId, "UTF-8");
}
catch (UnsupportedEncodingException e) {
// ignore
}
contentId = '<' + contentId + '>';
}
return mimeContainer.getAttachment(contentId);
}
if (contentId.startsWith("cid:")) {
contentId = contentId.substring("cid:".length());
try {
contentId = URLDecoder.decode(contentId, "UTF-8");
}
catch (UnsupportedEncodingException e) {
// ignore
}
contentId = '<' + contentId + '>';
}
return mimeContainer.getAttachment(contentId);
}
@Override
public boolean isXOPPackage() {
return mimeContainer.isXopPackage();
}
}
@Override
public boolean isXOPPackage() {
return mimeContainer.isXopPackage();
}
}
/*
* DataSource that wraps around a byte array
*/
private static class ByteArrayDataSource implements DataSource {
/*
* DataSource that wraps around a byte array
*/
private static class ByteArrayDataSource implements DataSource {
private byte[] data;
private byte[] data;
private String contentType;
private String contentType;
private int offset;
private int offset;
private int length;
private int length;
public ByteArrayDataSource(String contentType, byte[] data, int offset, int length) {
this.contentType = contentType;
this.data = data;
this.offset = offset;
this.length = length;
}
private ByteArrayDataSource(String contentType, byte[] data, int offset, int length) {
this.contentType = contentType;
this.data = data;
this.offset = offset;
this.length = length;
}
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(data, offset, length);
}
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(data, offset, length);
}
public OutputStream getOutputStream() throws IOException {
throw new UnsupportedOperationException();
}
public OutputStream getOutputStream() throws IOException {
throw new UnsupportedOperationException();
}
public String getContentType() {
return contentType;
}
public String getContentType() {
return contentType;
}
public String getName() {
return "ByteArrayDataSource";
}
}
public String getName() {
return "ByteArrayDataSource";
}
}
}

View File

@@ -24,12 +24,12 @@ import org.springframework.oxm.MarshallingFailureException;
*
* @author Arjen Poutsma
* @see JaxbUtils#convertJaxbException
* @since 1.0.0
* @since 3.0
*/
public class JaxbMarshallingFailureException extends MarshallingFailureException {
public JaxbMarshallingFailureException(MarshalException ex) {
super("JAXB marshalling exception: " + ex.getMessage(), ex);
}
public JaxbMarshallingFailureException(MarshalException ex) {
super("JAXB marshalling exception: " + ex.getMessage(), ex);
}
}

View File

@@ -25,11 +25,11 @@ import org.springframework.oxm.UncategorizedXmlMappingException;
*
* @author Arjen Poutsma
* @see JaxbUtils#convertJaxbException(javax.xml.bind.JAXBException)
* @since 1.0.0
* @since 3.0
*/
public class JaxbSystemException extends UncategorizedXmlMappingException {
public JaxbSystemException(JAXBException ex) {
super(ex.getMessage(), ex);
}
public JaxbSystemException(JAXBException ex) {
super(ex.getMessage(), ex);
}
}

View File

@@ -24,15 +24,15 @@ import org.springframework.oxm.UnmarshallingFailureException;
* JAXB-specific subclass of <code>UnmarshallingFailureException</code>.
*
* @author Arjen Poutsma
* @since 1.0.0
* @since 3.0
*/
public class JaxbUnmarshallingFailureException extends UnmarshallingFailureException {
public JaxbUnmarshallingFailureException(UnmarshalException ex) {
super("JAXB unmarshalling exception: " + ex.getMessage(), ex);
}
public JaxbUnmarshallingFailureException(UnmarshalException ex) {
super("JAXB unmarshalling exception: " + ex.getMessage(), ex);
}
public JaxbUnmarshallingFailureException(IOException ex) {
super("JAXB unmarshalling exception: " + ex.getMessage(), ex);
}
public JaxbUnmarshallingFailureException(IOException ex) {
super("JAXB unmarshalling exception: " + ex.getMessage(), ex);
}
}

View File

@@ -27,58 +27,58 @@ import org.springframework.util.ClassUtils;
* Generic utility methods for working with JAXB. Mainly for internal use within the framework.
*
* @author Arjen Poutsma
* @since 1.0.0
* @since 3.0
*/
public abstract class JaxbUtils {
public static final int JAXB_1 = 0;
public static final int JAXB_1 = 0;
public static final int JAXB_2 = 1;
public static final int JAXB_2 = 1;
private static final String JAXB_2_CLASS_NAME = "javax.xml.bind.Binder";
private static final String JAXB_2_CLASS_NAME = "javax.xml.bind.Binder";
private static int jaxbVersion = JAXB_1;
private static int jaxbVersion = JAXB_1;
static {
try {
ClassUtils.forName(JAXB_2_CLASS_NAME);
jaxbVersion = JAXB_2;
}
catch (ClassNotFoundException ex1) {
// leave JAXB 1 as default
}
}
static {
try {
ClassUtils.forName(JAXB_2_CLASS_NAME);
jaxbVersion = JAXB_2;
}
catch (ClassNotFoundException ex1) {
// leave JAXB 1 as default
}
}
/**
* Gets the major JAXB version. This means we can do things like if <code>(getJaxbVersion() &lt;= JAXB_2)</code>.
*
* @return a code comparable to the JAXP_XX codes in this class
* @see #JAXB_1
* @see #JAXB_2
*/
public static int getJaxbVersion() {
return jaxbVersion;
}
/**
* Gets the major JAXB version. This means we can do things like if <code>(getJaxbVersion() &lt;= JAXB_2)</code>.
*
* @return a code comparable to the JAXP_XX codes in this class
* @see #JAXB_1
* @see #JAXB_2
*/
public static int getJaxbVersion() {
return jaxbVersion;
}
/**
* Converts the given <code>JAXBException</code> to an appropriate exception from the
* <code>org.springframework.oxm</code> hierarchy.
*
* @param ex <code>JAXBException</code> that occured
* @return the corresponding <code>XmlMappingException</code>
*/
public static XmlMappingException convertJaxbException(JAXBException ex) {
if (ex instanceof MarshalException) {
return new JaxbMarshallingFailureException((MarshalException) ex);
}
else if (ex instanceof UnmarshalException) {
return new JaxbUnmarshallingFailureException((UnmarshalException) ex);
}
else if (ex instanceof ValidationException) {
return new JaxbValidationFailureException((ValidationException) ex);
}
// fallback
return new JaxbSystemException(ex);
}
/**
* Converts the given <code>JAXBException</code> to an appropriate exception from the
* <code>org.springframework.oxm</code> hierarchy.
*
* @param ex <code>JAXBException</code> that occured
* @return the corresponding <code>XmlMappingException</code>
*/
public static XmlMappingException convertJaxbException(JAXBException ex) {
if (ex instanceof MarshalException) {
return new JaxbMarshallingFailureException((MarshalException) ex);
}
else if (ex instanceof UnmarshalException) {
return new JaxbUnmarshallingFailureException((UnmarshalException) ex);
}
else if (ex instanceof ValidationException) {
return new JaxbValidationFailureException((ValidationException) ex);
}
// fallback
return new JaxbSystemException(ex);
}
}

View File

@@ -24,12 +24,12 @@ import org.springframework.oxm.ValidationFailureException;
*
* @author Arjen Poutsma
* @see JaxbUtils#convertJaxbException
* @since 1.0.0
* @since 3.0
*/
public class JaxbValidationFailureException extends ValidationFailureException {
public JaxbValidationFailureException(ValidationException ex) {
super("JAXB validation exception: " + ex.getMessage(), ex);
}
public JaxbValidationFailureException(ValidationException ex) {
super("JAXB validation exception: " + ex.getMessage(), ex);
}
}

View File

@@ -60,314 +60,309 @@ import org.springframework.oxm.AbstractMarshaller;
import org.springframework.oxm.XmlMappingException;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.xml.stream.StaxEventContentHandler;
import org.springframework.xml.stream.XmlEventStreamReader;
import org.springframework.util.xml.StaxUtils;
/**
* Implementation of the <code>Marshaller</code> and <code>Unmarshaller</code> interfaces for JiBX.
* <p/>
* The typical usage will be to set the <code>targetClass</code> and optionally the <code>bindingName</code> property on
* this bean, and to refer to it.
* Implementation of the <code>Marshaller</code> and <code>Unmarshaller</code> interfaces for JiBX. <p/> The typical
* usage will be to set the <code>targetClass</code> and optionally the <code>bindingName</code> property on this bean,
* and to refer to it.
*
* @author Arjen Poutsma
* @see org.jibx.runtime.IMarshallingContext
* @see org.jibx.runtime.IUnmarshallingContext
* @since 1.0.0
* @since 3.0
*/
public class JibxMarshaller extends AbstractMarshaller implements InitializingBean {
private Class targetClass;
private Class targetClass;
private String bindingName;
private String bindingName;
private IBindingFactory bindingFactory;
private IBindingFactory bindingFactory;
private static TransformerFactory transformerFactory = TransformerFactory.newInstance();
private static TransformerFactory transformerFactory = TransformerFactory.newInstance();
private int indent = -1;
private int indent = -1;
private String encoding;
private String encoding;
private Boolean standalone;
private Boolean standalone;
/** Sets the optional binding name for this instance. */
public void setBindingName(String bindingName) {
this.bindingName = bindingName;
}
/** Sets the optional binding name for this instance. */
public void setBindingName(String bindingName) {
this.bindingName = bindingName;
}
/** Sets the target class for this instance. This property is required. */
public void setTargetClass(Class targetClass) {
this.targetClass = targetClass;
}
/** Sets the target class for this instance. This property is required. */
public void setTargetClass(Class targetClass) {
this.targetClass = targetClass;
}
/** Sets the number of nesting indent spaces. Default is <code>-1</code>, i.e. no indentation. */
public void setIndent(int indent) {
this.indent = indent;
}
/** Sets the number of nesting indent spaces. Default is <code>-1</code>, i.e. no indentation. */
public void setIndent(int indent) {
this.indent = indent;
}
/** Sets the document encoding using for marshalling. Default is UTF-8. */
public void setEncoding(String encoding) {
this.encoding = encoding;
}
/** Sets the document encoding using for marshalling. Default is UTF-8. */
public void setEncoding(String encoding) {
this.encoding = encoding;
}
/** Sets the document standalone flag for marshalling. By default, this flag is not present. */
public void setStandalone(Boolean standalone) {
this.standalone = standalone;
}
/** Sets the document standalone flag for marshalling. By default, this flag is not present. */
public void setStandalone(Boolean standalone) {
this.standalone = standalone;
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(targetClass, "targetClass is required");
if (logger.isInfoEnabled()) {
if (StringUtils.hasLength(bindingName)) {
logger.info("Configured for target class [" + targetClass + "] using binding [" + bindingName + "]");
}
else {
logger.info("Configured for target class [" + targetClass + "]");
}
}
try {
if (StringUtils.hasLength(bindingName)) {
bindingFactory = BindingDirectory.getFactory(bindingName, targetClass);
}
else {
bindingFactory = BindingDirectory.getFactory(targetClass);
}
}
catch (JiBXException ex) {
throw new JibxSystemException(ex);
}
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(targetClass, "targetClass is required");
if (logger.isInfoEnabled()) {
if (StringUtils.hasLength(bindingName)) {
logger.info("Configured for target class [" + targetClass + "] using binding [" + bindingName + "]");
}
else {
logger.info("Configured for target class [" + targetClass + "]");
}
}
try {
if (StringUtils.hasLength(bindingName)) {
bindingFactory = BindingDirectory.getFactory(bindingName, targetClass);
}
else {
bindingFactory = BindingDirectory.getFactory(targetClass);
}
}
catch (JiBXException ex) {
throw new JibxSystemException(ex);
}
}
public boolean supports(Class clazz) {
Assert.notNull(clazz, "'clazz' must not be null");
String[] mappedClasses = bindingFactory.getMappedClasses();
String className = clazz.getName();
for (int i = 0; i < mappedClasses.length; i++) {
if (className.equals(mappedClasses[i])) {
return true;
}
}
return false;
}
public boolean supports(Class clazz) {
Assert.notNull(clazz, "'clazz' must not be null");
String[] mappedClasses = bindingFactory.getMappedClasses();
String className = clazz.getName();
for (String mappedClass : mappedClasses) {
if (className.equals(mappedClass)) {
return true;
}
}
return false;
}
/**
* Convert the given <code>JiBXException</code> to an appropriate exception from the
* <code>org.springframework.oxm</code> hierarchy.
* <p/>
* The default implementation delegates to <code>JibxUtils</code>. Can be overridden in subclasses.
* <p/>
* A boolean flag is used to indicate whether this exception occurs during marshalling or unmarshalling, since JiBX
* itself does not make this distinction in its exception hierarchy.
*
* @param ex <code>JiBXException</code> that occured
* @param marshalling indicates whether the exception occurs during marshalling (<code>true</code>), or
* unmarshalling (<code>false</code>)
* @return the corresponding <code>XmlMappingException</code> instance
* @see JibxUtils#convertJibxException(org.jibx.runtime.JiBXException,boolean)
*/
public XmlMappingException convertJibxException(JiBXException ex, boolean marshalling) {
return JibxUtils.convertJibxException(ex, marshalling);
}
/**
* Convert the given <code>JiBXException</code> to an appropriate exception from the
* <code>org.springframework.oxm</code> hierarchy. <p/> The default implementation delegates to <code>JibxUtils</code>.
* Can be overridden in subclasses. <p/> A boolean flag is used to indicate whether this exception occurs during
* marshalling or unmarshalling, since JiBX itself does not make this distinction in its exception hierarchy.
*
* @param ex <code>JiBXException</code> that occured
* @param marshalling indicates whether the exception occurs during marshalling (<code>true</code>), or unmarshalling
* (<code>false</code>)
* @return the corresponding <code>XmlMappingException</code> instance
* @see JibxUtils#convertJibxException(org.jibx.runtime.JiBXException,boolean)
*/
public XmlMappingException convertJibxException(JiBXException ex, boolean marshalling) {
return JibxUtils.convertJibxException(ex, marshalling);
}
//
// Supported Marshalling
//
//
// Supported Marshalling
//
@Override
@Override
protected void marshalOutputStream(Object graph, OutputStream outputStream)
throws XmlMappingException, IOException {
try {
IMarshallingContext marshallingContext = createMarshallingContext();
marshallingContext.marshalDocument(graph, encoding, standalone, outputStream);
}
catch (JiBXException ex) {
throw convertJibxException(ex, true);
}
}
throws XmlMappingException, IOException {
try {
IMarshallingContext marshallingContext = createMarshallingContext();
marshallingContext.marshalDocument(graph, encoding, standalone, outputStream);
}
catch (JiBXException ex) {
throw convertJibxException(ex, true);
}
}
@Override
@Override
protected void marshalWriter(Object graph, Writer writer) throws XmlMappingException, IOException {
try {
IMarshallingContext marshallingContext = createMarshallingContext();
marshallingContext.marshalDocument(graph, encoding, standalone, writer);
}
catch (JiBXException ex) {
throw convertJibxException(ex, true);
}
}
try {
IMarshallingContext marshallingContext = createMarshallingContext();
marshallingContext.marshalDocument(graph, encoding, standalone, writer);
}
catch (JiBXException ex) {
throw convertJibxException(ex, true);
}
}
@Override
@Override
protected void marshalXmlStreamWriter(Object graph, XMLStreamWriter streamWriter) throws XmlMappingException {
try {
MarshallingContext marshallingContext = (MarshallingContext) createMarshallingContext();
IXMLWriter xmlWriter = new StAXWriter(marshallingContext.getNamespaces(), streamWriter);
marshallingContext.setXmlWriter(xmlWriter);
marshallingContext.marshalDocument(graph);
}
catch (JiBXException ex) {
throw convertJibxException(ex, false);
}
}
try {
MarshallingContext marshallingContext = (MarshallingContext) createMarshallingContext();
IXMLWriter xmlWriter = new StAXWriter(marshallingContext.getNamespaces(), streamWriter);
marshallingContext.setXmlWriter(xmlWriter);
marshallingContext.marshalDocument(graph);
}
catch (JiBXException ex) {
throw convertJibxException(ex, false);
}
}
//
// Unsupported Marshalling
//
//
// Unsupported Marshalling
//
@Override
@Override
protected void marshalDomNode(Object graph, Node node) throws XmlMappingException {
try {
// JiBX does not support DOM natively, so we write to a buffer first, and transform that to the Node
ByteArrayOutputStream os = new ByteArrayOutputStream();
marshalOutputStream(graph, os);
ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(new StreamSource(is), new DOMResult(node));
}
catch (IOException ex) {
throw new JibxSystemException(ex);
}
catch (TransformerException ex) {
throw new JibxSystemException(ex);
}
}
try {
// JiBX does not support DOM natively, so we write to a buffer first, and transform that to the Node
ByteArrayOutputStream os = new ByteArrayOutputStream();
marshalOutputStream(graph, os);
ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(new StreamSource(is), new DOMResult(node));
}
catch (IOException ex) {
throw new JibxSystemException(ex);
}
catch (TransformerException ex) {
throw new JibxSystemException(ex);
}
}
@Override
@Override
protected void marshalSaxHandlers(Object graph, ContentHandler contentHandler, LexicalHandler lexicalHandler)
throws XmlMappingException {
try {
// JiBX does not support SAX natively, so we write to a buffer first, and transform that to the handlers
ByteArrayOutputStream os = new ByteArrayOutputStream();
marshalOutputStream(graph, os);
ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
Transformer transformer = transformerFactory.newTransformer();
SAXResult saxResult = new SAXResult(contentHandler);
saxResult.setLexicalHandler(lexicalHandler);
transformer.transform(new StreamSource(is), saxResult);
}
catch (IOException ex) {
throw new JibxSystemException(ex);
}
catch (TransformerException ex) {
throw new JibxSystemException(ex);
}
}
throws XmlMappingException {
try {
// JiBX does not support SAX natively, so we write to a buffer first, and transform that to the handlers
ByteArrayOutputStream os = new ByteArrayOutputStream();
marshalOutputStream(graph, os);
ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
Transformer transformer = transformerFactory.newTransformer();
SAXResult saxResult = new SAXResult(contentHandler);
saxResult.setLexicalHandler(lexicalHandler);
transformer.transform(new StreamSource(is), saxResult);
}
catch (IOException ex) {
throw new JibxSystemException(ex);
}
catch (TransformerException ex) {
throw new JibxSystemException(ex);
}
}
@Override
@Override
protected void marshalXmlEventWriter(Object graph, XMLEventWriter eventWriter) {
ContentHandler contentHandler = new StaxEventContentHandler(eventWriter);
marshalSaxHandlers(graph, contentHandler, null);
}
ContentHandler contentHandler = StaxUtils.createContentHandler(eventWriter);
marshalSaxHandlers(graph, contentHandler, null);
}
//
// Unmarshalling
//
//
// Unmarshalling
//
@Override
@Override
protected Object unmarshalInputStream(InputStream inputStream) throws XmlMappingException, IOException {
try {
IUnmarshallingContext unmarshallingContext = createUnmarshallingContext();
return unmarshallingContext.unmarshalDocument(inputStream, null);
}
catch (JiBXException ex) {
throw convertJibxException(ex, false);
}
}
try {
IUnmarshallingContext unmarshallingContext = createUnmarshallingContext();
return unmarshallingContext.unmarshalDocument(inputStream, null);
}
catch (JiBXException ex) {
throw convertJibxException(ex, false);
}
}
@Override
@Override
protected Object unmarshalReader(Reader reader) throws XmlMappingException, IOException {
try {
IUnmarshallingContext unmarshallingContext = createUnmarshallingContext();
return unmarshallingContext.unmarshalDocument(reader);
}
catch (JiBXException ex) {
throw convertJibxException(ex, false);
}
}
try {
IUnmarshallingContext unmarshallingContext = createUnmarshallingContext();
return unmarshallingContext.unmarshalDocument(reader);
}
catch (JiBXException ex) {
throw convertJibxException(ex, false);
}
}
@Override
@Override
protected Object unmarshalXmlStreamReader(XMLStreamReader streamReader) {
try {
UnmarshallingContext unmarshallingContext = (UnmarshallingContext) createUnmarshallingContext();
IXMLReader xmlReader = new StAXReaderWrapper(streamReader, null, true);
unmarshallingContext.setDocument(xmlReader);
return unmarshallingContext.unmarshalElement();
}
catch (JiBXException ex) {
throw convertJibxException(ex, false);
}
}
try {
UnmarshallingContext unmarshallingContext = (UnmarshallingContext) createUnmarshallingContext();
IXMLReader xmlReader = new StAXReaderWrapper(streamReader, null, true);
unmarshallingContext.setDocument(xmlReader);
return unmarshallingContext.unmarshalElement();
}
catch (JiBXException ex) {
throw convertJibxException(ex, false);
}
}
@Override
@Override
protected Object unmarshalXmlEventReader(XMLEventReader eventReader) {
try {
XMLStreamReader streamReader = new XmlEventStreamReader(eventReader);
return unmarshalXmlStreamReader(streamReader);
}
catch (XMLStreamException ex) {
throw new JibxSystemException(ex);
}
}
try {
XMLStreamReader streamReader = StaxUtils.createEventStreamReader(eventReader);
return unmarshalXmlStreamReader(streamReader);
}
catch (XMLStreamException ex) {
throw new JibxSystemException(ex);
}
}
//
// Unsupported Unmarshalling
//
//
// Unsupported Unmarshalling
//
@Override
@Override
protected Object unmarshalDomNode(Node node) throws XmlMappingException {
try {
Transformer transformer = transformerFactory.newTransformer();
ByteArrayOutputStream os = new ByteArrayOutputStream();
transformer.transform(new DOMSource(node), new StreamResult(os));
ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
return unmarshalInputStream(is);
}
catch (IOException ex) {
throw new JibxSystemException(ex);
}
catch (TransformerException ex) {
throw new JibxSystemException(ex);
}
}
try {
Transformer transformer = transformerFactory.newTransformer();
ByteArrayOutputStream os = new ByteArrayOutputStream();
transformer.transform(new DOMSource(node), new StreamResult(os));
ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
return unmarshalInputStream(is);
}
catch (IOException ex) {
throw new JibxSystemException(ex);
}
catch (TransformerException ex) {
throw new JibxSystemException(ex);
}
}
@Override
@Override
protected Object unmarshalSaxReader(XMLReader xmlReader, InputSource inputSource)
throws XmlMappingException, IOException {
try {
Transformer transformer = transformerFactory.newTransformer();
ByteArrayOutputStream os = new ByteArrayOutputStream();
transformer.transform(new SAXSource(xmlReader, inputSource), new StreamResult(os));
ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
return unmarshalInputStream(is);
}
catch (IOException ex) {
throw new JibxSystemException(ex);
}
catch (TransformerException ex) {
throw new JibxSystemException(ex);
}
}
throws XmlMappingException, IOException {
try {
Transformer transformer = transformerFactory.newTransformer();
ByteArrayOutputStream os = new ByteArrayOutputStream();
transformer.transform(new SAXSource(xmlReader, inputSource), new StreamResult(os));
ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
return unmarshalInputStream(is);
}
catch (IOException ex) {
throw new JibxSystemException(ex);
}
catch (TransformerException ex) {
throw new JibxSystemException(ex);
}
}
/**
* Creates a new <code>IMarshallingContext</code>, set with the correct indentation.
*
* @return the created marshalling context
* @throws JiBXException in case of errors
*/
protected IMarshallingContext createMarshallingContext() throws JiBXException {
IMarshallingContext marshallingContext = bindingFactory.createMarshallingContext();
marshallingContext.setIndent(indent);
return marshallingContext;
}
/**
* Creates a new <code>IMarshallingContext</code>, set with the correct indentation.
*
* @return the created marshalling context
* @throws JiBXException in case of errors
*/
protected IMarshallingContext createMarshallingContext() throws JiBXException {
IMarshallingContext marshallingContext = bindingFactory.createMarshallingContext();
marshallingContext.setIndent(indent);
return marshallingContext;
}
/**
* Creates a new <code>IUnmarshallingContext</code>, set with the correct indentation.
*
* @return the created unmarshalling context
* @throws JiBXException in case of errors
*/
protected IUnmarshallingContext createUnmarshallingContext() throws JiBXException {
return bindingFactory.createUnmarshallingContext();
}
/**
* Creates a new <code>IUnmarshallingContext</code>, set with the correct indentation.
*
* @return the created unmarshalling context
* @throws JiBXException in case of errors
*/
protected IUnmarshallingContext createUnmarshallingContext() throws JiBXException {
return bindingFactory.createUnmarshallingContext();
}
}

View File

@@ -17,6 +17,7 @@
package org.springframework.oxm.jibx;
import org.jibx.runtime.JiBXException;
import org.springframework.oxm.MarshallingFailureException;
/**
@@ -24,11 +25,11 @@ import org.springframework.oxm.MarshallingFailureException;
*
* @author Arjen Poutsma
* @see JibxUtils#convertJibxException(org.jibx.runtime.JiBXException,boolean)
* @since 1.0.0
* @since 3.0
*/
public class JibxMarshallingFailureException extends MarshallingFailureException {
public JibxMarshallingFailureException(JiBXException ex) {
super("JiBX marshalling exception: " + ex.getMessage(), ex);
}
public JibxMarshallingFailureException(JiBXException ex) {
super("JiBX marshalling exception: " + ex.getMessage(), ex);
}
}

View File

@@ -24,11 +24,11 @@ import org.springframework.oxm.UncategorizedXmlMappingException;
*
* @author Arjen Poutsma
* @see JibxUtils#convertJibxException(org.jibx.runtime.JiBXException,boolean)
* @since 1.0.0
* @since 3.0
*/
public class JibxSystemException extends UncategorizedXmlMappingException {
public JibxSystemException(Exception ex) {
super(ex.getMessage(), ex);
}
public JibxSystemException(Exception ex) {
super(ex.getMessage(), ex);
}
}

View File

@@ -17,6 +17,7 @@
package org.springframework.oxm.jibx;
import org.jibx.runtime.JiBXException;
import org.springframework.oxm.UnmarshallingFailureException;
/**
@@ -24,12 +25,12 @@ import org.springframework.oxm.UnmarshallingFailureException;
*
* @author Arjen Poutsma
* @see JibxUtils#convertJibxException(org.jibx.runtime.JiBXException,boolean)
* @since 1.0.0
* @since 3.0
*/
public class JibxUnmarshallingFailureException extends UnmarshallingFailureException {
public JibxUnmarshallingFailureException(JiBXException ex) {
super("JiBX unmarshalling exception: " + ex.getMessage(), ex);
}
public JibxUnmarshallingFailureException(JiBXException ex) {
super("JiBX unmarshalling exception: " + ex.getMessage(), ex);
}
}

View File

@@ -18,39 +18,39 @@ package org.springframework.oxm.jibx;
import org.jibx.runtime.JiBXException;
import org.jibx.runtime.ValidationException;
import org.springframework.oxm.XmlMappingException;
/**
* Generic utility methods for working with JiBX. Mainly for internal use within the framework.
*
* @author Arjen Poutsma
* @since 1.0.0
* @since 3.0
*/
public abstract class JibxUtils {
/**
* Converts the given <code>JiBXException</code> to an appropriate exception from the
* <code>org.springframework.oxm</code> hierarchy.
* <p/>
* A boolean flag is used to indicate whether this exception occurs during marshalling or unmarshalling, since JiBX
* itself does not make this distinction in its exception hierarchy.
*
* @param ex <code>JiBXException</code> that occured
* @param marshalling indicates whether the exception occurs during marshalling (<code>true</code>), or
* unmarshalling (<code>false</code>)
* @return the corresponding <code>XmlMappingException</code>
*/
public static XmlMappingException convertJibxException(JiBXException ex, boolean marshalling) {
if (ex instanceof ValidationException) {
return new JibxValidationFailureException((ValidationException) ex);
}
else {
if (marshalling) {
return new JibxMarshallingFailureException(ex);
}
else {
return new JibxUnmarshallingFailureException(ex);
}
}
}
/**
* Converts the given <code>JiBXException</code> to an appropriate exception from the
* <code>org.springframework.oxm</code> hierarchy. <p/> A boolean flag is used to indicate whether this exception
* occurs during marshalling or unmarshalling, since JiBX itself does not make this distinction in its exception
* hierarchy.
*
* @param ex <code>JiBXException</code> that occured
* @param marshalling indicates whether the exception occurs during marshalling (<code>true</code>), or unmarshalling
* (<code>false</code>)
* @return the corresponding <code>XmlMappingException</code>
*/
public static XmlMappingException convertJibxException(JiBXException ex, boolean marshalling) {
if (ex instanceof ValidationException) {
return new JibxValidationFailureException((ValidationException) ex);
}
else {
if (marshalling) {
return new JibxMarshallingFailureException(ex);
}
else {
return new JibxUnmarshallingFailureException(ex);
}
}
}
}

View File

@@ -17,6 +17,7 @@
package org.springframework.oxm.jibx;
import org.jibx.runtime.ValidationException;
import org.springframework.oxm.ValidationFailureException;
/**
@@ -24,12 +25,12 @@ import org.springframework.oxm.ValidationFailureException;
*
* @author Arjen Poutsma
* @see JibxUtils#convertJibxException(org.jibx.runtime.JiBXException,boolean)
* @since 1.0.0
* @since 3.0
*/
public class JibxValidationFailureException extends ValidationFailureException {
public JibxValidationFailureException(ValidationException ex) {
super("JiBX validation exception: " + ex.getMessage(), ex);
}
public JibxValidationFailureException(ValidationException ex) {
super("JiBX validation exception: " + ex.getMessage(), ex);
}
}

View File

@@ -23,40 +23,40 @@ import javax.activation.DataHandler;
*
* @author Arjen Poutsma
* @see <a href="http://www.w3.org/TR/2005/REC-xop10-20050125/">XML-binary Optimized Packaging</a>
* @since 1.0.0
* @since 3.0
*/
public interface MimeContainer {
/**
* Indicates whether this container is a XOP package.
*
* @return <code>true</code> when the constraints specified in <a href="http://www.w3.org/TR/2005/REC-xop10-20050125/#identifying_xop_documents">Identifying
* XOP Documents</a> are met.
* @see <a href="http://www.w3.org/TR/2005/REC-xop10-20050125/#xop_packages">XOP Packages</a>
*/
boolean isXopPackage();
/**
* Indicates whether this container is a XOP package.
*
* @return <code>true</code> when the constraints specified in <a href="http://www.w3.org/TR/2005/REC-xop10-20050125/#identifying_xop_documents">Identifying
* XOP Documents</a> are met.
* @see <a href="http://www.w3.org/TR/2005/REC-xop10-20050125/#xop_packages">XOP Packages</a>
*/
boolean isXopPackage();
/**
* Turns this message into a XOP package.
*
* @return <code>true</code> when the message is a XOP package
* @see <a href="http://www.w3.org/TR/2005/REC-xop10-20050125/#xop_packages">XOP Packages</a>
*/
boolean convertToXopPackage();
/**
* Turns this message into a XOP package.
*
* @return <code>true</code> when the message is a XOP package
* @see <a href="http://www.w3.org/TR/2005/REC-xop10-20050125/#xop_packages">XOP Packages</a>
*/
boolean convertToXopPackage();
/**
* Adds the given data handler as an attachment to this container.
*
* @param contentId the content id of the attachment
* @param dataHandler the data handler containing the data of the attachment
*/
void addAttachment(String contentId, DataHandler dataHandler);
/**
* Adds the given data handler as an attachment to this container.
*
* @param contentId the content id of the attachment
* @param dataHandler the data handler containing the data of the attachment
*/
void addAttachment(String contentId, DataHandler dataHandler);
/**
* Returns the attachment with the given content id, or <code>null</code> if not found.
*
* @param contentId the content id
* @return the attachment, as a data handler
*/
DataHandler getAttachment(String contentId);
/**
* Returns the attachment with the given content id, or <code>null</code> if not found.
*
* @param contentId the content id
* @return the attachment, as a data handler
*/
DataHandler getAttachment(String contentId);
}

View File

@@ -30,21 +30,21 @@ import org.springframework.oxm.XmlMappingException;
* @see <a href="http://www.w3.org/TR/2004/WD-soap12-mtom-20040608/">SOAP Message Transmission Optimization
* Mechanism</a>
* @see <a href="http://www.w3.org/TR/2005/REC-xop10-20050125/">XML-binary Optimized Packaging</a>
* @since 1.0.0
* @since 3.0
*/
public interface MimeMarshaller extends Marshaller {
/**
* Marshals the object graph with the given root into the provided {@link Result}, writing binary data to a {@link
* MimeContainer}.
*
* @param graph the root of the object graph to marshal
* @param result the result to marshal to
* @param mimeContainer the MIME container to write extracted binary content to
* @throws XmlMappingException if the given object cannot be marshalled to the result
* @throws IOException if an I/O exception occurs
*/
void marshal(Object graph, Result result, MimeContainer mimeContainer) throws XmlMappingException, IOException;
/**
* Marshals the object graph with the given root into the provided {@link Result}, writing binary data to a {@link
* MimeContainer}.
*
* @param graph the root of the object graph to marshal
* @param result the result to marshal to
* @param mimeContainer the MIME container to write extracted binary content to
* @throws XmlMappingException if the given object cannot be marshalled to the result
* @throws IOException if an I/O exception occurs
*/
void marshal(Object graph, Result result, MimeContainer mimeContainer) throws XmlMappingException, IOException;
}

View File

@@ -30,19 +30,19 @@ import org.springframework.oxm.XmlMappingException;
* @see <a href="http://www.w3.org/TR/2004/WD-soap12-mtom-20040608/">SOAP Message Transmission Optimization
* Mechanism</a>
* @see <a href="http://www.w3.org/TR/2005/REC-xop10-20050125/">XML-binary Optimized Packaging</a>
* @since 1.0.0
* @since 3.0
*/
public interface MimeUnmarshaller extends Unmarshaller {
/**
* Unmarshals the given provided {@link Source} into an object graph, reading binary attachments from a {@link
* MimeContainer}.
*
* @param source the source to marshal from
* @param mimeContainer the MIME container to read extracted binary content from
* @return the object graph
* @throws XmlMappingException if the given source cannot be mapped to an object
* @throws IOException if an I/O Exception occurs
*/
Object unmarshal(Source source, MimeContainer mimeContainer) throws XmlMappingException, IOException;
/**
* Unmarshals the given provided {@link Source} into an object graph, reading binary attachments from a {@link
* MimeContainer}.
*
* @param source the source to marshal from
* @param mimeContainer the MIME container to read extracted binary content from
* @return the object graph
* @throws XmlMappingException if the given source cannot be mapped to an object
* @throws IOException if an I/O Exception occurs
*/
Object unmarshal(Source source, MimeContainer mimeContainer) throws XmlMappingException, IOException;
}

View File

@@ -1,306 +0,0 @@
/*
* Copyright 2007 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.support;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jms.support.converter.MessageConversionException;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.MarshallingFailureException;
import org.springframework.oxm.Unmarshaller;
import org.springframework.oxm.UnmarshallingFailureException;
import org.springframework.util.Assert;
/**
* Spring JMS {@link MessageConverter} that uses a {@link Marshaller} and {@link Unmarshaller}. Marshals an object to a
* {@link BytesMessage}, or to a {@link TextMessage} if the {@link #setMarshalTo marshalTo} is set to {@link
* #MARSHAL_TO_TEXT_MESSAGE}. Unmarshals from a {@link TextMessage} or {@link BytesMessage} to an object.
*
* @author Arjen Poutsma
* @see org.springframework.jms.core.JmsTemplate#convertAndSend
* @see org.springframework.jms.core.JmsTemplate#receiveAndConvert
* @since 1.5.1
*/
public class MarshallingMessageConverter implements MessageConverter, InitializingBean {
/** Constant that indicates that {@link #toMessage(Object, Session)} should marshal to a {@link BytesMessage}. */
public static final int MARSHAL_TO_BYTES_MESSAGE = 1;
/** Constant that indicates that {@link #toMessage(Object, Session)} should marshal to a {@link TextMessage}. */
public static final int MARSHAL_TO_TEXT_MESSAGE = 2;
private Marshaller marshaller;
private Unmarshaller unmarshaller;
private int marshalTo = MARSHAL_TO_BYTES_MESSAGE;
/**
* Constructs a new <code>MarshallingMessageConverter</code> with no {@link Marshaller} set. The marshaller must be
* set after construction by invoking {@link #setMarshaller(Marshaller)}.
*/
public MarshallingMessageConverter() {
}
/**
* Constructs a new <code>MarshallingMessageConverter</code> with the given {@link Marshaller} set. If the given
* {@link Marshaller} also implements the {@link Unmarshaller} interface, it is used for both marshalling and
* unmarshalling. Otherwise, an exception is thrown.
* <p/>
* Note that all {@link Marshaller} implementations in Spring-WS also implement the {@link Unmarshaller} interface,
* so that you can safely use this constructor.
*
* @param marshaller object used as marshaller and unmarshaller
* @throws IllegalArgumentException when <code>marshaller</code> does not implement the {@link Unmarshaller}
* interface
*/
public MarshallingMessageConverter(Marshaller marshaller) {
Assert.notNull(marshaller, "marshaller must not be null");
if (!(marshaller instanceof Unmarshaller)) {
throw new IllegalArgumentException("Marshaller [" + marshaller + "] does not implement the Unmarshaller " +
"interface. Please set an Unmarshaller explicitely by using the " +
"AbstractMarshallingPayloadEndpoint(Marshaller, Unmarshaller) constructor.");
}
else {
this.marshaller = marshaller;
this.unmarshaller = (Unmarshaller) marshaller;
}
}
/**
* Creates a new <code>MarshallingMessageConverter</code> with the given marshaller and unmarshaller.
*
* @param marshaller the marshaller to use
* @param unmarshaller the unmarshaller to use
*/
public MarshallingMessageConverter(Marshaller marshaller, Unmarshaller unmarshaller) {
Assert.notNull(marshaller, "marshaller must not be null");
Assert.notNull(unmarshaller, "unmarshaller must not be null");
this.marshaller = marshaller;
this.unmarshaller = unmarshaller;
}
/**
* Indicates whether {@link #toMessage(Object,Session)} should marshal to a {@link BytesMessage} or a {@link
* TextMessage}. The default is {@link #MARSHAL_TO_BYTES_MESSAGE}, i.e. this converter marshals to a {@link
* BytesMessage}.
*
* @see #MARSHAL_TO_BYTES_MESSAGE
* @see #MARSHAL_TO_TEXT_MESSAGE
*/
public void setMarshalTo(int marshalTo) {
this.marshalTo = marshalTo;
}
/** Sets the {@link Marshaller} to be used by this message converter. */
public void setMarshaller(Marshaller marshaller) {
this.marshaller = marshaller;
}
/** Sets the {@link Unmarshaller} to be used by this message converter. */
public void setUnmarshaller(Unmarshaller unmarshaller) {
this.unmarshaller = unmarshaller;
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(marshaller, "Property 'marshaller' is required");
Assert.notNull(unmarshaller, "Property 'unmarshaller' is required");
}
/**
* Marshals the given object to a {@link TextMessage} or {@link javax.jms.BytesMessage}. The desired message type
* can be defined by setting the {@link #setMarshalTo(int) marshalTo} property.
*
* @see #marshalToTextMessage
* @see #marshalToBytesMessage
*/
public Message toMessage(Object object, Session session) throws JMSException, MessageConversionException {
try {
switch (marshalTo) {
case MARSHAL_TO_TEXT_MESSAGE:
return marshalToTextMessage(object, session, marshaller);
case MARSHAL_TO_BYTES_MESSAGE:
return marshalToBytesMessage(object, session, marshaller);
default:
return marshalToMessage(object, session, marshaller);
}
}
catch (MarshallingFailureException ex) {
throw new MessageConversionException("Could not marshal [" + object + "]", ex);
}
catch (IOException ex) {
throw new MessageConversionException("Could not marshal [" + object + "]", ex);
}
}
/**
* Unmarshals the given {@link Message} into an object.
*
* @see #unmarshalFromTextMessage
* @see #unmarshalFromBytesMessage
*/
public Object fromMessage(Message message) throws JMSException, MessageConversionException {
try {
if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
return unmarshalFromTextMessage(textMessage, unmarshaller);
}
else if (message instanceof BytesMessage) {
BytesMessage bytesMessage = (BytesMessage) message;
return unmarshalFromBytesMessage(bytesMessage, unmarshaller);
}
else {
return unmarshalFromMessage(message, unmarshaller);
}
}
catch (UnmarshallingFailureException ex) {
throw new MessageConversionException("Could not unmarshal message [" + message + "]", ex);
}
catch (IOException ex) {
throw new MessageConversionException("Could not unmarshal message [" + message + "]", ex);
}
}
/**
* Marshals the given object to a {@link TextMessage}.
*
* @param object the object to be marshalled
* @param session current JMS session
* @param marshaller the marshaller to use
* @return the resulting message
* @throws JMSException if thrown by JMS methods
* @throws IOException in case of I/O errors
* @see Session#createTextMessage
* @see Marshaller#marshal(Object, Result)
*/
protected TextMessage marshalToTextMessage(Object object, Session session, Marshaller marshaller)
throws JMSException, IOException {
StringWriter writer = new StringWriter();
Result result = new StreamResult(writer);
marshaller.marshal(object, result);
return session.createTextMessage(writer.toString());
}
/**
* Marshals the given object to a {@link BytesMessage}.
*
* @param object the object to be marshalled
* @param session current JMS session
* @param marshaller the marshaller to use
* @return the resulting message
* @throws JMSException if thrown by JMS methods
* @throws IOException in case of I/O errors
* @see Session#createBytesMessage
* @see Marshaller#marshal(Object, Result)
*/
protected BytesMessage marshalToBytesMessage(Object object, Session session, Marshaller marshaller)
throws JMSException, IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
StreamResult streamResult = new StreamResult(bos);
marshaller.marshal(object, streamResult);
BytesMessage message = session.createBytesMessage();
message.writeBytes(bos.toByteArray());
return message;
}
/**
* Template method that allows for custom message marshalling. Invoked when {@link #setMarshalTo(int)} is not {@link
* #MARSHAL_TO_TEXT_MESSAGE} or {@link #MARSHAL_TO_BYTES_MESSAGE}.
* <p/>
* Default implemenetation throws a {@link MessageConversionException}.
*
* @param object the object to marshal
* @param session the JMS session
* @param marshaller the marshaller to use
* @return the resulting message
* @throws JMSException if thrown by JMS methods
* @throws IOException in case of I/O errors
*/
protected Message marshalToMessage(Object object, Session session, Marshaller marshaller)
throws JMSException, IOException {
throw new MessageConversionException(
"Unknown 'marshalTo' value [" + marshalTo + "]. Cannot convert object to Message");
}
/**
* Unmarshals the given {@link TextMessage} into an object.
*
* @param message the message
* @param unmarshaller the unmarshaller to use
* @return the unmarshalled object
* @throws JMSException if thrown by JMS methods
* @throws IOException in case of I/O errors
* @see Unmarshaller#unmarshal(Source)
*/
protected Object unmarshalFromTextMessage(TextMessage message, Unmarshaller unmarshaller)
throws JMSException, IOException {
Source source = new StreamSource(new StringReader(message.getText()));
return unmarshaller.unmarshal(source);
}
/**
* Unmarshals the given {@link BytesMessage} into an object.
*
* @param message the message
* @param unmarshaller the unmarshaller to use
* @return the unmarshalled object
* @throws JMSException if thrown by JMS methods
* @throws IOException in case of I/O errors
* @see Unmarshaller#unmarshal(Source)
*/
protected Object unmarshalFromBytesMessage(BytesMessage message, Unmarshaller unmarshaller)
throws JMSException, IOException {
byte[] bytes = new byte[(int) message.getBodyLength()];
message.readBytes(bytes);
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
StreamSource source = new StreamSource(bis);
return unmarshaller.unmarshal(source);
}
/**
* Template method that allows for custom message unmarshalling. Invoked when {@link #fromMessage(Message)} is
* invoked with a message that is not a {@link TextMessage} or {@link BytesMessage}.
* <p/>
* Default implemenetation throws a {@link MessageConversionException}.
*
* @param message the message
* @param unmarshaller the unmarshaller to use
* @return the unmarshalled object
* @throws JMSException if thrown by JMS methods
* @throws IOException in case of I/O errors
*/
protected Object unmarshalFromMessage(Message message, Unmarshaller unmarshaller) throws JMSException, IOException {
throw new MessageConversionException(
"MarshallingMessageConverter only supports TextMessages and BytesMessages");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2007 the original author or authors.
* Copyright 2002-2009 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.
@@ -21,84 +21,194 @@ import javax.xml.transform.Source;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;
import org.springframework.oxm.Marshaller;
import org.springframework.util.Assert;
import org.springframework.xml.sax.AbstractXmlReader;
import org.xml.sax.ContentHandler;
import org.xml.sax.DTDHandler;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.ext.LexicalHandler;
import org.springframework.oxm.Marshaller;
import org.springframework.util.Assert;
/**
* {@link Source} implementation that uses a {@link Marshaller}.Can be constructed with a <code>Marshaller</code> and an
* object to be marshalled.
* <p/>
* Even though <code>StaxSource</code> extends from <code>SAXSource</code>, calling the methods of
*
* <p>Even though <code>MarshallingSource</code> extends from <code>SAXSource</code>, calling the methods of
* <code>SAXSource</code> is <strong>not supported</strong>. In general, the only supported operation on this class is
* to use the <code>XMLReader</code> obtained via {@link #getXMLReader()} to parse the input source obtained via {@link
* #getInputSource()}. Calling {@link #setXMLReader(org.xml.sax.XMLReader)} or {@link
* #setInputSource(org.xml.sax.InputSource)} will result in <code>UnsupportedOperationException</code>s.
* #getInputSource()}. Calling {@link #setXMLReader(XMLReader)} or {@link #setInputSource(InputSource)} will result in
* <code>UnsupportedOperationException</code>s.
*
* @author Arjen Poutsma
* @see javax.xml.transform.Transformer
* @since 1.0.0
* @since 3.0
*/
public class MarshallingSource extends SAXSource {
private final Marshaller marshaller;
private final Marshaller marshaller;
private final Object content;
private final Object content;
/**
* Creates a new <code>MarshallingSource</code> with the given marshaller and content.
*
* @param marshaller the marshaller to use
* @param content the object to be marshalled
*/
public MarshallingSource(Marshaller marshaller, Object content) {
Assert.notNull(marshaller, "'marshaller' must not be null");
Assert.notNull(content, "'content' must not be null");
this.marshaller = marshaller;
this.content = content;
setXMLReader(new MarshallingXmlReader());
setInputSource(new InputSource());
}
/**
* Creates a new <code>MarshallingSource</code> with the given marshaller and content.
*
* @param marshaller the marshaller to use
* @param content the object to be marshalled
*/
public MarshallingSource(Marshaller marshaller, Object content) {
super(new MarshallingXMLReader(marshaller, content), new InputSource());
Assert.notNull(marshaller, "'marshaller' must not be null");
Assert.notNull(content, "'content' must not be null");
this.marshaller = marshaller;
this.content = content;
}
/** Returns the <code>Marshaller</code> used by this <code>MarshallingSource</code>. */
public Marshaller getMarshaller() {
return marshaller;
}
/** Returns the <code>Marshaller</code> used by this <code>MarshallingSource</code>. */
public Marshaller getMarshaller() {
return marshaller;
}
/** Returns the object to be marshalled. */
public Object getContent() {
return content;
}
/** Returns the object to be marshalled. */
public Object getContent() {
return content;
}
private class MarshallingXmlReader extends AbstractXmlReader {
/**
* Throws a <code>UnsupportedOperationException</code>.
*
* @throws UnsupportedOperationException always
*/
@Override
public void setInputSource(InputSource inputSource) {
throw new UnsupportedOperationException("setInputSource is not supported");
}
public void parse(InputSource input) throws IOException, SAXException {
parse();
}
/**
* Throws a <code>UnsupportedOperationException</code>.
*
* @throws UnsupportedOperationException always
*/
@Override
public void setXMLReader(XMLReader reader) {
throw new UnsupportedOperationException("setXMLReader is not supported");
}
public void parse(String systemId) throws IOException, SAXException {
parse();
}
private static class MarshallingXMLReader implements XMLReader {
private void parse() throws SAXException {
SAXResult result = new SAXResult(getContentHandler());
result.setLexicalHandler(getLexicalHandler());
try {
marshaller.marshal(content, result);
}
catch (IOException ex) {
SAXParseException saxException = new SAXParseException(ex.getMessage(), null, null, -1, -1, ex);
if (getErrorHandler() != null) {
getErrorHandler().fatalError(saxException);
}
else {
throw saxException;
}
}
}
private final Marshaller marshaller;
}
private final Object content;
private DTDHandler dtdHandler;
private ContentHandler contentHandler;
private EntityResolver entityResolver;
private ErrorHandler errorHandler;
private LexicalHandler lexicalHandler;
private MarshallingXMLReader(Marshaller marshaller, Object content) {
Assert.notNull(marshaller, "'marshaller' must not be null");
Assert.notNull(content, "'content' must not be null");
this.marshaller = marshaller;
this.content = content;
}
public ContentHandler getContentHandler() {
return contentHandler;
}
public void setContentHandler(ContentHandler contentHandler) {
this.contentHandler = contentHandler;
}
public void setDTDHandler(DTDHandler dtdHandler) {
this.dtdHandler = dtdHandler;
}
public DTDHandler getDTDHandler() {
return dtdHandler;
}
public EntityResolver getEntityResolver() {
return entityResolver;
}
public void setEntityResolver(EntityResolver entityResolver) {
this.entityResolver = entityResolver;
}
public ErrorHandler getErrorHandler() {
return errorHandler;
}
public void setErrorHandler(ErrorHandler errorHandler) {
this.errorHandler = errorHandler;
}
protected LexicalHandler getLexicalHandler() {
return lexicalHandler;
}
public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
throw new SAXNotRecognizedException(name);
}
public void setFeature(String name, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException {
throw new SAXNotRecognizedException(name);
}
public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
if ("http://xml.org/sax/properties/lexical-handler".equals(name)) {
return lexicalHandler;
}
else {
throw new SAXNotRecognizedException(name);
}
}
public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException {
if ("http://xml.org/sax/properties/lexical-handler".equals(name)) {
lexicalHandler = (LexicalHandler) value;
}
else {
throw new SAXNotRecognizedException(name);
}
}
public void parse(InputSource input) throws IOException, SAXException {
parse();
}
public void parse(String systemId) throws IOException, SAXException {
parse();
}
private void parse() throws SAXException {
SAXResult result = new SAXResult(getContentHandler());
result.setLexicalHandler(getLexicalHandler());
try {
marshaller.marshal(content, result);
}
catch (IOException ex) {
SAXParseException saxException = new SAXParseException(ex.getMessage(), null, null, -1, -1, ex);
if (getErrorHandler() != null) {
getErrorHandler().fatalError(saxException);
}
else {
throw saxException;
}
}
}
}
}

View File

@@ -1,134 +0,0 @@
/*
* Copyright 2007 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.support;
import java.io.ByteArrayOutputStream;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.stream.StreamResult;
import org.springframework.beans.BeansException;
import org.springframework.oxm.Marshaller;
import org.springframework.util.Assert;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.view.AbstractUrlBasedView;
/**
* Spring-MVC {@link View} that allows for response context to be rendered as the result of marshalling by a {@link
* Marshaller}.
* <p/>
* The Object to be marshalled is supplied as a parameter in the model and then {@linkplain #locateToBeMarshalled(Map)
* detected} during response rendering. Users can either specify a specific entry in the model via the {@link
* #setModelKey(String) sourceKey} property or have Spring locate the Source object.
*
* @author Arjen Poutsma
* @since 1.5.1
*/
public class MarshallingView extends AbstractUrlBasedView {
/** Default content type. Overridable as bean property. */
public static final String DEFAULT_CONTENT_TYPE = "application/xml";
private Marshaller marshaller;
private String modelKey;
/**
* Constructs a new <code>MarshallingView</code> with no {@link Marshaller} set. The marshaller must be set after
* construction by invoking {@link #setMarshaller(Marshaller)}.
*/
public MarshallingView() {
setContentType(DEFAULT_CONTENT_TYPE);
}
/** Constructs a new <code>MarshallingView</code> with the given {@link Marshaller} set. */
public MarshallingView(Marshaller marshaller) {
Assert.notNull(marshaller, "'marshaller' must not be null");
setContentType(DEFAULT_CONTENT_TYPE);
this.marshaller = marshaller;
}
/** Sets the {@link Marshaller} to be used by this view. */
public void setMarshaller(Marshaller marshaller) {
Assert.notNull(marshaller, "'marshaller' must not be null");
this.marshaller = marshaller;
}
/**
* Set the name of the model key that represents the object to be marshalled. If not specified, the model map will
* be searched for a supported value type.
*
* @see Marshaller#supports(Class)
*/
public void setModelKey(String modelKey) {
this.modelKey = modelKey;
}
@Override
protected void initApplicationContext() throws BeansException {
Assert.notNull(marshaller, "Property 'marshaller' is required");
}
@Override
protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response)
throws Exception {
Object toBeMarshalled = locateToBeMarshalled(model);
if (toBeMarshalled == null) {
throw new ServletException("Unable to locate object to be marshalled in model: " + model);
}
ByteArrayOutputStream bos = new ByteArrayOutputStream(2048);
marshaller.marshal(toBeMarshalled, new StreamResult(bos));
response.setContentType(getContentType());
response.setContentLength(bos.size());
ServletOutputStream out = response.getOutputStream();
bos.writeTo(out);
out.flush();
}
/**
* Locates the object to be marshalled. The default implementation first attempts to look under the configured
* {@linkplain #setModelKey(String) model key}, if any, before attempting to locate an object of {@linkplain
* Marshaller#supports(Class) supported type}.
*
* @param model the model Map
* @return the Object to be marshalled (or <code>null</code> if none found)
* @throws ServletException if the model object specified by the {@linkplain #setModelKey(String) model key} is not
* supported by the marshaller
* @see #setModelKey(String)
*/
protected Object locateToBeMarshalled(Map model) throws ServletException {
if (this.modelKey != null) {
Object o = model.get(this.modelKey);
if (!this.marshaller.supports(o.getClass())) {
throw new ServletException("Model object [" + o + "] retrieved via key [" + modelKey +
"] is not supported by the Marshaller");
}
return o;
}
for (Object o : model.values()) {
if (this.marshaller.supports(o.getClass())) {
return o;
}
}
return null;
}
}

View File

@@ -19,12 +19,6 @@ import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.XmlSaxHandler;
import org.apache.xmlbeans.XmlValidationError;
import org.springframework.oxm.AbstractMarshaller;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.XmlMappingException;
import org.springframework.xml.stream.StaxEventContentHandler;
import org.springframework.xml.stream.StaxEventXmlReader;
import org.springframework.xml.stream.StaxStreamContentHandler;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
@@ -36,234 +30,233 @@ import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.XMLReader;
import org.xml.sax.ext.LexicalHandler;
import org.springframework.oxm.AbstractMarshaller;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.XmlMappingException;
import org.springframework.util.xml.StaxUtils;
/**
* Implementation of the {@link Marshaller} interface for XMLBeans. Further options can be set by setting the
* <code>xmlOptions</code> property. The {@link XmlOptionsFactoryBean} is provided to easily wire up {@link XmlOptions}
* instances.
* <p/>
* Unmarshalled objects can be validated by setting the <code>validating</code> property, or by calling the {@link
* #validate(XmlObject)} method directly. Invalid objects will result in an {@link XmlBeansValidationFailureException}.
* <p/>
* <strong>Note</strong> that due to the nature of XMLBeans, this marshaller requires all passed objects to be of type
* {@link XmlObject}.
* instances. <p/> Unmarshalled objects can be validated by setting the <code>validating</code> property, or by calling
* the {@link #validate(XmlObject)} method directly. Invalid objects will result in an {@link
* XmlBeansValidationFailureException}. <p/> <strong>Note</strong> that due to the nature of XMLBeans, this marshaller
* requires all passed objects to be of type {@link XmlObject}.
*
* @author Arjen Poutsma
* @see #setXmlOptions(org.apache.xmlbeans.XmlOptions)
* @see XmlOptionsFactoryBean
* @see #setValidating(boolean)
* @since 1.0.0
* @since 3.0
*/
public class XmlBeansMarshaller extends AbstractMarshaller {
private XmlOptions xmlOptions;
private XmlOptions xmlOptions;
private boolean validating = false;
private boolean validating = false;
/** Returns the <code>XmlOptions</code>. */
public XmlOptions getXmlOptions() {
return xmlOptions;
}
/** Returns the <code>XmlOptions</code>. */
public XmlOptions getXmlOptions() {
return xmlOptions;
}
/**
* Sets the <code>XmlOptions</code>.
*
* @see XmlOptionsFactoryBean
*/
public void setXmlOptions(XmlOptions xmlOptions) {
this.xmlOptions = xmlOptions;
}
/**
* Sets the <code>XmlOptions</code>.
*
* @see XmlOptionsFactoryBean
*/
public void setXmlOptions(XmlOptions xmlOptions) {
this.xmlOptions = xmlOptions;
}
/** Returns whether this marshaller should validate in- and outgoing documents. */
public boolean isValidating() {
return validating;
}
/** Returns whether this marshaller should validate in- and outgoing documents. */
public boolean isValidating() {
return validating;
}
/** Sets whether this marshaller should validate in- and outgoing documents. Default is <code>false</code>. */
public void setValidating(boolean validating) {
this.validating = validating;
}
/** Sets whether this marshaller should validate in- and outgoing documents. Default is <code>false</code>. */
public void setValidating(boolean validating) {
this.validating = validating;
}
/** Returns true if the given class is an implementation of {@link XmlObject}. */
public boolean supports(Class clazz) {
return XmlObject.class.isAssignableFrom(clazz);
}
/** Returns true if the given class is an implementation of {@link XmlObject}. */
public boolean supports(Class clazz) {
return XmlObject.class.isAssignableFrom(clazz);
}
@Override
@Override
protected final void marshalDomNode(Object graph, Node node) throws XmlMappingException {
Document document = node.getNodeType() == Node.DOCUMENT_NODE ? (Document) node : node.getOwnerDocument();
Node xmlBeansNode = ((XmlObject) graph).newDomNode(getXmlOptions());
NodeList xmlBeansChildNodes = xmlBeansNode.getChildNodes();
for (int i = 0; i < xmlBeansChildNodes.getLength(); i++) {
Node xmlBeansChildNode = xmlBeansChildNodes.item(i);
Node importedNode = document.importNode(xmlBeansChildNode, true);
node.appendChild(importedNode);
}
}
Document document = node.getNodeType() == Node.DOCUMENT_NODE ? (Document) node : node.getOwnerDocument();
Node xmlBeansNode = ((XmlObject) graph).newDomNode(getXmlOptions());
NodeList xmlBeansChildNodes = xmlBeansNode.getChildNodes();
for (int i = 0; i < xmlBeansChildNodes.getLength(); i++) {
Node xmlBeansChildNode = xmlBeansChildNodes.item(i);
Node importedNode = document.importNode(xmlBeansChildNode, true);
node.appendChild(importedNode);
}
}
@Override
@Override
protected final void marshalOutputStream(Object graph, OutputStream outputStream)
throws XmlMappingException, IOException {
((XmlObject) graph).save(outputStream, getXmlOptions());
}
throws XmlMappingException, IOException {
((XmlObject) graph).save(outputStream, getXmlOptions());
}
@Override
@Override
protected final void marshalSaxHandlers(Object graph, ContentHandler contentHandler, LexicalHandler lexicalHandler)
throws XmlMappingException {
try {
((XmlObject) graph).save(contentHandler, lexicalHandler, getXmlOptions());
}
catch (SAXException ex) {
throw convertXmlBeansException(ex, true);
}
}
throws XmlMappingException {
try {
((XmlObject) graph).save(contentHandler, lexicalHandler, getXmlOptions());
}
catch (SAXException ex) {
throw convertXmlBeansException(ex, true);
}
}
@Override
@Override
protected final void marshalWriter(Object graph, Writer writer) throws XmlMappingException, IOException {
((XmlObject) graph).save(writer, getXmlOptions());
}
((XmlObject) graph).save(writer, getXmlOptions());
}
@Override
@Override
protected final void marshalXmlEventWriter(Object graph, XMLEventWriter eventWriter) {
ContentHandler contentHandler = new StaxEventContentHandler(eventWriter);
marshalSaxHandlers(graph, contentHandler, null);
}
ContentHandler contentHandler = StaxUtils.createContentHandler(eventWriter);
marshalSaxHandlers(graph, contentHandler, null);
}
@Override
@Override
protected final void marshalXmlStreamWriter(Object graph, XMLStreamWriter streamWriter) throws XmlMappingException {
ContentHandler contentHandler = new StaxStreamContentHandler(streamWriter);
marshalSaxHandlers(graph, contentHandler, null);
}
ContentHandler contentHandler = StaxUtils.createContentHandler(streamWriter);
marshalSaxHandlers(graph, contentHandler, null);
}
@Override
@Override
protected final Object unmarshalDomNode(Node node) throws XmlMappingException {
try {
XmlObject object = XmlObject.Factory.parse(node, getXmlOptions());
validate(object);
return object;
}
catch (XmlException ex) {
throw convertXmlBeansException(ex, false);
}
}
try {
XmlObject object = XmlObject.Factory.parse(node, getXmlOptions());
validate(object);
return object;
}
catch (XmlException ex) {
throw convertXmlBeansException(ex, false);
}
}
@Override
@Override
protected final Object unmarshalInputStream(InputStream inputStream) throws XmlMappingException, IOException {
try {
XmlObject object = XmlObject.Factory.parse(inputStream, getXmlOptions());
validate(object);
return object;
}
catch (XmlException ex) {
throw convertXmlBeansException(ex, false);
}
}
try {
XmlObject object = XmlObject.Factory.parse(inputStream, getXmlOptions());
validate(object);
return object;
}
catch (XmlException ex) {
throw convertXmlBeansException(ex, false);
}
}
@Override
@Override
protected final Object unmarshalReader(Reader reader) throws XmlMappingException, IOException {
try {
XmlObject object = XmlObject.Factory.parse(reader, getXmlOptions());
validate(object);
return object;
}
catch (XmlException ex) {
throw convertXmlBeansException(ex, false);
}
}
try {
XmlObject object = XmlObject.Factory.parse(reader, getXmlOptions());
validate(object);
return object;
}
catch (XmlException ex) {
throw convertXmlBeansException(ex, false);
}
}
@Override
@Override
protected final Object unmarshalSaxReader(XMLReader xmlReader, InputSource inputSource)
throws XmlMappingException, IOException {
XmlSaxHandler saxHandler = XmlObject.Factory.newXmlSaxHandler(getXmlOptions());
xmlReader.setContentHandler(saxHandler.getContentHandler());
try {
xmlReader.setProperty("http://xml.org/sax/properties/lexical-handler", saxHandler.getLexicalHandler());
}
catch (SAXNotRecognizedException e) {
// ignore
}
catch (SAXNotSupportedException e) {
// ignore
}
try {
xmlReader.parse(inputSource);
XmlObject object = saxHandler.getObject();
validate(object);
return object;
}
catch (SAXException ex) {
throw convertXmlBeansException(ex, false);
}
catch (XmlException ex) {
throw convertXmlBeansException(ex, false);
}
}
throws XmlMappingException, IOException {
XmlSaxHandler saxHandler = XmlObject.Factory.newXmlSaxHandler(getXmlOptions());
xmlReader.setContentHandler(saxHandler.getContentHandler());
try {
xmlReader.setProperty("http://xml.org/sax/properties/lexical-handler", saxHandler.getLexicalHandler());
}
catch (SAXNotRecognizedException e) {
// ignore
}
catch (SAXNotSupportedException e) {
// ignore
}
try {
xmlReader.parse(inputSource);
XmlObject object = saxHandler.getObject();
validate(object);
return object;
}
catch (SAXException ex) {
throw convertXmlBeansException(ex, false);
}
catch (XmlException ex) {
throw convertXmlBeansException(ex, false);
}
}
@Override
@Override
protected final Object unmarshalXmlEventReader(XMLEventReader eventReader) throws XmlMappingException {
XMLReader reader = new StaxEventXmlReader(eventReader);
try {
return unmarshalSaxReader(reader, new InputSource());
}
catch (IOException ex) {
throw convertXmlBeansException(ex, false);
}
}
XMLReader reader = StaxUtils.createXMLReader(eventReader);
try {
return unmarshalSaxReader(reader, new InputSource());
}
catch (IOException ex) {
throw convertXmlBeansException(ex, false);
}
}
@Override
@Override
protected final Object unmarshalXmlStreamReader(XMLStreamReader streamReader) throws XmlMappingException {
try {
XmlObject object = XmlObject.Factory.parse(streamReader, getXmlOptions());
validate(object);
return object;
}
catch (XmlException ex) {
throw convertXmlBeansException(ex, false);
}
}
try {
XmlObject object = XmlObject.Factory.parse(streamReader, getXmlOptions());
validate(object);
return object;
}
catch (XmlException ex) {
throw convertXmlBeansException(ex, false);
}
}
/**
* Converts the given XMLBeans exception to an appropriate exception from the <code>org.springframework.oxm</code>
* hierarchy.
* <p/>
* The default implementation delegates to <code>XmlBeansUtils</code>. Can be overridden in subclasses.
* <p/>
* A boolean flag is used to indicate whether this exception occurs during marshalling or unmarshalling, since
* XMLBeans itself does not make this distinction in its exception hierarchy.
*
* @param ex XMLBeans Exception that occured
* @param marshalling indicates whether the exception occurs during marshalling (<code>true</code>), or
* unmarshalling (<code>false</code>)
* @return the corresponding <code>XmlMappingException</code>
* @see XmlBeansUtils#convertXmlBeansException(Exception,boolean)
*/
public XmlMappingException convertXmlBeansException(Exception ex, boolean marshalling) {
return XmlBeansUtils.convertXmlBeansException(ex, marshalling);
}
/**
* Converts the given XMLBeans exception to an appropriate exception from the <code>org.springframework.oxm</code>
* hierarchy. <p/> The default implementation delegates to <code>XmlBeansUtils</code>. Can be overridden in subclasses.
* <p/> A boolean flag is used to indicate whether this exception occurs during marshalling or unmarshalling, since
* XMLBeans itself does not make this distinction in its exception hierarchy.
*
* @param ex XMLBeans Exception that occured
* @param marshalling indicates whether the exception occurs during marshalling (<code>true</code>), or unmarshalling
* (<code>false</code>)
* @return the corresponding <code>XmlMappingException</code>
* @see XmlBeansUtils#convertXmlBeansException(Exception,boolean)
*/
public XmlMappingException convertXmlBeansException(Exception ex, boolean marshalling) {
return XmlBeansUtils.convertXmlBeansException(ex, marshalling);
}
/**
* Validates the given <code>XmlObject</code>.
*
* @param object the xml object to validate
* @throws XmlBeansValidationFailureException
* if the given object is not valid
*/
public void validate(XmlObject object) throws XmlBeansValidationFailureException {
if (isValidating() && object != null) {
// create a temporary xmlOptions just for validation
XmlOptions validateOptions = getXmlOptions() != null ? getXmlOptions() : new XmlOptions();
List errorsList = new ArrayList();
validateOptions.setErrorListener(errorsList);
if (!object.validate(validateOptions)) {
StringBuffer buffer = new StringBuffer("Could not validate XmlObject :");
for (Iterator iterator = errorsList.iterator(); iterator.hasNext();) {
XmlError xmlError = (XmlError) iterator.next();
if (xmlError instanceof XmlValidationError) {
buffer.append(xmlError.toString());
}
}
XmlException ex = new XmlException(buffer.toString(), null, errorsList);
throw new XmlBeansValidationFailureException(ex);
}
}
}
/**
* Validates the given <code>XmlObject</code>.
*
* @param object the xml object to validate
* @throws XmlBeansValidationFailureException
* if the given object is not valid
*/
public void validate(XmlObject object) throws XmlBeansValidationFailureException {
if (isValidating() && object != null) {
// create a temporary xmlOptions just for validation
XmlOptions validateOptions = getXmlOptions() != null ? getXmlOptions() : new XmlOptions();
List errorsList = new ArrayList();
validateOptions.setErrorListener(errorsList);
if (!object.validate(validateOptions)) {
StringBuilder builder = new StringBuilder("Could not validate XmlObject :");
for (Iterator iterator = errorsList.iterator(); iterator.hasNext();) {
XmlError xmlError = (XmlError) iterator.next();
if (xmlError instanceof XmlValidationError) {
builder.append(xmlError.toString());
}
}
XmlException ex = new XmlException(builder.toString(), null, errorsList);
throw new XmlBeansValidationFailureException(ex);
}
}
}
}

View File

@@ -16,24 +16,25 @@
package org.springframework.oxm.xmlbeans;
import org.apache.xmlbeans.XmlException;
import org.springframework.oxm.MarshallingFailureException;
import org.xml.sax.SAXException;
import org.springframework.oxm.MarshallingFailureException;
/**
* XMLBeans-specific subclass of <code>MarshallingFailureException</code>.
*
* @author Arjen Poutsma
* @see XmlBeansUtils#convertXmlBeansException(Exception,boolean)
* @since 1.0.0
* @since 3.0
*/
public class XmlBeansMarshallingFailureException extends MarshallingFailureException {
public XmlBeansMarshallingFailureException(XmlException ex) {
super("XMLBeans marshalling exception: " + ex.getMessage(), ex);
}
public XmlBeansMarshallingFailureException(XmlException ex) {
super("XMLBeans marshalling exception: " + ex.getMessage(), ex);
}
public XmlBeansMarshallingFailureException(SAXException ex) {
super("XMLBeans marshalling exception: " + ex.getMessage(), ex);
}
public XmlBeansMarshallingFailureException(SAXException ex) {
super("XMLBeans marshalling exception: " + ex.getMessage(), ex);
}
}

View File

@@ -22,12 +22,12 @@ import org.springframework.oxm.UncategorizedXmlMappingException;
* distinguished further.
*
* @author Arjen Poutsma
* @since 1.0.0
* @since 3.0
*/
public class XmlBeansSystemException extends UncategorizedXmlMappingException {
public XmlBeansSystemException(Exception e) {
super(e.getMessage(), e);
}
public XmlBeansSystemException(Exception e) {
super(e.getMessage(), e);
}
}

View File

@@ -16,24 +16,25 @@
package org.springframework.oxm.xmlbeans;
import org.apache.xmlbeans.XmlException;
import org.springframework.oxm.UnmarshallingFailureException;
import org.xml.sax.SAXException;
import org.springframework.oxm.UnmarshallingFailureException;
/**
* XMLBeans-specific subclass of <code>UnmarshallingFailureException</code>.
*
* @author Arjen Poutsma
* @see XmlBeansUtils#convertXmlBeansException(Exception,boolean)
* @since 1.0.0
* @since 3.0
*/
public class XmlBeansUnmarshallingFailureException extends UnmarshallingFailureException {
public XmlBeansUnmarshallingFailureException(XmlException ex) {
super("XMLBeans unmarshalling exception: " + ex.getMessage(), ex);
}
public XmlBeansUnmarshallingFailureException(XmlException ex) {
super("XMLBeans unmarshalling exception: " + ex.getMessage(), ex);
}
public XmlBeansUnmarshallingFailureException(SAXException ex) {
super("XMLBeans unmarshalling exception: " + ex.getMessage(), ex);
}
public XmlBeansUnmarshallingFailureException(SAXException ex) {
super("XMLBeans unmarshalling exception: " + ex.getMessage(), ex);
}
}

View File

@@ -17,53 +17,52 @@ package org.springframework.oxm.xmlbeans;
import org.apache.xmlbeans.XMLStreamValidationException;
import org.apache.xmlbeans.XmlException;
import org.springframework.oxm.XmlMappingException;
import org.xml.sax.SAXException;
import org.springframework.oxm.XmlMappingException;
/**
* Generic utility methods for working with XMLBeans. Mainly for internal use within the framework.
*
* @author Arjen Poutsma
* @since 1.0.0
* @since 3.0
*/
public class XmlBeansUtils {
/**
* Converts the given XMLBeans exception to an appropriate exception from the <code>org.springframework.oxm</code>
* hierarchy.
* <p/>
* A boolean flag is used to indicate whether this exception occurs during marshalling or unmarshalling, since
* XMLBeans itself does not make this distinction in its exception hierarchy.
*
* @param ex XMLBeans Exception that occured
* @param marshalling indicates whether the exception occurs during marshalling (<code>true</code>), or
* unmarshalling (<code>false</code>)
* @return the corresponding <code>XmlMappingException</code>
*/
public static XmlMappingException convertXmlBeansException(Exception ex, boolean marshalling) {
if (ex instanceof XMLStreamValidationException) {
return new XmlBeansValidationFailureException((XMLStreamValidationException) ex);
}
else if (ex instanceof XmlException) {
XmlException xmlException = (XmlException) ex;
if (marshalling) {
return new XmlBeansMarshallingFailureException(xmlException);
}
else {
return new XmlBeansUnmarshallingFailureException(xmlException);
}
}
else if (ex instanceof SAXException) {
SAXException saxException = (SAXException) ex;
if (marshalling) {
return new XmlBeansMarshallingFailureException(saxException);
}
else {
return new XmlBeansUnmarshallingFailureException(saxException);
}
}
// fallback
return new XmlBeansSystemException(ex);
}
/**
* Converts the given XMLBeans exception to an appropriate exception from the <code>org.springframework.oxm</code>
* hierarchy. <p/> A boolean flag is used to indicate whether this exception occurs during marshalling or
* unmarshalling, since XMLBeans itself does not make this distinction in its exception hierarchy.
*
* @param ex XMLBeans Exception that occured
* @param marshalling indicates whether the exception occurs during marshalling (<code>true</code>), or unmarshalling
* (<code>false</code>)
* @return the corresponding <code>XmlMappingException</code>
*/
public static XmlMappingException convertXmlBeansException(Exception ex, boolean marshalling) {
if (ex instanceof XMLStreamValidationException) {
return new XmlBeansValidationFailureException((XMLStreamValidationException) ex);
}
else if (ex instanceof XmlException) {
XmlException xmlException = (XmlException) ex;
if (marshalling) {
return new XmlBeansMarshallingFailureException(xmlException);
}
else {
return new XmlBeansUnmarshallingFailureException(xmlException);
}
}
else if (ex instanceof SAXException) {
SAXException saxException = (SAXException) ex;
if (marshalling) {
return new XmlBeansMarshallingFailureException(saxException);
}
else {
return new XmlBeansUnmarshallingFailureException(saxException);
}
}
// fallback
return new XmlBeansSystemException(ex);
}
}

View File

@@ -17,6 +17,7 @@ package org.springframework.oxm.xmlbeans;
import org.apache.xmlbeans.XMLStreamValidationException;
import org.apache.xmlbeans.XmlException;
import org.springframework.oxm.ValidationFailureException;
/**
@@ -24,15 +25,15 @@ import org.springframework.oxm.ValidationFailureException;
*
* @author Arjen Poutsma
* @see org.springframework.oxm.xmlbeans.XmlBeansUtils#convertXmlBeansException
* @since 1.0.0
* @since 3.0
*/
public class XmlBeansValidationFailureException extends ValidationFailureException {
public XmlBeansValidationFailureException(XMLStreamValidationException ex) {
super("XmlBeans validation exception: " + ex.getMessage(), ex);
}
public XmlBeansValidationFailureException(XMLStreamValidationException ex) {
super("XmlBeans validation exception: " + ex.getMessage(), ex);
}
public XmlBeansValidationFailureException(XmlException ex) {
super("XmlBeans validation exception: " + ex.getMessage(), ex);
}
public XmlBeansValidationFailureException(XmlException ex) {
super("XmlBeans validation exception: " + ex.getMessage(), ex);
}
}

View File

@@ -20,60 +20,60 @@ import java.util.Iterator;
import java.util.Map;
import org.apache.xmlbeans.XmlOptions;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
/**
* Factory bean that configures an XMLBeans <code>XmlOptions</code> object and provides it as a bean reference.
* <p/>
* Factory bean that configures an XMLBeans <code>XmlOptions</code> object and provides it as a bean reference. <p/>
* Typical usage will be to set XMLBeans options on this bean, and refer to it in the <code>XmlBeansMarshaller</code>.
*
* @author Arjen Poutsma
* @see XmlOptions
* @see #setOptions(java.util.Map)
* @see XmlBeansMarshaller#setXmlOptions(org.apache.xmlbeans.XmlOptions)
* @since 1.0.0
* @since 3.0
*/
public class XmlOptionsFactoryBean implements FactoryBean, InitializingBean {
private XmlOptions xmlOptions;
private XmlOptions xmlOptions;
private Map options;
private Map options;
/** Returns the singleton <code>XmlOptions</code>. */
public Object getObject() throws Exception {
return xmlOptions;
}
/** Returns the singleton <code>XmlOptions</code>. */
public Object getObject() throws Exception {
return xmlOptions;
}
/** Returns the class of <code>XmlOptions</code>. */
public Class getObjectType() {
return XmlOptions.class;
}
/** Returns the class of <code>XmlOptions</code>. */
public Class getObjectType() {
return XmlOptions.class;
}
/** Returns <code>true</code>. */
public boolean isSingleton() {
return true;
}
/** Returns <code>true</code>. */
public boolean isSingleton() {
return true;
}
/**
* Sets options on the underlying <code>XmlOptions</code> object. The keys of the supplied map should be one of the
* string constants defined in <code>XmlOptions</code>, the values vary per option.
*
* @see XmlOptions#put(Object,Object)
* @see XmlOptions#SAVE_PRETTY_PRINT
* @see XmlOptions#LOAD_STRIP_COMMENTS
*/
public void setOptions(Map options) {
this.options = options;
}
/**
* Sets options on the underlying <code>XmlOptions</code> object. The keys of the supplied map should be one of the
* string constants defined in <code>XmlOptions</code>, the values vary per option.
*
* @see XmlOptions#put(Object,Object)
* @see XmlOptions#SAVE_PRETTY_PRINT
* @see XmlOptions#LOAD_STRIP_COMMENTS
*/
public void setOptions(Map options) {
this.options = options;
}
public void afterPropertiesSet() throws Exception {
xmlOptions = new XmlOptions();
if (options != null) {
for (Iterator iterator = options.keySet().iterator(); iterator.hasNext();) {
Object option = iterator.next();
xmlOptions.put(option, options.get(option));
}
}
}
public void afterPropertiesSet() throws Exception {
xmlOptions = new XmlOptions();
if (options != null) {
for (Iterator iterator = options.keySet().iterator(); iterator.hasNext();) {
Object option = iterator.next();
xmlOptions.put(option, options.get(option));
}
}
}
}

View File

@@ -1,53 +0,0 @@
/*
* Copyright 2007 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.xstream;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.Annotations;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import org.springframework.util.Assert;
/**
* Subclass of the {@link XStreamMarshaller} that supports JDK 1.5+ annotation metadata for aliases.
*
* @author Arjen Poutsma
* @see XStreamAlias
* @since 1.0.2
*/
public class AnnotationXStreamMarshaller extends XStreamMarshaller {
/**
* Sets the classes, for which mappings will be read from class-level JDK 1.5+ annotation metadata.
*
* @see Annotations#configureAliases(XStream, Class[])
*/
public void setAnnotatedClass(Class<?> annotatedClass) {
Assert.notNull(annotatedClass, "'annotatedClass' must not be null");
Annotations.configureAliases(getXStream(), annotatedClass);
}
/**
* Sets annotated classes, for which aliases will be read from class-level JDK 1.5+ annotation metadata.
*
* @see Annotations#configureAliases(XStream, Class[])
*/
public void setAnnotatedClasses(Class<?>[] annotatedClasses) {
Assert.notEmpty(annotatedClasses, "'annotatedClasses' must not be empty");
Annotations.configureAliases(getXStream(), annotatedClasses);
}
}

View File

@@ -58,20 +58,17 @@ import org.xml.sax.ext.LexicalHandler;
import org.springframework.beans.propertyeditors.ClassEditor;
import org.springframework.oxm.AbstractMarshaller;
import org.springframework.oxm.XmlMappingException;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.xml.stream.StaxEventContentHandler;
import org.springframework.xml.stream.XmlEventStreamReader;
import org.springframework.util.xml.StaxUtils;
/**
* Implementation of the <code>Marshaller</code> interface for XStream. By default, XStream does not require any further
* configuration, though class aliases can be used to have more control over the behavior of XStream.
* <p/>
* Due to XStream's API, it is required to set the encoding used for writing to outputstreams. It defaults to
* <code>UTF-8</code>.
* <p/>
* <b>Note</b> that XStream is an XML serialization library, not a data binding library. Therefore, it has limited
* namespace support. As such, it is rather unsuitable for usage within Web services.
* configuration, though class aliases can be used to have more control over the behavior of XStream. <p/> Due to
* XStream's API, it is required to set the encoding used for writing to outputstreams. It defaults to
* <code>UTF-8</code>. <p/> <b>Note</b> that XStream is an XML serialization library, not a data binding library.
* Therefore, it has limited namespace support. As such, it is rather unsuitable for usage within Web services.
*
* @author Peter Meijer
* @author Arjen Poutsma
@@ -79,395 +76,411 @@ import org.springframework.xml.stream.XmlEventStreamReader;
* @see #DEFAULT_ENCODING
* @see #setAliases(Map)
* @see #setConverters(ConverterMatcher[])
* @since 1.0.0
* @since 3.0
*/
public class XStreamMarshaller extends AbstractMarshaller {
/** The default encoding used for stream access. */
public static final String DEFAULT_ENCODING = "UTF-8";
/** The default encoding used for stream access. */
public static final String DEFAULT_ENCODING = "UTF-8";
private XStream xstream = new XStream();
private XStream xstream = new XStream();
private String encoding;
private String encoding;
private Class[] supportedClasses;
private Class[] supportedClasses;
/** Specialized driver to be used with stream readers and writers */
private HierarchicalStreamDriver streamDriver;
/** Specialized driver to be used with stream readers and writers */
private HierarchicalStreamDriver streamDriver;
/**
* Returns the encoding to be used for stream access. If this property is not set, the default encoding is used.
*
* @see #DEFAULT_ENCODING
*/
public String getEncoding() {
return encoding != null ? encoding : DEFAULT_ENCODING;
}
/**
* Returns the encoding to be used for stream access. If this property is not set, the default encoding is used.
*
* @see #DEFAULT_ENCODING
*/
public String getEncoding() {
return encoding != null ? encoding : DEFAULT_ENCODING;
}
/**
* Sets the encoding to be used for stream access. If this property is not set, the default encoding is used.
*
* @see #DEFAULT_ENCODING
*/
public void setEncoding(String encoding) {
this.encoding = encoding;
}
/**
* Sets the encoding to be used for stream access. If this property is not set, the default encoding is used.
*
* @see #DEFAULT_ENCODING
*/
public void setEncoding(String encoding) {
this.encoding = encoding;
}
/** Returns the XStream instance used by this marshaller. */
public XStream getXStream() {
return xstream;
}
/** Returns the XStream instance used by this marshaller. */
public XStream getXStream() {
return xstream;
}
/**
* Sets the XStream mode.
*
* @see XStream#XPATH_REFERENCES
* @see XStream#ID_REFERENCES
* @see XStream#NO_REFERENCES
*/
public void setMode(int mode) {
getXStream().setMode(mode);
}
/**
* Sets the XStream mode.
*
* @see XStream#XPATH_REFERENCES
* @see XStream#ID_REFERENCES
* @see XStream#NO_REFERENCES
*/
public void setMode(int mode) {
getXStream().setMode(mode);
}
/**
* Sets the classes supported by this marshaller. If this property is empty (the default), all classes are
* supported.
*
* @see #supports(Class)
*/
public void setSupportedClasses(Class[] supportedClasses) {
this.supportedClasses = supportedClasses;
}
/**
* Sets the classes supported by this marshaller. If this property is empty (the default), all classes are supported.
*
* @see #supports(Class)
*/
public void setSupportedClasses(Class[] supportedClasses) {
this.supportedClasses = supportedClasses;
}
/**
* Sets the <code>Converters</code> or <code>SingleValueConverters</code> to be registered with the
* <code>XStream</code> instance.
*
* @see Converter
* @see SingleValueConverter
*/
public void setConverters(ConverterMatcher[] converters) {
for (int i = 0; i < converters.length; i++) {
if (converters[i] instanceof Converter) {
getXStream().registerConverter((Converter) converters[i], i);
}
else if (converters[i] instanceof SingleValueConverter) {
getXStream().registerConverter((SingleValueConverter) converters[i], i);
}
else {
throw new IllegalArgumentException("Invalid ConverterMatcher [" + converters[i] + "]");
}
}
}
/**
* Sets the <code>Converters</code> or <code>SingleValueConverters</code> to be registered with the
* <code>XStream</code> instance.
*
* @see Converter
* @see SingleValueConverter
*/
public void setConverters(ConverterMatcher[] converters) {
for (int i = 0; i < converters.length; i++) {
if (converters[i] instanceof Converter) {
getXStream().registerConverter((Converter) converters[i], i);
}
else if (converters[i] instanceof SingleValueConverter) {
getXStream().registerConverter((SingleValueConverter) converters[i], i);
}
else {
throw new IllegalArgumentException("Invalid ConverterMatcher [" + converters[i] + "]");
}
}
}
/** Sets the XStream hierarchical stream driver to be used with stream readers and writers */
public void setStreamDriver(HierarchicalStreamDriver streamDriver) {
this.streamDriver = streamDriver;
}
/** Sets the XStream hierarchical stream driver to be used with stream readers and writers */
public void setStreamDriver(HierarchicalStreamDriver streamDriver) {
this.streamDriver = streamDriver;
}
/**
* Set a alias/type map, consisting of string aliases mapped to <code>Class</code> instances (or Strings to be
* converted to <code>Class</code> instances).
*
* @see org.springframework.beans.propertyeditors.ClassEditor
*/
public void setAliases(Map aliases) {
for (Iterator iterator = aliases.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
// Check whether we need to convert from String to Class.
Class type;
if (entry.getValue() instanceof Class) {
type = (Class) entry.getValue();
}
else {
ClassEditor editor = new ClassEditor();
editor.setAsText(String.valueOf(entry.getValue()));
type = (Class) editor.getValue();
}
addAlias((String) entry.getKey(), type);
}
}
/**
* Set a alias/type map, consisting of string aliases mapped to <code>Class</code> instances (or Strings to be
* converted to <code>Class</code> instances).
*
* @see org.springframework.beans.propertyeditors.ClassEditor
*/
public void setAliases(Map aliases) {
for (Iterator iterator = aliases.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
// Check whether we need to convert from String to Class.
Class type;
if (entry.getValue() instanceof Class) {
type = (Class) entry.getValue();
}
else {
ClassEditor editor = new ClassEditor();
editor.setAsText(String.valueOf(entry.getValue()));
type = (Class) editor.getValue();
}
addAlias((String) entry.getKey(), type);
}
}
/**
* Adds an alias for the given type.
*
* @param name alias to be used for the type
* @param type the type to be aliased
*/
public void addAlias(String name, Class type) {
getXStream().alias(name, type);
}
/**
* Adds an alias for the given type.
*
* @param name alias to be used for the type
* @param type the type to be aliased
*/
public void addAlias(String name, Class type) {
getXStream().alias(name, type);
}
/**
* Sets types to use XML attributes for.
*
* @see XStream#useAttributeFor(Class)
*/
public void setUseAttributeForTypes(Class[] types) {
for (int i = 0; i < types.length; i++) {
getXStream().useAttributeFor(types[i]);
}
}
/**
* Sets types to use XML attributes for.
*
* @see XStream#useAttributeFor(Class)
*/
public void setUseAttributeForTypes(Class[] types) {
for (Class type : types) {
getXStream().useAttributeFor(type);
}
}
/**
* Sets the types to use XML attributes for. The given map can contain either <code>&lt;String, Class&gt;</code>
* pairs, in which case {@link XStream#useAttributeFor(String,Class)} is called, or <code>&lt;Class,
* String&gt;</code> pairs, which results in {@link XStream#useAttributeFor(Class,String)}.
*/
public void setUseAttributeFor(Map attributes) {
for (Iterator iterator = attributes.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
if (entry.getKey() instanceof String && entry.getValue() instanceof Class) {
getXStream().useAttributeFor((String) entry.getKey(), (Class) entry.getValue());
}
else if (entry.getKey() instanceof Class && entry.getValue() instanceof String) {
getXStream().useAttributeFor((Class) entry.getKey(), (String) entry.getValue());
}
else {
throw new IllegalArgumentException("Invalid attribute key and value pair. " +
"'useAttributesFor' property takes either a <String, Class> map or a <Class, String> map");
}
}
}
/**
* Sets the types to use XML attributes for. The given map can contain either <code>&lt;String, Class&gt;</code> pairs,
* in which case {@link XStream#useAttributeFor(String,Class)} is called, or <code>&lt;Class, String&gt;</code> pairs,
* which results in {@link XStream#useAttributeFor(Class,String)}.
*/
public void setUseAttributeFor(Map attributes) {
for (Iterator iterator = attributes.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
if (entry.getKey() instanceof String && entry.getValue() instanceof Class) {
getXStream().useAttributeFor((String) entry.getKey(), (Class) entry.getValue());
}
else if (entry.getKey() instanceof Class && entry.getValue() instanceof String) {
getXStream().useAttributeFor((Class) entry.getKey(), (String) entry.getValue());
}
else {
throw new IllegalArgumentException("Invalid attribute key and value pair. " +
"'useAttributesFor' property takes either a <String, Class> map or a <Class, String> map");
}
}
}
/**
* Adds an implicit Collection for the given type.
*
* @see XStream#addImplicitCollection(Class, String)
*/
public void addImplicitCollection(String name, Class type) {
getXStream().addImplicitCollection(type, name);
}
/**
* Adds an implicit Collection for the given type.
*
* @see XStream#addImplicitCollection(Class, String)
*/
public void addImplicitCollection(String name, Class type) {
getXStream().addImplicitCollection(type, name);
}
/**
* Set a implicit colletion/type map, consisting of string implicit collection mapped to <code>Class</code>
* instances (or Strings to be converted to <code>Class</code> instances).
*
* @see XStream#addImplicitCollection(Class, String)
*/
public void setImplicitCollection(Map implicitCollection) {
for (Iterator iterator = implicitCollection.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
// Check whether we need to convert from String to Class.
Class type;
if (entry.getValue() instanceof Class) {
type = (Class) entry.getValue();
}
else {
ClassEditor editor = new ClassEditor();
editor.setAsText(String.valueOf(entry.getValue()));
type = (Class) editor.getValue();
}
addImplicitCollection((String) entry.getKey(), type);
}
}
/**
* Set a implicit colletion/type map, consisting of string implicit collection mapped to <code>Class</code> instances
* (or Strings to be converted to <code>Class</code> instances).
*
* @see XStream#addImplicitCollection(Class, String)
*/
public void setImplicitCollection(Map implicitCollection) {
for (Iterator iterator = implicitCollection.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
// Check whether we need to convert from String to Class.
Class type;
if (entry.getValue() instanceof Class) {
type = (Class) entry.getValue();
}
else {
ClassEditor editor = new ClassEditor();
editor.setAsText(String.valueOf(entry.getValue()));
type = (Class) editor.getValue();
}
addImplicitCollection((String) entry.getKey(), type);
}
}
/**
* Adds an omitted field for the given type.
*
* @param type the type to be containing the field
* @param fieldName field to omitt
* @see XStream#omitField(Class, String)
*/
public void addOmittedField(Class type, String fieldName) {
getXStream().omitField(type, fieldName);
}
/**
* Adds an omitted field for the given type.
*
* @param type the type to be containing the field
* @param fieldName field to omitt
* @see XStream#omitField(Class, String)
*/
public void addOmittedField(Class type, String fieldName) {
getXStream().omitField(type, fieldName);
}
/**
* Sets a ommited field map, consisting of <code>Class</code> instances (or Strings to be converted to
* <code>Class</code> instances) mapped to comma separated field names.
*
* @see XStream#omitField(Class, String)
*/
public void setOmittedFields(Map omittedFields) {
for (Iterator iterator = omittedFields.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
// Check whether we need to convert from String to Class.
Class type;
if (entry.getKey() instanceof Class) {
type = (Class) entry.getKey();
}
else {
ClassEditor editor = new ClassEditor();
editor.setAsText(String.valueOf(entry.getKey()));
type = (Class) editor.getValue();
}
// add each omitted field for the current type
String fieldsString = (String) entry.getValue();
String[] fields = StringUtils.commaDelimitedListToStringArray(fieldsString);
for (int i = 0; i < fields.length; i++) {
addOmittedField(type, fields[i]);
}
}
}
/**
* Sets a ommited field map, consisting of <code>Class</code> instances (or Strings to be converted to
* <code>Class</code> instances) mapped to comma separated field names.
*
* @see XStream#omitField(Class, String)
*/
public void setOmittedFields(Map omittedFields) {
for (Iterator iterator = omittedFields.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
// Check whether we need to convert from String to Class.
Class type;
if (entry.getKey() instanceof Class) {
type = (Class) entry.getKey();
}
else {
ClassEditor editor = new ClassEditor();
editor.setAsText(String.valueOf(entry.getKey()));
type = (Class) editor.getValue();
}
// add each omitted field for the current type
String fieldsString = (String) entry.getValue();
String[] fields = StringUtils.commaDelimitedListToStringArray(fieldsString);
for (String field : fields) {
addOmittedField(type, field);
}
}
}
public boolean supports(Class clazz) {
if (ObjectUtils.isEmpty(supportedClasses)) {
return true;
}
else {
for (int i = 0; i < supportedClasses.length; i++) {
if (supportedClasses[i].isAssignableFrom(clazz)) {
return true;
}
}
return false;
}
}
/**
* Sets the classes, for which mappings will be read from class-level JDK 1.5+ annotation metadata.
*
* @see com.thoughtworks.xstream.annotations.Annotations#configureAliases(com.thoughtworks.xstream.XStream, Class[])
*/
public void setAnnotatedClass(Class<?> annotatedClass) {
Assert.notNull(annotatedClass, "'annotatedClass' must not be null");
getXStream().processAnnotations(annotatedClass);
}
/**
* Convert the given XStream exception to an appropriate exception from the <code>org.springframework.oxm</code>
* hierarchy.
* <p/>
* The default implementation delegates to <code>XStreamUtils</code>. Can be overridden in subclasses.
*
* @param ex exception that occured
* @param marshalling indicates whether the exception occurs during marshalling (<code>true</code>), or
* unmarshalling (<code>false</code>)
* @return the corresponding <code>XmlMappingException</code> instance
* @see XStreamUtils#convertXStreamException(Exception,boolean)
*/
public XmlMappingException convertXStreamException(Exception ex, boolean marshalling) {
return XStreamUtils.convertXStreamException(ex, marshalling);
}
/**
* Sets annotated classes, for which aliases will be read from class-level JDK 1.5+ annotation metadata.
*
* @see com.thoughtworks.xstream.annotations.Annotations#configureAliases(com.thoughtworks.xstream.XStream, Class[])
*/
public void setAnnotatedClasses(Class<?>[] annotatedClasses) {
Assert.notEmpty(annotatedClasses, "'annotatedClasses' must not be empty");
getXStream().processAnnotations(annotatedClasses);
}
//
// Marshalling
//
public boolean supports(Class clazz) {
if (ObjectUtils.isEmpty(supportedClasses)) {
return true;
}
else {
for (Class supportedClass : supportedClasses) {
if (supportedClass.isAssignableFrom(clazz)) {
return true;
}
}
return false;
}
}
/**
* Marshals the given graph to the given XStream HierarchicalStreamWriter. Converts exceptions using
* <code>convertXStreamException</code>.
*/
private void marshal(Object graph, HierarchicalStreamWriter streamWriter) {
try {
getXStream().marshal(graph, streamWriter);
}
catch (Exception ex) {
throw convertXStreamException(ex, true);
}
}
/**
* Convert the given XStream exception to an appropriate exception from the <code>org.springframework.oxm</code>
* hierarchy. <p/> The default implementation delegates to <code>XStreamUtils</code>. Can be overridden in subclasses.
*
* @param ex exception that occured
* @param marshalling indicates whether the exception occurs during marshalling (<code>true</code>), or unmarshalling
* (<code>false</code>)
* @return the corresponding <code>XmlMappingException</code> instance
* @see XStreamUtils#convertXStreamException(Exception,boolean)
*/
public XmlMappingException convertXStreamException(Exception ex, boolean marshalling) {
return XStreamUtils.convertXStreamException(ex, marshalling);
}
@Override
//
// Marshalling
//
/**
* Marshals the given graph to the given XStream HierarchicalStreamWriter. Converts exceptions using
* <code>convertXStreamException</code>.
*/
private void marshal(Object graph, HierarchicalStreamWriter streamWriter) {
try {
getXStream().marshal(graph, streamWriter);
}
catch (Exception ex) {
throw convertXStreamException(ex, true);
}
}
@Override
protected void marshalDomNode(Object graph, Node node) throws XmlMappingException {
HierarchicalStreamWriter streamWriter;
if (node instanceof Document) {
streamWriter = new DomWriter((Document) node);
}
else if (node instanceof Element) {
streamWriter = new DomWriter((Element) node, node.getOwnerDocument(), new XmlFriendlyReplacer());
}
else {
throw new IllegalArgumentException("DOMResult contains neither Document nor Element");
}
marshal(graph, streamWriter);
}
HierarchicalStreamWriter streamWriter;
if (node instanceof Document) {
streamWriter = new DomWriter((Document) node);
}
else if (node instanceof Element) {
streamWriter = new DomWriter((Element) node, node.getOwnerDocument(), new XmlFriendlyReplacer());
}
else {
throw new IllegalArgumentException("DOMResult contains neither Document nor Element");
}
marshal(graph, streamWriter);
}
@Override
@Override
protected void marshalXmlEventWriter(Object graph, XMLEventWriter eventWriter) throws XmlMappingException {
ContentHandler contentHandler = new StaxEventContentHandler(eventWriter);
marshalSaxHandlers(graph, contentHandler, null);
}
ContentHandler contentHandler = StaxUtils.createContentHandler(eventWriter);
marshalSaxHandlers(graph, contentHandler, null);
}
@Override
@Override
protected void marshalXmlStreamWriter(Object graph, XMLStreamWriter streamWriter) throws XmlMappingException {
try {
marshal(graph, new StaxWriter(new QNameMap(), streamWriter));
}
catch (XMLStreamException ex) {
throw convertXStreamException(ex, true);
}
}
try {
marshal(graph, new StaxWriter(new QNameMap(), streamWriter));
}
catch (XMLStreamException ex) {
throw convertXStreamException(ex, true);
}
}
@Override
@Override
protected void marshalOutputStream(Object graph, OutputStream outputStream)
throws XmlMappingException, IOException {
marshalWriter(graph, new OutputStreamWriter(outputStream, getEncoding()));
}
throws XmlMappingException, IOException {
marshalWriter(graph, new OutputStreamWriter(outputStream, getEncoding()));
}
@Override
@Override
protected void marshalSaxHandlers(Object graph, ContentHandler contentHandler, LexicalHandler lexicalHandler)
throws XmlMappingException {
SaxWriter saxWriter = new SaxWriter();
saxWriter.setContentHandler(contentHandler);
marshal(graph, saxWriter);
}
throws XmlMappingException {
SaxWriter saxWriter = new SaxWriter();
saxWriter.setContentHandler(contentHandler);
marshal(graph, saxWriter);
}
@Override
@Override
protected void marshalWriter(Object graph, Writer writer) throws XmlMappingException, IOException {
if (streamDriver != null) {
marshal(graph, streamDriver.createWriter(writer));
}
else {
marshal(graph, new CompactWriter(writer));
}
}
if (streamDriver != null) {
marshal(graph, streamDriver.createWriter(writer));
}
else {
marshal(graph, new CompactWriter(writer));
}
}
//
// Unmarshalling
//
//
// Unmarshalling
//
private Object unmarshal(HierarchicalStreamReader streamReader) {
try {
return getXStream().unmarshal(streamReader);
}
catch (Exception ex) {
throw convertXStreamException(ex, false);
}
}
private Object unmarshal(HierarchicalStreamReader streamReader) {
try {
return getXStream().unmarshal(streamReader);
}
catch (Exception ex) {
throw convertXStreamException(ex, false);
}
}
@Override
@Override
protected Object unmarshalDomNode(Node node) throws XmlMappingException {
HierarchicalStreamReader streamReader;
if (node instanceof Document) {
streamReader = new DomReader((Document) node);
}
else if (node instanceof Element) {
streamReader = new DomReader((Element) node);
}
else {
throw new IllegalArgumentException("DOMSource contains neither Document nor Element");
}
return unmarshal(streamReader);
}
HierarchicalStreamReader streamReader;
if (node instanceof Document) {
streamReader = new DomReader((Document) node);
}
else if (node instanceof Element) {
streamReader = new DomReader((Element) node);
}
else {
throw new IllegalArgumentException("DOMSource contains neither Document nor Element");
}
return unmarshal(streamReader);
}
@Override
@Override
protected Object unmarshalXmlEventReader(XMLEventReader eventReader) throws XmlMappingException {
try {
XMLStreamReader streamReader = new XmlEventStreamReader(eventReader);
return unmarshalXmlStreamReader(streamReader);
}
catch (XMLStreamException ex) {
throw convertXStreamException(ex, false);
}
}
try {
XMLStreamReader streamReader = StaxUtils.createEventStreamReader(eventReader);
return unmarshalXmlStreamReader(streamReader);
}
catch (XMLStreamException ex) {
throw convertXStreamException(ex, false);
}
}
@Override
@Override
protected Object unmarshalXmlStreamReader(XMLStreamReader streamReader) throws XmlMappingException {
return unmarshal(new StaxReader(new QNameMap(), streamReader));
}
return unmarshal(new StaxReader(new QNameMap(), streamReader));
}
@Override
@Override
protected Object unmarshalInputStream(InputStream inputStream) throws XmlMappingException, IOException {
return unmarshalReader(new InputStreamReader(inputStream, getEncoding()));
}
return unmarshalReader(new InputStreamReader(inputStream, getEncoding()));
}
@Override
@Override
protected Object unmarshalReader(Reader reader) throws XmlMappingException, IOException {
if (streamDriver != null) {
return unmarshal(streamDriver.createReader(reader));
}
else {
return unmarshal(new XppReader(reader));
}
}
if (streamDriver != null) {
return unmarshal(streamDriver.createReader(reader));
}
else {
return unmarshal(new XppReader(reader));
}
}
@Override
@Override
protected Object unmarshalSaxReader(XMLReader xmlReader, InputSource inputSource)
throws XmlMappingException, IOException {
throw new UnsupportedOperationException(
"XStreamMarshaller does not support unmarshalling using SAX XMLReaders");
}
throws XmlMappingException, IOException {
throw new UnsupportedOperationException(
"XStreamMarshaller does not support unmarshalling using SAX XMLReaders");
}
}

View File

@@ -19,31 +19,32 @@ package org.springframework.oxm.xstream;
import com.thoughtworks.xstream.alias.CannotResolveClassException;
import com.thoughtworks.xstream.converters.ConversionException;
import com.thoughtworks.xstream.io.StreamException;
import org.springframework.oxm.MarshallingFailureException;
/**
* XStream-specific subclass of <code>MarshallingFailureException</code>.
*
* @author Arjen Poutsma
* @since 1.0.0
* @since 3.0
*/
public class XStreamMarshallingFailureException extends MarshallingFailureException {
public XStreamMarshallingFailureException(String msg) {
super(msg);
}
public XStreamMarshallingFailureException(String msg) {
super(msg);
}
public XStreamMarshallingFailureException(StreamException ex) {
super("XStream marshalling exception: " + ex.getMessage(), ex);
public XStreamMarshallingFailureException(StreamException ex) {
super("XStream marshalling exception: " + ex.getMessage(), ex);
}
}
public XStreamMarshallingFailureException(CannotResolveClassException ex) {
super("XStream resolving exception: " + ex.getMessage(), ex);
}
public XStreamMarshallingFailureException(CannotResolveClassException ex) {
super("XStream resolving exception: " + ex.getMessage(), ex);
}
public XStreamMarshallingFailureException(ConversionException ex) {
super("XStream conversion exception: " + ex.getMessage(), ex);
}
public XStreamMarshallingFailureException(ConversionException ex) {
super("XStream conversion exception: " + ex.getMessage(), ex);
}
}

View File

@@ -23,12 +23,12 @@ import org.springframework.oxm.UncategorizedXmlMappingException;
* distinguished further.
*
* @author Arjen Poutsma
* @since 1.0.0
* @since 3.0
*/
public class XStreamSystemException extends UncategorizedXmlMappingException {
public XStreamSystemException(String msg, Throwable ex) {
super(msg, ex);
}
public XStreamSystemException(String msg, Throwable ex) {
super(msg, ex);
}
}

View File

@@ -21,34 +21,35 @@ import javax.xml.stream.XMLStreamException;
import com.thoughtworks.xstream.alias.CannotResolveClassException;
import com.thoughtworks.xstream.converters.ConversionException;
import com.thoughtworks.xstream.io.StreamException;
import org.springframework.oxm.UnmarshallingFailureException;
/**
* XStream-specific subclass of <code>UnmarshallingFailureException</code>.
*
* @author Arjen Poutsma
* @since 1.0.0
* @since 3.0
*/
public class XStreamUnmarshallingFailureException extends UnmarshallingFailureException {
public XStreamUnmarshallingFailureException(StreamException ex) {
super("XStream unmarshalling exception: " + ex.getMessage(), ex);
}
public XStreamUnmarshallingFailureException(StreamException ex) {
super("XStream unmarshalling exception: " + ex.getMessage(), ex);
}
public XStreamUnmarshallingFailureException(CannotResolveClassException ex) {
super("XStream resolving exception: " + ex.getMessage(), ex);
}
public XStreamUnmarshallingFailureException(CannotResolveClassException ex) {
super("XStream resolving exception: " + ex.getMessage(), ex);
}
public XStreamUnmarshallingFailureException(ConversionException ex) {
super("XStream conversion exception: " + ex.getMessage(), ex);
}
public XStreamUnmarshallingFailureException(ConversionException ex) {
super("XStream conversion exception: " + ex.getMessage(), ex);
}
public XStreamUnmarshallingFailureException(String msg) {
super(msg);
}
public XStreamUnmarshallingFailureException(String msg) {
super(msg);
}
public XStreamUnmarshallingFailureException(String msg, XMLStreamException ex) {
super(msg, ex);
}
public XStreamUnmarshallingFailureException(String msg, XMLStreamException ex) {
super(msg, ex);
}
}

View File

@@ -19,55 +19,54 @@ package org.springframework.oxm.xstream;
import com.thoughtworks.xstream.alias.CannotResolveClassException;
import com.thoughtworks.xstream.converters.ConversionException;
import com.thoughtworks.xstream.io.StreamException;
import org.springframework.oxm.XmlMappingException;
/**
* Generic utility methods for working with XStream. Mainly for internal use within the framework.
*
* @author Arjen Poutsma
* @since 1.0.0
* @since 3.0
*/
public abstract class XStreamUtils {
/**
* Converts the given XStream exception to an appropriate exception from the <code>org.springframework.oxm</code>
* hierarchy.
* <p/>
* A boolean flag is used to indicate whether this exception occurs during marshalling or unmarshalling, since
* XStream itself does not make this distinction in its exception hierarchy.
*
* @param ex XStream exception that occured
* @param marshalling indicates whether the exception occurs during marshalling (<code>true</code>), or
* unmarshalling (<code>false</code>)
* @return the corresponding <code>XmlMappingException</code>
*/
public static XmlMappingException convertXStreamException(Exception ex, boolean marshalling) {
if (ex instanceof StreamException) {
if (marshalling) {
return new XStreamMarshallingFailureException((StreamException) ex);
}
else {
return new XStreamUnmarshallingFailureException((StreamException) ex);
}
}
else if (ex instanceof CannotResolveClassException) {
if (marshalling) {
return new XStreamMarshallingFailureException((CannotResolveClassException) ex);
}
else {
return new XStreamUnmarshallingFailureException((CannotResolveClassException) ex);
}
}
else if (ex instanceof ConversionException) {
if (marshalling) {
return new XStreamMarshallingFailureException((ConversionException) ex);
}
else {
return new XStreamUnmarshallingFailureException((ConversionException) ex);
}
}
// fallback
return new XStreamSystemException("Unknown XStream exception: " + ex.getMessage(), ex);
}
/**
* Converts the given XStream exception to an appropriate exception from the <code>org.springframework.oxm</code>
* hierarchy. <p/> A boolean flag is used to indicate whether this exception occurs during marshalling or
* unmarshalling, since XStream itself does not make this distinction in its exception hierarchy.
*
* @param ex XStream exception that occured
* @param marshalling indicates whether the exception occurs during marshalling (<code>true</code>), or unmarshalling
* (<code>false</code>)
* @return the corresponding <code>XmlMappingException</code>
*/
public static XmlMappingException convertXStreamException(Exception ex, boolean marshalling) {
if (ex instanceof StreamException) {
if (marshalling) {
return new XStreamMarshallingFailureException((StreamException) ex);
}
else {
return new XStreamUnmarshallingFailureException((StreamException) ex);
}
}
else if (ex instanceof CannotResolveClassException) {
if (marshalling) {
return new XStreamMarshallingFailureException((CannotResolveClassException) ex);
}
else {
return new XStreamUnmarshallingFailureException((CannotResolveClassException) ex);
}
}
else if (ex instanceof ConversionException) {
if (marshalling) {
return new XStreamMarshallingFailureException((ConversionException) ex);
}
else {
return new XStreamUnmarshallingFailureException((ConversionException) ex);
}
}
// fallback
return new XStreamSystemException("Unknown XStream exception: " + ex.getMessage(), ex);
}
}

View File

@@ -1 +1 @@
http\://www.springframework.org/schema/oxm/spring-oxm-1.5.xsd=/org/springframework/oxm/config/spring-oxm-1.5.xsd
http\://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd=/org/springframework/oxm/config/spring-oxm-3.0.xsd

View File

@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://www.springframework.org/schema/oxm" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:tool="http://www.springframework.org/schema/tool"
targetNamespace="http://www.springframework.org/schema/oxm" elementFormDefault="qualified"
attributeFormDefault="unqualified">
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:tool="http://www.springframework.org/schema/tool"
targetNamespace="http://www.springframework.org/schema/oxm" elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans"/>
<xsd:import namespace="http://www.springframework.org/schema/tool"/>
@@ -14,35 +14,6 @@
</xsd:documentation>
</xsd:annotation>
<xsd:element name="jaxb1-marshaller">
<xsd:complexType>
<xsd:annotation>
<xsd:documentation source="java:org.springframework.oxm.jaxb.Jaxb1Marshaller">
Defines a JAXB1 Marshaller.
</xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="org.springframework.oxm.jaxb.Jaxb1Marshaller"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexContent>
<xsd:extension base="beans:identifiedType">
<xsd:attribute name="contextPath" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation>The JAXB Context path</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="validating" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation>Whether incoming XML should be validated.</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="jaxb2-marshaller">
<xsd:complexType>
<xsd:annotation>