org.eclipse.persistence.internal.oxm.XMLVariableXPathMappingNodeValue Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eclipselink Show documentation
Show all versions of eclipselink Show documentation
EclipseLink build based upon Git transaction f2b9fc5
/*
* 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:
// Denise Smith - 2.5.1 - Initial Implementation
package org.eclipse.persistence.internal.oxm;
import java.util.List;
import javax.xml.namespace.QName;
import org.eclipse.persistence.core.mappings.CoreAttributeAccessor;
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.mappings.CompositeObjectMapping;
import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
import org.eclipse.persistence.internal.oxm.mappings.DirectMapping;
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.mappings.VariableXPathObjectMapping;
import org.eclipse.persistence.internal.oxm.record.MarshalContext;
import org.eclipse.persistence.internal.oxm.record.MarshalRecord;
import org.eclipse.persistence.internal.oxm.record.UnmarshalRecord;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
public abstract class XMLVariableXPathMappingNodeValue extends XMLRelationshipMappingNodeValue{
/**
* INTERNAL:
* @param xPathFragment
* @return
*/
@Override
public boolean isOwningNode(XPathFragment xPathFragment) {
return null == xPathFragment;
}
@Override
protected Descriptor findReferenceDescriptor(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord, Attributes atts, Mapping mapping, UnmarshalKeepAsElementPolicy policy) {
return (Descriptor)mapping.getReferenceDescriptor();
}
@Override
public void attribute(UnmarshalRecord unmarshalRecord, String namespaceURI, String localName, String value) {
Descriptor referenceDescriptor = (Descriptor) getMapping().getReferenceDescriptor();
ObjectBuilder treeObjectBuilder = (ObjectBuilder) referenceDescriptor.getObjectBuilder();
MappingNodeValue textMappingNodeValue = (MappingNodeValue) treeObjectBuilder.getRootXPathNode().getTextNode().getNodeValue();
Mapping textMapping = textMappingNodeValue.getMapping();
Object childObject = referenceDescriptor.getInstantiationPolicy().buildNewInstance();
if(textMapping.isAbstractDirectMapping()) {
DirectMapping xmlDirectMapping = (DirectMapping) textMappingNodeValue.getMapping();
Field xmlField = (Field) xmlDirectMapping.getField();
Object realValue = unmarshalRecord.getXMLReader().convertValueBasedOnSchemaType(xmlField, value, (ConversionManager) unmarshalRecord.getSession().getDatasourcePlatform().getConversionManager(), unmarshalRecord);
Object convertedValue = xmlDirectMapping.getAttributeValue(realValue, unmarshalRecord.getSession(), unmarshalRecord);
xmlDirectMapping.setAttributeValueInObject(childObject, convertedValue);
} else {
Object oldChildObject = unmarshalRecord.getCurrentObject();
CompositeObjectMapping nestedXMLCompositeObjectMapping = (CompositeObjectMapping) textMappingNodeValue.getMapping();
unmarshalRecord.setCurrentObject(childObject);
textMappingNodeValue.attribute(unmarshalRecord, namespaceURI, localName, value);
unmarshalRecord.setCurrentObject(oldChildObject);
}
setXPathInObject(namespaceURI, localName, childObject);
setOrAddAttributeValue(unmarshalRecord, childObject, null, null);
}
@Override
public boolean marshalSingleValue(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, Object value, CoreAbstractSession session, NamespaceResolver namespaceResolver, MarshalContext marshalContext) {
if (null == value) {
return false;
}
Object originalValue = value;
VariableXPathObjectMapping mapping = this.getMapping();
Descriptor descriptor = (Descriptor)mapping.getReferenceDescriptor();
if(descriptor.hasInheritance()){
Class objectValueClass = value.getClass();
if(!(objectValueClass == descriptor.getJavaClass())){
descriptor = (Descriptor) session.getDescriptor(objectValueClass);
}
}
Marshaller marshaller = marshalRecord.getMarshaller();
ObjectBuilder objectBuilder = (ObjectBuilder)descriptor.getObjectBuilder();
List extraNamespaces = objectBuilder.addExtraNamespacesToNamespaceResolver(descriptor, marshalRecord, session, true, true);
//Change to get the value from the object
String defaultRootElementString = descriptor.getDefaultRootElement();
marshalRecord.beforeContainmentMarshal(value);
XPathFragment rootFragment = mapping.getXPathFragmentForValue(value, marshalRecord.getNamespaceResolver(), marshalRecord.isNamespaceAware(), marshalRecord.getNamespaceSeparator());
XPathFragment groupingFragment = marshalRecord.openStartGroupingElements(namespaceResolver);
if(mapping.isAttribute()){
ObjectBuilder tob = (ObjectBuilder) mapping.getReferenceDescriptor().getObjectBuilder();
MappingNodeValue textMappingNodeValue = (MappingNodeValue) tob.getRootXPathNode().getTextNode().getMarshalNodeValue();
Mapping textMapping = textMappingNodeValue.getMapping();
if(textMapping.isAbstractDirectMapping()) {
DirectMapping xmlDirectMapping = (DirectMapping) textMapping;
Object fieldValue = xmlDirectMapping.getFieldValue(xmlDirectMapping.valueFromObject(value, xmlDirectMapping.getField(), session), session, marshalRecord);
QName schemaType = ((Field) xmlDirectMapping.getField()).getSchemaTypeForValue(fieldValue, session);
marshalRecord.attribute(rootFragment, namespaceResolver, fieldValue, schemaType);
//marshalRecord.closeStartGroupingElements(groupingFragment);
return true;
} else {
return textMappingNodeValue.marshalSingleValue(rootFragment, marshalRecord, value, textMapping.getAttributeValueFromObject(value), session, namespaceResolver, marshalContext);
}
}else{
marshalRecord.closeStartGroupingElements(groupingFragment);
getXPathNode().startElement(marshalRecord, rootFragment, object, session, marshalRecord.getNamespaceResolver(), objectBuilder, value);
writeExtraNamespaces(extraNamespaces, marshalRecord, session);
marshalRecord.addXsiTypeAndClassIndicatorIfRequired(descriptor, (Descriptor)mapping.getReferenceDescriptor(), (Field)mapping.getField(), originalValue, value, false, false);
objectBuilder.buildRow(marshalRecord, value, session, marshaller, null);
marshalRecord.afterContainmentMarshal(object, value);
marshalRecord.endElement(rootFragment, namespaceResolver);
marshalRecord.removeExtraNamespacesFromNamespaceResolver(extraNamespaces, session);
}
return true;
}
@Override
public void endElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord) {
UnmarshalRecord childRecord = unmarshalRecord.getChildRecord();
if(childRecord != null){
Object childObject = childRecord.getCurrentObject();
String localName = xPathFragment.getLocalName();
setXPathInObject(xPathFragment.getNamespaceURI(), localName, childObject);
childObject = getMapping().convertDataValueToObjectValue(childObject, unmarshalRecord.getSession(), unmarshalRecord.getUnmarshaller());
setOrAddAttributeValue(unmarshalRecord, childObject, xPathFragment, null);
unmarshalRecord.setChildRecord(null);
} else {
unmarshalRecord.resetStringBuffer();
}
}
@Override
public abstract VariableXPathObjectMapping getMapping();
public void setXPathInObject(String uri, String localName, Object childObject) {
CoreAttributeAccessor variableAttributeAccessor = this.getMapping().getVariableAttributeAccessor();
if(!variableAttributeAccessor.isWriteOnly()){
Object value = null;
if(getMapping().getVariableAttributeAccessor().getAttributeClass() == CoreClassConstants.QNAME){
if(uri != null && uri.length() > 0) {
value = new QName(uri, localName);
}else{
value = new QName( localName);
}
}else{
value = localName;
}
variableAttributeAccessor.setAttributeValueInObject(childObject, value);
}
}
@Override
public boolean startElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord, Attributes atts) {
try {
processChild(xPathFragment, unmarshalRecord, atts, (Descriptor) getMapping().getReferenceDescriptor(), getMapping());
} catch (SAXException e) {
throw XMLMarshalException.unmarshalException(e);
}
return true;
}
@Override
public boolean isMixedContentNodeValue() {
return true;
}
}