org.eclipse.persistence.oxm.mappings.XMLInverseReferenceMapping 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:
// rbarkhouse - 2009-11-26 13:04:58 - 2.0 - initial implementation
package org.eclipse.persistence.oxm.mappings;
import java.util.Collection;
import java.util.Map;
import java.util.Vector;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.internal.descriptors.DescriptorIterator;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.oxm.mappings.InverseReferenceMapping;
import org.eclipse.persistence.internal.oxm.record.XMLRecord;
import org.eclipse.persistence.internal.queries.CollectionContainerPolicy;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.queries.JoinedAttributeManager;
import org.eclipse.persistence.internal.queries.ListContainerPolicy;
import org.eclipse.persistence.internal.queries.MapContainerPolicy;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.ChangeRecord;
import org.eclipse.persistence.internal.sessions.MergeManager;
import org.eclipse.persistence.internal.sessions.ObjectChangeSet;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.mappings.AggregateMapping;
import org.eclipse.persistence.mappings.AttributeAccessor;
import org.eclipse.persistence.mappings.ContainerMapping;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.queries.ObjectBuildingQuery;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.sessions.remote.DistributedSession;
/**
* This mapping is used to map a back-pointer. It represents the "opposite" of one of the
* following relationship mappings:
*
*
* - XMLCompositeObjectMapping
*
- XMLCompositeCollectionMapping
*
- XMLObjectReferenceMapping
*
- XMLCollectionReferenceMapping
*
*
* When configuring an XMLInverseReferenceMapping, the "mappedBy" field must be set to the
* field on the reference class that maps to this Descriptor. For example:
*
*
* // EMPLOYEE has a collection of PHONEs (phoneNumbers)
* // PHONE has a back-pointer to EMPLOYEE (owningEmployee)
*
* // EMPLOYEE Descriptor
* XMLCompositeCollectionMapping phone = new XMLCompositeCollectionMapping();
* phone.setReferenceClassName("org.example.PhoneNumber");
* phone.setAttributeName("phoneNumbers");
* ...
*
* // PHONE Descriptor
* XMLInverseReferenceMapping owningEmployee = new XMLInverseReferenceMapping();
* owningEmployee.setReferenceClassName("org.example.Employee");
* owningEmployee.setMappedBy("phoneNumbers");
* owningEmployee.setAttributeName("owningEmployee");
* ...
*
*/
public class XMLInverseReferenceMapping extends AggregateMapping implements InverseReferenceMapping, ContainerMapping {
private String mappedBy;
private ContainerPolicy containerPolicy;
private DatabaseMapping inlineMapping;
@Override
public boolean isXMLMapping() {
return true;
}
@Override
public void initialize(AbstractSession session) throws DescriptorException {
super.initialize(session);
setFields(new Vector ());
if(inlineMapping != null){
inlineMapping.initialize(session);
}
}
@Override
public void preInitialize(AbstractSession session){
super.preInitialize(session);
if(inlineMapping != null){
inlineMapping.setDescriptor(this.descriptor);
inlineMapping.preInitialize(session);
}
}
@Override
public void postInitialize(AbstractSession session) throws DescriptorException {
// Get the corresponding mapping from the reference descriptor and set up the
// inverse mapping.
DatabaseMapping mapping = getReferenceDescriptor().getMappingForAttributeName(this.mappedBy);
if (mapping instanceof XMLInverseReferenceMapping) {
mapping = ((XMLInverseReferenceMapping)mapping).getInlineMapping();
}
if (mapping instanceof XMLCompositeCollectionMapping) {
XMLCompositeCollectionMapping oppositeMapping = (XMLCompositeCollectionMapping) mapping;
oppositeMapping.setInverseReferenceMapping(this);
}
if (mapping instanceof XMLCompositeObjectMapping) {
XMLCompositeObjectMapping oppositeMapping = (XMLCompositeObjectMapping) mapping;
oppositeMapping.setInverseReferenceMapping(this);
}
if (mapping instanceof XMLObjectReferenceMapping) {
XMLObjectReferenceMapping oppositeMapping = (XMLObjectReferenceMapping) mapping;
oppositeMapping.setInverseReferenceMapping(this);
}
if (mapping instanceof XMLChoiceObjectMapping) {
XMLChoiceObjectMapping oppositeMapping = (XMLChoiceObjectMapping) mapping;
Collection nestedMappings = oppositeMapping.getChoiceElementMappings().values();
for(XMLMapping next:nestedMappings) {
if(next instanceof XMLCompositeObjectMapping) {
XMLCompositeObjectMapping compositeMapping = ((XMLCompositeObjectMapping)next);
if(compositeMapping.getReferenceClass() == this.getDescriptor().getJavaClass() || this.getDescriptor().getJavaClass().isAssignableFrom(compositeMapping.getReferenceClass())) {
compositeMapping.setInverseReferenceMapping(this);
}
} else if(next instanceof XMLObjectReferenceMapping) {
XMLObjectReferenceMapping refMapping = ((XMLObjectReferenceMapping)next);
if(refMapping.getReferenceClass() == this.getDescriptor().getJavaClass()) {
refMapping.setInverseReferenceMapping(this);
}
}
}
}
if (mapping instanceof XMLChoiceCollectionMapping) {
XMLChoiceCollectionMapping oppositeMapping = (XMLChoiceCollectionMapping) mapping;
Collection nestedMappings = oppositeMapping.getChoiceElementMappings().values();
for(XMLMapping next:nestedMappings) {
if(next instanceof XMLCompositeCollectionMapping) {
XMLCompositeCollectionMapping compositeMapping = ((XMLCompositeCollectionMapping)next);
if(compositeMapping.getReferenceClass() == this.getDescriptor().getJavaClass() || this.getDescriptor().getJavaClass().isAssignableFrom(compositeMapping.getReferenceClass())) {
compositeMapping.setInverseReferenceMapping(this);
}
} else if(next instanceof XMLCollectionReferenceMapping) {
XMLCollectionReferenceMapping refMapping = ((XMLCollectionReferenceMapping)next);
if(refMapping.getReferenceClass() == this.getDescriptor().getJavaClass()) {
refMapping.setInverseReferenceMapping(this);
}
}
}
}
if(inlineMapping != null){
inlineMapping.postInitialize(session);
}
}
public String getMappedBy() {
return mappedBy;
}
@Override
public void setMappedBy(String mappedBy) {
this.mappedBy = mappedBy;
}
// == AggregateMapping methods ============================================
@Override
public void buildBackupClone(Object clone, Object backup, UnitOfWorkImpl unitOfWork) {
}
@Override
public void buildClone(Object original, CacheKey cacheKey, Object clone, Integer refreshCascade, AbstractSession cloningSession) {
}
@Override
public void buildCloneFromRow(AbstractRecord databaseRow,
JoinedAttributeManager joinManager, Object clone, CacheKey sharedCacheKey,
ObjectBuildingQuery sourceQuery, UnitOfWorkImpl unitOfWork,
AbstractSession executionSession) {
}
@Override
public void cascadePerformRemoveIfRequired(Object object,
UnitOfWorkImpl uow, Map visitedObjects) {
}
@Override
public void cascadeRegisterNewIfRequired(Object object, UnitOfWorkImpl uow,
Map visitedObjects) {
}
@Override
public ChangeRecord compareForChange(Object clone, Object backup,
ObjectChangeSet owner, AbstractSession session) {
return null;
}
@Override
public boolean compareObjects(Object firstObject, Object secondObject,
AbstractSession session) {
return false;
}
@Override
public void fixObjectReferences(Object object, Map objectDescriptors,
Map processedObjects, ObjectLevelReadQuery query,
DistributedSession session) {
}
@Override
public void iterate(DescriptorIterator iterator) {
}
@Override
public void mergeChangesIntoObject(Object target,
ChangeRecord changeRecord, Object source, MergeManager mergeManager, AbstractSession targetSession) {
}
@Override
public void mergeIntoObject(Object target, boolean isTargetUninitialized,
Object source, MergeManager mergeManager, AbstractSession targetSession) {
}
// == ContainerPolicy methods =============================================
@Override
public void setContainerPolicy(ContainerPolicy containerPolicy) {
this.containerPolicy = containerPolicy;
}
@Override
public ContainerPolicy getContainerPolicy() {
return this.containerPolicy;
}
@Override
public void useCollectionClass(Class concreteClass) {
this.containerPolicy = new CollectionContainerPolicy(concreteClass);
}
@Override
public void useCollectionClassName(String concreteClass) {
this.containerPolicy = new CollectionContainerPolicy(concreteClass);
}
@Override
public void useListClassName(String concreteClass) {
this.containerPolicy = new ListContainerPolicy(concreteClass);
}
@Override
public void useMapClass(Class concreteClass, String methodName) {
this.containerPolicy = new MapContainerPolicy(concreteClass);
}
@Override
public void useMapClassName(String concreteClass, String methodName) {
this.containerPolicy = new MapContainerPolicy(concreteClass);
}
@Override
public DatabaseMapping getInlineMapping() {
return inlineMapping;
}
@Override
public void setInlineMapping(DatabaseMapping inlineMapping) {
this.inlineMapping = inlineMapping;
}
@Override
public void writeSingleValue(Object value, Object object, XMLRecord record, AbstractSession session) {
}
}