1 19 20 package org.apache.cayenne.access; 21 22 import java.util.ArrayList ; 23 import java.util.HashMap ; 24 import java.util.Iterator ; 25 import java.util.List ; 26 import java.util.Map ; 27 28 import org.apache.cayenne.CayenneRuntimeException; 29 import org.apache.cayenne.DataObject; 30 import org.apache.cayenne.DataRow; 31 import org.apache.cayenne.ObjectId; 32 import org.apache.cayenne.PersistenceState; 33 import org.apache.cayenne.Persistent; 34 import org.apache.cayenne.map.DbAttribute; 35 import org.apache.cayenne.map.DbEntity; 36 import org.apache.cayenne.map.EntityInheritanceTree; 37 import org.apache.cayenne.map.ObjEntity; 38 import org.apache.cayenne.reflect.ClassDescriptor; 39 40 46 class ObjectResolver { 47 48 DataContext context; 49 ClassDescriptor descriptor; 50 List primaryKey; 51 52 EntityInheritanceTree inheritanceTree; 53 boolean refreshObjects; 54 boolean resolveInheritance; 55 DataRowStore cache; 56 57 ObjectResolver(DataContext context, ClassDescriptor descriptor, boolean refresh, 58 boolean resolveInheritanceHierarchy) { 59 init(context, descriptor, refresh, resolveInheritanceHierarchy); 60 } 61 62 void init( 63 DataContext context, 64 ClassDescriptor descriptor, 65 boolean refresh, 66 boolean resolveInheritanceHierarchy) { 67 DbEntity dbEntity = descriptor.getEntity().getDbEntity(); 69 if (dbEntity == null) { 70 throw new CayenneRuntimeException("ObjEntity '" 71 + descriptor.getEntity().getName() 72 + "' has no DbEntity."); 73 } 74 75 this.primaryKey = dbEntity.getPrimaryKey(); 76 if (primaryKey.size() == 0) { 77 throw new CayenneRuntimeException("Won't be able to create ObjectId for '" 78 + descriptor.getEntity().getName() 79 + "'. Reason: DbEntity '" 80 + dbEntity.getName() 81 + "' has no Primary Key defined."); 82 } 83 84 this.context = context; 85 this.cache = context.getObjectStore().getDataRowCache(); 86 this.refreshObjects = refresh; 87 this.descriptor = descriptor; 88 this.inheritanceTree = context.getEntityResolver().lookupInheritanceTree( 89 descriptor.getEntity()); 90 this.resolveInheritance = (inheritanceTree != null) 91 ? resolveInheritanceHierarchy 92 : false; 93 } 94 95 98 List synchronizedObjectsFromDataRows(List rows) { 99 synchronized (context.getObjectStore()) { 100 return objectsFromDataRows(rows); 101 } 102 } 103 104 111 List objectsFromDataRows(List rows) { 112 if (rows == null || rows.size() == 0) { 113 return new ArrayList (1); 114 } 115 116 List results = new ArrayList (rows.size()); 117 Iterator it = rows.iterator(); 118 119 while (it.hasNext()) { 120 results.add(objectFromDataRow((DataRow) it.next())); 121 } 122 123 cache.snapshotsUpdatedForObjects(results, rows, refreshObjects); 125 126 return results; 127 } 128 129 139 List relatedObjectsFromDataRows(List rows, PrefetchProcessorNode node) { 140 if (rows == null || rows.size() == 0) { 141 return new ArrayList (1); 142 } 143 144 ObjEntity sourceObjEntity = (ObjEntity) node 145 .getIncoming() 146 .getRelationship() 147 .getSourceEntity(); 148 String relatedIdPrefix = node 149 .getIncoming() 150 .getRelationship() 151 .getReverseDbRelationshipPath() 152 + "."; 153 154 List results = new ArrayList (rows.size()); 155 Iterator it = rows.iterator(); 156 157 while (it.hasNext()) { 158 159 DataRow row = (DataRow) it.next(); 160 Persistent object = objectFromDataRow(row); 161 results.add(object); 162 163 165 ObjectId id = createObjectId(row, sourceObjEntity, relatedIdPrefix); 168 Persistent parentObject = (Persistent) context.getObjectStore().getNode(id); 169 170 if (parentObject != null 172 && parentObject.getPersistenceState() != PersistenceState.HOLLOW) { 173 node.linkToParent(object, parentObject); 174 } 175 } 176 177 cache.snapshotsUpdatedForObjects(results, rows, refreshObjects); 179 180 return results; 181 } 182 183 187 Persistent objectFromDataRow(DataRow row) { 188 189 ClassDescriptor classDescriptor; 191 192 if (resolveInheritance) { 193 ObjEntity objectEntity = inheritanceTree.entityMatchingRow(row); 194 195 classDescriptor = (objectEntity != null) ? context 197 .getEntityResolver() 198 .getClassDescriptor(objectEntity.getName()) : descriptor; 199 } 200 else { 201 classDescriptor = descriptor; 202 } 203 204 ObjectId anId = createObjectId(row, classDescriptor.getEntity(), null); 207 208 Persistent object = context.localObject(anId, null); 210 211 int state = object.getPersistenceState(); 213 switch (state) { 214 case PersistenceState.COMMITTED: 215 case PersistenceState.MODIFIED: 216 case PersistenceState.DELETED: 217 if (refreshObjects) { 219 DataRowUtils.mergeObjectWithSnapshot( 220 context, 221 classDescriptor, 222 object, 223 row); 224 225 if (object instanceof DataObject) { 226 ((DataObject) object).setSnapshotVersion(row.getVersion()); 227 } 228 } 229 break; 230 case PersistenceState.HOLLOW: 231 if (!refreshObjects) { 232 DataRow cachedRow = cache.getCachedSnapshot(anId); 233 if (cachedRow != null) { 234 row = cachedRow; 235 } 236 } 237 DataRowUtils.mergeObjectWithSnapshot( 238 context, 239 classDescriptor, 240 object, 241 row); 242 if (object instanceof DataObject) { 243 ((DataObject) object).setSnapshotVersion(row.getVersion()); 244 } 245 break; 246 default: 247 break; 248 } 249 250 return object; 251 } 252 253 ObjEntity getEntity() { 254 return descriptor.getEntity(); 255 } 256 257 ClassDescriptor getDescriptor() { 258 return descriptor; 259 } 260 261 ObjectId createObjectId(DataRow dataRow, ObjEntity objEntity, String namePrefix) { 262 263 List pk = objEntity == this.descriptor.getEntity() ? this.primaryKey : objEntity 264 .getDbEntity() 265 .getPrimaryKey(); 266 267 boolean prefix = namePrefix != null && namePrefix.length() > 0; 268 269 272 if (pk.size() == 1) { 273 DbAttribute attribute = (DbAttribute) pk.get(0); 274 275 String key = (prefix) ? namePrefix + attribute.getName() : attribute 276 .getName(); 277 278 Object val = dataRow.get(key); 279 if (val == null) { 280 throw new CayenneRuntimeException("Null value for '" 281 + key 282 + "'. Snapshot: " 283 + dataRow 284 + ". Prefix: " 285 + namePrefix); 286 } 287 288 return new ObjectId(objEntity.getName(), attribute.getName(), val); 290 } 291 292 294 Map idMap = new HashMap (pk.size() * 2); 295 Iterator it = pk.iterator(); 296 while (it.hasNext()) { 297 DbAttribute attribute = (DbAttribute) it.next(); 298 299 String key = (prefix) ? namePrefix + attribute.getName() : attribute 300 .getName(); 301 302 Object val = dataRow.get(key); 303 if (val == null) { 304 throw new CayenneRuntimeException("Null value for '" 305 + key 306 + "'. Snapshot: " 307 + dataRow 308 + ". Prefix: " 309 + namePrefix); 310 } 311 312 idMap.put(attribute.getName(), val); 314 } 315 316 return new ObjectId(objEntity.getName(), idMap); 317 } 318 } 319 | Popular Tags |