1 package org.apache.ojb.otm.swizzle; 2 3 17 18 import java.lang.reflect.Array ; 19 import java.util.Collection ; 20 import java.util.Iterator ; 21 import java.util.List ; 22 import java.util.Set ; 23 import org.apache.ojb.broker.Identity; 24 import org.apache.ojb.broker.PersistenceBroker; 25 import org.apache.ojb.broker.cache.ObjectCache; 26 import org.apache.ojb.broker.core.proxy.CollectionProxyDefaultImpl; 27 import org.apache.ojb.broker.core.proxy.ListProxyDefaultImpl; 28 import org.apache.ojb.broker.core.proxy.SetProxyDefaultImpl; 29 import org.apache.ojb.broker.metadata.ClassDescriptor; 30 import org.apache.ojb.broker.metadata.CollectionDescriptor; 31 import org.apache.ojb.broker.metadata.FieldDescriptor; 32 import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor; 33 import org.apache.ojb.broker.metadata.fieldaccess.PersistentField; 34 35 public class CopySwizzling implements Swizzling 36 { 37 38 41 public Object swizzle(Object newObj, Object oldObj, PersistenceBroker pb, 42 ObjectCache cache) 43 { 44 if (newObj == null) { 46 return null; 47 } 48 49 if (oldObj == null) 50 { 51 return newObj; 52 } 53 54 if (!newObj.getClass().equals(oldObj.getClass())) 55 { 56 System.err.println("Cannot swizzle objects of different classes: " 57 + newObj.getClass() + " and " + oldObj.getClass()); 58 return newObj; 59 } 60 61 ClassDescriptor mif = pb.getClassDescriptor(newObj.getClass()); 62 FieldDescriptor[] fieldDescs = mif.getFieldDescriptions(); 63 64 for (int i = 0; i < fieldDescs.length; i++) 65 { 66 FieldDescriptor fd = fieldDescs[i]; 67 PersistentField f = fd.getPersistentField(); 68 f.set(oldObj, f.get(newObj)); 69 } 70 71 Iterator iter = mif.getObjectReferenceDescriptors().iterator(); 73 ObjectReferenceDescriptor rds; 74 PersistentField field; 75 Object newRelObj; 76 Identity newRelOid; 77 Object oldRelObj; 78 79 while (iter.hasNext()) 80 { 81 rds = (ObjectReferenceDescriptor) iter.next(); 82 field = rds.getPersistentField(); 83 newRelObj = field.get(newObj); 84 oldRelObj = field.get(oldObj); 85 if ((newRelObj == null) && (oldRelObj != null)) 86 { 87 field.set(oldObj, null); 88 } 89 else if (newRelObj != null) 90 { 91 newRelOid = new Identity(newRelObj, pb); 92 if ((oldRelObj == null) || 93 !newRelOid.equals(new Identity(oldRelObj, pb))) 94 { 95 oldRelObj = cache.lookup(newRelOid); 97 if (oldRelObj == null) 98 { 99 throw new IllegalStateException ("Related object not found in the context: " + newRelOid); 100 } 101 field.set(oldObj, oldRelObj); 102 } 103 } 104 } 105 106 Iterator collections = mif.getCollectionDescriptors().iterator(); 108 CollectionDescriptor collectionDescriptor; 109 110 while (collections.hasNext()) 111 { 112 collectionDescriptor = (CollectionDescriptor) collections.next(); 113 field = collectionDescriptor.getPersistentField(); 114 if (Collection .class.isAssignableFrom(field.getType())) 115 { 116 Collection newCol; 117 Collection oldCol; 118 119 newCol = (Collection ) field.get(newObj); 120 if (newCol == null) 121 { 122 field.set(oldObj, null); 123 continue; 124 } 125 126 oldCol = (Collection ) field.get(oldObj); 127 if (newCol instanceof CollectionProxyDefaultImpl) 128 { 129 CollectionProxyDefaultImpl cp = (CollectionProxyDefaultImpl) newCol; 130 if (newCol instanceof List ) 131 { 132 oldCol = new ListProxyDefaultImpl(pb.getPBKey(), cp.getCollectionClass(), cp.getQuery()); 133 } 134 else if (newCol instanceof Set ) 135 { 136 oldCol = new SetProxyDefaultImpl(pb.getPBKey(), cp.getCollectionClass(), cp.getQuery()); 137 } 138 else 139 { 140 oldCol = new CollectionProxyDefaultImpl(pb.getPBKey(), cp.getCollectionClass(), cp.getQuery()); 141 } 142 if (!((CollectionProxyDefaultImpl) newCol).isLoaded()) 143 { 144 field.set(oldObj, oldCol); 145 continue; 146 } 147 oldCol.clear(); 148 } 149 else 150 { 151 try 152 { 153 oldCol = (Collection ) newCol.getClass().newInstance(); 154 } 155 catch (Exception ex) 156 { 157 System.err.println("Cannot instantiate collection field which is neither Collection nor array: " + field); 158 ex.printStackTrace(); 159 return newObj; 160 } 161 } 162 field.set(oldObj, oldCol); 163 for (Iterator it = newCol.iterator(); it.hasNext(); ) 164 { 165 newRelObj = it.next(); 166 newRelOid = new Identity(newRelObj, pb); 167 oldRelObj = cache.lookup(newRelOid); 168 if (oldRelObj == null) 169 { 170 oldRelObj = newRelObj; 171 } 172 oldCol.add(oldRelObj); 173 } 174 } 175 else if (field.getType().isArray()) 176 { 177 Object newArray = field.get(newObj); 178 int length = Array.getLength(newArray); 179 Object oldArray = 180 Array.newInstance(field.getType().getComponentType(), length); 181 182 for (int i = 0; i < length; i++) 183 { 184 newRelObj = Array.get(newArray, i); 185 newRelOid = new Identity(newRelObj, pb); 186 oldRelObj = cache.lookup(newRelOid); 187 if (oldRelObj == null) 188 { 189 throw new IllegalStateException ("Related object not found for swizzle: " + newRelOid); 190 } 191 Array.set(oldArray, i, oldRelObj); 192 } 193 field.set(oldObj, oldArray); 194 } 195 else 196 { 197 throw new IllegalStateException ("Cannot swizzle collection field: " + field); 198 } 199 } 200 201 return oldObj; 202 } 203 204 207 public boolean isSameInstance(Object swizzledObject, Object object) 208 { 209 return (swizzledObject == object); 210 } 211 212 215 public Object getRealTarget(Object swizzledObject) 216 { 217 return swizzledObject; 218 } 219 220 } 221 | Popular Tags |