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

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

The 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 org.eclipse.persistence.internal.core.helper.CoreField;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.internal.oxm.mappings.ObjectReferenceMapping;
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 javax.xml.namespace.QName;

/**
 * INTERNAL:
 * 

Purpose: Class to handle (un)marshal operations for * XMLObjectReferenceMappings. An instance of this class is required for each * XMLField set on the mapping, that is, for each source field in the * source-target key field association list.

* *

When unmarshalling, an instance of org.eclipse.persistence.internal.oxm.Reference is * created on a per mapping basis (keyed on source object instance) and sotred * on the associated session's org.eclipse.persistence.internal.oxm.ReferenceResolver * instance. Each target primary key value is stored in the Reference instance * for use during mapping resolution phase after unmarshalling completes.

* *

When marshalling, the target object's primary key value that is mapped to * this NodeValue's XMLField (in the XMLObjectReferenceMapping's source-target * key field association list) is retrieved and written out.

* * @see org.eclipse.persistence.internal.oxm.Reference * @see org.eclipse.persistence.internal.oxm.ReferenceResolver * @see org.eclipse.persistence.oxm.mappings.XMLObjectReferenceMapping */ public class XMLObjectReferenceMappingNodeValue extends MappingNodeValue { private ObjectReferenceMapping xmlObjectReferenceMapping; private Field xmlField; /** * This constructor sets the XMLObjectReferenceMapping member to the provided * value. * */ public XMLObjectReferenceMappingNodeValue(ObjectReferenceMapping xmlObjectReferenceMapping) { super(); this.xmlObjectReferenceMapping = xmlObjectReferenceMapping; } /** * This constructor sets the XMLObjectReferenceMapping and XMLField members to * the provided values. * */ public XMLObjectReferenceMappingNodeValue(ObjectReferenceMapping xmlObjectReferenceMapping, Field xmlField) { super(); this.xmlObjectReferenceMapping = xmlObjectReferenceMapping; this.xmlField = xmlField; } /** * Handle attribute operation. Here we will create and populate an * org.eclipse.persistence.internal.oxm.Reference instance to be used during * the mapping resolution stage. In particular, the primary key value * for this element will be added to the Reference object's list of * target primary key values. Note that if a reference already exists * for the xmlObjectReferenceMapping's source object instance, we will * simply add to the target pk value list. The Reference object will * is stored on the ReferenceResolver associated with the UnmarshalRecord's * session. */ @Override public void attribute(UnmarshalRecord unmarshalRecord, String namespaceURI, String localName, String value) { if (value != null) { Object realValue = unmarshalRecord.getXMLReader().convertValueBasedOnSchemaType(xmlField, value, (ConversionManager) unmarshalRecord.getSession().getDatasourcePlatform().getConversionManager(),unmarshalRecord); // build a reference which will be resolved after unmarshalling is complete xmlObjectReferenceMapping.buildReference(unmarshalRecord, xmlField, realValue, unmarshalRecord.getSession()); } } /** * Handle endElement operation. Here we will create and populate an * org.eclipse.persistence.internal.oxm.Reference instance to be used during * the mapping resolution stage. In particular, the primary key value * for this element will be added to the Reference object's list of * target primary key values. Note that if a reference already exists * for the xmlObjectReferenceMapping's source object instance, we will * simply add to the target pk value list. The Reference object will * is stored on the ReferenceResolver associated with the UnmarshalRecord's * session. */ @Override public void endElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord) { if (!xmlField.getLastXPathFragment().nameIsText()) { return; } Object value = unmarshalRecord.getCharacters().toString().trim(); unmarshalRecord.resetStringBuffer(); ConversionManager conversionManager = unmarshalRecord.getConversionManager(); if (unmarshalRecord.getTypeQName() != null) { Class typeClass = xmlField.getJavaClass(unmarshalRecord.getTypeQName(), conversionManager); value = conversionManager.convertObject(value, typeClass, unmarshalRecord.getTypeQName()); } else { value = unmarshalRecord.getXMLReader().convertValueBasedOnSchemaType(xmlField, value, conversionManager, unmarshalRecord); } // build a reference which will be resolved after unmarshalling is complete xmlObjectReferenceMapping.buildReference(unmarshalRecord, xmlField, value, unmarshalRecord.getSession()); } /** * Indicate if the XPathFragment is an attribute or text() node. */ @Override public boolean isOwningNode(XPathFragment xPathFragment) { return xPathFragment.isAttribute() || xPathFragment.nameIsText(); } /** * Handle the marshal operation for this NodeValue's XMLField. The target * object's primary key value that is mapped to this NodeValue's XMLField * (in the XMLObjectReferenceMapping's source-target key field association list) * is retrieved and written out. */ @Override public boolean marshal(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, CoreAbstractSession session, NamespaceResolver namespaceResolver) { return marshal(xPathFragment, marshalRecord, object, session, namespaceResolver, ObjectMarshalContext.getInstance()); } /** * Handle the marshal operation for this NodeValue's XMLField. The target * object's primary key value that is mapped to this NodeValue's XMLField * (in the XMLObjectReferenceMapping's source-target key field association list) * is retrieved and written out. */ @Override public boolean marshal(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, CoreAbstractSession session, NamespaceResolver namespaceResolver, MarshalContext marshalContext) { if (xmlObjectReferenceMapping.isReadOnly()) { return false; } Object targetObject = marshalContext.getAttributeValue(object, xmlObjectReferenceMapping); return this.marshalSingleValue(xPathFragment, marshalRecord, object, targetObject, session, namespaceResolver, marshalContext); } @Override public boolean marshalSingleValue(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, Object targetObject, CoreAbstractSession session, NamespaceResolver namespaceResolver, MarshalContext marshalContext) { Object fieldValue = xmlObjectReferenceMapping.buildFieldValue(targetObject, xmlField, session); if (fieldValue == null) { if(null != targetObject) { Field fkField = (Field) xmlObjectReferenceMapping.getSourceToTargetKeyFieldAssociations().get(xmlField); if(null == fkField) { Descriptor targetDescriptor = (Descriptor) session.getDescriptor(targetObject); fieldValue = marshalRecord.getMarshaller().getContext().getValueByXPath(targetObject, ((CoreField) targetDescriptor.getPrimaryKeyFields().get(0)).getName(), targetDescriptor.getNamespaceResolver(), Object.class); } else { fieldValue = marshalRecord.getMarshaller().getContext().getValueByXPath(targetObject, fkField.getXPath(), fkField.getNamespaceResolver(), Object.class); } } if(null == fieldValue) { return false; } } QName schemaType = xmlField.getSchemaTypeForValue(fieldValue, session); XPathFragment groupingFragment = marshalRecord.openStartGroupingElements(namespaceResolver); if (xPathFragment != null && xPathFragment.isAttribute()) { marshalRecord.attribute(xPathFragment, namespaceResolver, fieldValue, schemaType); marshalRecord.closeStartGroupingElements(groupingFragment); } else { marshalRecord.closeStartGroupingElements(groupingFragment); marshalRecord.characters(schemaType, fieldValue, null, false); } return true; } @Override public ObjectReferenceMapping getMapping() { return xmlObjectReferenceMapping; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy