org.eclipse.persistence.oxm.record.DOMRecord 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 180e602
/*******************************************************************************
* Copyright (c) 1998, 2013 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:
* Oracle - initial API and implementation from Oracle TopLink
******************************************************************************/
package org.eclipse.persistence.oxm.record;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.xml.namespace.QName;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.oxm.ReferenceResolver;
import org.eclipse.persistence.internal.oxm.UnmarshalXPathEngine;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.oxm.IDResolver;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.oxm.XMLConstants;
import org.eclipse.persistence.oxm.XMLLogin;
import org.eclipse.persistence.internal.oxm.XPathEngine;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.internal.oxm.record.TransformationRecord;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.mappings.nullpolicy.AbstractNullPolicy;
import org.eclipse.persistence.platform.xml.XMLParser;
import org.eclipse.persistence.platform.xml.XMLPlatform;
import org.eclipse.persistence.platform.xml.XMLPlatformFactory;
import org.eclipse.persistence.platform.xml.XMLTransformer;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* PUBLIC:
* Provides a Record/Map API on an XML DOM element.
*/
public class DOMRecord extends XMLRecord implements TransformationRecord {
private Node dom;
private Node currentNode;
private XMLField lastUpdatedField;
private ReferenceResolver referenceResolver;
/**
* INTERNAL:
* Default constructor.
*/
public DOMRecord() {
super();
setNamespaceResolver(new NamespaceResolver());
referenceResolver = new ReferenceResolver();
// Required for subclasses.
}
/**
* INTERNAL:
* Create a record with the root element name.
*/
public DOMRecord(String rootElementName) {
this(rootElementName, (NamespaceResolver)null);
}
/**
* INTERNAL:
* Create a record with the root element name get the namespace URI from the namespaceResolver.
*/
public DOMRecord(String rootElementName, NamespaceResolver namespaceResolver) {
this();
String rootElementNamespaceURI = resolveNamespace(namespaceResolver, rootElementName);
setDOM(createNewDocument(rootElementName, rootElementNamespaceURI));
}
/**
* INTERNAL:
* Create a record with the root element name get the namespace URI from the namespaceResolver.
*/
public DOMRecord(String rootElementName, String rootElementNamespaceURI) {
this();
setDOM(createNewDocument(rootElementName, rootElementNamespaceURI));
}
/**
* INTERNAL:
* Create a record with the local root element name, that is a child of the parent.
*/
public DOMRecord(String localRootElementName, Node parent) {
this(localRootElementName, (NamespaceResolver)null, parent);
}
/**
* INTERNAL:
* Create a record with the local root element name, that is a child of the parent.
* Lookup the namespace URI from the namespaceResolver.
*/
public DOMRecord(String localRootElementName, NamespaceResolver namespaceResolver, Node parent) {
this();
Document document;
if (parent instanceof Document) {
document = (Document)parent;
} else {
document = parent.getOwnerDocument();
}
String localRootElementNamespaceURI = resolveNamespace(namespaceResolver, localRootElementName);
Element child = document.createElementNS(localRootElementNamespaceURI, localRootElementName);
parent.appendChild(child);
setDOM(child);
}
/**
* INTERNAL:
* Create a record with the element.
*/
public DOMRecord(Element element) {
this();
setDOM(element);
}
public DOMRecord(Node node) {
this();
setDOM(node);
}
/**
* INTERNAL:
* Create a record with the element.
*/
public DOMRecord(Document document) {
this();
setDOM(document.getDocumentElement());
}
/**
* PUBLIC:
* Get the local name of the context root element.
*/
public String getLocalName() {
String localName = getDOM().getLocalName();
if (null != localName) {
return localName;
}
return getDOM().getNodeName();
}
/**
* PUBLIC:
* Get the namespace URI for the context root element.
*/
public String getNamespaceURI() {
return getDOM().getNamespaceURI();
}
/**
* 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;
}
/**
* INTERNAL:
* Add the field-value pair to the document.
*/
public void add(DatabaseField key, Object value) {
// Value may be a direct value, nested record, or collection of values.
Object nodeValue = convertToNodeValue(value);
XPathEngine.getInstance().create(convertToXMLField(key), dom, nodeValue, session);
}
/**
* INTERNAL:
* Convert the value which may be a direct value, nested record, or set of nested records,
* to a node value usable with the XPathEngine.
*/
private Object convertToNodeValue(Object value) {
if (value instanceof List) {
List values = (List)value;
Vector nodeValues = new Vector(values.size());
for (int index = 0; index < values.size(); index++) {
Object nestedValue = values.get(index);
nodeValues.add(convertToNodeValue(nestedValue));
}
return nodeValues;
} else if (value instanceof DOMRecord) {
return ((DOMRecord)value).getDOM();
} else if (value != null && value.getClass() == XMLEntry.class) {
XMLEntry entry = (XMLEntry)value;
entry.setValue(convertToNodeValue(entry.getValue()));
return entry;
} else {
return value;
}
}
/**
* PUBLIC:
* Clear the sub-nodes of the DOM.
*/
public void clear() {
if(getDOM() instanceof Element) {
String domName = ((Element)getDOM()).getTagName();
this.dom = createNewDocument(domName, null);
this.currentNode = this.dom;
}
}
/**
* INTERNAL:
* Clone the row and its values.
*/
public DOMRecord clone() {
DOMRecord clone = (DOMRecord)super.clone();
if (clone != null) {
clone.setDOM((Element)dom.cloneNode(true));
}
return clone;
}
/**
* INTERNAL:
* Creates a new Document and returns the root element of that document
*/
public Node createNewDocument(String defaultRootElementName) {
return createNewDocument(defaultRootElementName, null);
}
/**
* INTERNAL:
* Creates a new Document and returns the root element of that document
*/
public Node createNewDocument(String defaultRootElementName, String namespaceURI) {
XMLPlatform xmlPlatform = XMLPlatformFactory.getInstance().getXMLPlatform();
Document document = xmlPlatform.createDocument();
if (defaultRootElementName == null || defaultRootElementName.length() == 0) {
DocumentFragment fragment = document.createDocumentFragment();
return fragment;
} else {
Node rootNode = document.createElementNS(namespaceURI, defaultRootElementName);
document.appendChild(rootNode);
return document.getDocumentElement();
}
}
/**
* PUBLIC:
* Return the document.
*/
public Document getDocument() {
return getDOM().getOwnerDocument();
}
/**
* INTERNAL:
* Check if the field is contained in the row.
*/
public boolean containsKey(DatabaseField key) {
XMLField xmlField = convertToXMLField(key);
NodeList nodeList = UnmarshalXPathEngine.getInstance().selectNodes(dom, xmlField, xmlField.getNamespaceResolver());
return nodeList.getLength() > 0;
}
/**
* PUBLIC:
* Check if the value is contained in the row.
*/
public boolean contains(Object value) {
return values().contains(value);
}
public Object get(DatabaseField key) {
Object value = getIndicatingNoEntry(key);
if(value == noEntry) {
return null;
}
return value;
}
/**
* INTERNAL:
* Given a DatabaseField return the corresponding value from the document
*/
public Object getIndicatingNoEntry(DatabaseField key) {
return getIndicatingNoEntry(key, false, false);
}
public Object getIndicatingNoEntry(DatabaseField key, boolean shouldReturnNode) {
return getIndicatingNoEntry(key, shouldReturnNode, false);
}
public Object getIndicatingNoEntry(DatabaseField key, boolean shouldReturnNode, boolean checkForXsiNil) {
XMLField field = convertToXMLField(key);
// handle 'self' xpath
if (field.isSelfField()) {
return this;
}
Object result = UnmarshalXPathEngine.getInstance().selectSingleNode(dom, field, field.getNamespaceResolver(), checkForXsiNil);
if(result == noEntry) {
if(shouldReturnNode) {
return null;
}
return noEntry;
}
if (result == NIL) {
return NIL;
}
Node node = (Node)result;
if(shouldReturnNode) {
return node;
}
// If a node was not found return null
if (null == node) {
return null;
}
// For Attributes and Text nodes return their value
if (Node.ELEMENT_NODE != node.getNodeType()) {
if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
getValueFromAttribute((Attr)node, field);
}
// For Text, must handle typed elements
return getValueFromElement((Element)node.getParentNode(), node, field);
}
// If an element was found
return buildNestedRow((Element)node);
}
/**
* INTERNAL:
* Retrieve the value for the field name.
*/
public Object getValues(String key) {
Object value = getValuesIndicatingNoEntry(new XMLField(key));
if (value == AbstractRecord.noEntry) {
return null;
}
return value;
}
/**
* INTERNAL:
* Given a DatabaseField, return the corresponding values from the document
*/
public Object getValues(DatabaseField key) {
return this.getValues(key, null);
}
public Object getValues(DatabaseField key, AbstractNullPolicy nullPolicy) {
Object value = getValuesIndicatingNoEntry(key, nullPolicy);
if (value == AbstractRecord.noEntry) {
return null;
}
return value;
}
public Object getValuesIndicatingNoEntry(DatabaseField key) {
return this.getValuesIndicatingNoEntry(key, null);
}
public Object getValuesIndicatingNoEntry(DatabaseField key, AbstractNullPolicy nullPolicy) {
return getValuesIndicatingNoEntry(key, false, nullPolicy);
}
public List getValuesIndicatingNoEntry(List keys) {
return getValuesIndicatingNoEntry(keys, false);
}
public List getValuesIndicatingNoEntry(List keys, boolean shouldReturnNodes) {
List xmlFields = convertToXMLField(keys);
List values = UnmarshalXPathEngine.getInstance().selectNodes(dom, xmlFields, xmlFields.get(0).getNamespaceResolver());
if(shouldReturnNodes) {
return values;
}
for(XMLEntry next:values) {
Node nextNode = (Node)next.getValue();
if(!(nextNode.getNodeType() == Node.ELEMENT_NODE)) {
Object value = getValueFromElement((Element)nextNode.getParentNode(), nextNode, next.getXMLField());
next.setValue(value);
} else {
next.setValue(buildNestedRow((Element)nextNode));
}
}
return values;
}
/**
* INTERNAL:
* Given a DatabaseField, return the corresponding values from the document
*/
public Object getValuesIndicatingNoEntry(DatabaseField key, boolean shouldReturnNodes) {
return this.getValuesIndicatingNoEntry(key, shouldReturnNodes, null);
}
public Object getValuesIndicatingNoEntry(DatabaseField key, boolean shouldReturnNodes, AbstractNullPolicy nullPolicy) {
XMLField field = convertToXMLField(key);
NodeList nodeList = UnmarshalXPathEngine.getInstance().selectNodes(dom, field, field.getNamespaceResolver(), nullPolicy);
// If a node was not found return null
if (null == nodeList) {
return null;
}
int resultSize = nodeList.getLength();
Vector result = new Vector(resultSize);
if (resultSize == 0) {
return result;
}
if(shouldReturnNodes) {
//just copy all the nodes into the result vector and return it
for(int i = 0; i < resultSize; i++) {
result.add(nodeList.item(i));
}
return result;
}
// Assumption: NodeList contains nodes of the same type
Node firstNode = nodeList.item(0);
if ((firstNode == null) || (firstNode.getNodeType() != Node.ELEMENT_NODE)) {
if (field.usesSingleNode() && (resultSize == 1)) {
Node next = nodeList.item(0);
if (next == null) {
result.add(null);
} else {
Vector list = new Vector();
String sourceObject = next.getNodeValue();
StringTokenizer tokenizer = new StringTokenizer(sourceObject, " ");
while (tokenizer.hasMoreElements()) {
String token = tokenizer.nextToken();
Object nextItem = convertValue((Element)next.getParentNode(), field, token);
list.add(nextItem);
}
return list;
}
}
for (int x = 0; x < resultSize; x++) {
Node next = nodeList.item(x);
if (next == null) {
result.add(null);
} else {
result.add(getValueFromElement((Element)next.getParentNode(), next, field));
}
}
} else {
for (int x = 0; x < resultSize; x++) {
result.add(buildNestedRow((Element)nodeList.item(x)));
}
}
return result;
}
private Object getValueFromAttribute(Attr node, XMLField key) {
currentNode = node.getOwnerElement();
Object convertedValue = key.convertValueBasedOnSchemaType(node.getNodeValue(), (XMLConversionManager) session.getDatasourcePlatform().getConversionManager(), this);
currentNode = getDOM();
return convertedValue;
}
private Object getValueFromElement(Element node, Node textChild, Field key) {
Object value = textChild.getNodeValue();
return convertValue(node, key, value);
}
private Object convertValue(Element node, Field key, Object value) {
XMLConversionManager xmlCnvMgr = (XMLConversionManager) session.getDatasourcePlatform().getConversionManager();
if (key.isTypedTextField() && (node != null)) {
String schemaType = node.getAttributeNS(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, XMLConstants.SCHEMA_TYPE_ATTRIBUTE);
if ((null != schemaType) && (schemaType.length() > 0)) {
QName qname = null;
int index = schemaType.indexOf(XMLConstants.COLON);
if (index == -1) {
qname = new QName(schemaType);
Class convertClass = key.getJavaClass(qname, xmlCnvMgr);
return xmlCnvMgr.convertObject(value, convertClass);
} else {
String prefix = schemaType.substring(0, index);
String localPart = schemaType.substring(index + 1);
XMLPlatform xmlPlatform = XMLPlatformFactory.getInstance().getXMLPlatform();
String url = xmlPlatform.resolveNamespacePrefix(node, prefix);
qname = new QName(url, localPart);
Class convertClass = key.getJavaClass(qname, xmlCnvMgr);
return xmlCnvMgr.convertObject(value, convertClass, qname);
}
}
}
currentNode = node;
Object convertedValue = key.convertValueBasedOnSchemaType(value, xmlCnvMgr, this);
currentNode = getDOM();
return convertedValue;
}
/**
* INTERNAL:
* Build the nested record, this can be overwriten by subclasses to use their subclass instance.
*/
public XMLRecord buildNestedRow(Element element) {
DOMRecord record = new DOMRecord(element);
record.setUnmarshaller(this.getUnmarshaller());
record.setOwningObject(this.getCurrentObject());
record.setDocPresPolicy(this.getDocPresPolicy());
record.setReferenceResolver(referenceResolver);
return record;
}
/**
* PUBLIC:
* Return the DOM.
*/
public Node getDOM() {
return dom;
}
/**
* INTERNAL:
* Set the field value into the DOM.
* The field name must be a valid simple XPath expression.
*/
public Object put(DatabaseField key, Object value) {
// Value may be a direct value, nested record, or collection of values.
XMLField field = convertToXMLField(key);
Object nodeValue = convertToNodeValue(value);
NodeList replaced = null;
boolean isEmptyCollection = false;
if (nodeValue instanceof Collection) {
isEmptyCollection = ((Collection)nodeValue).size() == 0;
replaced = XPathEngine.getInstance().replaceCollection(convertToXMLField(key), dom, (Collection)nodeValue, session);
} else {
replaced = XPathEngine.getInstance().replaceValue(convertToXMLField(key), dom, nodeValue, session);
}
if (replaced.getLength() == 0) {
// Replace does nothing if the node did not exist, return no nodes.
XPathEngine.getInstance().create(convertToXMLField(key), dom, nodeValue, lastUpdatedField, getDocPresPolicy(), session);
} else if (replaced.item(0) == getDOM()) {
// If the root element/record element was changed must update the record's reference.
setDOM(getDocument().getDocumentElement());
}
if(!field.getXPathFragment().isAttribute() && !field.getXPathFragment().nameIsText()) {
if(value != null && !isEmptyCollection) {
this.lastUpdatedField = field;
}
}
return replaced;
}
public Object put(List xmlFields, List values) {
Vector valuesToWrite = (Vector)convertToNodeValue(values);
List replaced = null;
replaced = XPathEngine.getInstance().replaceCollection(xmlFields, valuesToWrite, dom, getDocPresPolicy(), lastUpdatedField, session);
if(replaced.size() == 0) {
XPathEngine.getInstance().create(xmlFields, dom, valuesToWrite, lastUpdatedField, getDocPresPolicy(), session);
}
return replaced;
}
public Object put(Object key, Object value) throws ValidationException {
if (key instanceof String) {
return put((String)key, value);
} else if (key instanceof DatabaseField) {
return put((DatabaseField)key, value);
} else if (key instanceof List) {
return put((List)key, (List)value);
} else {
throw ValidationException.onlyFieldsAreValidKeysForDatabaseRows();
}
}
/**
* INTERNAL:
* Remove the field key from the row.
*/
public Object remove(DatabaseField key) {
return XPathEngine.getInstance().remove(convertToXMLField(key), dom, true);
}
/**
* INTERNAL:
* replaces the value at index with value
*/
public void replaceAt(Object value, int index) {
throw XMLMarshalException.operationNotSupported("replaceAt(Object value, int index)");
}
/**
* PUBLIC:
*/
public Set entrySet() {
int size = this.size();
Map tempMap = new HashMap(size);
Vector fields = getFields();
Vector values = getValues();
for (int i = 0; i < size; i++) {
tempMap.put(fields.elementAt(i), values.elementAt(i));
}
return tempMap.entrySet();
}
/**
* INTERNAL:
* Setting fields vector will not update the document so this is not supported
*/
protected void setFields(Vector fields) throws XMLMarshalException {
throw XMLMarshalException.operationNotSupported("setField(Vector fields)");
}
/**
* INTERNAL:
* This should not be used, but added some support for it as
* is called from some places such as sdk call used in the descriptor to define operation not supported,
* may also be called from toplin in some places.
*/
public Vector getFields() {
int length = getDOM().getChildNodes().getLength();
Node nextNode = null;
if(length > 0) {
nextNode = getDOM().getChildNodes().item(0);
}
Vector fields = new Vector(length);
while(nextNode != null) {
fields.add(new DatabaseField(nextNode.getNodeName()));
nextNode = nextNode.getNextSibling();
}
return fields;
}
/**
* INTERNAL:
* This should not be used, but added some support for it as
* is called from some places such as sdk call used in the descriptor to define operation not supported,
* may also be called from TopLink in some places.
*/
public Vector getValues() {
int length = getDOM().getChildNodes().getLength();
Node nextNode = null;
if(length > 0) {
nextNode = getDOM().getFirstChild();
}
Vector values = new Vector(length);
while(nextNode != null) {
values.add(nextNode);
nextNode = nextNode.getNextSibling();
}
return values;
}
/**
* INTERNAL:
* Setting values vector will not update the document so this is not supported
*/
protected void setValues(Vector values) throws XMLMarshalException {
throw XMLMarshalException.operationNotSupported("setValues(Vector values)");
}
/**
* INTERNAL:
* Sets the dom and updated document to be the owner document of the given element
*/
public void setDOM(Node element) {
this.dom = element;
this.currentNode = element;
this.getNamespaceResolver().setDOM(element);
}
public void setDOM(Element element) {
this.dom = element;
this.currentNode = element;
this.getNamespaceResolver().setDOM(element);
}
/**
* INTERNAL:
* Print the dom XML string.
*/
public String toString() {
StringWriter writer = new StringWriter();
writer.write(Helper.getShortClassName(getClass()));
writer.write("(");
transformToWriter(writer);
writer.write(")");
return writer.toString();
}
/**
* PUBLIC:
* Return the set of element names from the DOM.
*/
public Set keySet() {
int length = getDOM().getChildNodes().getLength();
HashSet keys = new HashSet(length);
for (int index = 0; index < length; index++) {
keys.add(getDOM().getChildNodes().item(index).getNodeName());
}
return keys;
}
/**
* PUBLIC:
* Return the collection of element values from the DOM.
*/
public Collection values() {
int length = getDOM().getChildNodes().getLength();
Vector values = new Vector(length);
for (int index = 0; index < length; index++) {
values.add(getDOM().getChildNodes().item(index));
}
return values;
}
/**
* Return the number of elements in the DOM.
*/
public int size() {
return getDOM().getAttributes().getLength() + getDOM().getChildNodes().getLength();
}
/**
* Set the XML from an XML string.
*/
public void transformFromXML(String xml) {
Reader reader = new StringReader(xml);
transformFromXML(reader);
}
/**
* INTERNAL:
* Return the namespace uri for the prefix of the given local name
*/
private String resolveNamespace(NamespaceResolver namespaceResolver, String localName) {
if(localName == null) {
return null;
}
int colonIndex = localName.indexOf(XMLConstants.COLON);
if (colonIndex < 0) {
// handle target/default namespace
if (namespaceResolver != null) {
return namespaceResolver.getDefaultNamespaceURI();
}
return null;
} else {
if (namespaceResolver == null) {
//throw an exception if the name has a : in it but the namespaceresolver is null
throw XMLMarshalException.namespaceResolverNotSpecified(localName);
}
String prefix = localName.substring(0, colonIndex);
String uri = namespaceResolver.resolveNamespacePrefix(prefix);
if (uri == null) {
//throw an exception if the prefix is not found in the namespaceresolver
throw XMLMarshalException.namespaceNotFound(prefix);
}
return uri;
}
}
public void setSession(AbstractSession session) {
this.session = session;
if (session != null && session.getDatasourceLogin() instanceof XMLLogin) {
this.equalNamespaceResolvers = ((XMLLogin) session.getDatasourceLogin()).hasEqualNamespaceResolvers();
}
}
/**
* Set the XML from an XML reader.
*/
public void transformFromXML(Reader reader) {
XMLParser parser = XMLPlatformFactory.getInstance().getXMLPlatform().newXMLParser();
Document document = parser.parse(reader);
setDOM(document.getDocumentElement());
}
/**
* Return the XML string representation of the DOM.
*/
public String transformToXML() {
StringWriter writer = new StringWriter();
transformToWriter(writer);
return writer.toString();
}
/**
* Write the XML string representation of the DOM.
*/
public void transformToWriter(Writer writer) {
XMLTransformer xmlTransformer = XMLPlatformFactory.getInstance().getXMLPlatform().newXMLTransformer();
xmlTransformer.transform(this.getDOM(), writer);
}
public String resolveNamespacePrefix(String prefix) {
XMLPlatform xmlPlatform = XMLPlatformFactory.getInstance().getXMLPlatform();
return xmlPlatform.resolveNamespacePrefix(currentNode, prefix);
}
/**
* 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());
}
}
}