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

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

There is a newer version: 5.0.0-B03
Show newest version
/*
 * Copyright (c) 1998, 2020 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 java.util.List;

import javax.xml.namespace.QName;

import org.eclipse.persistence.core.queries.CoreAttributeGroup;
import org.eclipse.persistence.core.queries.CoreAttributeItem;
import org.eclipse.persistence.core.sessions.CoreSession;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.oxm.mappings.AnyObjectMapping;
import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.internal.oxm.mappings.Mapping;
import org.eclipse.persistence.internal.oxm.mappings.UnmarshalKeepAsElementPolicy;
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.XMLRecord;
import org.eclipse.persistence.internal.oxm.record.deferred.AnyMappingContentHandler;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

/**
 * INTERNAL:
 * 

Purpose: This is how the XML Any Object Mapping is handled when * used with the TreeObjectBuilder.

*/ public class XMLAnyObjectMappingNodeValue extends XMLRelationshipMappingNodeValue { private AnyObjectMapping xmlAnyObjectMapping; public XMLAnyObjectMappingNodeValue(AnyObjectMapping xmlAnyObjectMapping) { super(); this.xmlAnyObjectMapping = xmlAnyObjectMapping; } @Override public boolean isOwningNode(XPathFragment xPathFragment) { return null == xPathFragment; } @Override public boolean marshal(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, CoreAbstractSession session, NamespaceResolver namespaceResolver) { return marshal(xPathFragment, marshalRecord, object, session, namespaceResolver, ObjectMarshalContext.getInstance()); } @Override public boolean marshal(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, CoreAbstractSession session, NamespaceResolver namespaceResolver, MarshalContext marshalContext) { if (xmlAnyObjectMapping.isReadOnly()) { return false; } Object objectValue = marshalContext.getAttributeValue(object, xmlAnyObjectMapping); return this.marshalSingleValue(xPathFragment, marshalRecord, object, objectValue, session, namespaceResolver, marshalContext); } @Override public boolean marshalSingleValue(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, Object objectValue, CoreAbstractSession session, NamespaceResolver namespaceResolver, MarshalContext marshalContext) { XPathFragment rootFragment = null; Marshaller marshaller = marshalRecord.getMarshaller(); objectValue = xmlAnyObjectMapping.convertObjectValueToDataValue(objectValue, session, marshalRecord.getMarshaller()); if (null == objectValue) { return false; } XPathFragment groupingFragment = marshalRecord.openStartGroupingElements(namespaceResolver); marshalRecord.closeStartGroupingElements(groupingFragment); boolean wasXMLRoot = false; XPathFragment xmlRootFragment = null; Object originalValue = objectValue; if (xmlAnyObjectMapping.usesXMLRoot() && (objectValue instanceof Root)) { xmlRootFragment = new XPathFragment(); xmlRootFragment.setNamespaceAware(marshalRecord.isNamespaceAware()); wasXMLRoot = true; objectValue = ((Root) objectValue).getObject(); if(objectValue == null){ setupFragment(((Root) originalValue), xmlRootFragment, marshalRecord); marshalRecord.nilComplex(xmlRootFragment, namespaceResolver); return true; } } if (objectValue instanceof String) { marshalSimpleValue(xmlRootFragment, marshalRecord, originalValue, object, objectValue, session, namespaceResolver); } else { CoreSession childSession = null; try { childSession = marshaller.getContext().getSession(objectValue); } catch (XMLMarshalException e) { marshalSimpleValue(xmlRootFragment, marshalRecord, originalValue, object, objectValue, session, namespaceResolver); return true; } Descriptor descriptor = (Descriptor) childSession.getDescriptor(objectValue); CoreAttributeGroup group = marshalRecord.getCurrentAttributeGroup(); CoreAttributeItem item = group.getItem(getMapping().getAttributeName()); CoreAttributeGroup nestedGroup = XMLRecord.DEFAULT_ATTRIBUTE_GROUP; if(item != null) { if(item.getGroups() != null) { nestedGroup = item.getGroup(descriptor.getJavaClass()); } if(nestedGroup == null) { nestedGroup = item.getGroup() == null?XMLRecord.DEFAULT_ATTRIBUTE_GROUP:item.getGroup(); } } marshalRecord.pushAttributeGroup(nestedGroup); ObjectBuilder objectBuilder = (ObjectBuilder) descriptor.getObjectBuilder(); List extraNamespaces = objectBuilder.addExtraNamespacesToNamespaceResolver(descriptor, marshalRecord, session, true, true); if(wasXMLRoot){ setupFragment(((Root) originalValue), xmlRootFragment, marshalRecord); } /* * B5112171: 25 Apr 2006 * During marshalling - XML AnyObject and AnyCollection * mappings throw a NullPointerException when the * "document root element" on child object descriptors are not * all defined. These nodes will be ignored with a warning. */ String defaultRootElementString = descriptor.getDefaultRootElement(); if (!wasXMLRoot && (defaultRootElementString == null)) { throw XMLMarshalException.defaultRootElementNotSpecified(descriptor); } else { marshalRecord.beforeContainmentMarshal(objectValue); if (xmlRootFragment != null) { rootFragment = xmlRootFragment; } else { rootFragment = new XPathFragment(defaultRootElementString); //resolve URI if (rootFragment.getNamespaceURI() == null) { if(rootFragment.getPrefix() != null) { String uri = descriptor.getNonNullNamespaceResolver().resolveNamespacePrefix(rootFragment.getPrefix()); rootFragment.setNamespaceURI(uri); } else { rootFragment.setNamespaceURI(descriptor.getNonNullNamespaceResolver().getDefaultNamespaceURI()); } } } if (!wasXMLRoot) { marshalRecord.setLeafElementType(descriptor.getDefaultRootElementType()); } getXPathNode().startElement(marshalRecord, rootFragment, object, session, descriptor.getNonNullNamespaceResolver(), objectBuilder, objectValue); writeExtraNamespaces(extraNamespaces, marshalRecord, session); marshalRecord.addXsiTypeAndClassIndicatorIfRequired(descriptor, descriptor, (Field)xmlAnyObjectMapping.getField(), originalValue, objectValue, wasXMLRoot, false); objectBuilder.buildRow(marshalRecord, objectValue, (CoreAbstractSession) childSession, marshaller, null); marshalRecord.afterContainmentMarshal(object, objectValue); marshalRecord.endElement(rootFragment, namespaceResolver); marshalRecord.removeExtraNamespacesFromNamespaceResolver(extraNamespaces, session); } } return true; } @Override public boolean startElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord, Attributes atts) { try { Descriptor workingDescriptor = findReferenceDescriptor(xPathFragment, unmarshalRecord, atts, xmlAnyObjectMapping, xmlAnyObjectMapping.getKeepAsElementPolicy()); UnmarshalKeepAsElementPolicy policy = xmlAnyObjectMapping.getKeepAsElementPolicy(); if (null != policy && ((workingDescriptor == null && policy.isKeepUnknownAsElement()) || policy.isKeepAllAsElement())) { setupHandlerForKeepAsElementPolicy(unmarshalRecord, xPathFragment, atts); }else if (workingDescriptor != null) { processChild(xPathFragment, unmarshalRecord, atts, workingDescriptor, xmlAnyObjectMapping); }else{ AnyMappingContentHandler handler = new AnyMappingContentHandler(unmarshalRecord, xmlAnyObjectMapping.usesXMLRoot()); 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); return true; } } catch (SAXException e) { throw XMLMarshalException.unmarshalException(e); } return true; } @Override public void endElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord) { UnmarshalRecord childRecord = unmarshalRecord.getChildRecord(); if (null != childRecord) { Object childObject = childRecord.getCurrentObject(); // OBJECT VALUE if (xmlAnyObjectMapping.usesXMLRoot()) { Descriptor workingDescriptor = childRecord.getDescriptor(); if (workingDescriptor != null) { String prefix = xPathFragment.getPrefix(); if ((prefix == null) && (xPathFragment.getNamespaceURI() != null)) { prefix = unmarshalRecord.resolveNamespaceUri(xPathFragment.getNamespaceURI()); } childObject = workingDescriptor.wrapObjectInXMLRoot(childObject, xPathFragment.getNamespaceURI(), xPathFragment.getLocalName(), prefix, false, unmarshalRecord.isNamespaceAware(), unmarshalRecord.getUnmarshaller()); workingDescriptor = null; } } childObject = xmlAnyObjectMapping.convertDataValueToObjectValue(childObject, unmarshalRecord.getSession(), unmarshalRecord.getUnmarshaller()); unmarshalRecord.setAttributeValue(childObject, xmlAnyObjectMapping); } else { SAXFragmentBuilder builder = unmarshalRecord.getFragmentBuilder(); UnmarshalKeepAsElementPolicy keepAsElementPolicy = xmlAnyObjectMapping.getKeepAsElementPolicy(); if (null != keepAsElementPolicy && (keepAsElementPolicy.isKeepUnknownAsElement() || keepAsElementPolicy.isKeepAllAsElement()) && builder.getNodes().size() > 1) { setOrAddAttributeValueForKeepAsElement(builder, xmlAnyObjectMapping, xmlAnyObjectMapping, unmarshalRecord, false, null); } else { // TEXT VALUE if(xmlAnyObjectMapping.isMixedContent()) { endElementProcessText(unmarshalRecord, xmlAnyObjectMapping, xPathFragment, null); } else { unmarshalRecord.resetStringBuffer(); } } } } @Override protected void setOrAddAttributeValue(UnmarshalRecord unmarshalRecord, Object value, XPathFragment xPathFragment, Object collection){ if (!xmlAnyObjectMapping.usesXMLRoot()) { unmarshalRecord.setAttributeValue(value, xmlAnyObjectMapping); } else { Root xmlRoot = unmarshalRecord.createRoot(); xmlRoot.setNamespaceURI(xPathFragment.getNamespaceURI()); xmlRoot.setSchemaType(unmarshalRecord.getTypeQName()); xmlRoot.setLocalName(xPathFragment.getLocalName()); xmlRoot.setObject(value); // xmlRoot.setDeclaredType(type); unmarshalRecord.setAttributeValue(xmlRoot, xmlAnyObjectMapping); } } private Namespace setupFragment(Root originalValue, XPathFragment xmlRootFragment, MarshalRecord marshalRecord) { Namespace generatedNamespace = null; String xpath = originalValue.getLocalName(); if (originalValue.getNamespaceURI() != null) { xmlRootFragment.setNamespaceURI((originalValue).getNamespaceURI()); String prefix = marshalRecord.getNamespaceResolver().resolveNamespaceURI((originalValue).getNamespaceURI()); if (prefix == null || prefix.length() == 0) { prefix = marshalRecord.getNamespaceResolver().generatePrefix("ns0"); generatedNamespace = new Namespace(prefix, xmlRootFragment.getNamespaceURI()); xmlRootFragment.setGeneratedPrefix(true); } xpath = prefix + Constants.COLON + xpath; } xmlRootFragment.setXPath(xpath); return generatedNamespace; } private void marshalSimpleValue(XPathFragment xmlRootFragment, MarshalRecord marshalRecord, Object originalValue, Object object, Object value, CoreAbstractSession session, NamespaceResolver namespaceResolver) { QName qname = null; if (xmlRootFragment != null) { qname = ((Root) originalValue).getSchemaType(); setupFragment(((Root) originalValue), xmlRootFragment, marshalRecord); getXPathNode().startElement(marshalRecord, xmlRootFragment, object, session, namespaceResolver, null, null); updateNamespaces(qname, marshalRecord, null); } if (value instanceof org.w3c.dom.Node) { marshalRecord.node((org.w3c.dom.Node) value, marshalRecord.getNamespaceResolver()); } else { marshalRecord.characters(qname, value, null, false); } if (xmlRootFragment != null) { marshalRecord.endElement(xmlRootFragment, namespaceResolver); } } @Override public AnyObjectMapping getMapping() { return xmlAnyObjectMapping; } @Override public boolean isWhitespaceAware() { return false; } @Override public boolean isAnyMappingNodeValue() { return true; } @Override public boolean isMixedContentNodeValue() { return this.xmlAnyObjectMapping.isMixedContent(); } @Override protected Descriptor findReferenceDescriptor(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord, Attributes atts, Mapping mapping, UnmarshalKeepAsElementPolicy policy) { Descriptor referenceDescriptor = super.findReferenceDescriptor(xPathFragment, unmarshalRecord, atts, mapping, policy); if (referenceDescriptor == null) { Context xmlContext = unmarshalRecord.getUnmarshaller().getContext(); XPathQName xpathQName = new XPathQName(xPathFragment.getNamespaceURI(), xPathFragment.getLocalName(), unmarshalRecord.isNamespaceAware()); referenceDescriptor = xmlContext.getDescriptor(xpathQName); // Check if descriptor is for a wrapper, if it is null it out and let continue if (referenceDescriptor != null && referenceDescriptor.isWrapper()) { referenceDescriptor = null; } } return referenceDescriptor; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy