1 2 12 package com.versant.core.jdo.sco; 13 14 import com.versant.core.jdo.VersantPersistenceManagerImp; 15 import com.versant.core.jdo.VersantStateManager; 16 import com.versant.core.common.CollectionDiff; 17 import com.versant.core.common.VersantFieldMetaData; 18 19 import javax.jdo.spi.PersistenceCapable; 20 import java.util.Collection ; 21 import java.util.Iterator ; 22 import java.util.LinkedList ; 23 import java.util.ListIterator ; 24 25 import com.versant.core.common.BindingSupportImpl; 26 import com.versant.core.common.PersistenceContext; 27 28 33 public final class SCOLinkedList extends LinkedList implements VersantManagedSCOCollection, VersantAdvancedSCO { 34 35 private transient PersistenceCapable owner; 36 private final transient VersantFieldMetaData fmd; 37 private transient VersantStateManager stateManager; 38 private final transient boolean isMaster; 39 private final transient boolean isMany; 40 private final transient int inverseFieldNo; 41 private transient Object [] originalData; 42 private transient boolean beenReset; 43 44 public SCOLinkedList(PersistenceCapable owner, VersantStateManager stateManager, 45 VersantFieldMetaData fmd, Object [] originalData) { 46 this.owner = owner; 47 this.isMaster = fmd.isManaged() && fmd.isMaster(); 48 this.inverseFieldNo = fmd.getInverseFieldNo(); 49 this.isMany = fmd.isManaged() && fmd.isManyToMany(); 50 this.fmd = fmd; 51 this.stateManager = stateManager; 52 this.originalData = originalData; 53 int n = originalData == null ? 0 : originalData.length; 54 if (!owner.jdoIsNew()) { 55 for (int i = 0; i < n; i++) { 56 Object o = originalData[i]; 57 58 super.add( o); 59 } 60 } else if (isMaster) { 61 for (int i = 0; i < n; i++) { 62 Object o = originalData[i]; 63 super.add( o); 64 SCOInverseUtil.addMasterOnDetail(o, owner, inverseFieldNo); 65 } 66 } else if (isMany) { 67 for (int i = 0; i < n; i++) { 68 Object o = originalData[i]; 69 super.add( o); 70 SCOInverseUtil.addToOtherSideOfManyToMany(o, inverseFieldNo, owner); 71 } 72 } else { 73 for (int i = 0; i < n; i++) { 74 Object o = originalData[i]; 75 super.add( o); 76 } 77 } 78 } 79 80 public Object removeFirst() { 81 Object result = super.removeFirst(); 82 if (isMaster) { 83 SCOInverseUtil.removeMasterOnDetail(result, owner, inverseFieldNo); 84 } else if (isMany) { 85 SCOInverseUtil.removeFromOtherSideOfManyToMany(result, inverseFieldNo, owner); 86 } 87 makeDirty(); 88 return result; 89 } 90 91 public Object removeLast() { 92 Object result = super.removeLast(); 93 if (isMaster) { 94 SCOInverseUtil.removeMasterOnDetail(result, owner, inverseFieldNo); 95 } else if (isMany) { 96 SCOInverseUtil.removeFromOtherSideOfManyToMany(result, inverseFieldNo, owner); 97 } 98 makeDirty(); 99 return result; 100 } 101 102 public void addFirst(Object o) { 103 if (isMaster) { 104 super.addFirst(o); 105 makeDirty(); 106 SCOInverseUtil.addMasterOnDetail(o, owner, inverseFieldNo); 107 } else if (isMany) { 108 super.addFirst(o); 109 makeDirty(); 110 SCOInverseUtil.addToOtherSideOfManyToMany(o, inverseFieldNo, owner); 111 } else { 112 super.addFirst(o); 113 makeDirty(); 114 } 115 } 116 117 public void addLast(Object o) { 118 if (isMaster) { 119 super.addLast(o); 120 makeDirty(); 121 SCOInverseUtil.addMasterOnDetail(o, owner, inverseFieldNo); 122 } else if (isMany) { 123 super.addLast(o); 124 makeDirty(); 125 SCOInverseUtil.addToOtherSideOfManyToMany(o, inverseFieldNo, owner); 126 } else { 127 super.addLast(o); 128 makeDirty(); 129 } 130 131 } 132 133 public boolean addAll(int index, Collection c) { 134 if (isMaster) { 135 boolean result = false; 136 c.size(); for (Iterator iter = c.iterator(); iter.hasNext();) { 138 Object o = iter.next(); 139 if (o == null) { 140 } else { 141 super.add(index++, o); 142 SCOInverseUtil.addMasterOnDetail(o, owner, inverseFieldNo); 143 result = true; 144 } 145 } 146 if (result) { 147 makeDirty(); 148 } 149 return result; 150 } else if (isMany) { 151 boolean result = false; 152 c.size(); for (Iterator iter = c.iterator(); iter.hasNext();) { 154 Object o = iter.next(); 155 if (o == null) { 156 } else { 157 super.add(index++, o); 158 SCOInverseUtil.addToOtherSideOfManyToMany(o, inverseFieldNo, owner); 159 result = true; 160 } 161 } 162 if (result) { 163 makeDirty(); 164 } 165 return result; 166 } else { 167 if (super.addAll(index, c)) { 168 makeDirty(); 169 return true; 170 } 171 return false; 172 } 173 } 174 175 protected void removeRange(int fromIndex, int toIndex) { 176 if (isMaster) { 177 ListIterator iter = super.listIterator(fromIndex); 179 for (int i = 0, n = toIndex - fromIndex; i < n; i++) { 180 SCOInverseUtil.removeMasterOnDetail(iter.next(), owner, inverseFieldNo); 181 iter.remove(); 182 } 183 } else if (isMany) { 184 ListIterator iter = super.listIterator(fromIndex); 186 for (int i = 0, n = toIndex - fromIndex; i < n; i++) { 187 SCOInverseUtil.removeFromOtherSideOfManyToMany(iter.next(), inverseFieldNo, owner); 188 iter.remove(); 189 } 190 } else { 191 super.removeRange(fromIndex, toIndex); 192 } 193 makeDirty(); 194 } 195 196 public boolean removeAll(Collection c) { 197 boolean modified = false; 198 Iterator e = super.listIterator(0); 200 while (e.hasNext()) { 201 Object o = e.next(); 202 if (c.contains(o)) { 203 e.remove(); 204 modified = true; 205 if (isMaster) { 206 SCOInverseUtil.removeMasterOnDetail(o, owner, inverseFieldNo); 207 } else if (isMany) { 208 SCOInverseUtil.removeFromOtherSideOfManyToMany(o, inverseFieldNo, owner); 209 } 210 } 211 } 212 if (modified) makeDirty(); 213 return modified; 214 215 } 216 217 public boolean retainAll(Collection c) { 218 boolean modified = false; 219 Iterator e = super.listIterator(0); 221 while (e.hasNext()) { 222 Object o = e.next(); 223 if (!c.contains(o)) { 224 e.remove(); 225 modified = true; 226 if (isMaster) { 227 SCOInverseUtil.removeMasterOnDetail(o, owner, inverseFieldNo); 228 } else if (isMany) { 229 SCOInverseUtil.removeFromOtherSideOfManyToMany(o, inverseFieldNo, owner); 230 } 231 } 232 } 233 234 if (modified) makeDirty(); 235 return modified; 236 } 237 238 public Object set(int index, Object element) { 239 if (isMaster) { 240 Object result = super.set(index, element); 241 if (result != null) { 242 SCOInverseUtil.removeMasterOnDetail(result, owner, inverseFieldNo); 243 } 244 SCOInverseUtil.addMasterOnDetail(element, owner, inverseFieldNo); 245 makeDirty(); 246 return result; 247 } else if (isMany) { 248 Object result = super.set(index, element); 249 if (result != null) { 250 SCOInverseUtil.removeFromOtherSideOfManyToMany(result, inverseFieldNo, owner); 251 } 252 SCOInverseUtil.addToOtherSideOfManyToMany(element, inverseFieldNo, owner); 253 makeDirty(); 254 return result; 255 } else { 256 Object result = super.set(index, element); 257 makeDirty(); 258 return result; 259 } 260 } 261 262 public ListIterator listIterator(int index) { 263 return new ListIteratorImp(super.listIterator(index)); 264 } 265 266 private boolean isManaged() { 267 return isMaster || isMany; 268 } 269 270 276 private class ListIteratorImp implements ListIterator { 277 278 private ListIterator i; 279 280 public void set(Object o) { 281 if (SCOLinkedList.this.isManaged()) { 282 throw BindingSupportImpl.getInstance().runtime("ListIterator.set(Object) is not supported for " + 283 "managed relationships using LinkedList: " + 284 SCOLinkedList.this.fmd.getQName()); 285 } 286 i.set(o); 287 SCOLinkedList.this.makeDirty(); 288 } 289 290 public void remove() { 291 if (SCOLinkedList.this.isManaged()) { 292 throw BindingSupportImpl.getInstance().runtime("ListIterator.remove() is not supported for " + 293 "managed relationships using LinkedList: " + 294 SCOLinkedList.this.fmd.getQName()); 295 } 296 i.remove(); 297 SCOLinkedList.this.makeDirty(); 298 } 299 300 public void add(Object o) { 301 if (SCOLinkedList.this.isManaged()) { 302 throw BindingSupportImpl.getInstance().runtime("ListIterator.add(Object) is not supported for " + 303 "managed relationships using LinkedList: " + 304 SCOLinkedList.this.fmd.getQName()); 305 } 306 i.add(o); 307 SCOLinkedList.this.makeDirty(); 308 } 309 310 public ListIteratorImp(ListIterator i) { 311 this.i = i; 312 } 313 314 public boolean hasNext() { 315 return i.hasNext(); 316 } 317 318 public Object next() { 319 return i.next(); 320 } 321 322 public boolean hasPrevious() { 323 return i.hasPrevious(); 324 } 325 326 public Object previous() { 327 return i.previous(); 328 } 329 330 public int nextIndex() { 331 return i.nextIndex(); 332 } 333 334 public int previousIndex() { 335 return i.previousIndex(); 336 } 337 } 338 339 public boolean add(Object o) { 340 if (isMaster) { 341 super.add(o); 342 makeDirty(); 343 SCOInverseUtil.addMasterOnDetail(o, owner, inverseFieldNo); 344 return true; 345 } else if (isMany) { 346 super.add(o); 347 makeDirty(); 348 SCOInverseUtil.addToOtherSideOfManyToMany(o, inverseFieldNo, owner); 349 return true; 350 } else { 351 super.add(o); 352 makeDirty(); 353 return true; 354 } 355 } 356 357 public void add(int index, Object element) { 358 if (isMaster) { 359 super.add(index, element); 360 makeDirty(); 361 SCOInverseUtil.addMasterOnDetail(element, owner, inverseFieldNo); 362 } else if (isMany) { 363 super.add(index, element); 364 makeDirty(); 365 SCOInverseUtil.addToOtherSideOfManyToMany(element, inverseFieldNo, owner); 366 } else { 367 super.add(index, element); 368 makeDirty(); 369 } 370 371 } 372 373 public Object remove(int index) { 374 Object result = super.remove(index); 375 if (result != null) { 376 makeDirty(); 377 if (isMaster) { 378 SCOInverseUtil.removeMasterOnDetail(result, owner, inverseFieldNo); 379 } else if (isMany) { 380 SCOInverseUtil.removeFromOtherSideOfManyToMany(result, inverseFieldNo, owner); 381 } 382 } 383 return result; 384 } 385 386 public boolean remove(Object o) { 387 if (super.remove(o)) { 388 makeDirty(); 389 390 if (isMaster) { 391 SCOInverseUtil.removeMasterOnDetail(o, owner, inverseFieldNo); 392 } else if (isMany) { 393 SCOInverseUtil.removeFromOtherSideOfManyToMany(o, inverseFieldNo, owner); 394 } 395 396 return true; 397 } 398 return false; 399 } 400 401 public void clear() { 402 if (isMaster) { 403 for (Iterator iter = super.listIterator(0); iter.hasNext();) { 404 SCOInverseUtil.removeMasterOnDetail(iter.next(), owner, inverseFieldNo); 405 } 406 } else if (isMany) { 407 for (Iterator iter = super.listIterator(0); iter.hasNext();) { 408 SCOInverseUtil.removeFromOtherSideOfManyToMany(iter.next(), inverseFieldNo, owner); 409 } 410 } 411 super.clear(); 412 makeDirty(); 413 } 414 415 public CollectionDiff getCollectionDiff(PersistenceContext pm) { 416 Object [] data = toArray(); 417 if (fmd.isOrdered()) { 418 return CollectionDiffUtil.getOrderedCollectionDiff(fmd, pm, 419 data, data.length, (owner.jdoIsNew() && !beenReset) ? null : originalData); 420 } else { 421 return CollectionDiffUtil.getUnorderedCollectionDiff(fmd, pm, 422 data, data.length, (owner.jdoIsNew() && !beenReset) ? null : originalData); 423 } 424 } 425 426 public Object getOwner() { 427 return owner; 428 } 429 430 public void makeTransient() { 431 owner = null; 432 stateManager = null; 433 } 434 435 public void makeDirty() { 436 if (stateManager != null) { 437 stateManager.makeDirty(owner, fmd.getManagedFieldNo()); 438 } 439 } 440 441 public void reset() { 442 beenReset = true; 443 originalData = toArray(); 444 } 445 446 public void manyToManyAdd(Object o) { 447 super.add(o); 448 makeDirty(); 449 } 450 451 public void manyToManyRemove(Object o) { 452 if (super.remove(o)) { 453 makeDirty(); 454 } 455 456 } 457 458 461 public boolean isOrdered() { 462 return fmd.isOrdered(); 463 } 464 465 470 public CollectionData fillCollectionData(CollectionData collectionData) { 471 int size = size(); 472 collectionData.valueCount = size; 473 Object [] newData; 474 Object [] values = collectionData.values; 475 if (values == null || values.length < size) { 476 newData = new Object [size]; 477 } else { 478 newData = values; 479 } 480 for (int i = 0; i < size; i++) { 481 newData[i] = get(i); 482 } 483 collectionData.values = newData; 484 return collectionData; 485 } 486 } 487 | Popular Tags |