1 17 package org.eclipse.emf.common.notify.impl; 18 19 20 import java.util.Collection ; 21 import java.util.Collections ; 22 import java.util.Iterator ; 23 import java.util.ListIterator ; 24 25 import org.eclipse.emf.common.notify.Notification; 26 import org.eclipse.emf.common.notify.NotificationChain; 27 import org.eclipse.emf.common.notify.Notifier; 28 import org.eclipse.emf.common.notify.NotifyingList; 29 import org.eclipse.emf.common.util.BasicEList; 30 import org.eclipse.emf.common.util.DelegatingEList; 31 32 33 36 public abstract class DelegatingNotifyingListImpl extends DelegatingEList implements NotifyingList 37 { 38 41 public DelegatingNotifyingListImpl() 42 { 43 super(); 44 } 45 46 50 public DelegatingNotifyingListImpl(Collection collection) 51 { 52 super(collection); 53 } 54 55 59 public Object getNotifier() 60 { 61 return null; 62 } 63 64 68 public Object getFeature() 69 { 70 return null; 71 } 72 73 77 public int getFeatureID() 78 { 79 return Notification.NO_FEATURE_ID; 80 } 81 82 87 protected int getFeatureID(Class expectedClass) 88 { 89 return getFeatureID(); 90 } 91 92 97 protected boolean isSet() 98 { 99 return !isEmpty(); 100 } 101 102 106 protected boolean hasInverse() 107 { 108 return false; 109 } 110 111 115 protected boolean canContainNull() 116 { 117 return !hasInverse(); 118 } 119 120 124 protected boolean isNotificationRequired() 125 { 126 return false; 127 } 128 129 133 protected boolean hasShadow() 134 { 135 return false; 136 } 137 138 145 protected NotificationChain shadowAdd(Object object, NotificationChain notifications) 146 { 147 return notifications; 148 } 149 150 157 protected NotificationChain shadowRemove(Object object, NotificationChain notifications) 158 { 159 return notifications; 160 } 161 162 170 protected NotificationChain shadowSet(Object oldObject, Object newObject, NotificationChain notifications) 171 { 172 return notifications; 173 } 174 175 182 protected NotificationChain inverseAdd(Object object, NotificationChain notifications) 183 { 184 return notifications; 185 } 186 187 194 protected NotificationChain inverseRemove(Object object, NotificationChain notifications) 195 { 196 return notifications; 197 } 198 199 202 protected NotificationImpl createNotification(int eventType, Object oldObject, Object newObject, int index) 203 { 204 throw new UnsupportedOperationException ("Please change your code to call new five argument version of this method"); 205 } 206 207 215 protected NotificationImpl createNotification(int eventType, Object oldObject, Object newObject, int index, boolean wasSet) 216 { 217 return 218 new NotificationImpl(eventType, oldObject, newObject, index, wasSet) 219 { 220 public Object getNotifier() 221 { 222 return DelegatingNotifyingListImpl.this.getNotifier(); 223 } 224 225 public Object getFeature() 226 { 227 return DelegatingNotifyingListImpl.this.getFeature(); 228 } 229 230 public int getFeatureID(Class expectedClass) 231 { 232 return DelegatingNotifyingListImpl.this.getFeatureID(expectedClass); 233 } 234 }; 235 } 236 237 241 protected void dispatchNotification(Notification notification) 242 { 243 ((Notifier)getNotifier()).eNotify(notification); 244 } 245 246 257 public void addUnique(Object object) 258 { 259 if (isNotificationRequired()) 260 { 261 int index = size(); 262 boolean oldIsSet = isSet(); 263 super.addUnique(index, object); 264 NotificationImpl notification = createNotification(Notification.ADD, null, object, index, oldIsSet); 265 if (hasInverse()) 266 { 267 NotificationChain notifications = inverseAdd(object, null); 268 if (hasShadow()) 269 { 270 notifications = shadowAdd(object, notifications); 271 } 272 if (notifications == null) 273 { 274 dispatchNotification(notification); 275 } 276 else 277 { 278 notifications.add(notification); 279 notifications.dispatch(); 280 } 281 } 282 else 283 { 284 dispatchNotification(notification); 285 } 286 } 287 else 288 { 289 super.addUnique(object); 290 if (hasInverse()) 291 { 292 NotificationChain notifications = inverseAdd(object, null); 293 if (notifications != null) notifications.dispatch(); 294 } 295 } 296 } 297 298 309 public void addUnique(int index, Object object) 310 { 311 if (isNotificationRequired()) 312 { 313 boolean oldIsSet = isSet(); 314 super.addUnique(index, object); 315 NotificationImpl notification = createNotification(Notification.ADD, null, object, index, oldIsSet); 316 if (hasInverse()) 317 { 318 NotificationChain notifications = inverseAdd(object, null); 319 if (hasShadow()) 320 { 321 notifications = shadowAdd(object, notifications); 322 } 323 if (notifications == null) 324 { 325 dispatchNotification(notification); 326 } 327 else 328 { 329 notifications.add(notification); 330 notifications.dispatch(); 331 } 332 } 333 else 334 { 335 dispatchNotification(notification); 336 } 337 } 338 else 339 { 340 super.addUnique(index, object); 341 if (hasInverse()) 342 { 343 NotificationChain notifications = inverseAdd(object, null); 344 if (notifications != null) notifications.dispatch(); 345 } 346 } 347 } 348 349 356 public boolean addAllUnique(Collection collection) 357 { 358 return addAllUnique(size(), collection); 359 } 360 361 375 public boolean addAllUnique(int index, Collection collection) 376 { 377 int collectionSize = collection.size(); 378 if (collectionSize == 0) 379 { 380 return false; 381 } 382 else 383 { 384 if (isNotificationRequired()) 385 { 386 boolean oldIsSet = isSet(); 387 super.addAllUnique(index, collection); 388 NotificationImpl notification = 389 collectionSize == 1 ? 390 createNotification(Notification.ADD, null, collection.iterator().next(), index, oldIsSet) : 391 createNotification(Notification.ADD_MANY, null, collection, index, oldIsSet); 392 if (hasInverse()) 393 { 394 NotificationChain notifications = null; 395 int lastIndex = index + collectionSize; 396 for (int i = index; i < lastIndex; ++i) 397 { 398 Object value = delegateGet(i); 399 notifications = inverseAdd(value, notifications); 400 notifications = shadowAdd(value, notifications); 401 } 402 if (notifications == null) 403 { 404 dispatchNotification(notification); 405 } 406 else 407 { 408 notifications.add(notification); 409 notifications.dispatch(); 410 } 411 } 412 else 413 { 414 dispatchNotification(notification); 415 } 416 } 417 else 418 { 419 super.addAllUnique(index, collection); 420 if (hasInverse()) 421 { 422 NotificationChain notifications = null; 423 int lastIndex = index + collectionSize; 424 for (int i = index; i < lastIndex; ++i) 425 { 426 notifications = inverseAdd(delegateGet(i), notifications); 427 } 428 if (notifications != null) notifications.dispatch(); 429 } 430 } 431 432 return true; 433 } 434 } 435 436 446 public NotificationChain basicAdd(Object object, NotificationChain notifications) 447 { 448 if (isNotificationRequired()) 449 { 450 int index = size(); 451 boolean oldIsSet = isSet(); 452 super.addUnique(index, object); 453 NotificationImpl notification = createNotification(Notification.ADD, null, object, index, oldIsSet); 454 if (notifications == null) 455 { 456 notifications = notification; 457 } 458 else 459 { 460 notifications.add(createNotification(Notification.ADD, null, object, index, oldIsSet)); 461 } 462 } 463 else 464 { 465 super.addUnique(size(), object); 466 } 467 return notifications; 468 } 469 470 482 public Object remove(int index) 483 { 484 if (isNotificationRequired()) 485 { 486 NotificationChain notifications = null; 487 boolean oldIsSet = isSet(); 488 if (hasShadow()) 489 { 490 notifications = shadowRemove(basicGet(index), null); 491 } 492 NotificationImpl notification = createNotification(Notification.REMOVE, super.remove(index), null, index, oldIsSet); 493 Object oldObject = notification.getOldValue(); 494 if (hasInverse() && oldObject != null) 495 { 496 notifications = inverseRemove(oldObject, notifications); 497 if (notifications == null) 498 { 499 dispatchNotification(notification); 500 } 501 else 502 { 503 notifications.add(notification); 504 notifications.dispatch(); 505 } 506 } 507 else 508 { 509 if (notifications == null) 510 { 511 dispatchNotification(notification); 512 } 513 else 514 { 515 notifications.add(notification); 516 notifications.dispatch(); 517 } 518 } 519 return oldObject; 520 } 521 else 522 { 523 Object oldObject = super.remove(index); 524 if (hasInverse() && oldObject != null) 525 { 526 NotificationChain notifications = inverseRemove(oldObject, null); 527 if (notifications != null) notifications.dispatch(); 528 } 529 return oldObject; 530 } 531 } 532 533 544 public boolean removeAll(Collection collection) 545 { 546 boolean oldIsSet = isSet(); 547 NotificationChain notifications = null; 548 549 boolean result = false; 550 int [] positions = null; 551 if (isNotificationRequired()) 552 { 553 int listSize = collection.size(); 554 if (listSize > 0) 555 { 556 BasicEList list = new BasicEList(collection); 559 Object [] objects = list.data(); 560 positions = new int [listSize]; 561 int count = 0; 562 563 if (isUnique()) 564 { 565 for (ListIterator i = delegateListIterator(); i.hasNext(); ) 569 { 570 Object object = i.next(); 571 for (int j = listSize; --j >= 0; ) 572 { 573 if (equalObjects(object, objects[j])) 574 { 575 if (count != j) 576 { 577 Object x = objects[count]; 578 objects[count] = objects[j]; 579 objects[j] = x; 580 } 581 positions[count++] = i.previousIndex(); 582 break; 583 } 584 } 585 } 586 } 587 else 588 { 589 BasicEList resultList = new BasicEList(listSize); 590 591 for (ListIterator i = delegateListIterator(); i.hasNext(); ) 595 { 596 Object object = i.next(); 597 for (int j = listSize; --j >= 0; ) 598 { 599 if (equalObjects(object, objects[j])) 600 { 601 if (positions.length <= count) 602 { 603 int [] oldPositions = positions; 604 positions = new int [2 * positions.length]; 605 System.arraycopy(oldPositions, 0, positions, 0, count); 606 } 607 positions[count++] = i.previousIndex(); 608 resultList.add(objects[j]); 609 } 610 } 611 } 612 613 list = resultList; 614 objects = resultList.data(); 615 listSize = count; 616 617 if (count > positions.length) 618 { 619 int [] oldPositions = positions; 620 positions = new int [count]; 621 System.arraycopy(oldPositions, 0, positions, 0, count); 622 } 623 } 624 625 if (count > 0) 628 { 629 result = true; 630 631 if (hasShadow()) 632 { 633 for (int i = 0; i < count; ++i) 636 { 637 notifications = shadowRemove(objects[i], notifications); 638 } 639 } 640 641 for (int i = count; --i >= 0;) 644 { 645 super.remove(positions[i]); 646 } 647 648 if (count != listSize) 651 { 652 for (int i = listSize; --i >= count; ) 653 { 654 list.remove(i); 655 } 656 int [] oldPositions = positions; 657 positions = new int [count]; 658 System.arraycopy(oldPositions, 0, positions, 0, count); 659 } 660 661 collection = list; 662 } 663 } 664 } 665 else 666 { 667 collection = getDuplicates(collection); 668 669 for (int i = delegateSize(); --i >=0; ) 670 { 671 if (collection.contains(delegateGet(i))) 672 { 673 super.remove(i); 674 result = true; 675 } 676 } 677 } 678 679 if (result) 680 { 681 if (isNotificationRequired()) 682 { 683 int collectionSize = collection.size(); 684 NotificationImpl notification = 685 (collectionSize == 1 ? 686 createNotification(Notification.REMOVE, collection.iterator().next(), null, positions[0], oldIsSet) : 687 createNotification(Notification.REMOVE_MANY, collection, positions, positions[0], oldIsSet)); 688 689 if (hasInverse()) 690 { 691 for (Iterator i = collection.iterator(); i.hasNext(); ) 692 { 693 notifications = inverseRemove(i.next(), notifications); 694 } 695 if (notifications == null) 696 { 697 dispatchNotification(notification); 698 } 699 else 700 { 701 notifications.add(notification); 702 notifications.dispatch(); 703 } 704 } 705 else 706 { 707 if (notifications == null) 708 { 709 dispatchNotification(notification); 710 } 711 else 712 { 713 notifications.add(notification); 714 notifications.dispatch(); 715 } 716 } 717 } 718 else if (hasInverse()) 719 { 720 for (Iterator i = collection.iterator(); i.hasNext(); ) 721 { 722 notifications = inverseRemove(i.next(), notifications); 723 } 724 if (notifications != null) notifications.dispatch(); 725 } 726 return true; 727 } 728 else 729 { 730 return false; 731 } 732 } 733 734 744 public NotificationChain basicRemove(Object object, NotificationChain notifications) 745 { 746 int index = indexOf(object); 747 if (index != -1) 748 { 749 if (isNotificationRequired()) 750 { 751 boolean oldIsSet = isSet(); 752 Object oldObject = super.remove(index); 753 NotificationImpl notification = createNotification(Notification.REMOVE, oldObject, null, index, oldIsSet); 754 if (notifications == null) 755 { 756 notifications = notification; 757 } 758 else 759 { 760 notifications.add(notification); 761 } 762 } 763 else 764 { 765 super.remove(index); 766 } 767 } 768 return notifications; 769 } 770 771 780 public void clear() 781 { 782 if (isNotificationRequired()) 783 { 784 int size = size(); 785 boolean oldIsSet = isSet(); 786 if (size > 0) 787 { 788 BasicEList collection = new BasicEList(basicList()); 789 int collectionSize = size; 790 791 NotificationChain notifications = null; 792 if (hasShadow()) 793 { 794 for (int i = 0; i < size; ++i) 795 { 796 notifications = shadowRemove(collection.get(i), notifications); 797 } 798 } 799 800 doClear(collectionSize, collection.data()); 801 Notification notification = 802 (collectionSize == 1 ? 803 createNotification(Notification.REMOVE, collection.get(0), null, Notification.NO_INDEX, oldIsSet) : 804 createNotification(Notification.REMOVE_MANY, collection, null, Notification.NO_INDEX, oldIsSet)); 805 806 if (hasInverse()) 807 { 808 for (Iterator i = collection.iterator(); i.hasNext(); ) 809 { 810 notifications = inverseRemove(i.next(), notifications); 811 } 812 if (notifications == null) 813 { 814 dispatchNotification(notification); 815 } 816 else 817 { 818 notifications.add(notification); 819 notifications.dispatch(); 820 } 821 } 822 else 823 { 824 if (notifications == null) 825 { 826 dispatchNotification(notification); 827 } 828 else 829 { 830 notifications.add(notification); 831 notifications.dispatch(); 832 } 833 } 834 } 835 else 836 { 837 super.clear(); 838 dispatchNotification(createNotification(Notification.REMOVE_MANY, Collections.EMPTY_LIST, null, Notification.NO_INDEX, oldIsSet)); 839 } 840 } 841 else if (hasInverse()) 842 { 843 int size = size(); 844 if (size > 0) 845 { 846 Object [] oldData = delegateToArray(); 847 int oldSize = size; 848 doClear(size, oldData); 850 NotificationChain notifications = null; 851 for (int i = 0; i < oldSize; ++i) 852 { 853 notifications = inverseRemove(oldData[i], notifications); 854 } 855 if (notifications != null) notifications.dispatch(); 856 } 857 else 858 { 859 super.clear(); 860 } 861 } 862 else 863 { 864 super.clear(); 865 } 866 } 867 868 883 public Object setUnique(int index, Object object) 884 { 885 if (isNotificationRequired()) 886 { 887 NotificationChain notifications = null; 888 boolean oldIsSet = isSet(); 889 Notification notification = createNotification(Notification.SET, super.setUnique(index, object), object, index, oldIsSet); 890 Object oldObject = notification.getOldValue(); 891 if (hasInverse() && !equalObjects(oldObject, object)) 892 { 893 if (oldObject != null) 894 { 895 notifications = inverseRemove(oldObject, notifications); 896 } 897 notifications = inverseAdd(object, notifications); 898 899 if (hasShadow()) 900 { 901 notifications = shadowSet(oldObject, object, notifications); 902 } 903 904 if (notifications == null) 905 { 906 dispatchNotification(notification); 907 } 908 else 909 { 910 notifications.add(notification); 911 notifications.dispatch(); 912 } 913 } 914 else 915 { 916 if (hasShadow()) 917 { 918 notifications = shadowSet(oldObject, object, notifications); 919 } 920 921 if (notifications == null) 922 { 923 dispatchNotification(notification); 924 } 925 else 926 { 927 notifications.add(notification); 928 notifications.dispatch(); 929 } 930 } 931 return oldObject; 932 } 933 else 934 { 935 Object oldObject = super.setUnique(index, object); 936 if (hasInverse() && !equalObjects(oldObject, object)) 937 { 938 NotificationChain notifications = null; 939 if (oldObject != null) 940 { 941 notifications = inverseRemove(oldObject, null); 942 } 943 notifications = inverseAdd(object, notifications); 944 if (notifications != null) notifications.dispatch(); 945 } 946 return oldObject; 947 } 948 } 949 950 963 public NotificationChain basicSet(int index, Object object, NotificationChain notifications) 964 { 965 if (isNotificationRequired()) 966 { 967 boolean oldIsSet = isSet(); 968 NotificationImpl notification = createNotification(Notification.SET, super.setUnique(index, object), object, index, oldIsSet); 969 if (notifications == null) 970 { 971 notifications = notification; 972 } 973 else 974 { 975 notifications.add(notification); 976 } 977 } 978 else 979 { 980 super.setUnique(index, object); 981 } 982 return notifications; 983 } 984 985 996 public Object move(int targetIndex, int sourceIndex) 997 { 998 if (isNotificationRequired()) 999 { 1000 boolean oldIsSet = isSet(); 1001 Object object = super.move(targetIndex, sourceIndex); 1002 dispatchNotification 1003 (createNotification 1004 (Notification.MOVE, 1005 new Integer (sourceIndex), 1006 object, 1007 targetIndex, 1008 oldIsSet)); 1009 return object; 1010 } 1011 else 1012 { 1013 return super.move(targetIndex, sourceIndex); 1014 } 1015 } 1016} 1017 | Popular Tags |