FieldDescriptor[] fieldDescs = mif.getFieldDescriptions();
for (int i = 0; i < fieldDescs.length; i++)
{
FieldDescriptor fd = fieldDescs[i];
PersistentField f = fd.getPersistentField();
f.set(oldObj, f.get(newObj));
}
// N:1 relations
Iterator iter = mif.getObjectReferenceDescriptors().iterator();
ObjectReferenceDescriptor rds;
PersistentField field;
Object newRelObj;
Identity newRelOid;
Object oldRelObj;
while (iter.hasNext())
{
rds = (ObjectReferenceDescriptor) iter.next();
field = rds.getPersistentField();
newRelObj = field.get(newObj);
oldRelObj = field.get(oldObj);
if ((newRelObj == null) && (oldRelObj != null))
{
field.set(oldObj, null);
}
else if (newRelObj != null)
{
newRelOid = new Identity(newRelObj, pb);
if ((oldRelObj == null) ||
!newRelOid.equals(new Identity(oldRelObj, pb)))
{
// seek for existing old object with the new identity
oldRelObj = cache.lookup(newRelOid);
if (oldRelObj == null)
{
throw new IllegalStateException("Related object not found in the context: " + newRelOid);
}
field.set(oldObj, oldRelObj);
}
}
}
// 1:N relations
Iterator collections = mif.getCollectionDescriptors().iterator();
CollectionDescriptor collectionDescriptor;
while (collections.hasNext())
{
collectionDescriptor = (CollectionDescriptor) collections.next();
field = collectionDescriptor.getPersistentField();
if (Collection.class.isAssignableFrom(field.getType()))
{
Collection newCol;
Collection oldCol;
newCol = (Collection) field.get(newObj);
if (newCol == null)
{
field.set(oldObj, null);
continue;
}
oldCol = (Collection) field.get(oldObj);
if (newCol instanceof CollectionProxyDefaultImpl)
{
CollectionProxyDefaultImpl cp = (CollectionProxyDefaultImpl) newCol;
if (newCol instanceof List)
{
oldCol = new ListProxyDefaultImpl(pb.getPBKey(), cp.getCollectionClass(), cp.getQuery());
}
else if (newCol instanceof Set)
{
oldCol = new SetProxyDefaultImpl(pb.getPBKey(), cp.getCollectionClass(), cp.getQuery());
}
else
{
oldCol = new CollectionProxyDefaultImpl(pb.getPBKey(), cp.getCollectionClass(), cp.getQuery());
}
if (!((CollectionProxyDefaultImpl) newCol).isLoaded())
{
field.set(oldObj, oldCol);
continue;
}
oldCol.clear();
}
else
{
try
{
oldCol = (Collection) newCol.getClass().newInstance();
}
catch (Exception ex)
{
System.err.println("Cannot instantiate collection field which is neither Collection nor array: " + field);
ex.printStackTrace();
return newObj;
}
}
field.set(oldObj, oldCol);
for (Iterator it = newCol.iterator(); it.hasNext(); )
{
newRelObj = it.next();
newRelOid = new Identity(newRelObj, pb);
oldRelObj = cache.lookup(newRelOid);
if (oldRelObj == null)
{
oldRelObj = newRelObj;
}
oldCol.add(oldRelObj);
}
}
else if (field.getType().isArray())
{
Object newArray = field.get(newObj);
int length = Array.getLength(newArray);
Object oldArray =
Array.newInstance(field.getType().getComponentType(), length);
for (int i = 0; i < length; i++)
{
newRelObj = Array.get(newArray, i);
newRelOid = new Identity(newRelObj, pb);
oldRelObj = cache.lookup(newRelOid);
if (oldRelObj == null)
{
throw new IllegalStateException("Related object not found for swizzle: " + newRelOid);
}
Array.set(oldArray, i, oldRelObj);
}
field.set(oldObj, oldArray);
}
else
{
throw new IllegalStateException("Cannot swizzle collection field: " + field);
}