
org.eclipse.persistence.internal.oxm.ReferenceResolver 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 346465e
/*******************************************************************************
* 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.internal.oxm;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.concurrent.Callable;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.InheritancePolicy;
import org.eclipse.persistence.exceptions.ConversionException;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.identitymaps.CacheId;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.AttributeAccessor;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.oxm.IDResolver;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.oxm.mappings.XMLCollectionReferenceMapping;
import org.eclipse.persistence.oxm.mappings.XMLInverseReferenceMapping;
import org.eclipse.persistence.oxm.mappings.XMLObjectReferenceMapping;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
/**
* This class is leveraged by reference mappings. It plays 3 roles:
*
* - Stores objects with an ID
* - Stores key based relationships
* - Resolves key based relationships based on the objects stored by ID
*
*/
public class ReferenceResolver {
private ArrayList references;
private ReferenceKey lookupKey;
private Map> cache;
/**
* The default constructor initializes the list of References.
*/
public ReferenceResolver() {
references = new ArrayList();
lookupKey = new ReferenceKey(null, null);
cache = new HashMap>();
}
/**
* Add a Reference object to the list - these References will
* be resolved after unmarshalling is complete.
*
* @param ref
*/
public void addReference(Reference ref) {
references.add(ref);
}
/**
* INTERNAL:
* Create primary key values to be used for cache lookup. The map
* of primary keys on the reference is keyed on the reference descriptors primary
* key field names. Each of these primary keys contains all of the values for a
* particular key - in the order that they we read in from the document. For
* example, if the key field names are A, B, and C, and there are three reference
* object instances, then the hashmap would have the following:
* (A=[1,2,3], B=[X,Y,Z], C=[Jim, Joe, Jane]). If the primary key field names on
* the reference descriptor contained [B, C, A], then the result of this method call
* would be reference.primaryKeys=([X, Jim, 1], [Y, Joe, 2], [Z, Jane, 3]).
*
* @param reference
*/
private void createPKVectorsFromMap(Reference reference, XMLCollectionReferenceMapping mapping) {
ClassDescriptor referenceDescriptor = mapping.getReferenceDescriptor();
Vector pks = new Vector();
if(null == referenceDescriptor) {
CacheId pkVals = (CacheId) reference.getPrimaryKeyMap().get(null);
if(null == pkVals) {
return;
}
for(int x=0;x 1) {
Map idWrapper = new HashMap();
for (int y = 0; y < primaryKey.getPrimaryKey().length; y++) {
XMLObjectReferenceMapping refMapping = (XMLObjectReferenceMapping) reference.getMapping();
String idName = (String) refMapping.getReferenceDescriptor().getPrimaryKeyFieldNames().get(y);
Object idValue = primaryKey.getPrimaryKey()[y];
idWrapper.put(idName, idValue);
}
c = userSpecifiedResolver.resolve(idWrapper, reference.getTargetClass());
} else {
c = userSpecifiedResolver.resolve(primaryKey.getPrimaryKey()[0], reference.getTargetClass());
}
if (c != null) {
value = c.call();
}
} catch (Exception e) {
throw XMLMarshalException.unmarshalException(e);
}
} else {
value = getValue(session, reference, primaryKey, handler);
}
if (value != null) {
cPolicy.addInto(value, container, session);
}
}
}
// for each reference, get the source object and add it to the container policy
// when finished, set the policy on the mapping
mapping.setAttributeValueInObject(referenceSourceObject, container);
XMLInverseReferenceMapping inverseReferenceMapping = mapping.getInverseReferenceMapping();
if(inverseReferenceMapping != null && value != null) {
AttributeAccessor backpointerAccessor = inverseReferenceMapping.getAttributeAccessor();
ContainerPolicy backpointerContainerPolicy = inverseReferenceMapping.getContainerPolicy();
if(backpointerContainerPolicy == null) {
backpointerAccessor.setAttributeValueInObject(value, referenceSourceObject);
} else {
Object backpointerContainer = backpointerAccessor.getAttributeValueFromObject(value);
if(backpointerContainer == null) {
backpointerContainer = backpointerContainerPolicy.containerInstance();
backpointerAccessor.setAttributeValueInObject(value, backpointerContainer);
}
backpointerContainerPolicy.addInto(referenceSourceObject, backpointerContainer, session);
}
}
} else if (reference.getMapping() instanceof XMLObjectReferenceMapping) {
CacheId primaryKey = (CacheId) reference.getPrimaryKey();
Object value = null;
if (userSpecifiedResolver != null) {
final Callable c;
try {
if (primaryKey.getPrimaryKey().length > 1) {
Map idWrapper = new HashMap();
for (int y = 0; y < primaryKey.getPrimaryKey().length; y++) {
XMLObjectReferenceMapping refMapping = (XMLObjectReferenceMapping) reference.getMapping();
String idName = (String) refMapping.getReferenceDescriptor().getPrimaryKeyFieldNames().get(y);
Object idValue = primaryKey.getPrimaryKey()[y];
idWrapper.put(idName, idValue);
}
c = userSpecifiedResolver.resolve(idWrapper, reference.getTargetClass());
} else {
c = userSpecifiedResolver.resolve(primaryKey.getPrimaryKey()[0], reference.getTargetClass());
}
if (c != null) {
value = c.call();
}
} catch (Exception e) {
throw XMLMarshalException.unmarshalException(e);
}
} else {
value = getValue(session, reference, primaryKey, handler);
}
XMLObjectReferenceMapping mapping = (XMLObjectReferenceMapping)reference.getMapping();
if (value != null) {
mapping.setAttributeValueInObject(reference.getSourceObject(), value);
}
if (null != reference.getSetting()) {
reference.getSetting().setValue(value);
}
XMLInverseReferenceMapping inverseReferenceMapping = mapping.getInverseReferenceMapping();
if(inverseReferenceMapping != null) {
AttributeAccessor backpointerAccessor = inverseReferenceMapping.getAttributeAccessor();
ContainerPolicy backpointerContainerPolicy = inverseReferenceMapping.getContainerPolicy();
if(backpointerContainerPolicy == null) {
backpointerAccessor.setAttributeValueInObject(value, referenceSourceObject);
} else {
Object backpointerContainer = backpointerAccessor.getAttributeValueFromObject(value);
if(backpointerContainer == null) {
backpointerContainer = backpointerContainerPolicy.containerInstance();
backpointerAccessor.setAttributeValueInObject(value, backpointerContainer);
}
backpointerContainerPolicy.addInto(reference.getSourceObject(), backpointerContainer, session);
}
}
}
}
// reset the references list
references = new ArrayList();
cache.clear();
}
private Object getValue(AbstractSession session, Reference reference, CacheId primaryKey, ErrorHandler handler) {
Class referenceTargetClass = reference.getTargetClass();
if(null == referenceTargetClass || referenceTargetClass == ClassConstants.OBJECT) {
for(Object entry : session.getDescriptors().values()) {
Object value = null;
XMLDescriptor targetDescriptor = (XMLDescriptor) entry;
List pkFields = targetDescriptor.getPrimaryKeyFields();
if(null != pkFields && 1 == pkFields.size()) {
XMLField pkField = (XMLField) pkFields.get(0);
pkField = (XMLField) targetDescriptor.getTypedField(pkField);
Class targetType = pkField.getType();
if(targetType == ClassConstants.STRING || targetType == ClassConstants.OBJECT) {
value = getValue(targetDescriptor.getJavaClass(), primaryKey);
} else {
try {
Object[] pkValues = primaryKey.getPrimaryKey();
Object[] convertedPkValues = new Object[pkValues.length];
for(int x=0; x childDescriptors = inheritancePolicy.getAllChildDescriptors();
for(ClassDescriptor childDescriptor : childDescriptors) {
value = getValue(childDescriptor.getJavaClass(), primaryKey);
if(null != value) {
return value;
}
}
}
}
if(value == null && (primaryKey.getPrimaryKey()[0] != null) ){
XMLMarshalException e = XMLMarshalException.missingIDForIDRef(referenceTargetClass.getName(), primaryKey.getPrimaryKey());
if(handler != null){
SAXParseException saxParseException = new SAXParseException(e.getLocalizedMessage(), null, e);
try{
handler.warning(saxParseException);
}catch(SAXException saxException){
throw e;
}
}
}
return value;
}
}
private Object getValue(Class clazz, CacheId primaryKey) {
Map
© 2015 - 2025 Weber Informatics LLC | Privacy Policy