1 56 package org.objectstyle.cayenne.access; 57 58 import java.util.ArrayList ; 59 import java.util.Collections ; 60 import java.util.Iterator ; 61 import java.util.List ; 62 63 import org.objectstyle.cayenne.CayenneRuntimeException; 64 import org.objectstyle.cayenne.DataObject; 65 import org.objectstyle.cayenne.DataRow; 66 import org.objectstyle.cayenne.PersistenceState; 67 import org.objectstyle.cayenne.map.DeleteRule; 68 import org.objectstyle.cayenne.map.ObjEntity; 69 import org.objectstyle.cayenne.map.ObjRelationship; 70 71 77 class DataContextDeleteAction { 78 79 DataContext dataContext; 80 81 DataContextDeleteAction(DataContext context) { 82 this.dataContext = context; 83 } 84 85 88 boolean performDelete(DataObject object) throws DeleteDenyException { 89 int oldState = object.getPersistenceState(); 90 if (oldState == PersistenceState.DELETED 91 || oldState == PersistenceState.TRANSIENT) { 92 93 return false; 98 } 99 100 object.resolveFault(); 103 104 if (oldState == PersistenceState.NEW) { 105 deleteNew(object, oldState); 106 } 107 else { 108 deletePersistent(object, oldState); 109 } 110 111 return true; 112 } 113 114 private void deletePersistent(DataObject object, int oldState) 115 throws DeleteDenyException { 116 117 DataRow snapshot = dataContext.getObjectStore().getCachedSnapshot(object 121 .getObjectId()); 122 if (snapshot == null) { 123 snapshot = dataContext.currentSnapshot(object); 124 } 125 126 130 object.setPersistenceState(PersistenceState.DELETED); 131 processDeleteRules(object, oldState); 132 133 dataContext.getObjectStore().retainSnapshot(object, snapshot); 135 } 136 137 private void deleteNew(DataObject object, int oldState) throws DeleteDenyException { 138 object.setPersistenceState(PersistenceState.TRANSIENT); 139 processDeleteRules(object, oldState); 140 141 143 dataContext.getObjectStore().objectsUnregistered(Collections 144 .singletonList(object)); 145 object.setDataContext(null); 146 } 147 148 private void processDeleteRules(DataObject object, int oldState) 149 throws DeleteDenyException { 150 ObjEntity entity = dataContext.getEntityResolver().lookupObjEntity(object); 151 Iterator it = entity.getRelationships().iterator(); 152 while (it.hasNext()) { 153 ObjRelationship relationship = (ObjRelationship) it.next(); 154 155 boolean processFlattened = relationship.isFlattened() 156 && relationship.isToDependentEntity(); 157 158 if (relationship.getDeleteRule() == DeleteRule.NO_ACTION && !processFlattened) { 160 continue; 161 } 162 163 List relatedObjects = Collections.EMPTY_LIST; 164 if (relationship.isToMany()) { 165 166 List toMany = (List ) object.readNestedProperty(relationship.getName()); 167 168 if (toMany.size() > 0) { 169 relatedObjects = new ArrayList (toMany); 172 } 173 } 174 else { 175 Object relatedObject = object.readNestedProperty(relationship.getName()); 176 177 if (relatedObject != null) { 178 relatedObjects = Collections.singletonList(relatedObject); 179 } 180 } 181 182 if (relatedObjects.size() == 0) { 184 continue; 185 } 186 187 if (relationship.getDeleteRule() == DeleteRule.DENY) { 189 object.setPersistenceState(oldState); 190 191 String message = relatedObjects.size() == 1 192 ? "1 related object" 193 : relatedObjects.size() + " related objects"; 194 throw new DeleteDenyException(object, relationship, message); 195 } 196 197 if (processFlattened) { 201 ObjectStore objectStore = dataContext.getObjectStore(); 202 Iterator iterator = relatedObjects.iterator(); 203 while (iterator.hasNext()) { 204 DataObject relatedObject = (DataObject) iterator.next(); 205 objectStore.flattenedRelationshipUnset(object, 206 relationship, 207 relatedObject); 208 } 209 } 210 211 switch (relationship.getDeleteRule()) { 213 case DeleteRule.NO_ACTION: 214 break; 215 case DeleteRule.NULLIFY: 216 ObjRelationship inverseRelationship = relationship 217 .getReverseRelationship(); 218 219 if (inverseRelationship == null) { 220 break; 222 } 223 224 if (inverseRelationship.isToMany()) { 225 Iterator iterator = relatedObjects.iterator(); 226 while (iterator.hasNext()) { 227 DataObject relatedObject = (DataObject) iterator.next(); 228 relatedObject.removeToManyTarget(inverseRelationship 229 .getName(), object, true); 230 } 231 } 232 else { 233 Iterator iterator = relatedObjects.iterator(); 236 while (iterator.hasNext()) { 237 DataObject relatedObject = (DataObject) iterator.next(); 238 relatedObject.setToOneTarget(inverseRelationship.getName(), 239 null, 240 true); 241 } 242 } 243 244 break; 245 case DeleteRule.CASCADE: 246 Iterator iterator = relatedObjects.iterator(); 248 while (iterator.hasNext()) { 249 DataObject relatedObject = (DataObject) iterator.next(); 250 new DataContextDeleteAction(this.dataContext) 251 .performDelete(relatedObject); 252 } 253 254 break; 255 default: 256 object.setPersistenceState(oldState); 257 throw new CayenneRuntimeException("Invalid delete rule " 258 + relationship.getDeleteRule()); 259 } 260 } 261 } 262 } | Popular Tags |