Package org.eclipse.persistence.internal.oxm

Source Code of org.eclipse.persistence.internal.oxm.XMLBinaryDataMappingNodeValue

/*******************************************************************************
* Copyright (c) 1998, 2012 Oracle and/or its affiliates. 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.internal.oxm;

import javax.activation.DataHandler;
import javax.xml.namespace.QName;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.eclipse.persistence.core.sessions.CoreSession;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.core.helper.CoreClassConstants;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.oxm.XMLBinaryDataHelper;
import org.eclipse.persistence.internal.oxm.mappings.BinaryDataMapping;
import org.eclipse.persistence.internal.oxm.record.BinaryDataUnmarshalRecord;
import org.eclipse.persistence.internal.oxm.record.MarshalContext;
import org.eclipse.persistence.internal.oxm.record.ObjectMarshalContext;
import org.eclipse.persistence.internal.oxm.record.XMLReader;
import org.eclipse.persistence.internal.oxm.record.deferred.BinaryMappingContentHandler;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLConstants;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.oxm.XMLMarshaller;
import org.eclipse.persistence.oxm.XMLRoot;
import org.eclipse.persistence.oxm.record.MarshalRecord;
import org.eclipse.persistence.oxm.record.UnmarshalRecord;
import org.eclipse.persistence.sessions.Session;

/**
* INTERNAL:
* <p><b>Purpose</b>: This is how the XML Binary Data Mapping is handled when
* used with the TreeObjectBuilder.</p>
* @author  mmacivor
*/

public class XMLBinaryDataMappingNodeValue extends NodeValue implements NullCapableValue {
    private BinaryDataMapping xmlBinaryDataMapping;

    protected String getValueToWrite(QName schemaType, Object value, CoreAbstractSession session) {
        return (String) ((XMLConversionManager) session.getDatasourcePlatform().getConversionManager()).convertObject(value, CoreClassConstants.STRING, schemaType);
    }

    public boolean isOwningNode(XPathFragment xPathFragment) {
        return (xPathFragment.getNextFragment() == null) || xPathFragment.isAttribute();
    }

    public XMLBinaryDataMappingNodeValue(BinaryDataMapping mapping) {
        this.xmlBinaryDataMapping = mapping;
    }

    public boolean marshal(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, CoreAbstractSession session, NamespaceResolver namespaceResolver) {
        return marshal(xPathFragment, marshalRecord, object, session, namespaceResolver, ObjectMarshalContext.getInstance(), null);
    }

    public boolean marshal(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, CoreAbstractSession session, NamespaceResolver namespaceResolver, MarshalContext marshalContext, XPathFragment rootFragment) {
        if (xmlBinaryDataMapping.isReadOnly()) {
            return false;
        }
        Object objectValue = marshalContext.getAttributeValue(object, xmlBinaryDataMapping);
        return this.marshalSingleValue(xPathFragment, marshalRecord, object, objectValue, session, namespaceResolver, marshalContext, rootFragment);
    }

    public boolean marshalSingleValue(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, Object objectValue, CoreAbstractSession session, NamespaceResolver namespaceResolver, MarshalContext marshalContext) {
        return marshalSingleValue(xPathFragment, marshalRecord, object, objectValue, session, namespaceResolver, marshalContext, null);
    }
   
    public boolean marshalSingleValue(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, Object objectValue,CoreAbstractSession session, NamespaceResolver namespaceResolver, MarshalContext marshalContext, XPathFragment rootFragment) {
        XPathFragment xmlRootFrag = null;

        if (objectValue instanceof XMLRoot) {
            XMLRoot xmlRoot = (XMLRoot) objectValue;
            xmlRootFrag = new XPathFragment();
            if (xmlRoot.getNamespaceURI() != null && !xmlRoot.getNamespaceURI().equals(namespaceResolver.getDefaultNamespaceURI())) {
                String prefix = namespaceResolver.resolveNamespaceURI(xmlRoot.getNamespaceURI());
                xmlRootFrag.setXPath(prefix + XMLConstants.COLON + xmlRoot.getLocalName());
                xmlRootFrag.setNamespaceURI(xmlRoot.getNamespaceURI());
            }else{
              xmlRootFrag.setXPath(xmlRoot.getLocalName());
              if(xmlRoot.getNamespaceURI() != null && xmlRoot.getNamespaceURI().length() > 0) {
                  xmlRootFrag.setNamespaceURI(xmlRoot.getNamespaceURI());
              }
            }
        }

        XMLMarshaller marshaller = marshalRecord.getMarshaller();
        objectValue = xmlBinaryDataMapping.convertObjectValueToDataValue(objectValue, (Session) session, marshaller);
        XPathFragment groupingFragment = marshalRecord.openStartGroupingElements(namespaceResolver);
        if(xPathFragment.isAttribute()){
            if (objectValue == null) {
                marshalRecord.closeStartGroupingElements(groupingFragment);
                return true;
            }
        }else {
            marshalRecord.closeStartGroupingElements(groupingFragment);
            XPathFragment elementFragment = xPathFragment;
            if(xmlRootFrag != null) {
                elementFragment = xmlRootFrag;
            }
            if (objectValue == null) {
                XPathNode holderXPathNode = new XPathNode();
                holderXPathNode.setXPathFragment(elementFragment);
                marshalRecord.addGroupingElement(holderXPathNode);
                boolean returnVal = xmlBinaryDataMapping.getNullPolicy().directMarshal(xPathFragment, marshalRecord, object, session, namespaceResolver);
                if(returnVal){
                    marshalRecord.endElement(elementFragment, namespaceResolver);
                }
                marshalRecord.removeGroupingElement(holderXPathNode);
                return returnVal;
              }else if(!xPathFragment.isSelfFragment){
                marshalRecord.openStartElement(elementFragment, namespaceResolver);
                marshalRecord.closeStartElement();
            }
        }


      
       
        // figure out CID or bytes
        String c_id = null;
        byte[] bytes = null;
        String mimeType = this.xmlBinaryDataMapping.getMimeType(object);
        if(mimeType == null) {
            mimeType = "";
        }
        if (xmlBinaryDataMapping.isSwaRef() && (marshaller.getAttachmentMarshaller() != null)) {
            //object value should be a DataHandler
            if (xmlBinaryDataMapping.getAttributeClassification() == XMLBinaryDataHelper.getXMLBinaryDataHelper().DATA_HANDLER) {
                c_id = marshaller.getAttachmentMarshaller().addSwaRefAttachment((DataHandler) objectValue);
            } else {
                XMLBinaryDataHelper.EncodedData data = XMLBinaryDataHelper.getXMLBinaryDataHelper().getBytesForBinaryValue(//
                        objectValue, marshaller, xmlBinaryDataMapping.getMimeType(object));
                bytes = data.getData();
                c_id = marshaller.getAttachmentMarshaller().addSwaRefAttachment(bytes, 0, bytes.length);
            }
        } else if (marshalRecord.isXOPPackage() && !xmlBinaryDataMapping.shouldInlineBinaryData()) {
            XPathFragment lastFrag = ((XMLField) xmlBinaryDataMapping.getField()).getLastXPathFragment();
            if(xmlRootFrag != null) {
                lastFrag = xmlRootFrag;
            }
            String localName = null;
            String namespaceUri = null;
            if(rootFragment != null) {
                localName = rootFragment.getLocalName();
                namespaceUri = rootFragment.getNamespaceURI();
            }
            if(!lastFrag.isSelfFragment) {
                localName = lastFrag.getLocalName();
                namespaceUri = lastFrag.getNamespaceURI();
            }
            if (objectValue.getClass() == CoreClassConstants.APBYTE) {
                bytes = (byte[]) objectValue;
                c_id = marshaller.getAttachmentMarshaller().addMtomAttachment(bytes, 0, bytes.length, this.xmlBinaryDataMapping.getMimeType(object), localName, namespaceUri);
            } else if (xmlBinaryDataMapping.getAttributeClassification() == XMLBinaryDataHelper.getXMLBinaryDataHelper().DATA_HANDLER) {
                c_id = marshaller.getAttachmentMarshaller().addMtomAttachment((DataHandler) objectValue, localName, namespaceUri);
            } else {
                XMLBinaryDataHelper.EncodedData data = XMLBinaryDataHelper.getXMLBinaryDataHelper().getBytesForBinaryValue(//
                        objectValue, marshaller, xmlBinaryDataMapping.getMimeType(object));
                bytes = data.getData();
                c_id = marshaller.getAttachmentMarshaller().addMtomAttachment(bytes, 0, bytes.length, data.getMimeType(), localName, namespaceUri);
            }
        }

        // handle attributes
        if (xPathFragment.isAttribute()) {
            // if the CID is null there's nothing to write out
            if (c_id != null) {
                marshalRecord.attribute(xPathFragment, namespaceResolver, c_id);
            }else {
                String value = getValueToWrite(((XMLField) xmlBinaryDataMapping.getField()).getSchemaType(), objectValue, session);
                marshalRecord.attribute(xPathFragment, namespaceResolver, value);
            }
            marshalRecord.closeStartGroupingElements(groupingFragment);
            return true;
        }
       
        if (xmlBinaryDataMapping.isSwaRef() && (marshaller.getAttachmentMarshaller() != null)) {
            if(c_id != null) {
                marshalRecord.characters(c_id);
            } else {
                marshalRecord.characters(((XMLField) xmlBinaryDataMapping.getField()).getSchemaType(), objectValue, mimeType, false);
            }
        } else {
            if (marshalRecord.isXOPPackage() && !xmlBinaryDataMapping.shouldInlineBinaryData()) {
                if(c_id == null) {
                    marshalRecord.characters(((XMLField) xmlBinaryDataMapping.getField()).getSchemaType(), objectValue, mimeType, false);
                } else {
                    String xopPrefix = null;
                    // If the field's resolver is non-null and has an entry for XOP,
                    // use it - otherwise, create a new resolver, set the XOP entry,
                    // on it, and use it instead.
                    // We do this to avoid setting the XOP namespace declaration on
                    // a given field or descriptor's resolver, as it is only required
                    // on the current element

                    // 20061023: handle NPE on null NSR
                    if (namespaceResolver != null) {
                        xopPrefix = namespaceResolver.resolveNamespaceURI(XMLConstants.XOP_URL);
                    }
                    boolean addDeclaration = false;
                    if (xopPrefix == null || namespaceResolver == null) {
                        addDeclaration = true;
                        xopPrefix = XMLConstants.XOP_PREFIX;
                        namespaceResolver = new NamespaceResolver();
                        namespaceResolver.put(xopPrefix, XMLConstants.XOP_URL);
                    }
                    XPathFragment xopInclude = new XPathFragment(xopPrefix + ":Include");
                    xopInclude.setNamespaceURI(XMLConstants.XOP_URL);
                    marshalRecord.openStartElement(xopInclude, namespaceResolver);
                    marshalRecord.attribute(XMLConstants.EMPTY_STRING, "href", "href", c_id);
                    if (addDeclaration) {                       
                        marshalRecord.namespaceDeclaration(xopPrefix,  XMLConstants.XOP_URL);
                    }
                    marshalRecord.closeStartElement();
                    marshalRecord.endElement(xopInclude, namespaceResolver);
                    //marshal as an attachment
                }
            } else {
                marshalRecord.characters(((XMLField)xmlBinaryDataMapping.getField()).getSchemaType(), objectValue, mimeType, false);
            }
        }
       
        if(!xPathFragment.isSelfFragment()){
          marshalRecord.endElement(xPathFragment, namespaceResolver);
        }
        return true;
    }
   
    public boolean startElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord, Attributes atts) {
        try {
           
            unmarshalRecord.removeNullCapableValue(this);
            XMLField xmlField = (XMLField) xmlBinaryDataMapping.getField();
            XPathFragment lastFragment = xmlField.getLastXPathFragment();
            BinaryMappingContentHandler handler = new BinaryMappingContentHandler(unmarshalRecord, this, this.xmlBinaryDataMapping);
            String qnameString = xPathFragment.getLocalName();
            if (xPathFragment.getPrefix() != null) {
                qnameString = xPathFragment.getPrefix() + XMLConstants.COLON + qnameString;
            }
            handler.startElement(xPathFragment.getNamespaceURI(), xPathFragment.getLocalName(), qnameString, atts);
            XMLReader xmlReader = unmarshalRecord.getXMLReader();
            xmlReader.setContentHandler(handler);
            xmlReader.setLexicalHandler(handler);
            return true;
        } catch(SAXException ex) {
            throw XMLMarshalException.unmarshalException(ex);
        }
    }

    public void endElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord) {
        unmarshalRecord.resetStringBuffer();
    }

    /**
     * Handle swaRef and inline attribute cases.
     */
    public void attribute(UnmarshalRecord unmarshalRecord, String URI, String localName, String value) {
        unmarshalRecord.removeNullCapableValue(this);
        XMLField xmlField = (XMLField) xmlBinaryDataMapping.getField();
        XPathFragment lastFragment = xmlField.getLastXPathFragment();
       
        Object fieldValue = null;
        if (xmlBinaryDataMapping.isSwaRef()) {
            if (unmarshalRecord.getUnmarshaller().getAttachmentUnmarshaller() != null) {
                if (xmlBinaryDataMapping.getAttributeClassification() == XMLBinaryDataHelper.getXMLBinaryDataHelper().DATA_HANDLER) {
                    fieldValue = unmarshalRecord.getUnmarshaller().getAttachmentUnmarshaller().getAttachmentAsDataHandler(value);
                } else {
                    fieldValue = unmarshalRecord.getUnmarshaller().getAttachmentUnmarshaller().getAttachmentAsByteArray(value);
                }
                xmlBinaryDataMapping.setAttributeValueInObject(unmarshalRecord.getCurrentObject(), XMLBinaryDataHelper.getXMLBinaryDataHelper().convertObject(fieldValue, xmlBinaryDataMapping.getAttributeClassification(), unmarshalRecord.getSession()));
            }
        } else {
            // value should be base64 binary string
            fieldValue = ((XMLConversionManager) unmarshalRecord.getSession().getDatasourcePlatform().getConversionManager()).convertSchemaBase64ToByteArray(value);
            xmlBinaryDataMapping.setAttributeValueInObject(unmarshalRecord.getCurrentObject(), XMLBinaryDataHelper.getXMLBinaryDataHelper().convertObject(fieldValue, xmlBinaryDataMapping.getAttributeClassification(), unmarshalRecord.getSession()));
        }
    }

    public void setNullValue(Object object, CoreSession session) {
        Object value = xmlBinaryDataMapping.getObjectValue(null, (Session) session);
        xmlBinaryDataMapping.setAttributeValueInObject(object, value);
    }

    public boolean isNullCapableValue() {
        return xmlBinaryDataMapping.getNullPolicy().getIsSetPerformedForAbsentNode();
    }

    public DataHandler getDataHandlerForObjectValue(Object obj, Class classification) {
        if (classification == DataHandler.class) {
            return (DataHandler) obj;
        }
        return null;
    }
   
    public BinaryDataMapping getMapping() {
        return this.xmlBinaryDataMapping;
    }
   
    public UnmarshalRecord buildSelfRecord(UnmarshalRecord unmarshalRecord, Attributes atts) {  
        unmarshalRecord.removeNullCapableValue(this);
        BinaryDataUnmarshalRecord newRecord = new BinaryDataUnmarshalRecord(null, unmarshalRecord, this, xmlBinaryDataMapping);
        return newRecord;      
    }
   
    public void endSelfNodeValue(UnmarshalRecord unmarshalRecord, UnmarshalRecord selfRecord, Attributes attributes) {
        unmarshalRecord.resetStringBuffer();
    }

}
TOP

Related Classes of org.eclipse.persistence.internal.oxm.XMLBinaryDataMappingNodeValue

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.