1 17 package org.eclipse.emf.ecore.util; 18 19 20 import java.util.Collection ; 21 import java.util.Collections ; 22 import java.util.Iterator ; 23 import java.util.List ; 24 import java.util.ListIterator ; 25 26 import org.eclipse.emf.common.notify.Notification; 27 import org.eclipse.emf.common.notify.NotificationChain; 28 import org.eclipse.emf.common.notify.impl.NotificationImpl; 29 import org.eclipse.emf.common.util.BasicEList; 30 import org.eclipse.emf.common.util.EList; 31 import org.eclipse.emf.ecore.EObject; 32 import org.eclipse.emf.ecore.EReference; 33 import org.eclipse.emf.ecore.EStructuralFeature; 34 import org.eclipse.emf.ecore.InternalEObject; 35 import org.eclipse.emf.ecore.impl.ENotificationImpl; 36 37 38 39 public class BasicFeatureMap extends EDataTypeEList implements FeatureMap.Internal 40 { 41 protected final FeatureMapUtil.Validator featureMapValidator; 42 43 public BasicFeatureMap(InternalEObject owner, int featureID) 44 { 45 super(Entry.class, owner, featureID); 46 47 featureMapValidator = FeatureMapUtil.getValidator(owner.eClass(), getEStructuralFeature()); 48 } 49 50 protected Object validate(int index, Object object) 51 { 52 Object result = super.validate(index, object); 53 EStructuralFeature eStructuralFeature = ((Entry)object).getEStructuralFeature(); 54 if (!eStructuralFeature.isChangeable() || !featureMapValidator.isValid(eStructuralFeature)) 55 { 56 throw 57 new RuntimeException 58 ("Invalid entry feature '" + eStructuralFeature.getEContainingClass().getName() + "." + eStructuralFeature.getName() + "'"); 59 } 60 return result; 61 } 62 63 protected FeatureMap.Entry createEntry(EStructuralFeature eStructuralFeature, Object value) 64 { 65 return FeatureMapUtil.createEntry(eStructuralFeature, value); 66 } 67 68 protected NotificationImpl createNotification 69 (int eventType, EStructuralFeature feature, Object oldObject, Object newObject, int index, boolean wasSet) 70 { 71 return new FeatureMapUtil.FeatureENotificationImpl(owner, eventType, feature, oldObject, newObject, index, wasSet); 72 } 73 74 protected boolean isMany(EStructuralFeature feature) 75 { 76 return FeatureMapUtil.isMany(owner, feature); 77 } 78 79 protected boolean hasInverse() 80 { 81 return true; 82 } 83 84 protected boolean hasShadow() 85 { 86 return true; 87 } 88 89 protected int entryIndex(EStructuralFeature feature, int index) 90 { 91 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 92 int count = 0; 93 int result = size; 94 Entry [] entries = (Entry[])data; 95 for (int i = 0; i < size; ++i) 96 { 97 Entry entry = entries[i]; 98 if (validator.isValid(entry.getEStructuralFeature())) 99 { 100 if (index == count) 101 { 102 return i; 103 } 104 ++count; 105 result = i + 1; 106 } 107 } 108 109 if (index == count) 110 { 111 return result; 112 } 113 else 114 { 115 throw new IndexOutOfBoundsException ("index=" + index + ", size=" + count); 116 } 117 } 118 119 protected boolean isResolveProxies(EStructuralFeature feature) 120 { 121 return feature instanceof EReference && ((EReference)feature).isResolveProxies(); 122 } 123 124 public Object resolveProxy(EStructuralFeature feature, int entryIndex, int index, Object object) 125 { 126 EObject resolved = resolveProxy((EObject)object); 127 if (resolved != object) 128 { 129 Object oldObject = data[entryIndex]; 130 Entry entry = createEntry(feature, resolved); 131 assign(entryIndex, validate(entryIndex, entry)); 132 didSet(entryIndex, entry, oldObject); 133 134 if (isNotificationRequired()) 135 { 136 NotificationImpl notifications = 137 createNotification 138 (Notification.RESOLVE, 139 entry.getEStructuralFeature(), 140 object, 141 resolved, 142 index, 143 false); 144 145 notifications.add(createNotification(Notification.RESOLVE, oldObject, entry, index, false)); 146 notifications.dispatch(); 147 } 148 149 return resolved; 150 } 151 152 return object; 153 } 154 155 protected EObject resolveProxy(EObject eObject) 156 { 157 return owner.eResolveProxy((InternalEObject)eObject); 158 } 159 160 public int getModCount() 161 { 162 return modCount; 163 } 164 165 public EStructuralFeature getEStructuralFeature(int index) 166 { 167 return ((Entry)get(index)).getEStructuralFeature(); 168 } 169 170 public Object getValue(int index) 171 { 172 return ((Entry)get(index)).getValue(); 173 } 174 175 public Object setValue(int index, Object value) 176 { 177 return ((Entry)set(index, createEntry(getEStructuralFeature(index), value))).getValue(); 178 } 179 180 public NotificationChain shadowAdd(Object object, NotificationChain notifications) 181 { 182 if (isNotificationRequired()) 183 { 184 Entry entry = (Entry)object; 185 EStructuralFeature feature = entry.getEStructuralFeature(); 186 Object value = entry.getValue(); 187 NotificationImpl notification = 189 feature.isMany() ? 190 createNotification 191 (Notification.ADD, 192 feature, 193 null, 194 value, 195 indexOf(feature, value), 196 true) : 197 createNotification 198 (Notification.SET, 199 feature, 200 feature.getDefaultValue(), 201 value, 202 Notification.NO_INDEX, 203 true); 204 205 if (notifications != null) 206 { 207 notifications.add(notification); 208 } 209 else 210 { 211 notifications = notification; 212 } 213 } 214 return notifications; 215 } 216 217 public NotificationChain inverseAdd(Object object, NotificationChain notifications) 218 { 219 Entry entry = (Entry)object; 220 EStructuralFeature feature = entry.getEStructuralFeature(); 221 if (feature instanceof EReference) 222 { 223 EReference eReference = (EReference)feature; 224 EReference eOpposite = eReference.getEOpposite(); 225 if (eOpposite != null) 226 { 227 InternalEObject internalEObject = (InternalEObject)entry.getValue(); 228 229 if (internalEObject != null) 230 { 231 notifications = 232 internalEObject.eInverseAdd 233 (owner, 234 internalEObject.eClass().getFeatureID(eOpposite), 235 null, 236 notifications); 237 } 238 } 239 else if (eReference.isContainment()) 240 { 241 InternalEObject internalEObject = (InternalEObject)entry.getValue(); 242 if (internalEObject != null) 243 { 244 int containmentFeatureID = owner.eClass().getFeatureID(eReference); 245 notifications = 246 internalEObject.eInverseAdd 247 (owner, 248 InternalEObject.EOPPOSITE_FEATURE_BASE - (containmentFeatureID == -1 ? featureID : containmentFeatureID), 249 null, 250 notifications); 251 } 252 } 253 } 254 255 return notifications; 256 } 257 258 public NotificationChain shadowRemove(Object object, NotificationChain notifications) 259 { 260 if (isNotificationRequired()) 261 { 262 Entry entry = (Entry)object; 263 EStructuralFeature feature = entry.getEStructuralFeature(); 264 Object value = entry.getValue(); 265 NotificationImpl notification = 266 feature.isMany() ? 267 createNotification 268 (Notification.REMOVE, 269 feature, 270 value, 271 null, 272 indexOf(feature, value), 273 true) : 274 createNotification 275 (feature.isUnsettable() ? Notification.UNSET : Notification.SET, 276 feature, 277 value, 278 feature.getDefaultValue(), 279 Notification.NO_INDEX, 280 true); 281 282 if (notifications != null) 283 { 284 notifications.add(notification); 285 } 286 else 287 { 288 notifications = notification; 289 } 290 } 291 return notifications; 292 } 293 294 public NotificationChain inverseRemove(Object object, NotificationChain notifications) 295 { 296 Entry entry = (Entry)object; 297 EStructuralFeature feature = entry.getEStructuralFeature(); 298 if (feature instanceof EReference) 299 { 300 EReference eReference = (EReference)feature; 301 EReference eOpposite = eReference.getEOpposite(); 302 if (eOpposite != null) 303 { 304 InternalEObject internalEObject = (InternalEObject)entry.getValue(); 305 if (internalEObject != null) 306 { 307 notifications = 308 internalEObject.eInverseRemove 309 (owner, 310 internalEObject.eClass().getFeatureID(eOpposite), 311 null, 312 notifications); 313 } 314 } 315 else if (eReference.isContainment()) 316 { 317 InternalEObject internalEObject = (InternalEObject)entry.getValue(); 318 if (internalEObject != null) 319 { 320 int containmentFeatureID = owner.eClass().getFeatureID(eReference); 321 notifications = 322 internalEObject.eInverseRemove 323 (owner, 324 InternalEObject.EOPPOSITE_FEATURE_BASE - (containmentFeatureID == -1 ? featureID : containmentFeatureID), 325 null, 326 notifications); 327 } 328 } 329 } 330 return notifications; 331 } 332 333 public NotificationChain shadowSet(Object oldObject, Object newObject, NotificationChain notifications) 334 { 335 if (isNotificationRequired()) 336 { 337 Entry entry = (Entry)oldObject; 338 EStructuralFeature feature = entry.getEStructuralFeature(); 339 Object oldValue = entry.getValue(); 340 Object newValue = ((Entry)newObject).getValue(); 341 NotificationImpl notification = 342 createNotification 343 (Notification.SET, 344 feature, 345 oldValue, 346 newValue, 347 feature.isMany() ? indexOf(feature, newValue) : Notification.NO_INDEX, 348 true); 349 350 if (notifications != null) 351 { 352 notifications.add(notification); 353 } 354 else 355 { 356 notifications = notification; 357 } 358 } 359 return notifications; 360 } 361 362 public NotificationChain inverseTouch(Object object, NotificationChain notifications) 363 { 364 if (isNotificationRequired()) 365 { 366 Entry entry = (Entry)object; 367 EStructuralFeature feature = entry.getEStructuralFeature(); 368 Object value = entry.getValue(); 369 NotificationImpl notification = 370 createNotification 371 (Notification.SET, 372 feature, 373 value, 374 value, 375 feature.isMany() ? indexOf(feature, value) : Notification.NO_INDEX, 376 true); 377 378 if (notifications != null) 379 { 380 notifications.add(notification); 381 } 382 else 383 { 384 notifications = notification; 385 } 386 } 387 388 return notifications; 389 } 390 391 public Object move(int targetIndex, int sourceIndex) 392 { 393 if (isNotificationRequired()) 394 { 395 Entry [] entries = (Entry[])data; 396 Entry sourceEntry = entries[sourceIndex]; 397 EStructuralFeature feature = sourceEntry.getEStructuralFeature(); 398 if (isMany(feature)) 399 { 400 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 401 int featureTargetIndex = -1; 402 int featureSourceIndex = -1; 403 int count = 0; 404 for (int i = 0; i < size; ++i) 405 { 406 Entry entry = entries[i]; 407 if (i == targetIndex) 408 { 409 featureTargetIndex = count; 410 } 411 if (i == sourceIndex) 412 { 413 featureSourceIndex = count; 414 } 415 if (validator.isValid(entry.getEStructuralFeature())) 416 { 417 ++count; 418 } 419 } 420 421 Object result = doMove(targetIndex, sourceIndex); 422 if (featureSourceIndex != featureTargetIndex) 423 { 424 dispatchNotification 425 (new ENotificationImpl 426 (owner, 427 Notification.MOVE, 428 feature, 429 new Integer (featureSourceIndex), 430 sourceEntry.getValue(), 431 featureTargetIndex)); 432 } 433 return result; 434 } 435 else 436 { 437 return doMove(targetIndex, sourceIndex); 438 } 439 } 440 else 441 { 442 return doMove(targetIndex, sourceIndex); 443 } 444 } 445 446 protected Object doMove(int targetIndex, int sourceIndex) 447 { 448 return super.move(targetIndex, sourceIndex); 449 } 450 451 public Object set(int index, Object object) 452 { 453 Entry entry = (Entry)object; 454 EStructuralFeature entryFeature = entry.getEStructuralFeature(); 455 if (isMany(entryFeature)) 456 { 457 if (entryFeature.isUnique()) 458 { 459 Entry [] entries = (Entry[])data; 460 for (int i = 0; i < size; ++i) 461 { 462 Entry otherEntry = entries[i]; 463 if (otherEntry.equals(entry) && i != index) 464 { 465 throw new IllegalArgumentException ("The 'no duplicates' constraint is violated"); 466 } 467 } 468 } 469 } 470 else 471 { 472 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), entryFeature); 473 Entry [] entries = (Entry[])data; 474 for (int i = 0; i < size; ++i) 475 { 476 Entry otherEntry = entries[i]; 477 if (validator.isValid(otherEntry.getEStructuralFeature()) && i != index) 478 { 479 throw new IllegalArgumentException ("The multiplicity constraint is violated"); 480 } 481 } 482 } 483 484 return doSet(index, object); 485 } 486 487 public Object doSet(int index, Object object) 488 { 489 return super.set(index, object); 490 } 491 492 public boolean add(Object object) 493 { 494 Entry entry = (Entry)object; 495 EStructuralFeature entryFeature = entry.getEStructuralFeature(); 496 if (isMany(entryFeature)) 497 { 498 if (entryFeature.isUnique() && contains(entryFeature, entry.getValue())) 499 { 500 return false; 501 } 502 } 503 else 504 { 505 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), entryFeature); 506 Entry [] entries = (Entry[])data; 507 for (int i = 0; i < size; ++i) 508 { 509 Entry otherEntry = entries[i]; 510 if (validator.isValid(otherEntry.getEStructuralFeature())) 511 { 512 if (otherEntry.equals(entry)) 513 { 514 return false; 515 } 516 else 517 { 518 doSet(i, object); 519 return true; 520 } 521 } 522 } 523 } 524 525 return doAdd(object); 526 } 527 528 protected boolean doAdd(Object object) 529 { 530 return super.add(object); 531 } 532 533 public void add(int index, Object object) 534 { 535 Entry entry = (Entry)object; 536 EStructuralFeature entryFeature = entry.getEStructuralFeature(); 537 if (isMany(entryFeature)) 538 { 539 if (entryFeature.isUnique()) 540 { 541 Entry [] entries = (Entry[])data; 542 for (int i = 0; i < size; ++i) 543 { 544 Entry otherEntry = entries[i]; 545 if (otherEntry.equals(entry) && i != index) 546 { 547 throw new IllegalArgumentException ("The 'no duplicates' constraint is violated"); 548 } 549 } 550 } 551 } 552 else 553 { 554 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), entryFeature); 555 Entry [] entries = (Entry[])data; 556 for (int i = 0; i < size; ++i) 557 { 558 Entry otherEntry = entries[i]; 559 if (validator.isValid(otherEntry.getEStructuralFeature())) 560 { 561 throw new IllegalArgumentException ("The multiplicity constraint is violated"); 562 } 563 } 564 } 565 566 doAdd(index, object); 567 } 568 569 public void doAdd(int index, Object object) 570 { 571 super.add(index, object); 572 } 573 574 public boolean addAll(Collection collection) 575 { 576 Collection uniqueCollection = new BasicEList(collection.size()); 577 for (Iterator i = collection.iterator(); i.hasNext(); ) 578 { 579 Entry entry = (Entry)i.next(); 580 EStructuralFeature entryFeature = entry.getEStructuralFeature(); 581 if (isMany(entryFeature)) 582 { 583 if (!entryFeature.isUnique() || !contains(entryFeature, entry.getValue()) && !uniqueCollection.contains(entry)) 584 { 585 uniqueCollection.add(entry); 586 } 587 } 588 else 589 { 590 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), entryFeature); 591 Entry [] entries = (Entry[])data; 592 boolean include = true; 593 for (int j = 0; j < size; ++j) 594 { 595 Entry otherEntry = entries[j]; 596 if (validator.isValid(otherEntry.getEStructuralFeature())) 597 { 598 doSet(j, entry); 599 include = false; 600 break; 601 } 602 } 603 if (include) 604 { 605 uniqueCollection.add(entry); 606 } 607 } 608 } 609 610 return doAddAll(uniqueCollection); 611 } 612 613 public boolean doAddAll(Collection collection) 614 { 615 return super.addAll(collection); 616 } 617 618 public boolean addAll(int index, Collection collection) 619 { 620 Collection uniqueCollection = new BasicEList(collection.size()); 621 for (Iterator i = collection.iterator(); i.hasNext(); ) 622 { 623 Entry entry = (Entry)i.next(); 624 EStructuralFeature entryFeature = entry.getEStructuralFeature(); 625 if (isMany(entryFeature)) 626 { 627 if (!entryFeature.isUnique() || !contains(entryFeature, entry.getValue()) && !uniqueCollection.contains(entry)) 628 { 629 uniqueCollection.add(entry); 630 } 631 } 632 else 633 { 634 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), entryFeature); 635 Entry [] entries = (Entry[])data; 636 boolean include = true; 637 for (int j = 0; j < size; ++j) 638 { 639 Entry otherEntry = entries[j]; 640 if (validator.isValid(otherEntry.getEStructuralFeature())) 641 { 642 doSet(j, entry); 643 include = false; 644 break; 645 } 646 } 647 if (include) 648 { 649 uniqueCollection.add(entry); 650 } 651 } 652 } 653 654 return doAddAll(index, uniqueCollection); 655 } 656 657 public boolean doAddAll(int index, Collection collection) 658 { 659 return super.addAll(index, collection); 660 } 661 662 public int size(EStructuralFeature feature) 663 { 664 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 665 int result = 0; 666 Entry [] entries = (Entry[])data; 667 for (int i = 0; i < size; ++i) 668 { 669 Entry entry = entries[i]; 670 if (validator.isValid(entry.getEStructuralFeature())) 671 { 672 ++result; 673 } 674 } 675 return result; 676 } 677 678 public boolean isEmpty(EStructuralFeature feature) 679 { 680 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 681 Entry [] entries = (Entry[])data; 682 for (int i = 0; i < size; ++i) 683 { 684 Entry entry = entries[i]; 685 if (validator.isValid(entry.getEStructuralFeature())) 686 { 687 return false; 688 } 689 } 690 return true; 691 } 692 693 public boolean contains(EStructuralFeature feature, Object object) 694 { 695 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 696 Entry [] entries = (Entry[])data; 697 if (FeatureMapUtil.isFeatureMap(feature)) 698 { 699 for (int i = 0; i < size; ++i) 700 { 701 Entry entry = entries[i]; 702 if (validator.isValid(entry.getEStructuralFeature()) && entry.equals(object)) 703 { 704 return true; 705 } 706 } 707 } 708 else if (object != null) 709 { 710 for (int i = 0; i < size; ++i) 711 { 712 Entry entry = entries[i]; 713 if (validator.isValid(entry.getEStructuralFeature()) && object.equals(entry.getValue())) 714 { 715 return true; 716 } 717 } 718 } 719 else 720 { 721 for (int i = 0; i < size; ++i) 722 { 723 Entry entry = entries[i]; 724 if (validator.isValid(entry.getEStructuralFeature()) && entry.getValue() == null) 725 { 726 return false; 727 } 728 } 729 } 730 731 return false; 732 } 733 734 public boolean containsAll(EStructuralFeature feature, Collection collection) 735 { 736 for (Iterator i = collection.iterator(); i.hasNext(); ) 737 { 738 if (!contains(feature, i.next())) 739 { 740 return false; 741 } 742 } 743 744 return true; 745 } 746 747 public int indexOf(EStructuralFeature feature, Object object) 748 { 749 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 750 int result = 0; 751 Entry [] entries = (Entry[])data; 752 if (FeatureMapUtil.isFeatureMap(feature)) 753 { 754 for (int i = 0; i < size; ++i) 755 { 756 Entry entry = entries[i]; 757 if (validator.isValid(entry.getEStructuralFeature())) 758 { 759 if (entry.equals(object)) 760 { 761 return result; 762 } 763 ++result; 764 } 765 } 766 } 767 else if (object != null) 768 { 769 for (int i = 0; i < size; ++i) 770 { 771 Entry entry = entries[i]; 772 if (validator.isValid(entry.getEStructuralFeature())) 773 { 774 if (object.equals(entry.getValue())) 775 { 776 return result; 777 } 778 ++result; 779 } 780 } 781 } 782 else 783 { 784 for (int i = 0; i < size; ++i) 785 { 786 Entry entry = entries[i]; 787 if (validator.isValid(entry.getEStructuralFeature())) 788 { 789 if (entry.getValue() == null) 790 { 791 return result; 792 } 793 ++result; 794 } 795 } 796 } 797 798 return -1; 799 } 800 801 public int lastIndexOf(EStructuralFeature feature, Object object) 802 { 803 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 804 int result = -1; 805 int count = 0; 806 Entry [] entries = (Entry[])data; 807 if (FeatureMapUtil.isFeatureMap(feature)) 808 { 809 for (int i = 0; i < size; ++i) 810 { 811 Entry entry = entries[i]; 812 if (validator.isValid(entry.getEStructuralFeature())) 813 { 814 if (entry.equals(object)) 815 { 816 result = count; 817 } 818 ++count; 819 } 820 } 821 } 822 else if (object != null) 823 { 824 for (int i = 0; i < size; ++i) 825 { 826 Entry entry = entries[i]; 827 if (validator.isValid(entry.getEStructuralFeature())) 828 { 829 if (object.equals(entry.getValue())) 830 { 831 result = count; 832 } 833 ++count; 834 } 835 } 836 } 837 else 838 { 839 for (int i = 0; i < size; ++i) 840 { 841 Entry entry = entries[i]; 842 if (validator.isValid(entry.getEStructuralFeature())) 843 { 844 if (entry.getValue() == null) 845 { 846 result = count; 847 } 848 ++count; 849 } 850 } 851 } 852 853 return result; 854 } 855 856 public Iterator iterator(EStructuralFeature feature) 857 { 858 return 859 feature instanceof EReference && ((EReference)feature).isResolveProxies() ? 860 new ResolvingFeatureEIterator(feature, this) : 861 new FeatureEIterator(feature, this); 862 } 863 864 public ListIterator listIterator(EStructuralFeature feature) 865 { 866 return 867 feature instanceof EReference && ((EReference)feature).isResolveProxies() ? 868 new ResolvingFeatureEIterator(feature, this) : 869 new FeatureEIterator(feature, this); 870 } 871 872 public ListIterator listIterator(EStructuralFeature feature, int index) 873 { 874 ListIterator result = 875 feature instanceof EReference && ((EReference)feature).isResolveProxies() ? 876 new ResolvingFeatureEIterator(feature, this) : 877 new FeatureEIterator(feature, this); 878 for (int i = 0; i < index; ++i) 879 { 880 result.next(); 881 } 882 return result; 883 } 884 885 public ValueListIterator valueListIterator() 886 { 887 return new ValueListIteratorImpl(); 888 } 889 890 public ValueListIterator valueListIterator(int index) 891 { 892 return new ValueListIteratorImpl(index); 893 } 894 895 protected class ValueListIteratorImpl extends EListIterator implements ValueListIterator 896 { 897 public ValueListIteratorImpl() 898 { 899 super(); 900 } 901 902 public ValueListIteratorImpl(int index) 903 { 904 super(index); 905 } 906 907 public EStructuralFeature feature() 908 { 909 if (lastCursor == -1) 910 { 911 throw new IllegalStateException (); 912 } 913 return getEStructuralFeature(lastCursor); 914 } 915 916 public Object next() 917 { 918 return ((Entry)super.next()).getValue(); 919 } 920 921 public Object previous() 922 { 923 return ((Entry)super.next()).getValue(); 924 } 925 926 public void add(Object value) 927 { 928 super.add(FeatureMapUtil.createEntry(feature(), value)); 929 } 930 931 public void add(EStructuralFeature eStructuralFeature, Object value) 932 { 933 super.add(FeatureMapUtil.createEntry(eStructuralFeature, value)); 934 } 935 } 936 937 943 944 public EList list(EStructuralFeature feature) 945 { 946 return 947 FeatureMapUtil.isFeatureMap(feature) ? 948 new FeatureMapUtil.FeatureFeatureMap(feature, this) : 949 new FeatureMapUtil.FeatureEList(feature, this); 950 } 951 952 public EStructuralFeature.Setting setting(EStructuralFeature feature) 953 { 954 return 955 isMany(feature) ? 956 (EStructuralFeature.Setting)list(feature) : 957 (EStructuralFeature.Setting)new FeatureMapUtil.FeatureValue(feature, this); 958 } 959 960 public List basicList(final EStructuralFeature feature) 961 { 962 return new FeatureMapUtil.FeatureEList.Basic(feature, this); 963 } 964 965 public Iterator basicIterator(EStructuralFeature feature) 966 { 967 return new FeatureEIterator(feature, this); 968 } 969 970 public ListIterator basicListIterator(EStructuralFeature feature) 971 { 972 return new FeatureEIterator(feature, this); 973 } 974 975 public ListIterator basicListIterator(EStructuralFeature feature, int index) 976 { 977 ListIterator result = new FeatureEIterator(feature, this); 978 for (int i = 0; i < index; ++i) 979 { 980 result.next(); 981 } 982 return result; 983 } 984 985 public Object [] toArray(EStructuralFeature feature) 986 { 987 List result = new BasicEList(); 988 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 989 Entry [] entries = (Entry[])data; 990 if (FeatureMapUtil.isFeatureMap(feature)) 991 { 992 for (int i = 0; i < size; ++i) 993 { 994 Entry entry = entries[i]; 995 if (validator.isValid(entry.getEStructuralFeature())) 996 { 997 result.add(entry); 998 } 999 } 1000 } 1001 else 1002 { 1003 for (int i = 0; i < size; ++i) 1004 { 1005 Entry entry = entries[i]; 1006 if (validator.isValid(entry.getEStructuralFeature())) 1007 { 1008 result.add(entry.getValue()); 1009 } 1010 } 1011 } 1012 return result.toArray(); 1013 } 1014 1015 public Object [] toArray(EStructuralFeature feature, Object [] array) 1016 { 1017 List result = new BasicEList(); 1018 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 1019 Entry [] entries = (Entry[])data; 1020 if (FeatureMapUtil.isFeatureMap(feature)) 1021 { 1022 for (int i = 0; i < size; ++i) 1023 { 1024 Entry entry = entries[i]; 1025 if (validator.isValid(entry.getEStructuralFeature())) 1026 { 1027 result.add(entry); 1028 } 1029 } 1030 } 1031 else 1032 { 1033 for (int i = 0; i < size; ++i) 1034 { 1035 Entry entry = entries[i]; 1036 if (validator.isValid(entry.getEStructuralFeature())) 1037 { 1038 result.add(entry.getValue()); 1039 } 1040 } 1041 } 1042 return result.toArray(array); 1043 } 1044 1045 public void set(EStructuralFeature feature, Object object) 1046 { 1047 if (isMany(feature)) 1048 { 1049 List list = list(feature); 1050 list.clear(); 1051 list.addAll((Collection )object); 1052 } 1053 else 1054 { 1055 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 1056 Entry [] entries = (Entry[])data; 1057 for (int i = 0; i < size; ++i) 1058 { 1059 Entry entry = entries[i]; 1060 if (validator.isValid(entry.getEStructuralFeature())) 1061 { 1062 if (shouldUnset(feature, object)) 1063 { 1064 remove(i); 1065 } 1066 else 1067 { 1068 doSet(i, FeatureMapUtil.isFeatureMap(feature) ? (Entry)object : createEntry(feature, object)); 1069 } 1070 return; 1071 } 1072 } 1073 1074 if (!shouldUnset(feature, object)) 1075 { 1076 doAdd(FeatureMapUtil.isFeatureMap(feature) ? (Entry)object : createEntry(feature, object)); 1077 } 1078 } 1079 } 1080 1081 protected boolean shouldUnset(EStructuralFeature feature, Object value) 1082 { 1083 if (feature.getUpperBound() != EStructuralFeature.UNSPECIFIED_MULTIPLICITY && !feature.isUnsettable()) 1084 { 1085 Object defaultValue = feature.getDefaultValue(); 1086 return defaultValue == null ? value == null : defaultValue.equals(value); 1087 } 1088 else 1089 { 1090 return false; 1091 } 1092 } 1093 1094 public void add(int index, EStructuralFeature feature, Object object) 1095 { 1096 boolean isFeatureMap = FeatureMapUtil.isFeatureMap(feature); 1097 if (isMany(feature)) 1098 { 1099 if (feature.isUnique() && contains(feature, object)) 1100 { 1101 throw new IllegalArgumentException ("The 'no duplicates' constraint is violated"); 1102 } 1103 } 1104 else 1105 { 1106 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 1107 Entry [] entries = (Entry[])data; 1108 for (int i = 0; i < size; ++i) 1109 { 1110 Entry entry = entries[i]; 1111 if (validator.isValid(entry.getEStructuralFeature())) 1112 { 1113 if (isFeatureMap ? entry.equals(object) : object == null ? entry.getValue() == null : object.equals(entry.getValue())) 1114 { 1115 throw new IllegalArgumentException ("The 'no duplicates' constraint is violated"); 1116 } 1117 } 1118 } 1119 } 1120 1121 doAdd(index, isFeatureMap ? (Entry)object : createEntry(feature, object)); 1122 } 1123 1124 public boolean add(EStructuralFeature feature, Object object) 1125 { 1126 boolean isFeatureMap = FeatureMapUtil.isFeatureMap(feature); 1127 if (isMany(feature)) 1128 { 1129 if (feature.isUnique() && contains(feature, object)) 1130 { 1131 return false; 1132 } 1133 } 1134 else 1135 { 1136 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 1137 Entry [] entries = (Entry[])data; 1138 for (int i = 0; i < size; ++i) 1139 { 1140 Entry entry = entries[i]; 1141 if (validator.isValid(entry.getEStructuralFeature())) 1142 { 1143 if (isFeatureMap ? entry.equals(object) : object == null ? entry.getValue() == null : object.equals(entry.getValue())) 1144 { 1145 return false; 1146 } 1147 else 1148 { 1149 doSet(i, isFeatureMap ? (Entry)object : createEntry(feature, object)); 1150 return true; 1151 } 1152 } 1153 } 1154 } 1155 1156 return doAdd(isFeatureMap ? (Entry)object : createEntry(feature, object)); 1157 } 1158 1159 public void add(EStructuralFeature feature, int index, Object object) 1160 { 1161 boolean isFeatureMap = FeatureMapUtil.isFeatureMap(feature); 1162 if (isMany(feature)) 1163 { 1164 if (feature.isUnique() && contains(feature, object)) 1165 { 1166 throw new IllegalArgumentException ("The 'no duplicates' constraint is violated"); 1167 } 1168 } 1169 else 1170 { 1171 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 1172 Entry [] entries = (Entry[])data; 1173 for (int i = 0; i < size; ++i) 1174 { 1175 Entry entry = entries[i]; 1176 if (validator.isValid(entry.getEStructuralFeature())) 1177 { 1178 throw new IllegalArgumentException ("The multiplicity constraint is violated"); 1179 } 1180 } 1181 } 1182 1183 doAdd(entryIndex(feature, index), isFeatureMap ? (Entry)object : createEntry(feature, object)); 1184 } 1185 1186 public boolean addAll(int index, EStructuralFeature feature, Collection collection) 1187 { 1188 if (collection.size() == 0) 1189 { 1190 return false; 1191 } 1192 boolean isFeatureMap = FeatureMapUtil.isFeatureMap(feature); 1193 Collection entryCollection = isFeatureMap ? collection : new BasicEList(collection.size()); 1194 if (isMany(feature)) 1195 { 1196 if (feature.isUnique()) 1197 { 1198 for (Iterator i = collection.iterator(); i.hasNext(); ) 1199 { 1200 Object object = i.next(); 1201 if (!contains(feature, object)) 1202 { 1203 Entry entry = createEntry(feature, object); 1204 if (!entryCollection.contains(entry)) 1205 { 1206 entryCollection.add(entry); 1207 } 1208 } 1209 } 1210 } 1211 else if (!isFeatureMap) 1212 { 1213 for (Iterator i = collection.iterator(); i.hasNext(); ) 1214 { 1215 Entry entry = createEntry(feature, i.next()); 1216 entryCollection.add(entry); 1217 } 1218 } 1219 } 1220 else 1221 { 1222 if (collection.size() > 1) 1223 { 1224 throw new IllegalArgumentException ("The multiplicity constraint is violated"); 1225 } 1226 1227 if (isFeatureMap) 1228 { 1229 if (contains(feature, collection.iterator().next())) 1230 { 1231 return false; 1232 } 1233 } 1234 else 1235 { 1236 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 1237 Entry [] entries = (Entry[])data; 1238 for (int i = 0; i < size; ++i) 1239 { 1240 Entry entry = entries[i]; 1241 if (validator.isValid(entry.getEStructuralFeature())) 1242 { 1243 if (collection.contains(entry.getValue())) 1244 { 1245 return false; 1246 } 1247 else 1248 { 1249 throw new IllegalArgumentException ("The multiplicity constraint is violated"); 1250 } 1251 } 1252 } 1253 Entry entry = createEntry(feature, collection.iterator().next()); 1254 entryCollection.add(entry); 1255 } 1256 } 1257 1258 return doAddAll(index, entryCollection); 1259 } 1260 1261 public boolean addAll(EStructuralFeature feature, Collection collection) 1262 { 1263 if (collection.size() == 0) 1264 { 1265 return false; 1266 } 1267 boolean isFeatureMap = FeatureMapUtil.isFeatureMap(feature); 1268 Collection entryCollection = isFeatureMap ? collection : new BasicEList(collection.size()); 1269 if (isMany(feature)) 1270 { 1271 if (feature.isUnique()) 1272 { 1273 for (Iterator i = collection.iterator(); i.hasNext(); ) 1274 { 1275 Object object = i.next(); 1276 if (!contains(feature, object)) 1277 { 1278 Entry entry = createEntry(feature, object); 1279 if (!entryCollection.contains(entry)) 1280 { 1281 entryCollection.add(entry); 1282 } 1283 } 1284 } 1285 } 1286 else if (!isFeatureMap) 1287 { 1288 for (Iterator i = collection.iterator(); i.hasNext(); ) 1289 { 1290 Entry entry = createEntry(feature, i.next()); 1291 entryCollection.add(entry); 1292 } 1293 } 1294 } 1295 else 1296 { 1297 if (collection.size() > 1) 1298 { 1299 throw new IllegalArgumentException ("The multiplicity constraint is violated"); 1300 } 1301 1302 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 1303 Entry [] entries = (Entry[])data; 1304 for (int i = 0; i < size; ++i) 1305 { 1306 Entry entry = entries[i]; 1307 if (validator.isValid(entry.getEStructuralFeature())) 1308 { 1309 if (collection.contains(isFeatureMap ? entry : entry.getValue())) 1310 { 1311 return false; 1312 } 1313 else 1314 { 1315 for (Iterator j = collection.iterator(); j.hasNext(); ) 1316 { 1317 doSet(i, isFeatureMap ? j.next() : createEntry(feature, j.next())); 1318 } 1319 return true; 1320 } 1321 } 1322 } 1323 if (!isFeatureMap) 1324 { 1325 Entry entry = createEntry(feature, collection.iterator().next()); 1326 entryCollection.add(entry); 1327 } 1328 } 1329 1330 return doAddAll(entryCollection); 1331 } 1332 1333 public boolean addAll(EStructuralFeature feature, int index, Collection collection) 1334 { 1335 if (collection.size() == 0) 1336 { 1337 return false; 1338 } 1339 boolean isFeatureMap = FeatureMapUtil.isFeatureMap(feature); 1340 Collection entryCollection = isFeatureMap ? collection : new BasicEList(collection.size()); 1341 if (isMany(feature)) 1342 { 1343 if (feature.isUnique()) 1344 { 1345 for (Iterator i = collection.iterator(); i.hasNext(); ) 1346 { 1347 Object object = i.next(); 1348 if (!contains(feature, object)) 1349 { 1350 Entry entry = createEntry(feature, object); 1351 entryCollection.add(entry); 1352 } 1353 } 1354 } 1355 else if (!isFeatureMap) 1356 { 1357 for (Iterator i = collection.iterator(); i.hasNext(); ) 1358 { 1359 Entry entry = createEntry(feature, i.next()); 1360 entryCollection.add(entry); 1361 } 1362 } 1363 } 1364 else 1365 { 1366 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 1367 Entry [] entries = (Entry[])data; 1368 for (int i = 0; i < size; ++i) 1369 { 1370 Entry entry = entries[i]; 1371 if (validator.isValid(entry.getEStructuralFeature())) 1372 { 1373 throw new IllegalArgumentException ("The multiplicity constraint is violated"); 1374 } 1375 } 1376 1377 if (collection.size() > 1) 1378 { 1379 throw new IllegalArgumentException ("The multiplicity constraint is violated"); 1380 } 1381 1382 if (!isFeatureMap) 1383 { 1384 Entry entry = createEntry(feature, collection.iterator().next()); 1385 entryCollection.add(entry); 1386 } 1387 } 1388 1389 return doAddAll(entryIndex(feature, index), entryCollection); 1390 } 1391 1392 public void addUnique(EStructuralFeature feature, Object object) 1393 { 1394 addUnique(createEntry(feature, object)); 1395 } 1396 1397 public void addUnique(EStructuralFeature feature, int index, Object object) 1398 { 1399 addUnique(entryIndex(feature, index), createEntry(feature, object)); 1400 } 1401 1402 public NotificationChain basicAdd(EStructuralFeature feature, Object object, NotificationChain notifications) 1403 { 1404 if (object == null) 1405 { 1406 Entry [] entries = (Entry[])data; 1407 for (int i = 0; i < size; ++i) 1408 { 1409 Entry entry = entries[i]; 1410 if (entry.getEStructuralFeature() == feature) 1411 { 1412 return super.basicRemove(entry, notifications); 1413 } 1414 } 1415 } 1416 1417 Entry entry = FeatureMapUtil.isFeatureMap(feature) ? (Entry)object : createEntry(feature, object); 1418 1419 if (isNotificationRequired()) 1420 { 1421 boolean oldIsSet = !isEmpty(feature); 1422 notifications = basicAdd(entry, notifications); 1423 NotificationImpl notification = 1424 feature.isMany() ? 1425 createNotification 1426 (Notification.ADD, 1427 feature, 1428 null, 1429 object, 1430 indexOf(feature, object), 1431 oldIsSet) : 1432 createNotification 1433 (Notification.SET, 1434 feature, 1435 feature.getDefaultValue(), 1436 object, 1437 Notification.NO_INDEX, 1438 oldIsSet); 1439 1440 if (notifications != null) 1441 { 1442 notifications.add(notification); 1443 } 1444 else 1445 { 1446 notifications = notification; 1447 } 1448 } 1449 else 1450 { 1451 notifications = basicAdd(entry, notifications); 1452 } 1453 return notifications; 1454 } 1455 1456 public boolean remove(EStructuralFeature feature, Object object) 1457 { 1458 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 1459 Entry [] entries = (Entry[])data; 1460 if (FeatureMapUtil.isFeatureMap(feature)) 1461 { 1462 for (int i = 0; i < size; ++i) 1463 { 1464 Entry entry = entries[i]; 1465 if (validator.isValid(entry.getEStructuralFeature())) 1466 { 1467 if (entry.equals(object)) 1468 { 1469 remove(i); 1470 return true; 1471 } 1472 } 1473 } 1474 } 1475 else if (object != null) 1476 { 1477 for (int i = 0; i < size; ++i) 1478 { 1479 Entry entry = entries[i]; 1480 if (validator.isValid(entry.getEStructuralFeature())) 1481 { 1482 if (object.equals(entry.getValue())) 1483 { 1484 remove(i); 1485 return true; 1486 } 1487 } 1488 } 1489 } 1490 else 1491 { 1492 for (int i = 0; i < size; ++i) 1493 { 1494 Entry entry = entries[i]; 1495 if (validator.isValid(entry.getEStructuralFeature())) 1496 { 1497 if (entry.getValue() == null) 1498 { 1499 remove(i); 1500 return true; 1501 } 1502 } 1503 } 1504 } 1505 1506 return false; 1507 } 1508 1509 public Object remove(EStructuralFeature feature, int index) 1510 { 1511 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 1512 Entry [] entries = (Entry[])data; 1513 int count = 0; 1514 for (int i = 0; i < size; ++i) 1515 { 1516 Entry entry = entries[i]; 1517 if (validator.isValid(entry.getEStructuralFeature())) 1518 { 1519 if (count == index) 1520 { 1521 remove(i); 1522 return FeatureMapUtil.isFeatureMap(feature) ? entry : entry.getValue(); 1523 } 1524 ++count; 1525 } 1526 } 1527 1528 throw new IndexOutOfBoundsException ("index=" + index + ", size=" + count); 1529 } 1530 1531 public boolean removeAll(EStructuralFeature feature, Collection collection) 1532 { 1533 if (FeatureMapUtil.isFeatureMap(feature)) 1534 { 1535 return removeAll(collection); 1536 } 1537 else 1538 { 1539 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 1540 List entryCollection = new BasicEList(collection.size()); 1541 Entry [] entries = (Entry[])data; 1542 for (int i = size; --i >= 0; ) 1543 { 1544 Entry entry = entries[i]; 1545 if (validator.isValid(entry.getEStructuralFeature())) 1546 { 1547 if (collection.contains(entry.getValue())) 1548 { 1549 entryCollection.add(entry); 1550 } 1551 } 1552 } 1553 1554 return removeAll(entryCollection); 1555 } 1556 } 1557 1558 public NotificationChain basicRemove(EStructuralFeature feature, Object object, NotificationChain notifications) 1559 { 1560 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 1561 int count = 0; 1562 Entry [] entries = (Entry[])data; 1563 Entry match = null; 1564 if (FeatureMapUtil.isFeatureMap(feature)) 1565 { 1566 for (int i = 0; i < size; ++i) 1567 { 1568 Entry entry = entries[i]; 1569 if (validator.isValid(entry.getEStructuralFeature())) 1570 { 1571 if (entry.equals(object)) 1572 { 1573 match = entry; 1574 break; 1575 } 1576 ++count; 1577 } 1578 } 1579 } 1580 else if (object != null) 1581 { 1582 for (int i = 0; i < size; ++i) 1583 { 1584 Entry entry = entries[i]; 1585 if (validator.isValid(entry.getEStructuralFeature())) 1586 { 1587 if (object.equals(entry.getValue())) 1588 { 1589 match = entry; 1590 break; 1591 } 1592 ++count; 1593 } 1594 } 1595 } 1596 else 1597 { 1598 for (int i = 0; i < size; ++i) 1599 { 1600 Entry entry = entries[i]; 1601 if (validator.isValid(entry.getEStructuralFeature())) 1602 { 1603 if (entry.getValue() == null) 1604 { 1605 match = entry; 1606 break; 1607 } 1608 ++count; 1609 } 1610 } 1611 } 1612 1613 if (match != null) 1614 { 1615 if (isNotificationRequired()) 1616 { 1617 NotificationImpl notification = 1618 feature.isMany() ? 1619 createNotification 1620 (Notification.REMOVE, 1621 feature, 1622 object, 1623 null, 1624 count, 1625 true) : 1626 createNotification 1627 (feature.isUnsettable() ? Notification.UNSET : Notification.SET, 1628 feature, 1629 object, 1630 feature.getDefaultValue(), 1631 Notification.NO_INDEX, 1632 true); 1633 1634 if (notifications != null) 1635 { 1636 notifications.add(notification); 1637 } 1638 else 1639 { 1640 notifications = notification; 1641 } 1642 } 1643 notifications = basicRemove(match, notifications); 1644 } 1645 1646 return notifications; 1647 } 1648 1649 public boolean retainAll(EStructuralFeature feature, Collection collection) 1650 { 1651 boolean isFeatureMap = FeatureMapUtil.isFeatureMap(feature); 1652 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 1653 List entryCollection = new BasicEList(collection.size()); 1654 Entry [] entries = (Entry[])data; 1655 for (int i = size; --i >= 0; ) 1656 { 1657 Entry entry = entries[i]; 1658 if (validator.isValid(entry.getEStructuralFeature())) 1659 { 1660 if (!collection.contains(isFeatureMap ? entry : entry.getValue())) 1661 { 1662 entryCollection.add(entry); 1663 } 1664 } 1665 } 1666 1667 return removeAll(entryCollection); 1668 } 1669 1670 public void clear(EStructuralFeature feature) 1671 { 1672 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 1673 List entryCollection = new BasicEList(); 1674 Entry [] entries = (Entry[])data; 1675 for (int i = size; --i >= 0; ) 1676 { 1677 Entry entry = entries[i]; 1678 if (validator.isValid(entry.getEStructuralFeature())) 1679 { 1680 entryCollection.add(entry); 1681 } 1682 } 1683 1684 if (!removeAll(entryCollection)) 1685 { 1686 dispatchNotification 1687 (feature.isMany() ? 1688 createNotification 1689 (Notification.REMOVE_MANY, 1690 feature, 1691 Collections.EMPTY_LIST, 1692 null, 1693 Notification.NO_INDEX, 1694 false) : 1695 createNotification 1696 (feature.isUnsettable() ? Notification.UNSET : Notification.SET, 1697 feature, 1698 null, 1699 null, 1700 Notification.NO_INDEX, 1701 false)); 1702 } 1703 } 1704 1705 public void move(EStructuralFeature feature, int index, Object object) 1706 { 1707 move(feature, index, indexOf(feature, object)); 1708 } 1709 1710 public Object move(EStructuralFeature feature, int targetIndex, int sourceIndex) 1711 { 1712 if (isMany(feature)) 1713 { 1714 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 1715 Entry [] entries = (Entry[])data; 1716 Object result = null; 1717 int entryTargetIndex = -1; 1718 int entrySourceIndex = -1; 1719 int count = 0; 1720 for (int i = 0; i < size; ++i) 1721 { 1722 Entry entry = entries[i]; 1723 if (validator.isValid(entry.getEStructuralFeature())) 1724 { 1725 if (count == targetIndex) 1726 { 1727 entryTargetIndex = i; 1728 } 1729 if (count == sourceIndex) 1730 { 1731 entrySourceIndex = i; 1732 result = entry.getValue(); 1733 } 1734 ++count; 1735 } 1736 } 1737 if (entryTargetIndex == -1) 1738 { 1739 throw new IndexOutOfBoundsException ("targetIndex=" + targetIndex + ", size=" + count); 1740 } 1741 if (entrySourceIndex == -1) 1742 { 1743 throw new IndexOutOfBoundsException ("sourceIndex=" + targetIndex + ", size=" + count); 1744 } 1745 1746 doMove(entryTargetIndex, entrySourceIndex); 1747 1748 if (isNotificationRequired()) 1749 { 1750 dispatchNotification 1751 (createNotification 1752 (Notification.MOVE, 1753 feature, 1754 new Integer (sourceIndex), 1755 result, 1756 targetIndex, 1757 true)); 1758 } 1759 1760 return result; 1761 } 1762 else 1763 { 1764 throw new IllegalArgumentException ("The feature must be many-valued to support move"); 1765 } 1766 } 1767 1768 public Object get(EStructuralFeature feature, boolean resolve) 1769 { 1770 Entry [] entries = (Entry[])data; 1771 if (isMany(feature)) 1772 { 1773 return list(feature); 1774 } 1775 else 1776 { 1777 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 1778 int count = 0; 1779 for (int i = 0; i < size; ++i) 1780 { 1781 Entry entry = entries[i]; 1782 if (validator.isValid(entry.getEStructuralFeature())) 1783 { 1784 if (FeatureMapUtil.isFeatureMap(feature)) 1785 { 1786 return entry; 1787 } 1788 else 1789 { 1790 Object value = entry.getValue(); 1791 if (value != null && resolve && isResolveProxies(feature)) 1792 { 1793 value = resolveProxy(feature, i, count, value); 1794 } 1795 return value; 1796 } 1797 } 1798 ++count; 1799 } 1800 1801 return feature.getDefaultValue(); 1802 } 1803 } 1804 1805 public Object get(EStructuralFeature feature, int index, boolean resolve) 1806 { 1807 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 1808 Entry [] entries = (Entry[])data; 1809 if (isMany(feature)) 1810 { 1811 int count = 0; 1812 for (int i = 0; i < size; ++i) 1813 { 1814 Entry entry = entries[i]; 1815 if (validator.isValid(entry.getEStructuralFeature())) 1816 { 1817 if (count == index) 1818 { 1819 if (FeatureMapUtil.isFeatureMap(feature)) 1820 { 1821 return entry; 1822 } 1823 else 1824 { 1825 Object value = entry.getValue(); 1826 if (value != null && resolve && isResolveProxies(feature)) 1827 { 1828 value = resolveProxy(feature, i, count, value); 1829 } 1830 return value; 1831 } 1832 } 1833 ++count; 1834 } 1835 } 1836 throw new IndexOutOfBoundsException ("index=" + index + ", size=" + count); 1837 } 1838 else 1839 { 1840 int count = 0; 1841 for (int i = 0; i < size; ++i) 1842 { 1843 Entry entry = entries[i]; 1844 if (validator.isValid(entry.getEStructuralFeature())) 1845 { 1846 if (FeatureMapUtil.isFeatureMap(feature)) 1847 { 1848 return entry; 1849 } 1850 else 1851 { 1852 Object value = entry.getValue(); 1853 if (value != null && resolve && isResolveProxies(feature)) 1854 { 1855 value = resolveProxy(feature, i, count, value); 1856 } 1857 return value; 1858 } 1859 } 1860 ++count; 1861 } 1862 1863 return feature.getDefaultValue(); 1864 } 1865 } 1866 1867 public Object set(EStructuralFeature feature, int index, Object object) 1868 { 1869 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 1870 Entry [] entries = (Entry[])data; 1871 if (isMany(feature)) 1872 { 1873 if (feature.isUnique()) 1874 { 1875 int currentIndex = indexOf(feature, object); 1876 if (currentIndex >=0 && currentIndex != index) 1877 { 1878 throw new IllegalArgumentException ("The 'no duplicates' constraint is violated"); 1879 } 1880 } 1881 1882 int count = 0; 1883 for (int i = 0; i < size; ++i) 1884 { 1885 Entry entry = entries[i]; 1886 if (validator.isValid(entry.getEStructuralFeature())) 1887 { 1888 if (count == index) 1889 { 1890 return doSet(i, FeatureMapUtil.isFeatureMap(feature) ? object : createEntry(feature, object)); 1891 } 1892 ++count; 1893 } 1894 } 1895 throw new IndexOutOfBoundsException ("index=" + index + ", size=" + count); 1896 } 1897 else 1898 { 1899 1901 for (int i = 0; i < size; ++i) 1902 { 1903 Entry entry = entries[i]; 1904 if (validator.isValid(entry.getEStructuralFeature())) 1905 { 1906 return FeatureMapUtil.isFeatureMap(feature) ? entry : entry.getValue(); 1907 } 1908 } 1909 1910 return null; 1911 } 1912 } 1913 1914 public Object setUnique(EStructuralFeature feature, int index, Object object) 1915 { 1916 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 1917 Entry [] entries = (Entry[])data; 1918 if (isMany(feature)) 1919 { 1920 int count = 0; 1921 for (int i = 0; i < size; ++i) 1922 { 1923 Entry entry = entries[i]; 1924 if (validator.isValid(entry.getEStructuralFeature())) 1925 { 1926 if (count == index) 1927 { 1928 return setUnique(i, FeatureMapUtil.isFeatureMap(feature) ? object : createEntry(feature, object)); 1929 } 1930 ++count; 1931 } 1932 } 1933 throw new IndexOutOfBoundsException ("index=" + index + ", size=" + count); 1934 } 1935 else 1936 { 1937 1939 for (int i = 0; i < size; ++i) 1940 { 1941 Entry entry = entries[i]; 1942 if (validator.isValid(entry.getEStructuralFeature())) 1943 { 1944 return setUnique(i, FeatureMapUtil.isFeatureMap(feature) ? object : createEntry(feature, object)); 1945 } 1946 } 1947 1948 return feature.getDefaultValue(); 1949 } 1950 } 1951 1952 public boolean isSet(EStructuralFeature feature) 1953 { 1954 return !isEmpty(feature); 1955 } 1956 1957 public void unset(EStructuralFeature feature) 1958 { 1959 FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature); 1960 List removals = null; 1961 Entry [] entries = (Entry[])data; 1962 for (int i = 0; i < size; ++i) 1963 { 1964 Entry entry = entries[i]; 1965 if (validator.isValid(entry.getEStructuralFeature())) 1966 { 1967 if (removals == null) 1968 { 1969 removals = new BasicEList(); 1970 } 1971 removals.add(entry); 1972 } 1973 } 1974 1975 if (removals != null) 1976 { 1977 removeAll(removals); 1978 } 1979 } 1980 1981 public NotificationChain basicRemove(Object object, NotificationChain notifications) 1982 { 1983 if (object instanceof FeatureMap.Entry) 1986 { 1987 return super.basicRemove(object, notifications); 1988 } 1989 else 1990 { 1991 Entry match = null; 1992 EStructuralFeature feature = null; 1993 Entry [] entries = (Entry[])data; 1994 for (int i = 0; i < size; ++i) 1995 { 1996 Entry entry = entries[i]; 1997 if (object.equals(entry.getValue())) 1998 { 1999 feature = entry.getEStructuralFeature(); 2000 if (feature instanceof EReference && ((EReference)feature).isContainment()) 2001 { 2002 match = entry; 2003 break; 2004 } 2005 } 2006 } 2007 2008 if (match != null) 2009 { 2010 if (isNotificationRequired()) 2011 { 2012 NotificationImpl notification = 2013 feature.isMany() ? 2014 createNotification 2015 (Notification.REMOVE, 2016 feature, 2017 object, 2018 null, 2019 indexOf(feature, object), 2020 true) : 2021 createNotification 2022 (feature.isUnsettable() ? Notification.UNSET : Notification.SET, 2023 feature, 2024 object, 2025 feature.getDefaultValue(), 2026 Notification.NO_INDEX, 2027 true); 2028 2029 if (notifications != null) 2030 { 2031 notifications.add(notification); 2032 } 2033 else 2034 { 2035 notifications = notification; 2036 } 2037 } 2038 notifications = basicRemove(match, notifications); 2039 } 2040 2041 return notifications; 2042 } 2043 } 2044 2045 2048 public static class FeatureEIterator extends FeatureMapUtil.BasicFeatureEIterator 2049 { 2050 public FeatureEIterator(EStructuralFeature eStructuralFeature, FeatureMap.Internal featureMap) 2051 { 2052 super(eStructuralFeature, featureMap); 2053 } 2054 2055 protected boolean scanNext() 2056 { 2057 int size = featureMap.size(); 2058 Entry [] entries = (Entry [])((BasicEList)featureMap).data(); 2059 while (entryCursor < size) 2060 { 2061 Entry entry = entries[entryCursor]; 2062 if (validator.isValid(entry.getEStructuralFeature())) 2063 { 2064 preparedResult = extractValue(entry); 2065 prepared = 2; 2066 return true; 2067 } 2068 ++entryCursor; 2069 } 2070 2071 prepared = 1; 2072 lastCursor = -1; 2073 return false; 2074 } 2075 2076 protected boolean scanPrevious() 2077 { 2078 Entry [] entries = (Entry [])((BasicEList)featureMap).data(); 2079 while (--entryCursor >= 0) 2080 { 2081 Entry entry = entries[entryCursor]; 2082 if (validator.isValid(entry.getEStructuralFeature())) 2083 { 2084 preparedResult = extractValue(entry); 2085 prepared = -2; 2086 return true; 2087 } 2088 } 2089 2090 prepared = -1; 2091 lastCursor = -1; 2092 return false; 2093 } 2094 } 2095 2096 2099 public static class ResolvingFeatureEIterator extends FeatureEIterator 2100 { 2101 public ResolvingFeatureEIterator(EStructuralFeature eStructuralFeature, FeatureMap.Internal featureMap) 2102 { 2103 super(eStructuralFeature, featureMap); 2104 } 2105 2106 protected boolean resolve() 2107 { 2108 return true; 2109 } 2110 } 2111 2112 2115 public static class FeatureMapEObjectImpl extends org.eclipse.emf.ecore.impl.EObjectImpl 2116 { 2117 protected BasicFeatureMap featureMap = new BasicFeatureMap(this, -1); 2118 2119 public FeatureMapEObjectImpl() 2120 { 2121 super(); 2122 } 2123 2124 public Object eDynamicGet(EStructuralFeature eFeature, boolean resolve) 2125 { 2126 if (eFeature instanceof EReference && ((EReference)eFeature).isContainer()) 2127 { 2128 return eSettingDelegate(eFeature).dynamicGet(this, null, -1, true); 2129 } 2130 else 2131 { 2132 return featureMap.setting(eFeature).get(resolve); 2133 } 2134 } 2135 2136 public void eDynamicSet(EStructuralFeature eFeature, Object newValue) 2137 { 2138 if (eFeature instanceof EReference && ((EReference)eFeature).isContainer()) 2139 { 2140 eSettingDelegate(eFeature).dynamicSet(this, null, -1, newValue); 2141 } 2142 else 2143 { 2144 if (!eFeature.isUnsettable()) 2145 { 2146 Object defaultValue = eFeature.getDefaultValue(); 2147 if (defaultValue == null ? newValue == null : defaultValue.equals(newValue)) 2148 { 2149 featureMap.setting(eFeature).unset(); 2150 return; 2151 } 2152 } 2153 featureMap.setting(eFeature).set(newValue); 2154 } 2155 2156 2177 } 2178 2179 public void eDynamicUnset(EStructuralFeature eFeature) 2180 { 2181 if (eFeature instanceof EReference && ((EReference)eFeature).isContainer()) 2182 { 2183 eSettingDelegate(eFeature).dynamicUnset(this, null, -1); 2184 } 2185 else 2186 { 2187 featureMap.setting(eFeature).unset(); 2188 } 2189 } 2190 2191 public boolean eDynamicIsSet(EStructuralFeature eFeature) 2192 { 2193 if (eFeature instanceof EReference && ((EReference)eFeature).isContainer()) 2194 { 2195 return eSettingDelegate(eFeature).dynamicIsSet(this, null, -1); 2196 } 2197 else 2198 { 2199 return featureMap.setting(eFeature).isSet(); 2200 } 2201 } 2202 2203 public NotificationChain eDynamicInverseAdd(InternalEObject otherEnd, int featureID, Class inverseClass, NotificationChain notifications) 2204 { 2205 EStructuralFeature.Internal feature = (EStructuralFeature.Internal)eClass().getEStructuralFeature(featureID); 2206 if (feature.isMany()) 2207 { 2208 return featureMap.basicAdd(feature, otherEnd, notifications); 2209 } 2210 else if (feature instanceof EReference && ((EReference)feature).isContainer()) 2211 { 2212 return eSettingDelegate(feature).dynamicInverseAdd(this, null, -1, otherEnd, notifications); 2213 } 2214 else 2215 { 2216 InternalEObject oldValue = (InternalEObject)eDynamicGet(feature, false); 2217 if (oldValue != null) 2218 { 2219 notifications = oldValue.eInverseRemove 2220 (this, oldValue.eClass().getFeatureID(((EReference)feature).getEOpposite()), null, notifications); 2221 notifications = featureMap.basicRemove(feature, oldValue, notifications); 2222 } 2223 2224 return featureMap.basicAdd(feature, otherEnd, notifications); 2225 } 2226 } 2227 2228 public NotificationChain eDynamicInverseRemove(InternalEObject otherEnd, int featureID, Class inverseClass, NotificationChain notifications) 2229 { 2230 EStructuralFeature.Internal feature = (EStructuralFeature.Internal)eClass().getEStructuralFeature(featureID); 2231 if (feature instanceof EReference && ((EReference)feature).isContainer()) 2232 { 2233 return eSettingDelegate(feature).dynamicInverseRemove(this, null, -1, otherEnd, notifications); 2234 } 2235 else 2236 { 2237 return featureMap.basicRemove(feature, otherEnd, notifications); 2238 } 2239 } 2240 2241 public FeatureMap featureMap() 2242 { 2243 return featureMap; 2244 } 2245 2246 public void eNotify(Notification notification) 2247 { 2248 if (notification.getFeatureID(null) != -1) 2249 { 2250 super.eNotify(notification); 2251 } 2252 } 2253 2254 public String toString() 2255 { 2256 String result = super.toString(); 2257 result = "org.eclipse.emf.ecore.impl.EObjectImpl" + result.substring(result.indexOf("@")); 2258 return result; 2259 } 2260 } 2261} 2262 | Popular Tags |