Package org.eclipse.persistence.jaxb

Source Code of org.eclipse.persistence.jaxb.JAXBMarshaller

/*******************************************************************************
* Copyright (c) 1998, 2008 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
*     Oracle - initial API and implementation from Oracle TopLink
******************************************************************************/ 
package org.eclipse.persistence.jaxb;

import java.io.OutputStream;
import java.io.Writer;
import java.io.File;
import java.util.HashMap;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.MarshalException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.PropertyException;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.attachment.AttachmentMarshaller;
import javax.xml.bind.helpers.DefaultValidationEventHandler;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.Result;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import java.lang.reflect.Constructor;

import org.w3c.dom.Node;
import org.xml.sax.ContentHandler;

import org.eclipse.persistence.oxm.XMLConstants;
import org.eclipse.persistence.oxm.XMLMarshaller;
import org.eclipse.persistence.oxm.XMLRoot;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.helper.ClassConstants;

import org.eclipse.persistence.jaxb.attachment.*;

/**
* INTERNAL:
* <p><b>Purpose:</b>To Provide an implementation of the JAXB 2.0 Marshaller Interface
* <p><b>Responsibilities:</b>
* <ul>
* <li>Provide a JAXB wrapper on the XMLMarshaller API</li>
* <li>Perform Object to XML Conversions</li>
* </ul>
* <p>This implementation of the JAXB 2.0 Marshaller interface provides the required functionality
* by acting as a thin wrapper on the existing XMLMarshaller API.
*
* @author mmacivor
* @since Oracle TopLink 11.1.1.0.0
* @see javax.xml.bind.Marshaller
* @see org.eclipse.persistence.oxm.XMLMarshaller
*/

public class JAXBMarshaller implements javax.xml.bind.Marshaller {
  private ValidationEventHandler validationEventHandler;
  private XMLMarshaller xmlMarshaller;
    public static final String XML_JAVATYPE_ADAPTERS = "xml-javatype-adapters";
    private static String STAX_RESULT_CLASS_NAME = "javax.xml.transform.stax.StAXResult";

  /**
   * This constructor initializes various settings on the XML marshaller, and
   * stores the provided JAXBIntrospector instance for usage in marshal()
   * calls.
   *
   * @param newXMLMarshaller
   * @param newIntrospector
   */
  public JAXBMarshaller(XMLMarshaller newXMLMarshaller, JAXBIntrospector newIntrospector) {
    super();
    validationEventHandler = new DefaultValidationEventHandler();
    xmlMarshaller = newXMLMarshaller;
    xmlMarshaller.setEncoding("UTF-8");
    xmlMarshaller.setFormattedOutput(false);
    JAXBMarshalListener listener = new JAXBMarshalListener(this);
    xmlMarshaller.setMarshalListener(listener);
  }

  /**
   * Create an instance of XMLRoot populated from the contents of the provided
   * JAXBElement. XMLRoot will be used to hold the contents of the JAXBElement
   * while the marshal operation is performed by TopLink OXM. This will avoid
   * adding any runtime dependencies to TopLink.
   *
   * @param elt
   * @return
   */
  private XMLRoot createXMLRootFromJAXBElement(JAXBElement elt) {
    // create an XMLRoot to hand into the marshaller
    XMLRoot xmlroot = new XMLRoot();
    xmlroot.setObject(elt.getValue());
    QName qname = elt.getName();
    xmlroot.setLocalName(qname.getLocalPart());
    xmlroot.setNamespaceURI(qname.getNamespaceURI());
    if(elt.getDeclaredType() == ClassConstants.ABYTE || elt.getDeclaredType() == ClassConstants.APBYTE) {
      xmlroot.setSchemaType(XMLConstants.BASE_64_BINARY_QNAME);
    } else {
      xmlroot.setSchemaType((QName)org.eclipse.persistence.internal.oxm.XMLConversionManager.getDefaultJavaTypes().get(elt.getDeclaredType()));
    }
   
    return xmlroot;
  }

  public XmlAdapter getAdapter(Class javaClass) {
        HashMap result = (HashMap) xmlMarshaller.getProperty(XML_JAVATYPE_ADAPTERS);
        if (result == null) {
            return null;
        }
        return (XmlAdapter) result.get(javaClass);
  }
 
  public AttachmentMarshaller getAttachmentMarshaller() {
    return ((AttachmentMarshallerAdapter)xmlMarshaller.getAttachmentMarshaller()).getAttachmentMarshaller();
  }

  public ValidationEventHandler getEventHandler() throws JAXBException {
    return validationEventHandler;
  }

  public Marshaller.Listener getListener() {
    return ((JAXBMarshalListener) xmlMarshaller.getMarshalListener()).getListener();
  }
 
  public Node getNode(Object object) throws JAXBException {
    throw new UnsupportedOperationException();
  }

  public Object getProperty(String key) throws PropertyException {
    if (key == null) {
      throw new IllegalArgumentException();
    } else if (JAXB_FORMATTED_OUTPUT.equals(key)) {
      return new Boolean(xmlMarshaller.isFormattedOutput());
    } else if (JAXB_ENCODING.equals(key)) {
      return xmlMarshaller.getEncoding();
    } else if (JAXB_SCHEMA_LOCATION.equals(key)) {
      return xmlMarshaller.getSchemaLocation();
    } else if (JAXB_NO_NAMESPACE_SCHEMA_LOCATION.equals(key)) {
      return xmlMarshaller.getNoNamespaceSchemaLocation();
    } else if (XMLConstants.JAXB_FRAGMENT.equals(key)) {
      return new Boolean(xmlMarshaller.isFragment());
    }
    throw new PropertyException("Unsupported Property");
  }

  public Schema getSchema() {
    try {
            //TODO: Need to generate a proper schema and convert to Sun Schema model
      return SchemaFactory.newInstance(XMLConstants.SCHEMA_URL).newSchema();
    } catch (org.xml.sax.SAXException ex) {
    }
    return null;
  }

  public void marshal(Object object, ContentHandler contentHandler) throws JAXBException {
        if (object == null || contentHandler == null) {
            throw new IllegalArgumentException();
        }
    // TODO:  in our case, we only care if the object is an instance
        // of JAXBElement, and do not need to use the introspector...
        // let the JAXBIntrospector determine if the object is a JAXBElement
    //if (jaxbIntrospector.isElement(object)) {
            // use the JAXBElement's properties to populate an XMLRoot
            // object = createXMLRootFromJAXBElement((JAXBElement) object);
        //}

        if (object instanceof JAXBElement) {
            // use the JAXBElement's properties to populate an XMLRoot
      object = createXMLRootFromJAXBElement((JAXBElement) object);
    }
    try {
      xmlMarshaller.marshal(object, contentHandler);
    } catch (Exception e) {
      throw new MarshalException(e);
    }
  }

  // TODO: add support for StAX
  public void marshal(Object object, XMLEventWriter eventWriter) throws JAXBException {
    try {
      Class staxResult = PrivilegedAccessHelper.getClassForName(STAX_RESULT_CLASS_NAME);
      Constructor cons = PrivilegedAccessHelper.getDeclaredConstructorFor(staxResult, new Class[]{XMLEventWriter.class}, false);
      Result result = (Result)PrivilegedAccessHelper.invokeConstructor(cons, new Object[]{eventWriter});
      this.marshal(object, result);
    } catch(Exception ex) {
      throw new MarshalException(ex);
    }
  }

  public void marshal(Object object, Node node) throws JAXBException {
        if (object == null || node == null) {
            throw new IllegalArgumentException();
        }
    // let the JAXBIntrospector determine if the object is a JAXBElement
    if (object instanceof JAXBElement) {
      // use the JAXBElement's properties to populate an XMLRoot
      object = createXMLRootFromJAXBElement((JAXBElement) object);
    }
    try {
      xmlMarshaller.marshal(object, node);
    } catch (Exception e) {
      throw new MarshalException(e);
    }
  }
 
  public void marshal(Object object, OutputStream outputStream) throws JAXBException {
        if (object == null || outputStream == null) {
            throw new IllegalArgumentException();
        }
    // let the JAXBIntrospector determine if the object is a JAXBElement
    if (object instanceof JAXBElement) {
      // use the JAXBElement's properties to populate an XMLRoot
      object = createXMLRootFromJAXBElement((JAXBElement) object);
    }
    try {
      xmlMarshaller.marshal(object, outputStream);
    } catch (Exception e) {
      throw new MarshalException(e);
    }
  }

  public void marshal(Object object, File file) throws JAXBException {
    try {
      java.io.FileWriter writer = new java.io.FileWriter(file);
      marshal(object, writer);
    } catch(Exception ex) {
      throw new MarshalException(ex);
    }
  }
  public void marshal(Object object, Result result) throws JAXBException {
        if (object == null || result == null) {
            throw new IllegalArgumentException();
        }
    // let the JAXBIntrospector determine if the object is a JAXBElement
    if (object instanceof JAXBElement) {
      // use the JAXBElement's properties to populate an XMLRoot
      object = createXMLRootFromJAXBElement((JAXBElement) object);
    }
    try {
      xmlMarshaller.marshal(object, result);
    } catch (Exception e) {
      throw new MarshalException(e);
    }
  }

  // TODO: add support for StAX
  public void marshal(Object object, XMLStreamWriter streamWriter) throws JAXBException {
    try {
      Class staxResult = PrivilegedAccessHelper.getClassForName(STAX_RESULT_CLASS_NAME);
      Constructor cons = PrivilegedAccessHelper.getDeclaredConstructorFor(staxResult, new Class[]{XMLStreamWriter.class}, false);
      Result result = (Result)PrivilegedAccessHelper.invokeConstructor(cons, new Object[]{streamWriter});
      this.marshal(object, result);
    } catch(Exception ex) {
      throw new MarshalException(ex);
    }   
  }

  public void marshal(Object object, Writer writer) throws JAXBException {
        if (object == null || writer == null) {
            throw new IllegalArgumentException();
        }
    // let the JAXBIntrospector determine if the object is a JAXBElement
    if (object instanceof JAXBElement) {
      // use the JAXBElement's properties to populate an XMLRoot
      object = createXMLRootFromJAXBElement((JAXBElement) object);
    }
    try {
      xmlMarshaller.marshal(object, writer);
    } catch (Exception e) {
      throw new MarshalException(e);
    }
  }

  public void setAdapter(Class javaClass, XmlAdapter adapter) {
        HashMap result = (HashMap) xmlMarshaller.getProperty(XML_JAVATYPE_ADAPTERS);
        if (result == null) {
            result = new HashMap();
            xmlMarshaller.getProperties().put(XML_JAVATYPE_ADAPTERS, result);
        }
        result.put(javaClass, adapter);
  }

  public void setAdapter(XmlAdapter adapter) {
        setAdapter(adapter.getClass(), adapter);
  }

  public void setAttachmentMarshaller(AttachmentMarshaller attachmentMarshaller) {
    xmlMarshaller.setAttachmentMarshaller(new AttachmentMarshallerAdapter(attachmentMarshaller));
  }

  public void setEventHandler(ValidationEventHandler newValidationEventHandler) throws JAXBException {
    if (null == newValidationEventHandler) {
      validationEventHandler = new DefaultValidationEventHandler();
    } else {
      validationEventHandler = newValidationEventHandler;
    }
  }
 
  public void setListener(Marshaller.Listener listener) {
    ((JAXBMarshalListener) xmlMarshaller.getMarshalListener()).setListener(listener);
  }

  public void setMarshalCallbacks(java.util.HashMap callbacks) {
    ((JAXBMarshalListener) xmlMarshaller.getMarshalListener()).setClassBasedMarshalEvents(callbacks);
  }

  public void setProperty(String key, Object value) throws PropertyException {
    try {
      if (key == null) {
        throw new IllegalArgumentException();
      } else if (JAXB_FORMATTED_OUTPUT.equals(key)) {
        Boolean formattedOutput = (Boolean) value;
        xmlMarshaller.setFormattedOutput(formattedOutput.booleanValue());
      } else if (JAXB_ENCODING.equals(key)) {
        xmlMarshaller.setEncoding((String) value);
      } else if (JAXB_SCHEMA_LOCATION.equals(key)) {
        xmlMarshaller.setSchemaLocation((String) value);
      } else if (JAXB_NO_NAMESPACE_SCHEMA_LOCATION.equals(key)) {
        xmlMarshaller.setNoNamespaceSchemaLocation((String) value);
      } else if (XMLConstants.JAXB_FRAGMENT.equals(key)) {
        Boolean fragment = (Boolean) value;
        xmlMarshaller.setFragment(fragment.booleanValue());
      } else {
        throw new PropertyException(key, value);
      }
    } catch (ClassCastException exception) {
      throw new PropertyException(key, exception);
    }
  }

  public void setSchema(Schema schema) {
  }
}
TOP

Related Classes of org.eclipse.persistence.jaxb.JAXBMarshaller

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.