1 56 57 package org.objectstyle.cayenne.access; 58 59 import java.util.Iterator ; 60 import java.util.Map ; 61 62 import org.objectstyle.cayenne.DataObject; 63 import org.objectstyle.cayenne.DataRow; 64 import org.objectstyle.cayenne.Fault; 65 import org.objectstyle.cayenne.ObjectId; 66 import org.objectstyle.cayenne.PersistenceState; 67 import org.objectstyle.cayenne.conf.Configuration; 68 import org.objectstyle.cayenne.map.DbJoin; 69 import org.objectstyle.cayenne.map.DbRelationship; 70 import org.objectstyle.cayenne.map.ObjAttribute; 71 import org.objectstyle.cayenne.map.ObjEntity; 72 import org.objectstyle.cayenne.map.ObjRelationship; 73 import org.objectstyle.cayenne.util.Util; 74 75 82 class DataRowUtils { 83 84 89 static void refreshObjectWithSnapshot( 90 ObjEntity objEntity, 91 DataObject object, 92 DataRow snapshot, 93 boolean invalidateToManyRelationships) { 94 95 Map attrMap = objEntity.getAttributeMap(); 96 Iterator it = attrMap.keySet().iterator(); 97 boolean isPartialSnapshot = false; 98 while (it.hasNext()) { 99 String attrName = (String ) it.next(); 100 ObjAttribute attr = (ObjAttribute) attrMap.get(attrName); 101 String dbAttrPath = attr.getDbAttributePath(); 102 object.writePropertyDirectly(attrName, snapshot.get(dbAttrPath)); 103 if (!snapshot.containsKey(dbAttrPath)) { 104 isPartialSnapshot = true; 112 } 113 } 114 115 Iterator rit = objEntity.getRelationships().iterator(); 116 while (rit.hasNext()) { 117 ObjRelationship rel = (ObjRelationship) rit.next(); 118 if (rel.isToMany()) { 119 120 125 Object toManyList = object.readPropertyDirectly(rel.getName()); 126 127 if (toManyList == null) { 128 object.writePropertyDirectly(rel.getName(), Fault.getToManyFault()); 129 } 130 else if ( 131 invalidateToManyRelationships && toManyList instanceof ToManyList) { 132 ((ToManyList) toManyList).invalidateObjectList(); 133 } 134 135 continue; 136 } 137 138 object.writePropertyDirectly(rel.getName(), Fault.getToOneFault()); 140 } 141 142 if (isPartialSnapshot) { 143 object.setPersistenceState(PersistenceState.HOLLOW); 144 } 145 else { 146 object.setPersistenceState(PersistenceState.COMMITTED); 147 object.setSnapshotVersion(snapshot.getVersion()); 148 } 149 150 } 151 152 static void forceMergeWithSnapshot( 153 ObjEntity entity, 154 DataObject anObject, 155 DataRow snapshot) { 156 157 DataContext context = anObject.getDataContext(); 158 Map oldSnap = 159 context.getObjectStore().getSnapshot(anObject.getObjectId(), context); 160 161 Map attrMap = entity.getAttributeMap(); 163 Iterator it = attrMap.keySet().iterator(); 164 while (it.hasNext()) { 165 String attrName = (String ) it.next(); 166 ObjAttribute attr = (ObjAttribute) attrMap.get(attrName); 167 168 String dbAttrPath = attr.getDbAttributePath(); 170 171 Object newVal = snapshot.get(dbAttrPath); 176 if (newVal == null && !snapshot.containsKey(dbAttrPath)) { 177 continue; 178 } 179 180 Object curVal = anObject.readPropertyDirectly(attrName); 181 Object oldVal = oldSnap.get(dbAttrPath); 182 183 if (Util.nullSafeEquals(curVal, oldVal) 186 && !Util.nullSafeEquals(newVal, curVal)) { 187 anObject.writePropertyDirectly(attrName, newVal); 188 } 189 } 190 191 Iterator rit = entity.getRelationships().iterator(); 193 while (rit.hasNext()) { 194 ObjRelationship rel = (ObjRelationship) rit.next(); 195 if (rel.isToMany()) { 196 continue; 197 } 198 199 202 if (!isToOneTargetModified(rel, anObject, oldSnap) 205 && isJoinAttributesModified(rel, snapshot, oldSnap)) { 206 207 DbRelationship dbRelationship = 208 (DbRelationship) rel.getDbRelationships().get(0); 209 210 ObjectId id = 211 snapshot.createTargetObjectId( 212 ((ObjEntity) rel.getTargetEntity()).getJavaClass( 213 Configuration.getResourceLoader()), 214 dbRelationship); 215 DataObject target = (id != null) ? context.registeredObject(id) : null; 216 217 anObject.writePropertyDirectly(rel.getName(), target); 218 } 219 } 220 } 221 222 227 static void mergeObjectWithSnapshot( 228 ObjEntity entity, 229 DataObject anObject, 230 Map snapshot) { 231 232 DataRow dataRow = 236 (snapshot instanceof DataRow) ? (DataRow) snapshot : new DataRow(snapshot); 237 238 if (entity.isReadOnly() 239 || anObject.getPersistenceState() == PersistenceState.HOLLOW) { 240 refreshObjectWithSnapshot(entity, anObject, dataRow, true); 241 } 242 else if (anObject.getPersistenceState() == PersistenceState.COMMITTED) { 243 refreshObjectWithSnapshot(entity, anObject, dataRow, false); 246 } 247 else { 248 forceMergeWithSnapshot(entity, anObject, dataRow); 249 } 250 } 251 252 256 static boolean isJoinAttributesModified( 257 ObjRelationship relationship, 258 Map newSnapshot, 259 Map storedSnapshot) { 260 261 Iterator it = 262 ((DbRelationship) relationship.getDbRelationships().get(0)) 263 .getJoins() 264 .iterator(); 265 while (it.hasNext()) { 266 DbJoin join = (DbJoin) it.next(); 267 String propertyName = join.getSourceName(); 268 269 if (!Util 272 .nullSafeEquals( 273 newSnapshot.get(propertyName), 274 storedSnapshot.get(propertyName))) { 275 return true; 276 } 277 } 278 279 return false; 280 } 281 282 286 static boolean isToOneTargetModified( 287 ObjRelationship relationship, 288 DataObject object, 289 Map storedSnapshot) { 290 291 if (object.getPersistenceState() != PersistenceState.MODIFIED) { 292 return false; 293 } 294 295 Object targetObject = object.readPropertyDirectly(relationship.getName()); 296 if (targetObject instanceof Fault) { 297 return false; 298 } 299 300 DataObject toOneTarget = (DataObject) targetObject; 301 ObjectId currentId = (toOneTarget != null) ? toOneTarget.getObjectId() : null; 302 303 if (currentId != null && currentId.isTemporary()) { 306 return true; 307 } 308 309 Iterator it = 312 ((DbRelationship) relationship.getDbRelationships().get(0)) 313 .getJoins() 314 .iterator(); 315 316 while (it.hasNext()) { 317 DbJoin join = (DbJoin) it.next(); 318 String propertyName = join.getSourceName(); 319 320 if (currentId == null) { 321 if (storedSnapshot.get(propertyName) != null) { 323 return true; 324 } 325 } 326 else { 327 if (!Util 332 .nullSafeEquals( 333 currentId.getValueForAttribute(join.getTarget().getName()), 334 storedSnapshot.get(propertyName))) { 335 return true; 336 } 337 } 338 } 339 340 return false; 341 } 342 343 346 DataRowUtils() { 347 super(); 348 } 349 } 350 | Popular Tags |