use of org.eclipse.persistence.internal.queries.ContainerPolicy in project eclipselink by eclipse-ee4j.
the class ArrayCollectionMappingHelper method mergeChangesIntoObjectWithoutOrder.
/**
* Merge changes from the source to the target object.
* Make the necessary removals and adds and map key modifications.
*/
private void mergeChangesIntoObjectWithoutOrder(Object target, ChangeRecord changeRecord, Object source, MergeManager mergeManager, AbstractSession targetSession) {
EISCollectionChangeRecord sdkChangeRecord = (EISCollectionChangeRecord) changeRecord;
ContainerPolicy cp = getContainerPolicy();
AbstractSession session = mergeManager.getSession();
Object targetCollection = null;
if (sdkChangeRecord.getOwner().isNew()) {
targetCollection = cp.containerInstance(sdkChangeRecord.getAdds().size());
} else {
targetCollection = getRealCollectionAttributeValueFromObject(target, session);
}
List removes = sdkChangeRecord.getRemoves();
List adds = sdkChangeRecord.getAdds();
List changedMapKeys = sdkChangeRecord.getChangedMapKeys();
synchronized (targetCollection) {
for (Object removed : removes) {
Object removeElement = buildRemovedElementFromChangeSet(removed, mergeManager, targetSession);
Object targetElement = null;
for (Object iter = cp.iteratorFor(targetCollection); cp.hasNext(iter); ) {
targetElement = cp.next(iter, session);
if (compareElements(targetElement, removeElement, session)) {
// matching element found - skip the rest of them
break;
}
}
if (targetElement != null) {
// a matching element was found, remove it
cp.removeFrom(targetElement, targetCollection, session);
}
}
for (Object added : adds) {
Object addElement = buildAddedElementFromChangeSet(added, mergeManager, targetSession);
cp.addInto(addElement, targetCollection, session);
}
for (Object changed : changedMapKeys) {
Object changedMapKeyElement = buildAddedElementFromChangeSet(changed, mergeManager, targetSession);
Object originalElement = ((UnitOfWorkImpl) session).getOriginalVersionOfObject(changedMapKeyElement);
cp.removeFrom(originalElement, targetCollection, session);
cp.addInto(changedMapKeyElement, targetCollection, session);
}
}
// reset the attribute to allow for set method to re-morph changes if the collection is not being stored directly
setRealAttributeValueInObject(target, targetCollection);
}
use of org.eclipse.persistence.internal.queries.ContainerPolicy in project eclipselink by eclipse-ee4j.
the class ArrayCollectionMappingHelper method compareForChange.
/**
* INTERNAL:
* Build and return the change record that results
* from comparing the two collection attributes.
*/
public ChangeRecord compareForChange(Object clone, Object backup, ObjectChangeSet owner, AbstractSession session) {
ContainerPolicy cp = this.getContainerPolicy();
Object cloneCollection = this.getRealCollectionAttributeValueFromObject(clone, session);
Object backupCollection = null;
if (owner.isNew()) {
backupCollection = cp.containerInstance(1);
} else {
backupCollection = this.getRealCollectionAttributeValueFromObject(backup, session);
}
if (cp.hasOrder()) {
return this.compareAttributeValuesForChangeWithOrder(cloneCollection, backupCollection, owner, session);
} else {
return this.compareAttributeValuesForChangeWithoutOrder(cloneCollection, backupCollection, owner, session);
}
}
use of org.eclipse.persistence.internal.queries.ContainerPolicy in project eclipselink by eclipse-ee4j.
the class ArrayCollectionMappingHelper method compareAttributeValuesForChangeWithoutOrder.
/**
* Build and return the change record that results
* from comparing the two collection attributes.
* Ignore the order of the elements.
*/
private ChangeRecord compareAttributeValuesForChangeWithoutOrder(Object cloneCollection, Object backupCollection, ObjectChangeSet owner, AbstractSession session) {
ContainerPolicy cp = this.getContainerPolicy();
// "clone" it so we can clear out the slots
Vector backupVector = cp.vectorFor(backupCollection, session);
EISCollectionChangeRecord changeRecord = new EISCollectionChangeRecord(owner, getAttributeName(), this.getDatabaseMapping());
for (Object cloneIter = cp.iteratorFor(cloneCollection); cp.hasNext(cloneIter); ) {
Object cloneElement = cp.next(cloneIter, session);
boolean found = false;
for (int i = 0; i < backupVector.size(); i++) {
if (this.compareElementsForChange(cloneElement, backupVector.elementAt(i), session)) {
// the clone element was found in the backup collection
found = true;
// clear out the matching backup element
backupVector.setElementAt(XXX, i);
if (this.mapKeyHasChanged(cloneElement, session)) {
changeRecord.addChangedMapKeyChangeSet(this.buildChangeSet(cloneElement, owner, session));
}
// matching backup element found - skip the rest of them
break;
}
}
if (!found) {
// the clone element was not found, so it must have been added
changeRecord.addAddedChangeSet(this.buildChangeSet(cloneElement, owner, session));
}
}
for (int i = 0; i < backupVector.size(); i++) {
Object backupElement = backupVector.elementAt(i);
if (backupElement != XXX) {
// the backup element was not in the clone collection, so it must have been removed
changeRecord.addRemovedChangeSet(this.buildChangeSet(backupElement, owner, session));
}
}
if (changeRecord.hasChanges()) {
return changeRecord;
} else {
return null;
}
}
use of org.eclipse.persistence.internal.queries.ContainerPolicy in project eclipselink by eclipse-ee4j.
the class XMLCollectionReferenceMapping method useMapClass.
/**
* PUBLIC:
* Configure the mapping to use an instance of the specified container class
* to hold the target objects. The key used to index the value in the Map
* is the value returned by a call to the specified zero-argument method.
* The method must be implemented by the class (or a superclass) of the
* value to be inserted into the Map.
* <p>jdk1.2.x: The container class must implement (directly or indirectly) the Map interface.
* <p>jdk1.1.x: The container class must be a subclass of Hashtable.
* <p>The referenceClass must be set before calling this method.
*/
@Override
public void useMapClass(Class<?> concreteContainerClass, String methodName) {
// the reference class has to be specified before coming here
if (this.getReferenceClass() == null) {
throw DescriptorException.referenceClassNotSpecified(this);
}
ContainerPolicy policy = ContainerPolicy.buildPolicyFor(concreteContainerClass);
policy.setKeyName(methodName, getReferenceClass().getName());
this.setContainerPolicy(policy);
}
use of org.eclipse.persistence.internal.queries.ContainerPolicy in project eclipselink by eclipse-ee4j.
the class XMLCollectionReferenceMapping method initialize.
/**
* INTERNAL:
* The mapping is initialized with the given session. This mapping is fully initialized
* after this.
*/
@Override
public void initialize(AbstractSession session) throws DescriptorException {
super.initialize(session);
if (null != getField()) {
setField(getDescriptor().buildField(getField()));
}
ContainerPolicy cp = getContainerPolicy();
if (cp != null) {
if (cp.getContainerClass() == null) {
Class<Object> cls = session.getDatasourcePlatform().getConversionManager().convertClassNameToClass(cp.getContainerClassName());
cp.setContainerClass(cls);
}
}
}
Aggregations