1 19 20 package org.apache.cayenne.access; 21 22 import java.util.ArrayList ; 23 import java.util.Collection ; 24 import java.util.Collections ; 25 import java.util.Iterator ; 26 import java.util.List ; 27 import java.util.Map ; 28 29 import org.apache.cayenne.ObjectId; 30 import org.apache.cayenne.PersistenceState; 31 import org.apache.cayenne.Persistent; 32 import org.apache.cayenne.Validating; 33 import org.apache.cayenne.graph.CompoundDiff; 34 import org.apache.cayenne.graph.GraphChangeHandler; 35 import org.apache.cayenne.graph.GraphDiff; 36 import org.apache.cayenne.validation.ValidationException; 37 import org.apache.cayenne.validation.ValidationResult; 38 39 46 class ObjectStoreGraphDiff implements GraphDiff { 47 48 private ObjectStore objectStore; 49 private GraphDiff resolvedDiff; 50 51 ObjectStoreGraphDiff(ObjectStore objectStore) { 52 this.objectStore = objectStore; 53 preprocess(objectStore); 54 } 55 56 Map getChangesByObjectId() { 57 return objectStore.getChangesByObjectId(); 58 } 59 60 63 boolean validateAndCheckNoop() { 64 if (getChangesByObjectId().isEmpty()) { 65 return true; 66 } 67 68 boolean noop = true; 69 70 73 Collection objectsToValidate = null; 74 75 Iterator it = getChangesByObjectId().values().iterator(); 76 while (it.hasNext()) { 77 78 ObjectDiff diff = (ObjectDiff) it.next(); 79 80 if (!diff.isNoop()) { 81 82 noop = false; 83 84 if (diff.getObject() instanceof Validating) { 85 if (objectsToValidate == null) { 86 objectsToValidate = new ArrayList (); 87 } 88 89 objectsToValidate.add(diff.getObject()); 90 } 91 92 } 93 } 94 95 if (objectsToValidate != null) { 96 ValidationResult result = new ValidationResult(); 97 98 Iterator validationIt = objectsToValidate.iterator(); 99 while (validationIt.hasNext()) { 100 Validating object = (Validating) validationIt.next(); 101 switch (((Persistent) object).getPersistenceState()) { 102 case PersistenceState.NEW: 103 object.validateForInsert(result); 104 break; 105 case PersistenceState.MODIFIED: 106 object.validateForUpdate(result); 107 break; 108 case PersistenceState.DELETED: 109 object.validateForDelete(result); 110 break; 111 } 112 } 113 114 if (result.hasFailures()) { 115 throw new ValidationException(result); 116 } 117 } 118 119 return noop; 120 } 121 122 public boolean isNoop() { 123 if (getChangesByObjectId().isEmpty()) { 124 return true; 125 } 126 127 Iterator it = getChangesByObjectId().values().iterator(); 128 while (it.hasNext()) { 129 if (!((ObjectDiff) it.next()).isNoop()) { 130 return false; 131 } 132 } 133 134 return true; 135 } 136 137 public void apply(GraphChangeHandler handler) { 138 resolveDiff(); 139 resolvedDiff.apply(handler); 140 } 141 142 public void undo(GraphChangeHandler handler) { 143 resolveDiff(); 144 resolvedDiff.undo(handler); 145 } 146 147 151 private void resolveDiff() { 152 if (resolvedDiff == null) { 153 154 CompoundDiff diff = new CompoundDiff(); 155 Map changes = getChangesByObjectId(); 156 157 if (!changes.isEmpty()) { 158 List allChanges = new ArrayList (changes.size() * 2); 159 160 Iterator it = changes.values().iterator(); 161 while (it.hasNext()) { 162 ((ObjectDiff) it.next()).appendDiffs(allChanges); 163 } 164 165 Collections.sort(allChanges); 166 diff.addAll(allChanges); 167 } 168 169 this.resolvedDiff = diff; 170 } 171 } 172 173 private void preprocess(ObjectStore objectStore) { 174 175 Map changes = getChangesByObjectId(); 176 if (!changes.isEmpty()) { 177 178 Iterator it = changes.entrySet().iterator(); 179 while (it.hasNext()) { 180 Map.Entry entry = (Map.Entry ) it.next(); 181 182 ObjectId id = (ObjectId) entry.getKey(); 183 184 Persistent object = (Persistent) objectStore.getNode(id); 185 186 ObjectId objectId = object.getObjectId(); 188 if (!id.equals(objectId)) { 189 190 if (objectId != null) { 191 Map replacement = id.getReplacementIdMap(); 192 replacement.clear(); 193 replacement.putAll(objectId.getIdSnapshot()); 194 } 195 196 object.setObjectId(id); 197 } 198 } 199 } 200 } 201 } 202 | Popular Tags |