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.List ; 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 31 32 35 public class NotifyingListImpl extends BasicEList implements NotifyingList 36 { 37 40 public NotifyingListImpl() 41 { 42 super(); 43 } 44 45 49 public NotifyingListImpl(int initialCapacity) 50 { 51 super(initialCapacity); 52 } 53 54 58 public NotifyingListImpl(Collection collection) 59 { 60 super(collection); 61 } 62 63 67 public Object getNotifier() 68 { 69 return null; 70 } 71 72 76 public Object getFeature() 77 { 78 return null; 79 } 80 81 85 public int getFeatureID() 86 { 87 return Notification.NO_FEATURE_ID; 88 } 89 90 95 protected int getFeatureID(Class expectedClass) 96 { 97 return getFeatureID(); 98 } 99 100 105 protected boolean isSet() 106 { 107 return !isEmpty(); 108 } 109 110 114 protected boolean hasInverse() 115 { 116 return false; 117 } 118 119 123 protected boolean canContainNull() 124 { 125 return !hasInverse(); 126 } 127 128 132 protected boolean isNotificationRequired() 133 { 134 return false; 135 } 136 137 141 protected boolean hasShadow() 142 { 143 return false; 144 } 145 146 153 protected NotificationChain shadowAdd(Object object, NotificationChain notifications) 154 { 155 return notifications; 156 } 157 158 165 protected NotificationChain shadowRemove(Object object, NotificationChain notifications) 166 { 167 return notifications; 168 } 169 170 178 protected NotificationChain shadowSet(Object oldObject, Object newObject, NotificationChain notifications) 179 { 180 return notifications; 181 } 182 183 190 protected NotificationChain inverseAdd(Object object, NotificationChain notifications) 191 { 192 return notifications; 193 } 194 195 202 protected NotificationChain inverseRemove(Object object, NotificationChain notifications) 203 { 204 return notifications; 205 } 206 207 210 protected NotificationImpl createNotification(int eventType, Object oldObject, Object newObject, int index) 211 { 212 throw new UnsupportedOperationException ("Please change your code to call new five argument version of this method"); 213 } 214 215 223 protected NotificationImpl createNotification(int eventType, Object oldObject, Object newObject, int index, boolean wasSet) 224 { 225 return 226 new NotificationImpl(eventType, oldObject, newObject, index, wasSet) 227 { 228 public Object getNotifier() 229 { 230 return NotifyingListImpl.this.getNotifier(); 231 } 232 233 public Object getFeature() 234 { 235 return NotifyingListImpl.this.getFeature(); 236 } 237 238 public int getFeatureID(Class expectedClass) 239 { 240 return NotifyingListImpl.this.getFeatureID(expectedClass); 241 } 242 }; 243 } 244 245 249 protected void dispatchNotification(Notification notification) 250 { 251 ((Notifier)getNotifier()).eNotify(notification); 252 } 253 254 265 public void addUnique(Object object) 266 { 267 if (isNotificationRequired()) 268 { 269 int index = size; 270 boolean oldIsSet = isSet(); 271 super.addUnique(index, object); 272 NotificationImpl notification = createNotification(Notification.ADD, null, object, index, oldIsSet); 273 if (hasInverse()) 274 { 275 NotificationChain notifications = inverseAdd(object, null); 276 if (hasShadow()) 277 { 278 notifications = shadowAdd(object, notifications); 279 } 280 281 if (notifications == null) 282 { 283 dispatchNotification(notification); 284 } 285 else 286 { 287 notifications.add(notification); 288 notifications.dispatch(); 289 } 290 } 291 else 292 { 293 dispatchNotification(notification); 294 } 295 } 296 else 297 { 298 super.addUnique(object); 299 if (hasInverse()) 300 { 301 NotificationChain notifications = inverseAdd(object, null); 302 if (notifications != null) notifications.dispatch(); 303 } 304 } 305 } 306 307 318 public void addUnique(int index, Object object) 319 { 320 if (isNotificationRequired()) 321 { 322 boolean oldIsSet = isSet(); 323 super.addUnique(index, object); 324 NotificationImpl notification = createNotification(Notification.ADD, null, object, index, oldIsSet); 325 if (hasInverse()) 326 { 327 NotificationChain notifications = inverseAdd(object, null); 328 if (hasShadow()) 329 { 330 notifications = shadowAdd(object, notifications); 331 } 332 if (notifications == null) 333 { 334 dispatchNotification(notification); 335 } 336 else 337 { 338 notifications.add(notification); 339 notifications.dispatch(); 340 } 341 } 342 else 343 { 344 dispatchNotification(notification); 345 } 346 } 347 else 348 { 349 super.addUnique(index, object); 350 if (hasInverse()) 351 { 352 NotificationChain notifications = inverseAdd(object, null); 353 if (notifications != null) notifications.dispatch(); 354 } 355 } 356 } 357 358 365 public boolean addAllUnique(Collection collection) 366 { 367 return addAllUnique(size, collection); 368 } 369 370 384 public boolean addAllUnique(int index, Collection collection) 385 { 386 int collectionSize = collection.size(); 387 if (collectionSize == 0) 388 { 389 return false; 390 } 391 else 392 { 393 if (isNotificationRequired()) 394 { 395 boolean oldIsSet = isSet(); 396 super.addAllUnique(index, collection); 397 NotificationImpl notification = 398 collectionSize == 1 ? 399 createNotification(Notification.ADD, null, collection.iterator().next(), index, oldIsSet) : 400 createNotification(Notification.ADD_MANY, null, collection, index, oldIsSet); 401 if (hasInverse()) 402 { 403 NotificationChain notifications = null; 404 int lastIndex = index + collectionSize; 405 for (int i = index; i < lastIndex; ++i) 406 { 407 Object value = data[i]; 408 notifications = inverseAdd(value, notifications); 409 notifications = shadowAdd(value, notifications); 410 } 411 if (notifications == null) 412 { 413 dispatchNotification(notification); 414 } 415 else 416 { 417 notifications.add(notification); 418 notifications.dispatch(); 419 } 420 } 421 else 422 { 423 dispatchNotification(notification); 424 } 425 } 426 else 427 { 428 super.addAllUnique(index, collection); 429 if (hasInverse()) 430 { 431 NotificationChain notifications = null; 432 int lastIndex = index + collectionSize; 433 for (int i = index; i < lastIndex; ++i) 434 { 435 notifications = inverseAdd(data[i], notifications); 436 } 437 if (notifications != null) notifications.dispatch(); 438 } 439 } 440 441 return true; 442 } 443 } 444 445 455 public NotificationChain basicAdd(Object object, NotificationChain notifications) 456 { 457 if (isNotificationRequired()) 458 { 459 int index = size; 460 boolean oldIsSet = isSet(); 461 super.addUnique(index, object); 462 NotificationImpl notification = createNotification(Notification.ADD, null, object, index, oldIsSet); 463 if (notifications == null) 464 { 465 notifications = notification; 466 } 467 else 468 { 469 notifications.add(createNotification(Notification.ADD, null, object, index, oldIsSet)); 470 } 471 } 472 else 473 { 474 super.addUnique(size, object); 475 } 476 return notifications; 477 } 478 479 491 public Object remove(int index) 492 { 493 if (isNotificationRequired()) 494 { 495 NotificationChain notifications = null; 496 boolean oldIsSet = isSet(); 497 if (hasShadow()) 498 { 499 notifications = shadowRemove(basicGet(index), null); 500 } 501 NotificationImpl notification = createNotification(Notification.REMOVE, super.remove(index), null, index, oldIsSet); 502 Object oldObject = notification.getOldValue(); 503 if (hasInverse() && oldObject != null) 504 { 505 notifications = inverseRemove(oldObject, notifications); 506 if (notifications == null) 507 { 508 dispatchNotification(notification); 509 } 510 else 511 { 512 notifications.add(notification); 513 notifications.dispatch(); 514 } 515 } 516 else 517 { 518 if (notifications == null) 519 { 520 dispatchNotification(notification); 521 } 522 else 523 { 524 notifications.add(notification); 525 notifications.dispatch(); 526 } 527 } 528 return oldObject; 529 } 530 else 531 { 532 Object oldObject = super.remove(index); 533 if (hasInverse() && oldObject != null) 534 { 535 NotificationChain notifications = inverseRemove(oldObject, null); 536 if (notifications != null) notifications.dispatch(); 537 } 538 return oldObject; 539 } 540 } 541 542 553 public boolean removeAll(Collection collection) 554 { 555 boolean oldIsSet = isSet(); 556 NotificationChain notifications = null; 557 558 boolean result = false; 559 int [] positions = null; 560 if (isNotificationRequired()) 561 { 562 int listSize = collection.size(); 563 if (listSize > 0) 564 { 565 BasicEList list = new BasicEList(collection); 568 Object [] objects = list.data(); 569 positions = new int [listSize]; 570 int count = 0; 571 572 if (isUnique()) 573 { 574 for (int i = 0; i < size; ++i) 578 { 579 Object object = data[i]; 580 for (int j = listSize; --j >= 0; ) 581 { 582 if (equalObjects(object, objects[j])) 583 { 584 if (count != j) 585 { 586 Object x = objects[count]; 587 objects[count] = objects[j]; 588 objects[j] = x; 589 } 590 positions[count++] = i; 591 break; 592 } 593 } 594 } 595 } 596 else 597 { 598 BasicEList resultList = new BasicEList(listSize); 599 600 for (int i = 0; i < size; ++i) 604 { 605 Object object = data[i]; 606 for (int j = listSize; --j >= 0; ) 607 { 608 if (equalObjects(object, objects[j])) 609 { 610 if (positions.length <= count) 611 { 612 int [] oldPositions = positions; 613 positions = new int [2 * positions.length]; 614 System.arraycopy(oldPositions, 0, positions, 0, count); 615 } 616 positions[count++] = i; 617 resultList.add(objects[j]); 618 } 619 } 620 } 621 622 list = resultList; 623 objects = resultList.data(); 624 listSize = count; 625 626 if (count > positions.length) 627 { 628 int [] oldPositions = positions; 629 positions = new int [count]; 630 System.arraycopy(oldPositions, 0, positions, 0, count); 631 } 632 } 633 634 if (count > 0) 637 { 638 result = true; 639 640 if (hasShadow()) 641 { 642 for (int i = 0; i < count; ++i) 645 { 646 notifications = shadowRemove(objects[i], notifications); 647 } 648 } 649 650 for (int i = count; --i >= 0;) 653 { 654 super.remove(positions[i]); 655 } 656 657 if (count != listSize) 660 { 661 for (int i = listSize; --i >= count; ) 662 { 663 list.remove(i); 664 } 665 int [] oldPositions = positions; 666 positions = new int [count]; 667 System.arraycopy(oldPositions, 0, positions, 0, count); 668 } 669 670 collection = list; 671 } 672 } 673 } 674 else 675 { 676 collection = getDuplicates(collection); 677 678 for (int i = size; --i >= 0; ) 679 { 680 if (collection.contains(data[i])) 681 { 682 super.remove(i); 683 result = true; 684 } 685 } 686 } 687 688 if (result) 689 { 690 if (isNotificationRequired()) 691 { 692 int collectionSize = collection.size(); 693 NotificationImpl notification = 694 (collectionSize == 1 ? 695 createNotification(Notification.REMOVE, collection.iterator().next(), null, positions[0], oldIsSet) : 696 createNotification(Notification.REMOVE_MANY, collection, positions, positions[0], oldIsSet)); 697 698 if (hasInverse()) 699 { 700 for (Iterator i = collection.iterator(); i.hasNext(); ) 701 { 702 notifications = inverseRemove(i.next(), notifications); 703 } 704 if (notifications == null) 705 { 706 dispatchNotification(notification); 707 } 708 else 709 { 710 notifications.add(notification); 711 notifications.dispatch(); 712 } 713 } 714 else 715 { 716 if (notifications == null) 717 { 718 dispatchNotification(notification); 719 } 720 else 721 { 722 notifications.add(notification); 723 notifications.dispatch(); 724 } 725 } 726 } 727 else if (hasInverse()) 728 { 729 for (Iterator i = collection.iterator(); i.hasNext(); ) 730 { 731 notifications = inverseRemove(i.next(), notifications); 732 } 733 if (notifications != null) notifications.dispatch(); 734 } 735 return true; 736 } 737 else 738 { 739 return false; 740 } 741 } 742 743 753 public NotificationChain basicRemove(Object object, NotificationChain notifications) 754 { 755 int index = indexOf(object); 756 if (index != -1) 757 { 758 if (isNotificationRequired()) 759 { 760 boolean oldIsSet = isSet(); 761 Object oldObject = super.remove(index); 762 NotificationImpl notification = createNotification(Notification.REMOVE, oldObject, null, index, oldIsSet); 763 if (notifications == null) 764 { 765 notifications = notification; 766 } 767 else 768 { 769 notifications.add(notification); 770 } 771 } 772 else 773 { 774 super.remove(index); 775 } 776 } 777 return notifications; 778 } 779 780 789 public void clear() 790 { 791 if (isNotificationRequired()) 792 { 793 boolean oldIsSet = isSet(); 794 if (size > 0) 795 { 796 List collection = new UnmodifiableEList(size, data); 797 int collectionSize = size; 798 799 NotificationChain notifications = null; 800 if (hasShadow()) 801 { 802 for (int i = 0; i < size; ++i) 803 { 804 notifications = shadowRemove(data[i], notifications); 805 } 806 } 807 808 super.clear(); 809 Notification notification = 810 (collectionSize == 1 ? 811 createNotification(Notification.REMOVE, collection.get(0), null, Notification.NO_INDEX, oldIsSet) : 812 createNotification(Notification.REMOVE_MANY, collection, null, Notification.NO_INDEX, oldIsSet)); 813 814 if (hasInverse()) 815 { 816 for (Iterator i = collection.iterator(); i.hasNext(); ) 817 { 818 notifications = inverseRemove(i.next(), notifications); 819 } 820 if (notifications == null) 821 { 822 dispatchNotification(notification); 823 } 824 else 825 { 826 notifications.add(notification); 827 notifications.dispatch(); 828 } 829 } 830 else 831 { 832 if (notifications == null) 833 { 834 dispatchNotification(notification); 835 } 836 else 837 { 838 notifications.add(notification); 839 notifications.dispatch(); 840 } 841 } 842 } 843 else 844 { 845 super.clear(); 846 dispatchNotification(createNotification(Notification.REMOVE_MANY, Collections.EMPTY_LIST, null, Notification.NO_INDEX, oldIsSet)); 847 } 848 } 849 else if (hasInverse()) 850 { 851 if (size > 0) 852 { 853 Object [] oldData = data; 854 int oldSize = size; 855 super.clear(); 856 NotificationChain notifications = null; 857 for (int i = 0; i < oldSize; ++i) 858 { 859 notifications = inverseRemove(oldData[i], notifications); 860 } 861 if (notifications != null) notifications.dispatch(); 862 } 863 else 864 { 865 super.clear(); 866 } 867 } 868 else 869 { 870 super.clear(); 871 } 872 } 873 874 889 public Object setUnique(int index, Object object) 890 { 891 if (isNotificationRequired()) 892 { 893 NotificationChain notifications = null; 894 boolean oldIsSet = isSet(); 895 Notification notification = createNotification(Notification.SET, super.setUnique(index, object), object, index, oldIsSet); 896 Object oldObject = notification.getOldValue(); 897 if (hasInverse() && !equalObjects(oldObject, object)) 898 { 899 if (oldObject != null) 900 { 901 notifications = inverseRemove(oldObject, notifications); 902 } 903 904 notifications = inverseAdd(object, notifications); 905 906 if (hasShadow()) 907 { 908 notifications = shadowSet(oldObject, object, notifications); 909 } 910 911 if (notifications == null) 912 { 913 dispatchNotification(notification); 914 } 915 else 916 { 917 notifications.add(notification); 918 notifications.dispatch(); 919 } 920 } 921 else 922 { 923 if (hasShadow()) 924 { 925 notifications = shadowSet(oldObject, object, notifications); 926 } 927 928 if (notifications == null) 929 { 930 dispatchNotification(notification); 931 } 932 else 933 { 934 notifications.add(notification); 935 notifications.dispatch(); 936 } 937 } 938 939 return oldObject; 940 } 941 else 942 { 943 Object oldObject = super.setUnique(index, object); 944 if (hasInverse() && !equalObjects(oldObject, object)) 945 { 946 NotificationChain notifications = null; 947 if (oldObject != null) 948 { 949 notifications = inverseRemove(oldObject, null); 950 } 951 notifications = inverseAdd(object, notifications); 952 if (notifications != null) notifications.dispatch(); 953 } 954 return oldObject; 955 } 956 } 957 958 971 public NotificationChain basicSet(int index, Object object, NotificationChain notifications) 972 { 973 if (isNotificationRequired()) 974 { 975 boolean oldIsSet = isSet(); 976 NotificationImpl notification = createNotification(Notification.SET, super.setUnique(index, object), object, index, oldIsSet); 977 if (notifications == null) 978 { 979 notifications = notification; 980 } 981 else 982 { 983 notifications.add(notification); 984 } 985 } 986 else 987 { 988 super.setUnique(index, object); 989 } 990 return notifications; 991 } 992 993 1004 public Object move(int targetIndex, int sourceIndex) 1005 { 1006 if (isNotificationRequired()) 1007 { 1008 boolean oldIsSet = isSet(); 1009 Object object = super.move(targetIndex, sourceIndex); 1010 dispatchNotification 1011 (createNotification 1012 (Notification.MOVE, 1013 new Integer (sourceIndex), 1014 object, 1015 targetIndex, 1016 oldIsSet)); 1017 return object; 1018 } 1019 else 1020 { 1021 return super.move(targetIndex, sourceIndex); 1022 } 1023 } 1024} 1025 | Popular Tags |