All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.oxm.xstream.XStreamMarshaller Maven / Gradle / Ivy

There is a newer version: 1.5.10
Show newest version
/*
 * Copyright 2006 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 java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.Iterator;
import java.util.Map;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.ConverterMatcher;
import com.thoughtworks.xstream.converters.SingleValueConverter;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.CompactWriter;
import com.thoughtworks.xstream.io.xml.DomReader;
import com.thoughtworks.xstream.io.xml.DomWriter;
import com.thoughtworks.xstream.io.xml.QNameMap;
import com.thoughtworks.xstream.io.xml.SaxWriter;
import com.thoughtworks.xstream.io.xml.StaxReader;
import com.thoughtworks.xstream.io.xml.StaxWriter;
import com.thoughtworks.xstream.io.xml.XppReader;
import org.springframework.beans.propertyeditors.ClassEditor;
import org.springframework.oxm.AbstractMarshaller;
import org.springframework.oxm.XmlMappingException;
import org.springframework.xml.stream.StaxEventContentHandler;
import org.springframework.xml.stream.XmlEventStreamReader;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.ext.LexicalHandler;

/**
 * Implementation of the Marshaller 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.
 * 

* Due to XStream's API, it is required to set the encoding used for writing to outputstreams. It defaults to * UTF-8. *

* Note 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 * @see #setEncoding(String) * @see #DEFAULT_ENCODING * @see #setAliases(Map) * @see #setConverters(ConverterMatcher[]) * @since 1.0.0 */ public class XStreamMarshaller extends AbstractMarshaller { /** The default encoding used for stream access. */ public static final String DEFAULT_ENCODING = "UTF-8"; private XStream xstream = new XStream(); private String 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 XStream mode. * * @see XStream#XPATH_REFERENCES * @see XStream#ID_REFERENCES * @see XStream#NO_REFERENCES */ public void setMode(int mode) { xstream.setMode(mode); } /** * Sets the Converters or SingleValueConverters to be registered with the * XStream instance. * * @see Converter * @see SingleValueConverter */ public void setConverters(ConverterMatcher[] converters) { for (int i = 0; i < converters.length; i++) { if (converters[i] instanceof Converter) { xstream.registerConverter((Converter) converters[i], i); } else if (converters[i] instanceof SingleValueConverter) { xstream.registerConverter((SingleValueConverter) converters[i], i); } else { throw new IllegalArgumentException("Invalid ConverterMatcher [" + converters[i] + "]"); } } } /** * Set a alias/type map, consisting of string aliases mapped to Class instances (or Strings to be * converted to Class 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 = null; 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) { xstream.alias(name, type); } public boolean supports(Class clazz) { return true; } /** * Convert the given XStream exception to an appropriate exception from the org.springframework.oxm * hierarchy. *

* The default implementation delegates to XStreamUtils. Can be overridden in subclasses. * * @param ex exception that occured * @param marshalling indicates whether the exception occurs during marshalling (true), or * unmarshalling (false) * @return the corresponding XmlMappingException instance * @see XStreamUtils#convertXStreamException(Exception,boolean) */ public XmlMappingException convertXStreamException(Exception ex, boolean marshalling) { return XStreamUtils.convertXStreamException(ex, marshalling); } /** * Marshals the given graph to the given XStream HierarchicalStreamWriter. Converts exceptions using * convertXStreamException. */ private void marshal(Object graph, HierarchicalStreamWriter streamWriter) { try { xstream.marshal(graph, streamWriter); } catch (Exception ex) { throw convertXStreamException(ex, true); } } protected void marshalDomNode(Object graph, Node node) throws XmlMappingException { HierarchicalStreamWriter streamWriter = null; if (node instanceof Document) { streamWriter = new DomWriter((Document) node); } else if (node instanceof Element) { streamWriter = new DomWriter((Element) node); } else { throw new IllegalArgumentException("DOMResult contains neither Document nor Element"); } marshal(graph, streamWriter); } protected void marshalXmlEventWriter(Object graph, XMLEventWriter eventWriter) throws XmlMappingException { ContentHandler contentHandler = new StaxEventContentHandler(eventWriter); marshalSaxHandlers(graph, contentHandler, null); } protected void marshalXmlStreamWriter(Object graph, XMLStreamWriter streamWriter) throws XmlMappingException { try { marshal(graph, new StaxWriter(new QNameMap(), streamWriter)); } catch (XMLStreamException ex) { throw convertXStreamException(ex, true); } } protected void marshalOutputStream(Object graph, OutputStream outputStream) throws XmlMappingException, IOException { marshalWriter(graph, new OutputStreamWriter(outputStream, getEncoding())); } protected void marshalSaxHandlers(Object graph, ContentHandler contentHandler, LexicalHandler lexicalHandler) throws XmlMappingException { SaxWriter saxWriter = new SaxWriter(); saxWriter.setContentHandler(contentHandler); marshal(graph, saxWriter); } protected void marshalWriter(Object graph, Writer writer) throws XmlMappingException, IOException { marshal(graph, new CompactWriter(writer)); } private Object unmarshal(HierarchicalStreamReader streamReader) { try { return xstream.unmarshal(streamReader); } catch (Exception ex) { throw convertXStreamException(ex, false); } } protected Object unmarshalDomNode(Node node) throws XmlMappingException { HierarchicalStreamReader streamReader = null; 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); } protected Object unmarshalXmlEventReader(XMLEventReader eventReader) throws XmlMappingException { try { XMLStreamReader streamReader = new XmlEventStreamReader(eventReader); return unmarshalXmlStreamReader(streamReader); } catch (XMLStreamException ex) { throw convertXStreamException(ex, false); } } protected Object unmarshalXmlStreamReader(XMLStreamReader streamReader) throws XmlMappingException { return unmarshal(new StaxReader(new QNameMap(), streamReader)); } protected Object unmarshalInputStream(InputStream inputStream) throws XmlMappingException, IOException { return unmarshalReader(new InputStreamReader(inputStream, getEncoding())); } protected Object unmarshalReader(Reader reader) throws XmlMappingException, IOException { return unmarshal(new XppReader(reader)); } protected Object unmarshalSaxReader(XMLReader xmlReader, InputSource inputSource) throws XmlMappingException, IOException { throw new UnsupportedOperationException( "XStreamMarshaller does not support unmarshalling using SAX XMLReaders"); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy