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

org.eclipse.persistence.internal.oxm.XMLBinaryDataCollectionMappingNodeValue Maven / Gradle / Ivy

There is a newer version: 5.0.0-B03
Show newest version
/*
 * Copyright (c) 1998, 2023 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 v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.oxm;

import jakarta.activation.DataHandler;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.core.helper.CoreClassConstants;
import org.eclipse.persistence.internal.core.queries.CoreContainerPolicy;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.oxm.mappings.BinaryDataCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.internal.oxm.record.MarshalContext;
import org.eclipse.persistence.internal.oxm.record.MarshalRecord;
import org.eclipse.persistence.internal.oxm.record.ObjectMarshalContext;
import org.eclipse.persistence.internal.oxm.record.UnmarshalRecord;
import org.eclipse.persistence.internal.oxm.record.XMLReader;
import org.eclipse.persistence.internal.oxm.record.deferred.BinaryMappingContentHandler;
import org.eclipse.persistence.oxm.mappings.nullpolicy.AbstractNullPolicy;
import org.eclipse.persistence.oxm.mappings.nullpolicy.XMLNullRepresentationType;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import javax.xml.namespace.QName;

/**
 * INTERNAL:
 * 

Purpose: This is how the XML Binary Data Collection Mapping is * handled when used with the TreeObjectBuilder.

*/ public class XMLBinaryDataCollectionMappingNodeValue extends MappingNodeValue implements ContainerValue { private BinaryDataCollectionMapping xmlBinaryDataCollectionMapping; private int index = -1; public XMLBinaryDataCollectionMappingNodeValue(BinaryDataCollectionMapping mapping) { this.xmlBinaryDataCollectionMapping = mapping; } @Override public void setContainerInstance(Object object, Object containerInstance) { xmlBinaryDataCollectionMapping.setAttributeValueInObject(object, containerInstance); } @Override public Object getContainerInstance() { return getContainerPolicy().containerInstance(); } @Override public CoreContainerPolicy getContainerPolicy() { return xmlBinaryDataCollectionMapping.getContainerPolicy(); } protected String getValueToWrite(QName schemaType, Object value, CoreAbstractSession session) { return ((ConversionManager) session.getDatasourcePlatform().getConversionManager()).convertObject(value, CoreClassConstants.STRING, schemaType); } @Override public boolean isOwningNode(XPathFragment xPathFragment) { return xPathFragment.getNextFragment() == null || xPathFragment.isAttribute(); } @Override public boolean isWrapperAllowedAsCollectionName() { return true; } @Override public boolean marshal(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, CoreAbstractSession session, NamespaceResolver namespaceResolver) { if (xmlBinaryDataCollectionMapping.isReadOnly()) { return false; } Object collection = xmlBinaryDataCollectionMapping.getAttributeAccessor().getAttributeValueFromObject(object); if (null == collection) { AbstractNullPolicy wrapperNP = xmlBinaryDataCollectionMapping.getWrapperNullPolicy(); if (wrapperNP != null && wrapperNP.getMarshalNullRepresentation() == XMLNullRepresentationType.XSI_NIL) { marshalRecord.nilSimple(namespaceResolver); return true; } else { return false; } } CoreContainerPolicy cp = getContainerPolicy(); Object iterator = cp.iteratorFor(collection); if (!cp.hasNext(iterator)) { return marshalRecord.emptyCollection(xPathFragment, namespaceResolver, xmlBinaryDataCollectionMapping.getWrapperNullPolicy() != null); } XPathFragment groupingFragment = marshalRecord.openStartGroupingElements(namespaceResolver); marshalRecord.closeStartGroupingElements(groupingFragment); int valueSize = cp.sizeFor(collection); if(marshalRecord.getMarshaller().isApplicationJSON() && (valueSize > 1 || !marshalRecord.getMarshaller().isReduceAnyArrays())) { marshalRecord.startCollection(); } while (cp.hasNext(iterator)) { Object objectValue = cp.next(iterator, session); marshalSingleValue(xPathFragment, marshalRecord, object, objectValue, session, namespaceResolver, ObjectMarshalContext.getInstance()); } if(marshalRecord.getMarshaller().isApplicationJSON() && (valueSize > 1 || !marshalRecord.getMarshaller().isReduceAnyArrays())) { marshalRecord.endCollection(); } return true; } @Override public boolean startElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord, Attributes atts) { try { Field xmlField = (Field)xmlBinaryDataCollectionMapping.getField(); XPathFragment lastFragment = xmlField.getLastXPathFragment(); if(!lastFragment.isAttribute()) { //set a new content handler to deal with the Include element's event. BinaryMappingContentHandler handler = new BinaryMappingContentHandler(unmarshalRecord, this, this.xmlBinaryDataCollectionMapping); String qnameString = xPathFragment.getLocalName(); if (xPathFragment.getPrefix() != null) { qnameString = xPathFragment.getPrefix() + Constants.COLON + qnameString; } handler.startElement(xPathFragment.getNamespaceURI(), xPathFragment.getLocalName(), qnameString, atts); XMLReader xmlReader = unmarshalRecord.getXMLReader(); xmlReader.setContentHandler(handler); xmlReader.setLexicalHandler(handler); } else if (lastFragment.isAttribute()) { //handle swaRef and inline attribute cases here: String value = atts.getValue(lastFragment.getNamespaceURI(), lastFragment.getLocalName()); Object fieldValue = null; if (xmlBinaryDataCollectionMapping.isSwaRef()) { if (unmarshalRecord.getUnmarshaller().getAttachmentUnmarshaller() != null) { if (xmlBinaryDataCollectionMapping.getAttributeClassification() == XMLBinaryDataHelper.getXMLBinaryDataHelper().DATA_HANDLER) { fieldValue = unmarshalRecord.getUnmarshaller().getAttachmentUnmarshaller().getAttachmentAsDataHandler(value); } else { fieldValue = unmarshalRecord.getUnmarshaller().getAttachmentUnmarshaller().getAttachmentAsByteArray(value); } xmlBinaryDataCollectionMapping.setAttributeValueInObject(unmarshalRecord.getCurrentObject(), XMLBinaryDataHelper.getXMLBinaryDataHelper().convertObject(fieldValue, xmlBinaryDataCollectionMapping.getAttributeClassification(), unmarshalRecord.getSession(), xmlBinaryDataCollectionMapping.getContainerPolicy())); } } else { //value should be base64 binary string fieldValue = ((ConversionManager) unmarshalRecord.getSession().getDatasourcePlatform().getConversionManager()).convertSchemaBase64ToByteArray(value); xmlBinaryDataCollectionMapping.setAttributeValueInObject(unmarshalRecord.getCurrentObject(), XMLBinaryDataHelper.getXMLBinaryDataHelper().convertObject(fieldValue, xmlBinaryDataCollectionMapping.getAttributeClassification(), unmarshalRecord.getSession(),xmlBinaryDataCollectionMapping.getContainerPolicy())); } } return true; } catch(SAXException ex) { throw XMLMarshalException.unmarshalException(ex); } } @Override public void endElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord) { unmarshalRecord.resetStringBuffer(); } @Override public void endElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord, Object container) { this.endElement(xPathFragment, unmarshalRecord); } public DataHandler getDataHandlerForObjectValue(Object obj, Class classification) { if (classification == DataHandler.class) { return (DataHandler) obj; } return null; } @Override public boolean isContainerValue() { return true; } @Override public boolean marshalSingleValue(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, Object objectValue, CoreAbstractSession session, NamespaceResolver namespaceResolver, MarshalContext marshalContext) { Marshaller marshaller = marshalRecord.getMarshaller(); objectValue = xmlBinaryDataCollectionMapping.convertObjectValueToDataValue(objectValue, session, marshaller); if(objectValue == null) { AbstractNullPolicy nullPolicy = xmlBinaryDataCollectionMapping.getNullPolicy(); if (nullPolicy.getMarshalNullRepresentation() != XMLNullRepresentationType.ABSENT_NODE) { XPathNode holderXPathNode = new XPathNode(); holderXPathNode.setXPathFragment(xPathFragment); marshalRecord.addGroupingElement(holderXPathNode); boolean returnVal = xmlBinaryDataCollectionMapping.getNullPolicy().directMarshal(xPathFragment, marshalRecord, object, session, namespaceResolver); if(returnVal){ marshalRecord.endElement(xPathFragment, namespaceResolver); } marshalRecord.removeGroupingElement(holderXPathNode); return returnVal; } return true; } String mimeType = this.xmlBinaryDataCollectionMapping.getMimeType(object); String attachmentType = mimeType; if(mimeType == null) { mimeType = Constants.EMPTY_STRING; attachmentType = "application/octet-stream"; } marshalRecord.openStartElement(xPathFragment, namespaceResolver); marshalRecord.closeStartElement(); if (xmlBinaryDataCollectionMapping.isSwaRef() && marshaller.getAttachmentMarshaller() != null) { //object value should be a DataHandler String c_id = null; byte[] bytes = null; if (xmlBinaryDataCollectionMapping.getAttributeElementClass() == XMLBinaryDataHelper.getXMLBinaryDataHelper().DATA_HANDLER) { c_id = marshaller.getAttachmentMarshaller().addSwaRefAttachment((DataHandler) objectValue); } else { XMLBinaryDataHelper.EncodedData data = XMLBinaryDataHelper.getXMLBinaryDataHelper().getBytesForBinaryValue(// objectValue, marshaller, xmlBinaryDataCollectionMapping.getMimeType(object)); bytes = data.getData(); c_id = marshaller.getAttachmentMarshaller().addSwaRefAttachment(bytes, 0, bytes.length); } if(c_id != null) { marshalRecord.characters(c_id); } else { marshalRecord.characters(((Field) xmlBinaryDataCollectionMapping.getField()).getSchemaType(), objectValue, mimeType, false); } } else { if (marshalRecord.isXOPPackage() && !xmlBinaryDataCollectionMapping.shouldInlineBinaryData()) { XPathFragment lastFrag = ((Field) xmlBinaryDataCollectionMapping.getField()).getLastXPathFragment(); String c_id = Constants.EMPTY_STRING; byte[] bytes = null; if (objectValue.getClass() == CoreClassConstants.APBYTE) { bytes = (byte[]) objectValue; c_id = marshaller.getAttachmentMarshaller().addMtomAttachment(bytes, 0, bytes.length, attachmentType, lastFrag.getLocalName(), lastFrag.getNamespaceURI()); } else if (xmlBinaryDataCollectionMapping.getAttributeElementClass() == XMLBinaryDataHelper.getXMLBinaryDataHelper().DATA_HANDLER) { c_id = marshaller.getAttachmentMarshaller().addMtomAttachment((DataHandler) objectValue, lastFrag.getLocalName(), lastFrag.getNamespaceURI()); } else { XMLBinaryDataHelper.EncodedData data = XMLBinaryDataHelper.getXMLBinaryDataHelper().getBytesForBinaryValue(// objectValue, marshaller, xmlBinaryDataCollectionMapping.getMimeTypePolicy().getMimeType(object)); bytes = data.getData(); c_id = marshaller.getAttachmentMarshaller().addMtomAttachment(bytes, 0, bytes.length, // data.getMimeType(), lastFrag.getLocalName(), lastFrag.getNamespaceURI()); } if(c_id == null) { marshalRecord.characters(((Field) xmlBinaryDataCollectionMapping.getField()).getSchemaType(), objectValue, mimeType, false); } else { boolean addDeclaration = false; String xopPrefix = null; if(marshalRecord.getNamespaceResolver() != null){ xopPrefix = marshalRecord.getNamespaceResolver().resolveNamespaceURI(Constants.XOP_URL); } if (xopPrefix == null) { addDeclaration = true; xopPrefix = marshalRecord.getNamespaceResolver().generatePrefix(Constants.XOP_PREFIX); marshalRecord.getNamespaceResolver().put(xopPrefix, Constants.XOP_URL); namespaceResolver = marshalRecord.getNamespaceResolver(); } XPathFragment xopInclude = new XPathFragment(xopPrefix + ":Include"); xopInclude.setNamespaceURI(Constants.XOP_URL); marshalRecord.openStartElement(xopInclude, namespaceResolver); marshalRecord.attribute(Constants.EMPTY_STRING, "href", "href", c_id); if (addDeclaration) { marshalRecord.namespaceDeclaration(xopPrefix, Constants.XOP_URL); } marshalRecord.closeStartElement(); marshalRecord.endElement(xPathFragment, namespaceResolver); //marshal as an attachment. if (addDeclaration) { marshalRecord.getNamespaceResolver().removeNamespace(Constants.XOP_PREFIX); } } } else { marshalRecord.characters(((Field)xmlBinaryDataCollectionMapping.getField()).getSchemaType(), objectValue, mimeType, false); } } marshalRecord.endElement(xPathFragment, namespaceResolver); return true; } @Override public BinaryDataCollectionMapping getMapping() { return xmlBinaryDataCollectionMapping; } @Override public boolean getReuseContainer() { return getMapping().getReuseContainer(); } /** * INTERNAL: * Used to track the index of the corresponding containerInstance in the containerInstances Object[] on UnmarshalRecord */ @Override public void setIndex(int index){ this.index = index; } /** * INTERNAL: * Set to track the index of the corresponding containerInstance in the containerInstances Object[] on UnmarshalRecord * Set during TreeObjectBuilder initialization */ @Override public int getIndex(){ return index; } /** * INTERNAL * Return true if an empty container should be set on the object if there * is no presence of the collection in the XML document. * @since EclipseLink 2.3.3 */ @Override public boolean isDefaultEmptyContainer() { return getMapping().isDefaultEmptyContainer(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy