Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 1998, 2021 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
// 06/03/2013-2.5.1 Guy Pelletier
// - 402380: 3 jpa21/advanced tests failed on server with
// "java.lang.NoClassDefFoundError: org/eclipse/persistence/testing/models/jpa21/advanced/enums/Gender"
package org.eclipse.persistence.mappings.foundation;
import java.util.*;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.internal.descriptors.*;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.internal.queries.*;
import org.eclipse.persistence.internal.sessions.*;
import org.eclipse.persistence.internal.sessions.remote.ObjectDescriptor;
import org.eclipse.persistence.mappings.*;
import org.eclipse.persistence.mappings.converters.*;
import org.eclipse.persistence.mappings.structures.ArrayCollectionMapping;
import org.eclipse.persistence.mappings.structures.ArrayCollectionMappingHelper;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.sessions.remote.*;
import org.eclipse.persistence.sessions.CopyGroup;
/**
* AbstractCompositeDirectCollectionMapping consolidates the behavior of mappings that
* map collections of "native" data objects (e.g. Strings).
* These are objects that do not have their own descriptor and repeat within the XML record
* for the containing object.
*
* @author Big Country
* @since TOPLink/Java 3.0
*/
public abstract class AbstractCompositeDirectCollectionMapping extends DatabaseMapping implements ContainerMapping, ArrayCollectionMapping {
/** This is the field holding the nested collection. */
protected DatabaseField field;
/** This is the "data type" associated with each element in the nested collection.
Depending on the data store, this could be optional. */
protected String elementDataTypeName;
/** Allows user defined conversion between the object value and the database value. */
protected Converter valueConverter;
/** This determines the type of container used to hold the nested collection
in the object. */
private ContainerPolicy containerPolicy;
/**
* Default constructor.
*/
protected AbstractCompositeDirectCollectionMapping() {
super();
this.containerPolicy = ContainerPolicy.buildDefaultPolicy();
this.elementDataTypeName = "";
this.setWeight(WEIGHT_AGGREGATE);
}
/**
* PUBLIC:
* Return the converter on the mapping.
* A converter can be used to convert between the direct collection's object value and database value.
*/
public Converter getValueConverter() {
return valueConverter;
}
/**
* PUBLIC:
* Indicates if there is a converter on the mapping.
*/
public boolean hasValueConverter() {
return getValueConverter() != null;
}
/**
* PUBLIC:
* Set the converter on the mapping.
* A converter can be used to convert between the direct collection's object value and database value.
*/
public void setValueConverter(Converter valueConverter) {
this.valueConverter = valueConverter;
}
/**
* INTERNAL:
* Build and return a new element based on the change set.
*/
@Override
public Object buildAddedElementFromChangeSet(Object changeSet, MergeManager mergeManager, AbstractSession targetSession) {
return this.buildElementFromChangeSet(changeSet, mergeManager, targetSession);
}
/**
* INTERNAL:
* Clone the attribute from the clone and assign it to the backup.
* For these mappings, this is the same as building the first clone.
*/
@Override
public void buildBackupClone(Object clone, Object backup, UnitOfWorkImpl unitOfWork) {
this.buildClone(clone, null, backup, null, unitOfWork);
}
/**
* INTERNAL:
* Build and return a change set for the specified element.
* Direct collections simply store the element itself, since it is immutable.
*/
@Override
public Object buildChangeSet(Object element, ObjectChangeSet owner, AbstractSession session) {
return element;
}
/**
* INTERNAL:
* Clone the attribute from the original and assign it to the clone.
*/
@Override
public void buildClone(Object original, CacheKey cacheKey, Object clone, Integer refreshCascade, AbstractSession cloningSession) {
Object attributeValue = this.getAttributeValueFromObject(original);
this.setAttributeValueInObject(clone, this.buildClonePart(attributeValue, cacheKey, cloningSession));
}
/**
* INTERNAL:
* Extract value from the row and set the attribute to this value in the
* working copy clone.
* In order to bypass the shared cache when in transaction a UnitOfWork must
* be able to populate working copies directly from the row.
*/
@Override
public void buildCloneFromRow(AbstractRecord row, JoinedAttributeManager joinManager, Object clone, CacheKey sharedCacheKey, ObjectBuildingQuery sourceQuery, UnitOfWorkImpl unitOfWork, AbstractSession executionSession) {
// for direct collection a cloned value is no different from an original value
Object cloneAttributeValue = valueFromRow(row, joinManager, sourceQuery, sharedCacheKey, executionSession, true, new Boolean[1]);
setAttributeValueInObject(clone, cloneAttributeValue);
}
/**
* Build and return a clone of the specified attribute value.
*/
protected Object buildClonePart(Object attributeValue, CacheKey parentCacheKey, AbstractSession cloningSession) {
if (attributeValue == null) {
return this.getContainerPolicy().containerInstance();
} else {
if ((getValueConverter() == null) || (!getValueConverter().isMutable())) {
return this.getContainerPolicy().cloneFor(attributeValue);
}
// Clone the values of the collection as well.
Object cloneContainer = this.getContainerPolicy().containerInstance();
Object iterator = this.getContainerPolicy().iteratorFor(attributeValue);
while (this.getContainerPolicy().hasNext(iterator)) {
Object originalValue = this.getContainerPolicy().next(iterator, cloningSession);
// Bug 4182377 - there was a typo in the conversion logic
Object cloneValue = getValueConverter().convertDataValueToObjectValue(getValueConverter().convertObjectValueToDataValue(originalValue, cloningSession), cloningSession);
this.getContainerPolicy().addInto(cloneValue, cloneContainer, cloningSession);
}
return cloneContainer;
}
}
/**
* INTERNAL:
* Copy of the attribute of the object.
* This is NOT used for unit of work but for templatizing an object.
*/
@Override
public void buildCopy(Object copy, Object original, CopyGroup group) {
Object attributeValue = getAttributeValueFromObject(original);
if (attributeValue == null) {
attributeValue = getContainerPolicy().containerInstance();
} else {
attributeValue = getContainerPolicy().cloneFor(attributeValue);
}
setAttributeValueInObject(copy, attributeValue);
}
/**
* Build and return a new element based on the change set.
* Direct collections simply store the element itself, since it is immutable.
*/
protected Object buildElementFromChangeSet(Object changeSet, MergeManager mergeManager, AbstractSession targetSession) {
return changeSet;
}
/**
* INTERNAL:
* Build and return a new element based on the specified element.
* Direct collections simply return the element itself, since it is immutable.
*/
@Override
public Object buildElementFromElement(Object object, MergeManager mergeManager, AbstractSession targetSession) {
return object;
}
/**
* INTERNAL:
* Build and return a new element based on the change set.
*/
@Override
public Object buildRemovedElementFromChangeSet(Object changeSet, MergeManager mergeManager, AbstractSession targetSession) {
return this.buildElementFromChangeSet(changeSet, mergeManager, targetSession);
}
/**
* INTERNAL:
* Cascade perform delete through mappings that require the cascade
*/
@Override
public void cascadePerformRemoveIfRequired(Object object, UnitOfWorkImpl uow, Map visitedObjects) {
//objects referenced by this mapping are not registered as they have
// no identity, this is a no-op.
}
/**
* INTERNAL:
* Cascade registerNew for Create through mappings that require the cascade
*/
@Override
public void cascadeRegisterNewIfRequired(Object object, UnitOfWorkImpl uow, Map visitedObjects) {
//objects referenced by this mapping are not registered as they have
// no identity, this is a no-op.
}
/**
* Return the fields handled by the mapping.
*/
@Override
protected Vector collectFields() {
Vector fields = new Vector(1);
fields.addElement(this.getField());
return fields;
}
/**
* INTERNAL:
* Compare the non-null elements. Return true if they are alike.
* Use #equals() to determine if two elements are the same.
*/
@Override
public boolean compareElements(Object element1, Object element2, AbstractSession session) {
return element1.equals(element2);
}
/**
* INTERNAL:
* Compare the non-null elements and return true if they are alike.
*/
@Override
public boolean compareElementsForChange(Object element1, Object element2, AbstractSession session) {
return this.compareElements(element1, element2, session);
}
protected ChangeRecord convertToChangeRecord(Object cloneCollection, ObjectChangeSet owner, AbstractSession session) {
//since a minimal update for composites can't be done, we are only recording
//an all-or-none change. Therefore, this can be treated as a simple direct
//value.
ContainerPolicy cp = this.getContainerPolicy();
Object container = cp.containerInstance();
Object iter = cp.iteratorFor(cloneCollection);
while (cp.hasNext(iter)) {
cp.addInto(cp.next(iter, session), container, session);
}
DirectToFieldChangeRecord changeRecord = new DirectToFieldChangeRecord(owner);
changeRecord.setAttribute(getAttributeName());
changeRecord.setMapping(this);
changeRecord.setNewValue(container);
return changeRecord;
}
/**
* INTERNAL:
* An object has been serialized from the server to the client.
* Replace the transient attributes of the remote value holders
* with client-side objects.
*/
@Override
public void fixObjectReferences(Object object, Map