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

org.duracloud.common.xml.XmlSerializer Maven / Gradle / Ivy

/*
 * The contents of this file are subject to the license and copyright
 * detailed in the LICENSE and NOTICE files at the root of the source
 * tree and available online at
 *
 *     http://duracloud.org/license/
 */
package org.duracloud.common.xml;

import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import org.duracloud.common.xml.error.XmlSerializationException;
import org.xml.sax.SAXException;

/**
 * Handles the transfer of java beans to XML and back through JAXB
 *
 * @author: Bill Branan
 * Date: 7/8/11
 */
public class XmlSerializer {

    private Class clazz;
    private String schemaName;
    private String schemaVersion;

    private JAXBContext context;
    private Schema schema;

    /**
     * Creates a serializer which will be used to handle serializations
     * to and from the given top level class, using the given schema.
     *
     * @param clazz         class which should be annotated as an XmlRootElement
     * @param schemaName    name of the schema to use for validation
     * @param schemaVersion version of the schema expected
     */
    protected XmlSerializer(Class clazz,
                            String schemaName,
                            String schemaVersion) {
        this.clazz = clazz;
        this.schemaName = schemaName;
        this.schemaVersion = schemaVersion;
        try {
            context = JAXBContext.newInstance(clazz);
        } catch (JAXBException e) {
            throw new XmlSerializationException("Exception encountered " +
                                                "creating serializer: " +
                                                getErrorMsg(e), e);
        }

        try {
            SchemaFactory factory =
                SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
            Source schemaSource =
                new StreamSource(getClass().getClassLoader()
                                           .getResourceAsStream(schemaName));
            schema = factory.newSchema(schemaSource);
        } catch (SAXException e) {
            throw new XmlSerializationException("Unable to load schema for " +
                                                "validation due to: " +
                                                e.getMessage());
        }
    }

    /**
     * Serializes the data stored within a java bean to XML. The bean and any
     * ancillary beans should include JAXB binding annotations.
     *
     * @param obj to serialize
     * @return XML
     */
    public String serialize(T obj) {
        try {
            Marshaller marshaller = context.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            StringWriter writer = new StringWriter();
            marshaller.marshal(obj, writer);
            return writer.toString();
        } catch (JAXBException e) {
            throw new XmlSerializationException("Exception encountered " +
                                                "serializing report: " +
                                                getErrorMsg(e), e);
        }
    }

    /**
     * De-serializes XML into an object structure.
     *
     * @param xml to de-serialize
     * @return de-serialized object
     */
    public T deserialize(String xml) {
        if (xml == null || xml.equals("")) {
            throw new RuntimeException("XML cannot be null or empty");
        } else {
            return deserialize(new StreamSource(new StringReader(xml)));
        }
    }

    /**
     * De-serializes XML from an InputStream into an object structure.
     *
     * @param stream containing XML to de-serialize
     * @return de-serialized object
     */
    public T deserialize(InputStream stream) {
        if (stream == null) {
            throw new RuntimeException("Stream cannot be null");
        } else {
            return deserialize(new StreamSource(stream));
        }
    }

    private T deserialize(StreamSource stream) {
        try {
            Unmarshaller unmarshaller = context.createUnmarshaller();
            unmarshaller.setSchema(schema); // turn on schema validation
            JAXBElement report = unmarshaller.unmarshal(stream, clazz);
            return report.getValue();
        } catch (JAXBException e) {
            String error = "Exception encountered de-serializing xml " +
                           "using schema " + schemaName + " at version " +
                           schemaVersion + ": " + getErrorMsg(e);
            throw new XmlSerializationException(error, e);
        }
    }

    private String getErrorMsg(Throwable error) {
        while (null != error && null == error.getMessage()) {
            error = error.getCause();
        }
        return error.getMessage();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy