/******************************************************************************* * Copyright (c) 1998, 2015 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: * 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 */ public boolean isOwningNode(XPathFragment xPathFragment) { return null == xPathFragment; } protected Descriptor findReferenceDescriptor(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord, Attributes atts, Mapping mapping, UnmarshalKeepAsElementPolicy policy) { return (Descriptor)mapping.getReferenceDescriptor(); } 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); } 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 = (VariableXPathObjectMapping)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; } 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(); } } public abstract VariableXPathObjectMapping getMapping(); public void setXPathInObject(String uri, String localName, Object childObject) { CoreAttributeAccessor variableAttributeAccessor = ((VariableXPathObjectMapping)this.getMapping()).getVariableAttributeAccessor(); if(!variableAttributeAccessor.isWriteOnly()){ Object value = null; if(((VariableXPathObjectMapping)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); } } 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; } }