org.eclipse.persistence.internal.oxm.record.UnmarshalRecordImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.eclipse.persistence.core Show documentation
Show all versions of org.eclipse.persistence.core Show documentation
EclipseLink build based upon Git transaction ecdf3c32c4
/*
* 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
// Marcel Valovy - 2.6.0 - added case insensitive unmarshalling
package org.eclipse.persistence.internal.oxm.record;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.namespace.QName;
import org.eclipse.persistence.core.descriptors.CoreDescriptor;
import org.eclipse.persistence.core.descriptors.CoreDescriptorEventManager;
import org.eclipse.persistence.core.descriptors.CoreInheritancePolicy;
import org.eclipse.persistence.core.queries.CoreAttributeGroup;
import org.eclipse.persistence.descriptors.DescriptorEvent;
import org.eclipse.persistence.descriptors.DescriptorEventManager;
import org.eclipse.persistence.exceptions.EclipseLinkException;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.core.helper.CoreField;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractRecord;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.identitymaps.CacheId;
import org.eclipse.persistence.internal.oxm.Constants;
import org.eclipse.persistence.internal.oxm.ContainerValue;
import org.eclipse.persistence.internal.oxm.ConversionManager;
import org.eclipse.persistence.internal.oxm.IDResolver;
import org.eclipse.persistence.internal.oxm.MappingNodeValue;
import org.eclipse.persistence.internal.oxm.NamespaceResolver;
import org.eclipse.persistence.internal.oxm.NodeValue;
import org.eclipse.persistence.internal.oxm.NullCapableValue;
import org.eclipse.persistence.internal.oxm.ObjectBuilder;
import org.eclipse.persistence.internal.oxm.Reference;
import org.eclipse.persistence.internal.oxm.ReferenceResolver;
import org.eclipse.persistence.internal.oxm.Root;
import org.eclipse.persistence.internal.oxm.SAXFragmentBuilder;
import org.eclipse.persistence.internal.oxm.StrBuffer;
import org.eclipse.persistence.internal.oxm.Unmarshaller;
import org.eclipse.persistence.internal.oxm.XPathFragment;
import org.eclipse.persistence.internal.oxm.XPathNode;
import org.eclipse.persistence.internal.oxm.XPathPredicate;
import org.eclipse.persistence.internal.oxm.XPathQName;
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.TransformationMapping;
import org.eclipse.persistence.internal.oxm.record.namespaces.StackUnmarshalNamespaceResolver;
import org.eclipse.persistence.internal.oxm.record.namespaces.UnmarshalNamespaceResolver;
import org.eclipse.persistence.internal.oxm.unmapped.UnmappedContentHandler;
import org.eclipse.persistence.internal.security.PrivilegedNewInstanceFromClass;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.sessions.coordination.CommandProcessor;
import org.w3c.dom.Document;
import org.xml.sax.Attributes;
import org.xml.sax.ErrorHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.ext.Locator2;
import org.xml.sax.ext.Locator2Impl;
/**
* Purpose:Provide an implementation of ContentHandler that is used by TopLink OXM to
* build mapped Java Objects from SAX events.
*
Responsibilities:
* - Implement the ContentHandler and LexicalHandler interfaces
* - Make calls into the appropriate NodeValues based on the incoming SAXEvents
* - Make callbacks into XMLReader for newObject events
* - Maintain a map of Collections to be populated for collection mappings.
*
* @see org.eclipse.persistence.internal.oxm.XPathNode
* @see org.eclipse.persistence.internal.oxm.NodeValue
* @see org.eclipse.persistence.internal.oxm.TreeObjectBuilder
* @author bdoughan
*
*/
public class UnmarshalRecordImpl extends CoreAbstractRecord implements UnmarshalRecord {
protected XMLReader xmlReader;
private ObjectBuilder treeObjectBuilder;
private XPathFragment xPathFragment;
private XPathNode xPathNode;
/**
* Used to increase performance. We are trying to predict next mapping to unmarshal.
* It can reduce the number of map lookups.
*/
private XPathNode predictedNextXPathNode;
private int levelIndex;
private UnmarshalRecord childRecord;
protected UnmarshalRecord parentRecord;
private TRANSFORMATION_RECORD transformationRecord;
private List selfRecords;
private Map indexMap;
private List nullCapableValues;
private Object[] containerInstances;
private List defaultEmptyContainerValues;
private List populatedContainerValues;
private boolean isBufferCDATA;
private Attributes attributes;
private QName typeQName;
protected String rootElementLocalName;
protected String rootElementName;
protected String rootElementNamespaceUri;
private SAXFragmentBuilder fragmentBuilder;
private Map prefixesForFragment;
private String encoding;
private String version;
private String schemaLocation;
private String noNamespaceSchemaLocation;
private boolean isSelfRecord;
private UnmarshalContext unmarshalContext;
private UnmarshalNamespaceResolver unmarshalNamespaceResolver;
private boolean isXsiNil;
private boolean xpathNodeIsMixedContent = false;
private int unmappedLevel = -1;
private ReferenceResolver referenceResolver;
protected Unmarshaller unmarshaller;
protected Object currentObject;
protected CoreAbstractSession session;
protected boolean namespaceAware;
private XPathQName leafElementType;
private NamespaceResolver namespaceResolver;
private CoreAttributeGroup unmarshalAttributeGroup;
// The "snapshot" location of this object, for @XmlLocation
private Locator xmlLocation;
protected XPathFragment textWrapperFragment;
private ConversionManager conversionManager;
protected UnmarshalRecordImpl() {
}
public UnmarshalRecordImpl(ObjectBuilder objectBuilder) {
this(objectBuilder, new ReferenceResolver());
}
private UnmarshalRecordImpl(ObjectBuilder objectBuilder, ReferenceResolver referenceResolver) {
super();
this.referenceResolver = referenceResolver;
this.xPathFragment = new XPathFragment();
xPathFragment.setNamespaceAware(isNamespaceAware());
this.setUnmarshalAttributeGroup(DEFAULT_ATTRIBUTE_GROUP);
initialize(objectBuilder);
}
public UnmarshalRecord initialize(ObjectBuilder treeObjectBuilder) {
this.isBufferCDATA = false;
this.treeObjectBuilder = treeObjectBuilder;
if (null != treeObjectBuilder) {
this.xPathNode = treeObjectBuilder.getRootXPathNode();
if (null != treeObjectBuilder.getNullCapableValues()) {
this.nullCapableValues = new ArrayList(treeObjectBuilder.getNullCapableValues());
}
if (null != treeObjectBuilder.getDefaultEmptyContainerValues()){
this.defaultEmptyContainerValues = new ArrayList(treeObjectBuilder.getDefaultEmptyContainerValues());
}
}
isSelfRecord = false;
return this;
}
private void reset() {
xPathNode = null;
childRecord = null;
transformationRecord = null;
if(null != selfRecords) {
selfRecords.clear();
}
if(null != indexMap) {
indexMap.clear();
}
nullCapableValues = null;
isBufferCDATA = false;
attributes = null;
typeQName = null;
isSelfRecord = false;
unmarshalContext = null;
isXsiNil = false;
unmappedLevel = -1;
predictedNextXPathNode = null;
}
@Override
public String getLocalName() {
return rootElementLocalName;
}
public void setLocalName(String localName) {
rootElementLocalName = localName;
}
public String getNamespaceURI() {
throw XMLMarshalException.operationNotSupported("getNamespaceURI");
}
public void clear() {
throw XMLMarshalException.operationNotSupported("clear");
}
public Document getDocument() {
throw XMLMarshalException.operationNotSupported("getDocument");
}
public String transformToXML() {
throw XMLMarshalException.operationNotSupported("transformToXML");
}
public XMLReader getXMLReader() {
return this.xmlReader;
}
public void setXMLReader(XMLReader xmlReader) {
this.xmlReader = xmlReader;
namespaceAware = xmlReader.isNamespaceAware();
if(xPathFragment != null){
xPathFragment.setNamespaceAware(isNamespaceAware());
}
}
public UnmarshalRecord getChildRecord() {
return this.childRecord;
}
public void setChildRecord(UnmarshalRecord childRecord) {
this.childRecord = childRecord;
if (null != childRecord) {
childRecord.setParentRecord(this);
}
}
public UnmarshalRecord getParentRecord() {
return this.parentRecord;
}
/**
* INTERNAL:
* The ReferenceResolver that is leveraged by key based mappings.
* @since EclipseLink 2.5.0
*/
public ReferenceResolver getReferenceResolver() {
if(null == referenceResolver) {
referenceResolver = new ReferenceResolver();
}
return referenceResolver;
}
/**
* INTERNAL:
* Set the ReferenceResolver that will be leveraged by key based mappings.
* @since EclipseLink 2.5.0
*/
public void setReferenceResolver(ReferenceResolver referenceResolver) {
this.referenceResolver = referenceResolver;
}
/**
* Return the root element's prefix qualified name
*/
public String getRootElementName() {
return rootElementName;
}
public void setRootElementName(String qName) {
this.rootElementName = qName;
}
/**
* Return the root element's namespace URI
*/
public String getRootElementNamespaceUri() {
return rootElementNamespaceUri;
}
public void setRootElementNamespaceUri(String uri) {
this.rootElementNamespaceUri = uri;
}
public void setParentRecord(UnmarshalRecord parentRecord) {
this.parentRecord = parentRecord;
}
@Override
public TRANSFORMATION_RECORD getTransformationRecord() {
return this.transformationRecord;
}
@Override
public void setTransformationRecord(TRANSFORMATION_RECORD transformationRecord) {
this.transformationRecord = transformationRecord;
}
public UnmarshalNamespaceResolver getUnmarshalNamespaceResolver() {
if(null == unmarshalNamespaceResolver) {
this.unmarshalNamespaceResolver = new StackUnmarshalNamespaceResolver();
}
return this.unmarshalNamespaceResolver;
}
public void setUnmarshalNamespaceResolver(UnmarshalNamespaceResolver anUnmarshalNamespaceResolver) {
this.unmarshalNamespaceResolver = anUnmarshalNamespaceResolver;
}
public List getNullCapableValues() {
if (null == nullCapableValues) {
this.nullCapableValues = new ArrayList();
}
return this.nullCapableValues;
}
public void removeNullCapableValue(NullCapableValue nullCapableValue) {
if(null != nullCapableValues) {
nullCapableValues.remove(nullCapableValue);
}
}
public Object getContainerInstance(ContainerValue c) {
return getContainerInstance(c, true);
}
public Object getContainerInstance(ContainerValue c, boolean createContainerIfNecessary) {
Object containerInstance = containerInstances[c.getIndex()];
if (containerInstance == null) {
Mapping mapping = c.getMapping();
//don't attempt to do a get on a readOnly property.
if(c.getReuseContainer() && !(mapping.isReadOnly())) {
containerInstance = mapping.getAttributeValueFromObject(currentObject);
}
if(null == containerInstance && createContainerIfNecessary) {
containerInstance = c.getContainerInstance();
}
containerInstances[c.getIndex()] = containerInstance;
populatedContainerValues.add(c);
if(defaultEmptyContainerValues != null){
defaultEmptyContainerValues.remove(c);
}
}
return containerInstance;
}
public void setContainerInstance(int index, Object containerInstance) {
containerInstances[index] = containerInstance;
}
/**
* PUBLIC:
* Gets the encoding for this document. Only set on the root-level UnmarshalRecord
* @return a String representing the encoding for this doc
*/
public String getEncoding() {
return encoding;
}
/**
* INTERNAL:
*/
public void setEncoding(String enc) {
this.encoding = enc;
}
/**
* PUBLIC:
* Gets the XML Version for this document. Only set on the root-level
* UnmarshalRecord, if supported by the parser.
*/
public String getVersion() {
return version;
}
/**
* INTERNAL:
*/
public void setVersion(String version) {
this.version = version;
}
public String getSchemaLocation() {
return schemaLocation;
}
public void setSchemaLocation(String schemaLocation) {
this.schemaLocation = schemaLocation;
}
public String getNoNamespaceSchemaLocation() {
return noNamespaceSchemaLocation;
}
public void setNoNamespaceSchemaLocation(String location) {
this.noNamespaceSchemaLocation = location;
}
protected StrBuffer getStringBuffer() {
return unmarshaller.getStringBuffer();
}
public CharSequence getCharacters() {
return unmarshaller.getStringBuffer();
}
public Attributes getAttributes() {
return this.attributes;
}
public void setAttributes(Attributes attributes) {
this.attributes = attributes;
}
public QName getTypeQName() {
return this.typeQName;
}
public void setTypeQName(QName typeQName) {
this.typeQName = typeQName;
}
public void setDocumentLocator(Locator locator) {
if(xmlReader != null){
xmlReader.setLocator(locator);
if (null == rootElementName && null == rootElementLocalName && parentRecord == null && locator instanceof Locator2){
Locator2 loc = (Locator2)locator;
this.setEncoding(loc.getEncoding());
this.setVersion(loc.getXMLVersion());
}
}
}
public Locator getDocumentLocator() {
if(xmlReader != null){
return xmlReader.getLocator();
}
return null;
}
public Object get(CoreField key) {
Field xmlField = this.convertToXMLField(key);
XPathFragment lastFragment = xmlField.getLastXPathFragment();
String namespaceURI = lastFragment.getNamespaceURI();
if(namespaceURI == null){
NamespaceResolver namespaceResolver = xmlField.getNamespaceResolver();
namespaceURI = Constants.EMPTY_STRING;
if (null != namespaceResolver && !(lastFragment.isAttribute() && lastFragment.getPrefix() == null)) {
namespaceURI = namespaceResolver.resolveNamespacePrefix(lastFragment.getPrefix());
if (null == namespaceURI) {
namespaceURI = Constants.EMPTY_STRING;
}
}
}
if(isNamespaceAware()){
return attributes.getValue(namespaceURI, lastFragment.getLocalName());
}
return attributes.getValue(lastFragment.getLocalName());
}
public XPathNode getXPathNode() {
return xPathNode;
}
public Descriptor getDescriptor() {
return (Descriptor) treeObjectBuilder.getDescriptor();
}
public UnmarshalContext getUnmarshalContext() {
return unmarshalContext;
}
public void setUnmarshalContext(UnmarshalContext unmarshalContext) {
this.unmarshalContext = unmarshalContext;
}
public boolean isNil() {
return this.isXsiNil;
}
public void setNil(boolean nil) {
this.isXsiNil = nil;
}
public void startDocument() throws SAXException {
if (unmarshaller.getIDResolver() != null && parentRecord == null) {
unmarshaller.getIDResolver().startDocument(unmarshaller.getErrorHandler());
}
}
private void initializeRecord(Attributes attrs) throws SAXException{
this.setAttributes(attrs);
Descriptor xmlDescriptor = (Descriptor) treeObjectBuilder.getDescriptor();
if(!xmlDescriptor.hasInheritance() || xmlDescriptor.getInheritancePolicy().getClassIndicatorField() == null){
initialize((ObjectBuilder)xmlDescriptor.getObjectBuilder());
initializeRecord((Mapping)null);
return;
}
CoreInheritancePolicy inheritancePolicy = xmlDescriptor.getInheritancePolicy();
Class classValue = treeObjectBuilder.classFromRow(this, session);
if (classValue == null) {
// no xsi:type attribute - look for type indicator on the default root element
QName leafElementType = xmlDescriptor.getDefaultRootElementType();
// if we have a user-set type, try to get the class from the inheritance policy
if (leafElementType != null) {
XPathQName xpathQName = new XPathQName(leafElementType, isNamespaceAware());
Object indicator = inheritancePolicy.getClassIndicatorMapping().get(xpathQName);
if(indicator != null) {
classValue = (Class)indicator;
}
}
}
if (classValue != null) {
xmlDescriptor = (Descriptor)session.getDescriptor(classValue);
}
initialize((ObjectBuilder)xmlDescriptor.getObjectBuilder());
initializeRecord((Mapping)null);
}
public void initializeRecord(Mapping selfRecordMapping) throws SAXException {
try {
Descriptor xmlDescriptor = (Descriptor) treeObjectBuilder.getDescriptor();
if(xmlDescriptor.isSequencedObject()) {
unmarshalContext = new SequencedUnmarshalContext();
} else {
unmarshalContext = ObjectUnmarshalContext.getInstance();
}
currentObject = this.xmlReader.getCurrentObject(session, selfRecordMapping);
if (currentObject == null) {
currentObject = treeObjectBuilder.buildNewInstance();
}
if (xmlDescriptor.getLocationAccessor() != null && xmlReader.getLocator() != null){
// Check to see if this Descriptor isLocationAware
// Store the snapshot of the current documentLocator
xmlLocation = new Locator2Impl(xmlReader.getLocator());
}
Object parentRecordCurrentObject = null;
if (null != this.parentRecord) {
parentRecordCurrentObject = parentRecord.getCurrentObject();
}
Unmarshaller.Listener xmlUnmarshalListener = unmarshaller.getUnmarshalListener();
if (null != xmlUnmarshalListener) {
if (null == this.parentRecord) {
xmlUnmarshalListener.beforeUnmarshal(currentObject, null);
} else {
xmlUnmarshalListener.beforeUnmarshal(currentObject, parentRecordCurrentObject);
}
}
if (null == parentRecord) {
this.xmlReader.newObjectEvent(currentObject, null, selfRecordMapping);
} else {
this.xmlReader.newObjectEvent(currentObject, parentRecordCurrentObject, selfRecordMapping);
}
List containerValues = treeObjectBuilder.getContainerValues();
if (null != containerValues) {
int containerSize = containerValues.size();
containerInstances = new Object[containerSize];
populatedContainerValues = new ArrayList(containerSize);
}
if (null != xPathNode.getSelfChildren()) {
int selfChildrenSize = xPathNode.getSelfChildren().size();
selfRecords = new ArrayList(selfChildrenSize);
for (int x = 0; x < selfChildrenSize; x++) {
NodeValue nv = xPathNode.getSelfChildren().get(x).getNodeValue();
if (null != nv) {
selfRecords.add(nv.buildSelfRecord(this, attributes));
}
}
}
} catch (EclipseLinkException e) {
if (null == xmlReader.getErrorHandler()) {
throw e;
} else {
SAXParseException saxParseException = new SAXParseException(null, getDocumentLocator(), e);
xmlReader.getErrorHandler().error(saxParseException);
}
}
}
public void endDocument() throws SAXException {
if (unmarshaller.getIDResolver() != null && parentRecord == null) {
unmarshaller.getIDResolver().endDocument();
}
if (null != selfRecords) {
for (int x = 0, selfRecordsSize = selfRecords.size(); x < selfRecordsSize; x++) {
UnmarshalRecord selfRecord = selfRecords.get(x);
if(selfRecord != null){
selfRecord.endDocument();
}
}
}
if (null != xPathNode.getSelfChildren()) {
int selfChildrenSize = xPathNode.getSelfChildren().size();
for (int x = 0; x < selfChildrenSize; x++) {
XPathNode selfNode = xPathNode.getSelfChildren().get(x);
if (null != selfNode.getNodeValue()) {
selfNode.getNodeValue().endSelfNodeValue(this, selfRecords.get(x), attributes);
}
}
}
CoreDescriptor xmlDescriptor = (CoreDescriptor) treeObjectBuilder.getDescriptor();
try {
// PROCESS COLLECTION MAPPINGS
//All populated containerValues need to be set on the object
if(null != populatedContainerValues){
for (int populatedCVSize=populatedContainerValues.size(), i = populatedCVSize-1; i>=0; i--) {
ContainerValue cv = ((ContainerValue) populatedContainerValues.get(i));
cv.setContainerInstance(currentObject, getContainerInstance(cv, cv.isDefaultEmptyContainer()));
}
}
//Additionally if any containerValues are defaultEmptyContainerValues they need to be set to a new empty container
if(null != defaultEmptyContainerValues){
for (int defaultEmptyCVSize=defaultEmptyContainerValues.size(),i = defaultEmptyCVSize-1; i>=0; i--) {
ContainerValue cv = ((ContainerValue) defaultEmptyContainerValues.get(i));
cv.setContainerInstance(currentObject, getContainerInstance(cv, cv.isDefaultEmptyContainer()));
}
}
// PROCESS NULL CAPABLE VALUES
// This must be done because the node may not have existed to
// trigger the mapping.
if(null != nullCapableValues) {
for (int x = 0, nullValuesSize = nullCapableValues.size(); x < nullValuesSize; x++) {
nullCapableValues.get(x).setNullValue(currentObject, session);
}
}
// PROCESS TRANSFORMATION MAPPINGS
List transformationMappings = treeObjectBuilder.getTransformationMappings();
if (null != transformationMappings) {
for (int x = 0, transformationMappingsSize = transformationMappings.size(); x < transformationMappingsSize; x++) {
TransformationMapping transformationMapping = transformationMappings.get(x);
transformationMapping.readFromRowIntoObject((XMLRecord) transformationRecord, currentObject, session, true);
}
}
Unmarshaller.Listener listener = unmarshaller.getUnmarshalListener();
if (listener != null) {
if (this.parentRecord != null) {
listener.afterUnmarshal(currentObject, parentRecord.getCurrentObject());
} else {
listener.afterUnmarshal(currentObject, null);
}
}
// HANDLE POST BUILD EVENTS
if(xmlDescriptor.hasEventManager()) {
CoreDescriptorEventManager eventManager = xmlDescriptor.getEventManager();
if (null != eventManager && eventManager.hasAnyEventListeners()) {
DescriptorEvent event = new DescriptorEvent(currentObject);
event.setSession((AbstractSession) session);
event.setRecord(null); //this);
event.setEventCode(DescriptorEventManager.PostBuildEvent);
eventManager.executeEvent(event);
}
}
} catch (EclipseLinkException e) {
if (null == xmlReader.getErrorHandler()) {
throw e;
} else {
SAXParseException saxParseException = new SAXParseException(null, getDocumentLocator(), e);
xmlReader.getErrorHandler().error(saxParseException);
}
}
// if the object has any primary key fields set, add it to the cache
if(null != referenceResolver) {
if(null != xmlDescriptor) {
List primaryKeyFields = xmlDescriptor.getPrimaryKeyFields();
if(null != primaryKeyFields) {
int primaryKeyFieldsSize = primaryKeyFields.size();
if (primaryKeyFieldsSize > 0) {
CacheId pk = (CacheId) treeObjectBuilder.extractPrimaryKeyFromObject(currentObject, session);
for (int x=0; x 1) {
Map idWrapper = new HashMap();
for (int x = 0; x < primaryKeyFieldsSize; x++) {
String idName = (String) xmlDescriptor.getPrimaryKeyFieldNames().get(x);
Object idValue = pk.getPrimaryKey()[x];
idWrapper.put(idName, idValue);
}
unmarshaller.getIDResolver().bind(idWrapper, currentObject);
} else {
unmarshaller.getIDResolver().bind(pk.getPrimaryKey()[0], currentObject);
}
} catch (SAXException e) {
throw XMLMarshalException.unmarshalException(e);
}
}
}
}
}
}
if(null != parentRecord) {
reset();
}
// Set XML Location if applicable
if (xmlLocation != null && ((Descriptor) xmlDescriptor).getLocationAccessor() != null) {
((Descriptor) xmlDescriptor).getLocationAccessor().setAttributeValueInObject(getCurrentObject(), xmlLocation);
}
}
public void startPrefixMapping(String prefix, String uri) throws SAXException {
getUnmarshalNamespaceResolver().push(prefix, uri);
getPrefixesForFragment().put(prefix, uri);
}
public void endPrefixMapping(String prefix) throws SAXException {
getUnmarshalNamespaceResolver().pop(prefix);
}
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
if (currentObject == null) {
initializeRecord(atts);
}
XPathFragment xPathNodeXPathFragment = xPathNode.getXPathFragment();
if((null != xPathNodeXPathFragment && xPathNodeXPathFragment.nameIsText()) || xpathNodeIsMixedContent) {
xpathNodeIsMixedContent = false;
NodeValue xPathNodeUnmarshalNodeValue = xPathNode.getUnmarshalNodeValue();
if (null != xPathNodeUnmarshalNodeValue) {
boolean isIncludedInAttributeGroup = true;
if(xPathNodeUnmarshalNodeValue.isMappingNodeValue()) {
Mapping mapping = ((MappingNodeValue)xPathNodeUnmarshalNodeValue).getMapping();
isIncludedInAttributeGroup = this.unmarshalAttributeGroup.containsAttributeInternal(mapping.getAttributeName());
}
if(isIncludedInAttributeGroup) {
xPathNodeUnmarshalNodeValue.endElement(xPathFragment, this);
if (xPathNode.getParent() != null) {
xPathNode = xPathNode.getParent();
}
}
}
}
// set the root element's local name and namespace prefix and look for
// schema locations etc.
if (null == rootElementName && null == rootElementLocalName && parentRecord == null){
rootElementLocalName = localName;
rootElementName = qName;
rootElementNamespaceUri = namespaceURI;
schemaLocation = atts.getValue(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, Constants.SCHEMA_LOCATION);
noNamespaceSchemaLocation = atts.getValue(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, Constants.NO_NS_SCHEMA_LOCATION);
}
try {
if (null != selfRecords) {
for (int x = 0, selfRecordsSize = selfRecords.size(); x < selfRecordsSize; x++) {
UnmarshalRecord selfRecord = selfRecords.get(x);
if(selfRecord == null){
getFragmentBuilder().startElement(namespaceURI, localName, qName, atts);
}else{
selfRecord.startElement(namespaceURI, localName, qName, atts);
}
}
}
if(unmappedLevel != -1 && unmappedLevel <= levelIndex) {
levelIndex++;
return;
}
XPathNode node = null;
if (null != predictedNextXPathNode) {
XPathFragment xpf = predictedNextXPathNode.getXPathFragment();
if (null != xpf && xPathNode == predictedNextXPathNode.getParent() && (localName == xpf.getLocalName() || localName.equals(xpf.getLocalName())) && (namespaceURI == xpf.getNamespaceURI() || namespaceURI.equals(xpf.getNamespaceURI())) && null == xpf.getPredicate() && !xpf.containsIndex()) {
updateXPathFragment(qName, localName, namespaceURI);
node = predictedNextXPathNode;
}
}
if (null == node) {
node = getNonAttributeXPathNode(namespaceURI, localName, qName, atts);
}
if (null == node) {
NodeValue parentNodeValue = xPathNode.getUnmarshalNodeValue();
if ((null == xPathNode.getXPathFragment()) && (parentNodeValue != null)) {
XPathFragment parentFragment = new XPathFragment();
parentFragment.setNamespaceAware(isNamespaceAware());
if(namespaceURI != null && namespaceURI.length() == 0){
parentFragment.setLocalName(qName);
parentFragment.setNamespaceURI(null);
} else {
parentFragment.setLocalName(localName);
parentFragment.setNamespaceURI(namespaceURI);
}
if (parentNodeValue.startElement(parentFragment, this, atts)) {
levelIndex++;
} else {
// UNMAPPED CONTENT
startUnmappedElement(namespaceURI, localName, qName, atts);
return;
}
} else {
// UNMAPPED CONTENT
levelIndex++;
startUnmappedElement(namespaceURI, localName, qName, atts);
return;
}
} else {
xPathNode = node;
unmarshalContext.startElement(this);
levelIndex++;
if(xmlReader.getMediaType().isApplicationXML()) {
String xsiNilValue = atts.getValue(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, Constants.SCHEMA_NIL_ATTRIBUTE);
if (xsiNilValue != null) {
setNil(xsiNilValue.equals(Constants.BOOLEAN_STRING_TRUE) || xsiNilValue.equals("1"));
}
}
if(node.getNullCapableValue() != null){
getNullCapableValues().add(node.getNullCapableValue());
}
NodeValue nodeValue = node.getUnmarshalNodeValue();
if (null != nodeValue) {
boolean isIncludedInAttributeGroup = true;
if(nodeValue.isMappingNodeValue()) {
Mapping mapping = ((MappingNodeValue)nodeValue).getMapping();
isIncludedInAttributeGroup = this.unmarshalAttributeGroup.containsAttributeInternal(mapping.getAttributeName());
}
if (!isIncludedInAttributeGroup || !nodeValue.startElement(xPathFragment, this, atts)) {
// UNMAPPED CONTENT
startUnmappedElement(namespaceURI, localName, qName, atts);
return;
}
}
//Handle Attributes
if(xPathNode.getAttributeChildren() != null || xPathNode.getAnyAttributeNodeValue() != null || selfRecords != null) {
for (int i = 0, size=atts.getLength(); i < size; i++) {
String attNamespace = atts.getURI(i);
String attLocalName = atts.getLocalName(i);
String value = atts.getValue(i);
NodeValue attributeNodeValue = null;
// Some parsers don't set the URI/local name for namespace
// attributes
if ((attLocalName == null) || (attLocalName.length() == 0)) {
String qname = atts.getQName(i);
if (qname != null) {
int qnameLength = qname.length();
if (qnameLength > 0) {
int idx = qname.indexOf(Constants.COLON);
if (idx > 0) {
attLocalName = qname.substring(idx + 1, qnameLength);
String attPrefix = qname.substring(0, idx);
if (attPrefix.equals(javax.xml.XMLConstants.XMLNS_ATTRIBUTE)) {
attNamespace = javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
}
} else {
attLocalName = qname;
if (attLocalName.equals(javax.xml.XMLConstants.XMLNS_ATTRIBUTE)) {
attNamespace = javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
}
}
}
}
}
//Look for any Self-Mapping nodes that may want this attribute.
if (this.selfRecords != null) {
for (int j = 0; j < selfRecords.size(); j++) {
UnmarshalRecord nestedRecord = selfRecords.get(j);
if(nestedRecord != null){
attributeNodeValue = nestedRecord.getAttributeChildNodeValue(attNamespace, attLocalName);
if (attributeNodeValue != null) {
attributeNodeValue.attribute(nestedRecord, attNamespace, attLocalName, value);
}
}
}
}
if (attributeNodeValue == null) {
attributeNodeValue = this.getAttributeChildNodeValue(attNamespace, attLocalName);
try {
if (attributeNodeValue != null) {
if(attributeNodeValue.isMappingNodeValue()) {
Mapping mapping = ((MappingNodeValue)attributeNodeValue).getMapping();
if(!unmarshalAttributeGroup.containsAttributeInternal(mapping.getAttributeName())) {
continue;
}
}
attributeNodeValue.attribute(this, attNamespace, attLocalName, value);
} else {
if (xPathNode.getAnyAttributeNodeValue() != null) {
xPathNode.getAnyAttributeNodeValue().attribute(this, attNamespace, attLocalName, value);
}
}
} catch(EclipseLinkException e) {
if ((null == xmlReader) || (null == xmlReader.getErrorHandler())) {
throw e;
} else {
SAXParseException saxParseException = new SAXParseException(e.getLocalizedMessage(), getDocumentLocator(), e);
xmlReader.getErrorHandler().warning(saxParseException);
}
}
}
}
}
}
if(prefixesForFragment != null){
this.prefixesForFragment.clear();
}
} catch (EclipseLinkException e) {
if ((null == xmlReader) || (null == xmlReader.getErrorHandler())) {
throw e;
} else {
SAXParseException saxParseException = new SAXParseException(e.getLocalizedMessage(), getDocumentLocator(), e);
xmlReader.getErrorHandler().error(saxParseException);
}
}
}
private void updateXPathFragment(String qName, String localName, String namespaceURI) {
if (namespaceURI != null && namespaceURI.length() == 0) {
xPathFragment.setLocalName(qName);
xPathFragment.setNamespaceURI(null);
} else {
xPathFragment.setLocalName(localName);
xPathFragment.setNamespaceURI(namespaceURI);
}
}
public void startUnmappedElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
if(xmlReader.getMediaType().isApplicationXML() && null == selfRecords && !isSelfRecord) {
ErrorHandler errorHandler = xmlReader.getErrorHandler();
// Bug 452584 - check if a warning exception should be generated when an unmapped element is encountered
if(null != errorHandler && unmarshaller.shouldWarnOnUnmappedElement()) {
StringBuilder messageBuilder = new StringBuilder("unexpected element (uri:\"");
if(null != namespaceURI) {
messageBuilder.append(namespaceURI);
}
messageBuilder.append("\", local:\"");
messageBuilder.append(localName);
messageBuilder.append("\"). Expected elements are ");
List nonAttributeChildren = xPathNode.getNonAttributeChildren();
if(nonAttributeChildren == null || nonAttributeChildren.size() == 0) {
messageBuilder.append("(none)");
} else {
for(int x=0, size=nonAttributeChildren.size(); x');
if(x 0) {
setNil(false);
}
if ((0 == levelIndex) && (null !=parentRecord) && !isSelfRecord()) {
endDocument();
// don't endElement on, or pass control to, a 'self' parent
UnmarshalRecord pRec = parentRecord;
while (pRec.isSelfRecord()) {
pRec = pRec.getParentRecord();
}
pRec.endElement(namespaceURI, localName, qName);
xmlReader.setContentHandler(pRec);
xmlReader.setLexicalHandler(pRec);
}
} catch (EclipseLinkException e) {
if ((null == xmlReader) || (null == xmlReader.getErrorHandler())) {
throw e;
} else {
Locator locator = xmlReader.getLocator();
SAXParseException saxParseException = new SAXParseException(null, getDocumentLocator(), e);
xmlReader.getErrorHandler().warning(saxParseException);
}
}
}
public void endUnmappedElement(String namespaceURI, String localName, String qName) throws SAXException {
typeQName = null;
levelIndex--;
if ((0 == levelIndex) && (null != parentRecord) && !isSelfRecord()) {
endDocument();
// don't endElement on, or pass control to, a 'self' parent
UnmarshalRecord pRec = parentRecord;
while (pRec.isSelfRecord()) {
pRec = pRec.getParentRecord();
}
pRec.endElement(namespaceURI, localName, qName);
xmlReader.setContentHandler(pRec);
xmlReader.setLexicalHandler(pRec);
}
setNil(false); // null unmapped element processed. We have to reset nil status
}
public void characters(char[] ch, int start, int length) throws SAXException {
if(currentObject == null){
return;
}
try {
int strBufferInitialLength = -1;
if (null != selfRecords) {
strBufferInitialLength = getStringBuffer().length();
for (int x = 0, selfRecordsSize = selfRecords.size(); x < selfRecordsSize; x++) {
UnmarshalRecord selfRecord = selfRecords.get(x);
if(selfRecord != null){
selfRecord.characters(ch, start, length);
} else {
getFragmentBuilder().characters(ch, start, length);
}
}
}
if(-1 != unmappedLevel && unmappedLevel <= levelIndex) {
return;
}
XPathNode textNode = xPathNode.getTextNode();
if (null == textNode) {
textNode = xPathNode.getAnyNode();
if (textNode != null) {
xpathNodeIsMixedContent = true;
this.xPathFragment.setLocalName(null);
this.xPathFragment.setNamespaceURI(null);
if (0 == length) {
return;
}
}
}
if (null != textNode) {
if(textNode.getUnmarshalNodeValue().isMixedContentNodeValue()) {
String tmpString = new String(ch, start, length);
if (!textNode.isWhitespaceAware() && tmpString.trim().length() == 0) {
return;
}
}
xPathNode = textNode;
unmarshalContext.characters(this);
}
NodeValue unmarshalNodeValue = xPathNode.getUnmarshalNodeValue();
if (null != unmarshalNodeValue && !unmarshalNodeValue.isWrapperNodeValue()) {
if(strBufferInitialLength == -1) {
getStringBuffer().append(ch, start, length);
} else {
StrBuffer strBuffer = getStringBuffer();
if(strBufferInitialLength == strBuffer.length()) {
strBuffer.append(ch, start, length);
}
}
}
} catch (EclipseLinkException e) {
if (null == xmlReader.getErrorHandler()) {
throw e;
} else {
SAXParseException saxParseException = new SAXParseException(null, getDocumentLocator(), e);
xmlReader.getErrorHandler().error(saxParseException);
}
}
}
public void characters(CharSequence characters) throws SAXException {
if(null != characters) {
String string = characters.toString();
characters(string.toCharArray(), 0, string.length());
}
}
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
}
public void processingInstruction(String target, String data) throws SAXException {
}
public void skippedEntity(String name) throws SAXException {
}
/**
* INTERNAL:
*/
public XPathNode getNonAttributeXPathNode(String namespaceURI, String localName, String qName, Attributes attributes) {
if (0 == levelIndex) {
return xPathNode;
}
updateXPathFragment(qName, localName, namespaceURI);
Map nonAttributeChildrenMap = xPathNode.getNonAttributeChildrenMap();
if (null != nonAttributeChildrenMap) {
XPathNode resultNode;
if (unmarshaller.isCaseInsensitive()){
resultNode = getNodeFromLookupTable(nonAttributeChildrenMap, false);
} else {
resultNode = nonAttributeChildrenMap.get(xPathFragment);
}
XPathNode nonPredicateNode = null;
if(resultNode != null && resultNode.hasPredicateSiblings()) {
nonPredicateNode = resultNode;
resultNode = null;
}
if (null == resultNode) {
// POSITIONAL MAPPING
int newIndex;
if (null == this.indexMap) {
this.indexMap = new HashMap();
newIndex = 1;
} else {
Integer oldIndex = indexMap.get(xPathFragment);
if (null == oldIndex) {
newIndex = 1;
} else {
newIndex = oldIndex.intValue() + 1;
}
}
indexMap.put(xPathFragment, newIndex);
XPathFragment predicateFragment = new XPathFragment();
predicateFragment.setNamespaceAware(isNamespaceAware());
predicateFragment.setNamespaceURI(xPathFragment.getNamespaceURI());
predicateFragment.setLocalName(xPathFragment.getLocalName());
predicateFragment.setIndexValue(newIndex);
resultNode = nonAttributeChildrenMap.get(predicateFragment);
if (null == resultNode) {
predicateFragment.setIndexValue(-1);
if(attributes != null){
for(int x = 0, length = attributes.getLength(); x attributeChildrenMap = xPathNode.getAttributeChildrenMap();
if (attributeChildrenMap != null) {
XPathNode resultNode;
xPathFragment.setLocalName(localName);
xPathFragment.setNamespaceURI(namespace);
if (unmarshaller.isCaseInsensitive()){
resultNode = getNodeFromLookupTable(attributeChildrenMap, true);
} else {
resultNode = attributeChildrenMap.get(xPathFragment);
}
if (resultNode != null) {
return resultNode.getUnmarshalNodeValue();
}
}
return null;
}
/**
* INTERNAL:
* Retrieves the XPathNode by searching in the auxiliary case insensitive lookup table.
*
* @param childrenMap Original Map for construction of the auxiliary table.
* @param isAttribute Determine if searching for an element or an attribute.
* @return XPathNode object reference, which is also present in the original children map.
* @since 2.6.0
*/
private XPathNode getNodeFromLookupTable(Map childrenMap, boolean isAttribute) {
Map lookupTable = xPathNode.getChildrenLookupTable(isAttribute);
if(!xPathNode.isChildrenLookupTableFilled(isAttribute)){
this.fillLookupTable(childrenMap, lookupTable);
xPathNode.setChildrenLookupTableFilled(isAttribute);
}
String lowerCaseFragment = xPathFragment.getLocalName().toLowerCase();
if (!xPathFragment.getChildrenCollisionSet(isAttribute).add(lowerCaseFragment))
handleCollision(lowerCaseFragment, false);
return lookupTable.get(lowerCaseFragment);
}
/**
* INTERNAL:
* Creates an auxiliary lookup table containing lower-cased localNames of XPathFragments.
*
* Does NOT pass the Turkey test.
*
* For future development: Handle ISO-8859-9 encoding.
* if (encoding.equals("ISO-8859-9")) {
* String auxLocalName = entry.getKey().getLocalName().toLowerCase(Locale.forLanguageTag("tr-TR"));
* }
*
* @param childrenMap Table from which the data is acquired.
* @param lookupTable Table to which the lower-cased data is stored.
* @since 2.6.0
*/
private void fillLookupTable(Map childrenMap, Map lookupTable) {
String lookupName;
for (Map.Entry entry : childrenMap.entrySet()) {
lookupName = entry.getKey().getLocalName().toLowerCase();
if (lookupTable.put(lookupName, entry.getValue()) != null){
handleCollision(lookupName, true);
}
}
}
/**
* INTERNAL:
* Handles collisions, i.e. fragments or fields with the same name, different case.
*
* @param lookupName Lookup variant of the localName.
* @param onXPathNode true - the collision occurred on XPathNode (case for Java fields),
* false - the collision occurred on XPathFragment (case for XML elements/attributes).
* @since 2.6.0
*/
private void handleCollision(String lookupName, boolean onXPathNode) {
StringBuilder sb = new StringBuilder()
.append(">\nUnmarshalRecordImpl.handleCollision() -->\tCOLLISION on ")
.append(
onXPathNode
? "XPathNode fields by case insensitive localName \""
: "XPathFragments by case insensitive localName \""
).append(lookupName).append("\".");
// session.setLogLevel(SessionLog.WARNING); // for debugging
((AbstractSession) session).logMessage(CommandProcessor.LOG_WARNING, sb.toString());
}
public SAXFragmentBuilder getFragmentBuilder() {
if(this.fragmentBuilder == null){
fragmentBuilder = new SAXFragmentBuilder(this);
}
return fragmentBuilder;
}
public void setFragmentBuilder(SAXFragmentBuilder builder) {
this.fragmentBuilder = builder;
}
public void resetStringBuffer() {
this.getStringBuffer().reset();
this.isBufferCDATA = false;
}
public boolean isBufferCDATA() {
return isBufferCDATA;
}
public void comment(char[] data, int start, int length) {
}
public void startCDATA() {
if (null != xPathNode && xPathNode.getUnmarshalNodeValue() != null) {
this.isBufferCDATA = true;
}
}
public void endCDATA() {
}
public void startEntity(String entity) {
}
public void endEntity(String entity) {
}
public void startDTD(String a, String b, String c) {
}
public void endDTD() {
}
/**
* Sets the flag which indicates if this UnmarshalRecord
* represents a 'self' record
*
* @param isSelfRecord true if this record represents
* 'self', false otherwise
*/
public void setSelfRecord(boolean isSelfRecord) {
this.isSelfRecord = isSelfRecord;
}
/**
* Indicates if this UnmarshalRecord represents a 'self' record
*
* @return true if this record represents 'self', false otherwise
*/
public boolean isSelfRecord() {
return isSelfRecord;
}
public int getLevelIndex() {
return levelIndex;
}
/**
* INTERNAL
* @since EclipseLink 2.5.0
*/
public void setAttributeValue(Object value, Mapping mapping) {
this.unmarshalContext.setAttributeValue(this, value, mapping);
}
public void addAttributeValue(ContainerValue containerValue, Object value) {
this.unmarshalContext.addAttributeValue(this, containerValue, value);
}
public void addAttributeValue(ContainerValue containerValue, Object value, Object collection) {
this.unmarshalContext.addAttributeValue(this, containerValue, value, collection);
}
public void setAttributeValueNull(ContainerValue containerValue) {
this.unmarshalContext.setAttributeValue(this, null, containerValue.getMapping());
int containerIndex = containerValue.getIndex();
populatedContainerValues.remove(containerValue);
containerInstances[containerIndex] = null;
}
public void reference(Reference reference) {
this.unmarshalContext.reference(reference);
}
public void unmappedContent() {
if(this.xPathNode.getParent() != null) {
xPathNode = xPathNode.getParent();
}
this.unmarshalContext.unmappedContent(this);
}
public UnmarshalRecord getChildUnmarshalRecord(ObjectBuilder treeObjectBuilder) {
if(childRecord != null && !childRecord.isSelfRecord()){
childRecord.initialize(treeObjectBuilder);
childRecord.setParentRecord(this);
return childRecord;
}else{
childRecord = new UnmarshalRecordImpl(treeObjectBuilder, referenceResolver);
childRecord.setSession(session);
childRecord.setUnmarshaller(unmarshaller);
childRecord.setTextWrapperFragment(textWrapperFragment);
childRecord.setXMLReader(this.xmlReader);
childRecord.setFragmentBuilder(fragmentBuilder);
childRecord.setUnmarshalNamespaceResolver(unmarshalNamespaceResolver);
childRecord.setParentRecord(this);
}
return childRecord;
}
/**
* INTERNAL:
*/
public void setUnmarshaller(Unmarshaller unmarshaller) {
this.unmarshaller = unmarshaller; //super.setUnmarshaller(unmarshaller);
if(xPathFragment != null){
xPathFragment.setNamespaceAware(isNamespaceAware());
}
}
/**
* INTERNAL
* Returns a Map of any prefix mappings that were made before the most recent start
* element event. This Map is used so the prefix mappings can be passed along to a
* fragment builder in the event that the element in question is going to be unmarshalled
* as a Node.
*/
public Map getPrefixesForFragment() {
if(prefixesForFragment == null){
prefixesForFragment = new HashMap();
}
return prefixesForFragment;
}
public char getNamespaceSeparator(){
return xmlReader.getNamespaceSeparator();
}
public void setTextWrapperFragment(XPathFragment newTextWrapperFragment) {
textWrapperFragment = newTextWrapperFragment;
}
public XPathFragment getTextWrapperFragment() {
if(xmlReader.getMediaType() .isApplicationJSON()){
if(textWrapperFragment == null){
textWrapperFragment = new XPathFragment();
textWrapperFragment.setLocalName(unmarshaller.getValueWrapper());
textWrapperFragment.setNamespaceAware(isNamespaceAware());
textWrapperFragment.setNamespaceSeparator(getNamespaceSeparator());
}
return textWrapperFragment;
}
return null;
}
/**
* INTERNAL:
* If the UnmarshalRecord has a ReferenceResolver, tell it to resolve its
* references.
* @since EclipseLink 2.5.0
*/
public void resolveReferences(CoreAbstractSession abstractSession, IDResolver idResolver) {
if(null != referenceResolver) {
referenceResolver.resolveReferences(abstractSession, idResolver, unmarshaller.getErrorHandler());
}
}
/**
* INTERNAL:
* @since EclipseLink 2.5.0
*/
public Root createRoot() {
return unmarshaller.createRoot();
}
/**
* WHAT ABOUT THESE?
*/
private Field convertToXMLField(CoreField key) {
return (Field) key;
}
@Override
public CoreAbstractSession getSession() {
return session;
}
@Override
public Unmarshaller getUnmarshaller() {
return unmarshaller;
}
@Override
public boolean isNamespaceAware() {
return namespaceAware;
}
@Override
public Object getCurrentObject() {
return currentObject;
}
@Override
public XPathQName getLeafElementType() {
return leafElementType;
}
@Override
public void setCurrentObject(Object object) {
this.currentObject = object;
}
@Override
public void setLeafElementType(QName type) {
if (type != null) {
setLeafElementType(new XPathQName(type, isNamespaceAware()));
} else {
setLeafElementType((XPathQName) null);
}
}
public void setLeafElementType(XPathQName type) {
leafElementType = type;
}
@Override
public void setSession(CoreAbstractSession session) {
this.session = session;
}
public CoreAttributeGroup getUnmarshalAttributeGroup() {
return unmarshalAttributeGroup;
}
public void setUnmarshalAttributeGroup(CoreAttributeGroup unmarshalAttributeGroup) {
this.unmarshalAttributeGroup = unmarshalAttributeGroup;
}
/**
* @since EclipseLink 2.6.0
*/
@Override
public ConversionManager getConversionManager() {
if(null == conversionManager) {
conversionManager = (ConversionManager) session.getDatasourcePlatform().getConversionManager();
}
return conversionManager;
}
}