1 21 package oracle.toplink.essentials.internal.queryframework; 23 24 import java.security.AccessController ; 25 import java.security.PrivilegedActionException ; 26 import java.util.Vector ; 27 import java.util.Hashtable ; 28 import java.util.Enumeration ; 29 import java.io.Serializable ; 30 import java.lang.reflect.Constructor ; 31 32 import java.util.IdentityHashMap ; 33 34 import oracle.toplink.essentials.internal.helper.Helper; 35 import oracle.toplink.essentials.internal.helper.ClassConstants; 36 import oracle.toplink.essentials.internal.helper.IdentityHashtable; 37 import oracle.toplink.essentials.internal.sessions.CollectionChangeRecord; 38 import oracle.toplink.essentials.internal.sessions.MergeManager; 39 import oracle.toplink.essentials.internal.sessions.ObjectChangeSet; 40 import oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet; 41 import oracle.toplink.essentials.internal.sessions.CollectionChangeRecord; 42 import oracle.toplink.essentials.queryframework.*; 43 import oracle.toplink.essentials.exceptions.*; 44 import oracle.toplink.essentials.internal.security.PrivilegedAccessHelper; 45 import oracle.toplink.essentials.internal.security.PrivilegedNewInstanceFromClass; 46 import oracle.toplink.essentials.internal.security.PrivilegedInvokeConstructor; 47 import oracle.toplink.essentials.internal.security.PrivilegedGetConstructorFor; 48 import oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl; 49 import oracle.toplink.essentials.internal.sessions.AbstractSession; 50 import oracle.toplink.essentials.descriptors.ClassDescriptor; 51 52 63 public abstract class ContainerPolicy implements Cloneable , Serializable { 64 65 protected transient ClassDescriptor elementDescriptor; 66 protected transient Constructor constructor; 67 68 71 public ContainerPolicy() { 72 } 73 74 80 protected boolean addInto(Object key, Object element, Object container) { 81 throw QueryException.cannotAddToContainer(element, container, this); 82 } 83 84 91 public boolean addInto(Object element, Object container, AbstractSession session) { 92 return addInto(null, element, container, session); 93 } 94 95 102 public boolean addInto(Object key, Object element, Object container, AbstractSession session) { 103 Object elementToAdd = element; 104 if (hasElementDescriptor()) { 105 elementToAdd = getElementDescriptor().getObjectBuilder().wrapObject(element, session); 106 } 107 return addInto(key, elementToAdd, container); 108 } 109 110 117 public void addIntoWithOrder(Integer index, Object element, Object container) { 118 throw QueryException.methodDoesNotExistInContainerClass("set", getContainerClass()); 119 } 120 121 128 public void addIntoWithOrder(Integer index, Object element, Object container, AbstractSession session) { 129 Object elementToAdd = element; 130 if (hasElementDescriptor()) { 131 elementToAdd = getElementDescriptor().getObjectBuilder().wrapObject(element, session); 132 } 133 addIntoWithOrder(index, elementToAdd, container); 134 } 135 136 143 public void addIntoWithOrder(Vector indexes, Hashtable elements, Object container, AbstractSession session) { 144 throw QueryException.methodDoesNotExistInContainerClass("set", getContainerClass()); 145 } 146 147 151 public Object buildContainerFromVector(Vector vector, AbstractSession session) { 152 Object container = containerInstance(vector.size()); 153 154 for (Enumeration e = vector.elements(); e.hasMoreElements();) { 155 addInto(e.nextElement(), container, session); 156 } 157 return container; 158 } 159 160 165 public static ContainerPolicy buildPolicyFor(Class concreteContainerClass) { 166 return buildPolicyFor(concreteContainerClass, false); 167 } 168 169 174 public static ContainerPolicy buildPolicyFor(Class concreteContainerClass, boolean hasOrdering) { 175 if (Helper.classImplementsInterface(concreteContainerClass, ClassConstants.List_Class)) { 176 if (hasOrdering) { 177 return new OrderedListContainerPolicy(concreteContainerClass); 178 } else { 179 return new ListContainerPolicy(concreteContainerClass); 180 } 181 } else if (Helper.classImplementsInterface(concreteContainerClass, ClassConstants.SortedSet_Class)) { 182 return new SortedCollectionContainerPolicy(concreteContainerClass); 183 } else if (Helper.classImplementsInterface(concreteContainerClass, ClassConstants.Collection_Class)) { 184 return new CollectionContainerPolicy(concreteContainerClass); 185 } else if (Helper.classImplementsInterface(concreteContainerClass, ClassConstants.Map_Class)) { 186 return new MapContainerPolicy(concreteContainerClass); 187 } 188 189 throw ValidationException.illegalContainerClass(concreteContainerClass); 190 } 191 192 197 public void clear(Object container) { 198 throw QueryException.methodNotValid(this, "clear(Object container)"); 199 } 200 201 public Object clone() { 202 try { 203 return super.clone(); 204 } catch (CloneNotSupportedException e) { 205 throw new InternalError (); 206 } 207 } 208 209 public ContainerPolicy clone(ReadQuery query) { 210 return (ContainerPolicy)clone(); 211 } 212 213 217 public Object cloneFor(Object container) { 218 throw QueryException.cannotCreateClone(this, container); 219 } 220 221 225 public void compareCollectionsForChange(Object oldCollection, Object newCollection, CollectionChangeRecord changeRecord, AbstractSession session, ClassDescriptor referenceDescriptor) { 226 IdentityHashMap originalKeyValues = new IdentityHashMap (); 228 IdentityHashMap cloneKeyValues = new IdentityHashMap (); 229 230 if (oldCollection != null) { 232 Object backUpIter = iteratorFor(oldCollection); 233 234 while (hasNext(backUpIter)) { 235 Object secondObject = next(backUpIter, session); 236 237 if (secondObject != null) { 239 originalKeyValues.put(secondObject, secondObject); 240 } 241 } 242 } 243 244 if (newCollection != null){ 245 Object cloneIter = iteratorFor(newCollection); 247 248 while (hasNext(cloneIter)) { 249 Object firstObject = next(cloneIter, session); 250 251 if (firstObject != null) { 254 if (originalKeyValues.containsKey(firstObject)) { 255 if ((compareKeys(firstObject, session))) { 257 originalKeyValues.remove(firstObject); 259 } else { 260 Object backUpVersion = null; 264 265 if (((UnitOfWorkImpl)session).isClassReadOnly(firstObject.getClass())) { 268 backUpVersion = ((UnitOfWorkImpl)session).getOriginalVersionOfObject(firstObject); 269 } else { 270 backUpVersion = ((UnitOfWorkImpl)session).getBackupClone(firstObject); 271 } 272 273 ObjectChangeSet changeSet = referenceDescriptor.getObjectBuilder().createObjectChangeSet(firstObject, (UnitOfWorkChangeSet) changeRecord.getOwner().getUOWChangeSet(), session); 274 changeSet.setOldKey(keyFrom(backUpVersion, session)); 275 changeSet.setNewKey(keyFrom(firstObject, session)); 276 cloneKeyValues.put(firstObject, firstObject); 277 } 278 } else { 279 cloneKeyValues.put(firstObject, firstObject); 281 } 282 } 283 } 284 } 285 286 changeRecord.addAdditionChange(cloneKeyValues, (UnitOfWorkChangeSet) changeRecord.getOwner().getUOWChangeSet(), session); 287 changeRecord.addRemoveChange(originalKeyValues, (UnitOfWorkChangeSet) changeRecord.getOwner().getUOWChangeSet(), session); 288 } 289 290 296 public boolean compareKeys(Object sourceKey, AbstractSession session) { 297 return true; 298 } 299 300 306 public Object concatenateContainers(Object firstContainer, Object secondContainer) { 307 Object container = containerInstance(sizeFor(firstContainer) + sizeFor(secondContainer)); 308 309 for (Object firstIter = iteratorFor(firstContainer); hasNext(firstIter);) { 310 addInto(null, next(firstIter), container); 311 } 312 313 for (Object secondIter = iteratorFor(secondContainer); hasNext(secondIter);) { 314 addInto(null, next(secondIter), container); 315 } 316 return container; 317 } 318 319 325 public Object containerInstance() { 326 try { 327 if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ 328 try { 329 return AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(getContainerClass())); 330 } catch (PrivilegedActionException exception) { 331 throw QueryException.couldNotInstantiateContainerClass(getContainerClass(), exception.getException()); 332 } 333 } else { 334 return PrivilegedAccessHelper.newInstanceFromClass(getContainerClass()); 335 } 336 } catch (Exception ex) { 337 throw QueryException.couldNotInstantiateContainerClass(getContainerClass(), ex); 338 } 339 } 340 341 347 public Object containerInstance(int initialCapacity) { 348 if (getConstructor() == null) { 349 return containerInstance(); 350 } 351 try { 352 Object [] arguments = new Object [1]; 353 354 arguments[0] = new Integer (initialCapacity); 356 if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ 357 try { 358 return AccessController.doPrivileged(new PrivilegedInvokeConstructor(getConstructor(), arguments)); 359 } catch (PrivilegedActionException exception) { 360 throw QueryException.couldNotInstantiateContainerClass(getContainerClass(), exception.getException()); 361 } 362 } else { 363 return PrivilegedAccessHelper.invokeConstructor(getConstructor(), arguments); 364 } 365 } catch (Exception ex) { 366 throw QueryException.couldNotInstantiateContainerClass(getContainerClass(), ex); 367 } 368 } 369 370 374 protected boolean contains(Object element, Object container) { 375 throw QueryException.methodNotValid(this, "contains(Object element, Object container)"); 376 } 377 378 384 public boolean contains(Object element, Object container, AbstractSession session) { 385 if (hasElementDescriptor() && getElementDescriptor().hasWrapperPolicy()) { 386 Object iterator = iteratorFor(container); 388 while (hasNext(iterator)) { 389 Object next = next(iterator); 390 if (getElementDescriptor().getObjectBuilder().unwrapObject(next, session).equals(element)) { 391 return true; 392 } 393 } 394 return false; 395 } else { 396 return contains(element, container); 397 } 398 } 399 400 404 protected boolean containsKey(Object element, Object container) { 405 throw QueryException.methodNotValid(this, "containsKey(Object element, Object container)"); 406 } 407 408 415 public void convertClassNamesToClasses(ClassLoader classLoader){}; 416 417 421 public Object execute() { 422 throw QueryException.methodNotValid(this, "execute()"); 423 } 424 425 429 protected Constructor getConstructor() { 430 return constructor; 431 } 432 433 437 public Class getContainerClass() { 438 throw QueryException.methodNotValid(this, "getContainerClass()"); 439 } 440 441 445 public String getContainerClassName() { 446 throw QueryException.methodNotValid(this, "getContainerClassName()"); 447 } 448 449 453 public ClassDescriptor getElementDescriptor() { 454 return elementDescriptor; 455 } 456 457 461 public boolean hasElementDescriptor() { 462 return getElementDescriptor() != null; 463 } 464 465 473 public abstract boolean hasNext(Object iterator); 474 475 479 public boolean hasOrder() { 480 return false; 481 } 482 483 488 public void initializeConstructor() { 489 try { 490 Constructor constructor = null; 491 if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ 492 try { 493 constructor = (Constructor )AccessController.doPrivileged(new PrivilegedGetConstructorFor(getContainerClass(), new Class [] { ClassConstants.PINT }, false)); 494 } catch (PrivilegedActionException exception) { 495 return; 497 } 498 } else { 499 constructor = PrivilegedAccessHelper.getConstructorFor(getContainerClass(), new Class [] { ClassConstants.PINT }, false); 500 } 501 setConstructor(constructor); 502 } catch (Exception exception) { 503 return; 505 } 506 } 507 508 public boolean isCollectionPolicy() { 509 return false; 510 } 511 512 516 public boolean isCursoredStreamPolicy() { 517 return false; 518 } 519 520 public boolean isCursorPolicy() { 521 return false; 522 } 523 524 public boolean isCursorStreamPolicy() { 525 return false; 526 } 527 528 public boolean isDirectMapPolicy() { 529 return false; 530 } 531 532 536 public boolean isEmpty(Object container) { 537 return sizeFor(container) == 0; 538 } 539 540 public boolean isListPolicy() { 541 return false; 542 } 543 544 public boolean isMapPolicy() { 545 return false; 546 } 547 548 public boolean isScrollableCursorPolicy() { 549 return false; 550 } 551 552 559 public boolean isValidContainer(Object container) { 560 throw QueryException.methodNotValid(this, "isValidContainer(Object container)"); 561 } 562 563 567 public boolean isValidContainerType(Class containerType) { 568 throw QueryException.methodNotValid(this, "isValidContainerType(Class containerType)"); 569 } 570 571 580 public abstract Object iteratorFor(Object container); 581 582 589 public Object keyFrom(Object element, AbstractSession session) { 590 return null; 591 } 592 593 599 public Object mergeCascadeParts(ObjectChangeSet objectChanges, MergeManager mergeManager, AbstractSession parentSession) { 600 Object object = null; 601 602 if (mergeManager.shouldMergeChangesIntoDistributedCache()) { 603 object = objectChanges.getTargetVersionOfSourceObject(parentSession); 605 606 if ((object == null) && (objectChanges.isNew() || objectChanges.isAggregate()) && objectChanges.containsChangesFromSynchronization()) { 607 if (!mergeManager.getObjectsAlreadyMerged().containsKey(objectChanges)) { 608 Class objectClass = objectChanges.getClassType(mergeManager.getSession()); 614 object = mergeManager.getSession().getDescriptor(objectClass).getObjectBuilder().buildNewInstance(); 615 mergeManager.getObjectsAlreadyMerged().put(objectChanges, object); 617 } else { 618 object = mergeManager.getObjectsAlreadyMerged().get(objectChanges); 622 } 623 } else { 624 object = objectChanges.getTargetVersionOfSourceObject(parentSession, true); 625 } 626 627 if (objectChanges.containsChangesFromSynchronization()) { 628 mergeManager.mergeChanges(object, objectChanges); 629 } 630 } else { 631 mergeManager.mergeChanges(objectChanges.getUnitOfWorkClone(), objectChanges); 632 } 633 634 return object; 635 } 636 637 643 public void mergeChanges(CollectionChangeRecord changeRecord, Object valueOfTarget, boolean shouldMergeCascadeParts, MergeManager mergeManager, AbstractSession parentSession) { 644 ObjectChangeSet objectChanges; 645 646 Enumeration removeObjects = changeRecord.getRemoveObjectList().keys(); 648 649 while (removeObjects.hasMoreElements()) { 650 objectChanges = (ObjectChangeSet) removeObjects.nextElement(); 651 652 synchronized (valueOfTarget) { 653 removeFrom(objectChanges.getOldKey(), objectChanges.getTargetVersionOfSourceObject(mergeManager.getSession()), valueOfTarget, parentSession); 654 } 655 656 if (!mergeManager.shouldMergeChangesIntoDistributedCache()) { 657 mergeManager.registerRemovedNewObjectIfRequired(objectChanges.getUnitOfWorkClone()); 658 } 659 } 660 661 Enumeration addObjects = changeRecord.getAddObjectList().keys(); 663 664 while (addObjects.hasMoreElements()) { 665 objectChanges = (ObjectChangeSet) addObjects.nextElement(); 666 Object object = null; 667 668 if (shouldMergeCascadeParts) { 669 object = mergeCascadeParts(objectChanges, mergeManager, parentSession); 670 } 671 672 if (object == null) { 673 object = objectChanges.getTargetVersionOfSourceObject(mergeManager.getSession(), false); 675 } 676 677 synchronized (valueOfTarget) { 678 if (mergeManager.shouldMergeChangesIntoDistributedCache()) { 680 if (!contains(object, valueOfTarget, mergeManager.getSession())) { 682 addInto(objectChanges.getNewKey(), object, valueOfTarget, mergeManager.getSession()); 683 } 684 } else { 685 addInto(objectChanges.getNewKey(), object, valueOfTarget, mergeManager.getSession()); 686 } 687 } 688 } 689 } 690 691 699 protected abstract Object next(Object iterator); 700 701 707 public Object next(Object iterator, AbstractSession session) { 708 Object next = next(iterator); 709 if (hasElementDescriptor()) { 710 next = getElementDescriptor().getObjectBuilder().unwrapObject(next, session); 711 } 712 return next; 713 } 714 715 718 public boolean overridesRead() { 719 return false; 720 } 721 722 726 public void prepare(DatabaseQuery query, AbstractSession session) throws QueryException { 727 if (query.isReadAllQuery() && (!query.isReportQuery()) && query.shouldUseWrapperPolicy()) { 728 setElementDescriptor(query.getDescriptor()); 729 } else if (query.isDataReadQuery()) { 731 ((DataReadQuery)query).setContainerPolicy(this); 732 } 733 } 734 735 739 public void prepareForExecution() throws QueryException { 740 } 741 742 748 public void recordAddToCollectionInChangeRecord(ObjectChangeSet changeSetToAdd, CollectionChangeRecord collectionChangeRecord){ 749 if (collectionChangeRecord.getRemoveObjectList().containsKey(changeSetToAdd)) { 750 collectionChangeRecord.getRemoveObjectList().remove(changeSetToAdd); 751 } else { 752 collectionChangeRecord.getAddObjectList().put(changeSetToAdd, changeSetToAdd); 753 } 754 } 755 756 762 public void recordRemoveFromCollectionInChangeRecord(ObjectChangeSet changeSetToRemove, CollectionChangeRecord collectionChangeRecord){ 763 if(collectionChangeRecord.getAddObjectList().containsKey(changeSetToRemove)) { 764 collectionChangeRecord.getAddObjectList().remove(changeSetToRemove); 765 } else { 766 collectionChangeRecord.getRemoveObjectList().put(changeSetToRemove, changeSetToRemove); 767 } 768 } 769 770 773 public Object remoteExecute() { 774 return null; 775 } 776 777 782 public void removeAllElements(Object container) { 783 clear(container); 784 } 785 786 791 protected boolean removeFrom(Object key, Object element, Object container) { 792 throw QueryException.cannotRemoveFromContainer(element, container, this); 793 } 794 795 801 public boolean removeFrom(Object key, Object element, Object container, AbstractSession session) { 802 Object objectToRemove = element; 803 if (hasElementDescriptor() && getElementDescriptor().hasWrapperPolicy()) { 804 Object iterator = iteratorFor(container); 806 while (hasNext(iterator)) { 807 Object next = next(iterator); 808 if (getElementDescriptor().getObjectBuilder().unwrapObject(next, session).equals(element)) { 809 objectToRemove = next; 810 break; 811 } 812 } 813 } 814 815 return removeFrom(key, objectToRemove, container); 816 } 817 818 824 public boolean removeFrom(Object element, Object container, AbstractSession session) { 825 return removeFrom(null, element, container, session); 826 } 827 828 835 public void removeFromWithOrder(int beginIndex, Object container) { 836 throw QueryException.methodDoesNotExistInContainerClass("remove(index)", getContainerClass()); 837 } 838 839 843 protected void setConstructor(Constructor constructor) { 844 this.constructor = constructor; 845 } 846 847 851 public void setContainerClass(Class containerClass) { 852 throw QueryException.methodNotValid(this, "getContainerClass()"); 853 } 854 855 859 public void setContainerClassName(String containerClassName) { 860 throw QueryException.methodNotValid(this, "getContainerClassName()"); 861 } 862 863 867 public void setElementDescriptor(ClassDescriptor elementDescriptor) { 868 this.elementDescriptor = elementDescriptor; 869 } 870 871 878 public void setKeyName(String instanceVariableName, String elementClassName) { 879 throw ValidationException.containerPolicyDoesNotUseKeys(this, instanceVariableName); 880 } 881 882 886 public int sizeFor(Object container) { 887 throw QueryException.methodNotValid(this, "sizeFor(Object container)"); 888 } 889 890 public String toString() { 891 return Helper.getShortClassName(this.getClass()) + "(" + toStringInfo() + ")"; 892 } 893 894 protected Object toStringInfo() { 895 return ""; 896 } 897 898 902 public void validateElementAndRehashIfRequired(Object sourceValue, Object target, AbstractSession session, Object targetVersionOfSource) { 903 } 905 906 912 public Vector vectorFor(Object container, AbstractSession session) { 913 Vector result = new Vector (sizeFor(container)); 914 915 for (Object iter = iteratorFor(container); hasNext(iter);) { 916 result.addElement(next(iter, session)); 917 } 918 return result; 919 } 920 } 921 | Popular Tags |