1 19 20 package org.apache.cayenne.util; 21 22 import java.util.Collection ; 23 import java.util.Iterator ; 24 import java.util.LinkedList ; 25 import java.util.List ; 26 import java.util.ListIterator ; 27 28 import org.apache.cayenne.CayenneRuntimeException; 29 import org.apache.cayenne.PersistenceState; 30 import org.apache.cayenne.Persistent; 31 import org.apache.cayenne.ValueHolder; 32 33 39 public class PersistentObjectList extends RelationshipFault implements List , ValueHolder { 40 41 protected List objectList; 43 44 protected LinkedList addedToUnresolved; 46 protected LinkedList removedFromUnresolved; 47 48 private PersistentObjectList() { 50 51 } 52 53 60 public PersistentObjectList(Persistent relationshipOwner, String relationshipName) { 61 super(relationshipOwner, relationshipName); 62 } 63 64 67 public boolean isFault() { 68 69 if (objectList != null) { 70 return false; 71 } 72 else if (isTransientParent()) { 76 objectList = new LinkedList (); 77 return false; 78 } 79 else { 80 return true; 81 } 82 } 83 84 87 public void invalidate() { 88 setObjectList(null); 89 } 90 91 public Object setValueDirectly(Object value) throws CayenneRuntimeException { 92 if (value == null || value instanceof List ) { 93 Object old = this.objectList; 94 setObjectList((List ) value); 95 return old; 96 } 97 else { 98 throw new CayenneRuntimeException("Value must be a list, got: " 99 + value.getClass().getName()); 100 } 101 } 102 103 public Object getValue() throws CayenneRuntimeException { 104 return resolvedObjectList(); 105 } 106 107 public Object getValueDirectly() throws CayenneRuntimeException { 108 return objectList; 109 } 110 111 public Object setValue(Object value) throws CayenneRuntimeException { 112 resolvedObjectList(); 113 return setValueDirectly(objectList); 114 } 115 116 public void setObjectList(List objectList) { 117 this.objectList = objectList; 118 } 119 120 124 public boolean add(Object o) { 125 if ((isFault()) ? addLocal(o) : objectList.add(o)) { 126 postprocessAdd(o); 127 return true; 128 } 129 130 return false; 131 } 132 133 public void add(int index, Object o) { 134 resolvedObjectList().add(index, o); 135 postprocessAdd(o); 136 } 137 138 public boolean addAll(Collection c) { 139 if (resolvedObjectList().addAll(c)) { 140 postprocessAdd(c); 144 145 return true; 146 } 147 148 return false; 149 } 150 151 public boolean addAll(int index, Collection c) { 152 if (resolvedObjectList().addAll(index, c)) { 153 postprocessAdd(c); 157 158 return true; 159 } 160 161 return false; 162 } 163 164 public void clear() { 165 List resolved = resolvedObjectList(); 166 postprocessRemove(resolved); 167 resolved.clear(); 168 } 169 170 public boolean contains(Object o) { 171 return resolvedObjectList().contains(o); 172 } 173 174 public boolean containsAll(Collection c) { 175 return resolvedObjectList().containsAll(c); 176 } 177 178 public boolean equals(Object o) { 179 if (o == null) { 180 return false; 181 } 182 183 if (!(o instanceof PersistentObjectList)) { 184 return false; 185 } 186 187 return resolvedObjectList().equals( 188 ((PersistentObjectList) o).resolvedObjectList()); 189 } 190 191 public int hashCode() { 192 return 37 + resolvedObjectList().hashCode(); 193 } 194 195 public Object get(int index) { 196 return resolvedObjectList().get(index); 197 } 198 199 public int indexOf(Object o) { 200 return resolvedObjectList().indexOf(o); 201 } 202 203 public boolean isEmpty() { 204 return resolvedObjectList().isEmpty(); 205 } 206 207 public Iterator iterator() { 208 return resolvedObjectList().iterator(); 209 } 210 211 public int lastIndexOf(Object o) { 212 return resolvedObjectList().lastIndexOf(o); 213 } 214 215 public ListIterator listIterator() { 216 return resolvedObjectList().listIterator(); 217 } 218 219 public ListIterator listIterator(int index) { 220 return resolvedObjectList().listIterator(index); 221 } 222 223 public Object remove(int index) { 224 Object removed = resolvedObjectList().remove(index); 225 postprocessRemove(removed); 226 return removed; 227 } 228 229 public boolean remove(Object o) { 230 if ((isFault()) ? removeLocal(o) : objectList.remove(o)) { 231 postprocessRemove(o); 232 return true; 233 } 234 235 return false; 236 } 237 238 public boolean removeAll(Collection c) { 239 if (resolvedObjectList().removeAll(c)) { 240 postprocessRemove(c); 244 return true; 245 } 246 247 return false; 248 } 249 250 public boolean retainAll(Collection c) { 251 return resolvedObjectList().retainAll(c); 253 } 254 255 public Object set(int index, Object o) { 256 Object oldValue = resolvedObjectList().set(index, o); 257 258 postprocessAdd(o); 259 postprocessRemove(oldValue); 260 261 return oldValue; 262 } 263 264 public int size() { 265 return resolvedObjectList().size(); 266 } 267 268 public List subList(int fromIndex, int toIndex) { 269 return resolvedObjectList().subList(fromIndex, toIndex); 272 } 273 274 public Object [] toArray() { 275 return resolvedObjectList().toArray(); 276 } 277 278 public Object [] toArray(Object [] a) { 279 return resolvedObjectList().toArray(a); 280 } 281 282 287 290 protected List resolvedObjectList() { 291 if (isFault()) { 292 293 synchronized (this) { 294 295 if (isFault()) { 298 List localList = resolveFromDB(); 299 300 mergeLocalChanges(localList); 301 this.objectList = localList; 302 } 303 } 304 } 305 306 return objectList; 307 } 308 309 void clearLocalChanges() { 310 addedToUnresolved = null; 311 removedFromUnresolved = null; 312 } 313 314 void mergeLocalChanges(List fetchedList) { 315 316 if (isUncommittedParent()) { 320 321 if (removedFromUnresolved != null) { 322 fetchedList.removeAll(removedFromUnresolved); 323 } 324 325 if (addedToUnresolved != null && !addedToUnresolved.isEmpty()) { 328 Iterator it = addedToUnresolved.iterator(); 329 while (it.hasNext()) { 330 Object next = it.next(); 331 332 if (next instanceof Persistent) { 333 Persistent dataObject = (Persistent) next; 334 if (dataObject.getPersistenceState() == PersistenceState.TRANSIENT) { 335 continue; 336 } 337 } 338 339 if (!fetchedList.contains(next)) { 340 fetchedList.add(next); 341 } 342 } 343 } 344 } 345 346 clearLocalChanges(); 348 } 349 350 boolean addLocal(Object object) { 351 352 if (removedFromUnresolved != null) { 353 removedFromUnresolved.remove(object); 354 } 355 356 if (addedToUnresolved == null) { 357 addedToUnresolved = new LinkedList (); 358 } 359 360 addedToUnresolved.addLast(object); 361 362 return true; 365 } 366 367 boolean removeLocal(Object object) { 368 if (addedToUnresolved != null) { 369 addedToUnresolved.remove(object); 370 } 371 372 if (removedFromUnresolved == null) { 373 removedFromUnresolved = new LinkedList (); 374 } 375 376 removedFromUnresolved.addLast(object); 377 378 return true; 381 } 382 383 void postprocessAdd(Collection collection) { 384 Iterator it = collection.iterator(); 385 while (it.hasNext()) { 386 postprocessAdd(it.next()); 387 } 388 } 389 390 void postprocessRemove(Collection collection) { 391 Iterator it = collection.iterator(); 392 while (it.hasNext()) { 393 postprocessRemove(it.next()); 394 } 395 } 396 397 void postprocessAdd(Object addedObject) { 398 399 if (relationshipOwner.getObjectContext() != null) { 401 relationshipOwner.getObjectContext().propertyChanged( 402 relationshipOwner, 403 relationshipName, 404 null, 405 addedObject); 406 } 407 } 408 409 void postprocessRemove(Object removedObject) { 410 411 if (relationshipOwner.getObjectContext() != null) { 413 relationshipOwner.getObjectContext().propertyChanged( 414 relationshipOwner, 415 relationshipName, 416 removedObject, 417 null); 418 } 419 } 420 421 public String toString() { 422 return (objectList != null) ? objectList.toString() : "[<unresolved>]"; 423 } 424 } 425 | Popular Tags |