1 17 package org.eclipse.emf.ecore.util; 18 19 20 import java.util.Iterator ; 21 import java.util.List ; 22 import java.util.ListIterator ; 23 24 import org.eclipse.emf.common.notify.Notification; 25 import org.eclipse.emf.common.notify.NotificationChain; 26 import org.eclipse.emf.common.notify.impl.DelegatingNotifyingListImpl; 27 import org.eclipse.emf.common.notify.impl.NotificationImpl; 28 import org.eclipse.emf.common.util.DelegatingEList; 29 import org.eclipse.emf.ecore.EClass; 30 import org.eclipse.emf.ecore.EClassifier; 31 import org.eclipse.emf.ecore.EDataType; 32 import org.eclipse.emf.ecore.EEnum; 33 import org.eclipse.emf.ecore.EObject; 34 import org.eclipse.emf.ecore.EReference; 35 import org.eclipse.emf.ecore.EStructuralFeature; 36 import org.eclipse.emf.ecore.InternalEObject; 37 import org.eclipse.emf.ecore.impl.ENotificationImpl; 38 39 40 public abstract class DelegatingEcoreEList 41 extends DelegatingNotifyingListImpl 42 implements InternalEList.Unsettable, EStructuralFeature.Setting 43 { 44 public static abstract class Unsettable extends DelegatingEcoreEList 45 { 46 protected boolean isSet; 47 48 public Unsettable(InternalEObject owner) 49 { 50 super(owner); 51 } 52 53 protected void didChange() 54 { 55 isSet = true; 56 } 57 58 public boolean isSet() 59 { 60 return isSet; 61 } 62 63 public void unset() 64 { 65 super.unset(); 66 if (isNotificationRequired()) 67 { 68 boolean oldIsSet = isSet; 69 isSet = false; 70 owner.eNotify(createNotification(Notification.UNSET, oldIsSet, false)); 71 } 72 else 73 { 74 isSet = false; 75 } 76 } 77 } 78 79 protected final InternalEObject owner; 80 81 public DelegatingEcoreEList(InternalEObject owner) 82 { 83 super(); 84 this.owner = owner; 85 } 86 87 protected boolean canContainNull() 88 { 89 EClassifier eClassifier = getFeatureType(); 90 if (eClassifier instanceof EDataType) 91 { 92 if (eClassifier instanceof EEnum) 93 { 94 return false; 95 } 96 else 97 { 98 return !eClassifier.getInstanceClass().isPrimitive(); 99 } 100 } 101 else 102 { 103 return false; 104 } 105 } 106 107 protected boolean isUnique() 108 { 109 return getEStructuralFeature().isUnique(); 110 } 111 112 protected boolean hasInverse() 113 { 114 EStructuralFeature eStructuralFeature = getEStructuralFeature(); 115 if (eStructuralFeature instanceof EReference) 116 { 117 EReference eReference = (EReference)eStructuralFeature; 118 return eReference.isContainment() || ((EReference)eStructuralFeature).getEOpposite() != null; 119 } 120 else 121 { 122 return false; 123 } 124 } 125 126 protected Object validate(int index, Object object) 127 { 128 super.validate(index, object); 129 if (object != null && !getFeatureType().isInstance(object)) 130 { 131 throw new ArrayStoreException (); 132 } 133 return object; 134 } 135 136 public Object getNotifier() 137 { 138 return owner; 139 } 140 141 public Object getFeature() 142 { 143 return getEStructuralFeature(); 144 } 145 146 public int getFeatureID() 147 { 148 return getEStructuralFeature().getFeatureID(); 149 } 150 151 public EStructuralFeature getEStructuralFeature() 152 { 153 return owner.eClass().getEStructuralFeature(getFeatureID()); 154 } 155 156 protected EClassifier getFeatureType() 157 { 158 return getEStructuralFeature().getEType(); 159 } 160 161 protected EReference getInverseEReference() 162 { 163 return ((EReference)getEStructuralFeature()).getEOpposite(); 164 } 165 166 protected int getInverseFeatureID() 167 { 168 return getInverseEReference().getFeatureID(); 169 } 170 171 protected Class getInverseFeatureClass() 172 { 173 return ((EClass)getInverseEReference().getEType()).getInstanceClass(); 174 } 175 176 protected boolean hasManyInverse() 177 { 178 EStructuralFeature eStructuralFeature = getEStructuralFeature(); 179 if (eStructuralFeature instanceof EReference) 180 { 181 EReference eReference = (EReference)eStructuralFeature; 182 EReference oppositeEReference = eReference.getEOpposite(); 183 return oppositeEReference != null && oppositeEReference.isMany(); 184 } 185 else 186 { 187 return false; 188 } 189 } 190 191 protected boolean hasNavigableInverse() 192 { 193 EStructuralFeature eStructuralFeature = getEStructuralFeature(); 194 if (eStructuralFeature instanceof EReference) 195 { 196 EReference eReference = (EReference)eStructuralFeature; 197 EReference oppositeEReference = eReference.getEOpposite(); 198 return oppositeEReference != null; 199 } 200 else 201 { 202 return false; 203 } 204 } 205 206 protected boolean isEObject() 207 { 208 return getFeatureType() instanceof EClass; 209 } 210 211 protected boolean isContainment() 212 { 213 EStructuralFeature eStructuralFeature = getEStructuralFeature(); 214 if (eStructuralFeature instanceof EReference) 215 { 216 EReference eReference = (EReference)eStructuralFeature; 217 return eReference.isContainment(); 218 } 219 else 220 { 221 return false; 222 } 223 } 224 225 protected boolean hasProxies() 226 { 227 EStructuralFeature eStructuralFeature = getEStructuralFeature(); 228 if (eStructuralFeature instanceof EReference) 229 { 230 EReference eReference = (EReference)eStructuralFeature; 231 return eReference.isResolveProxies(); 232 } 233 else 234 { 235 return false; 236 } 237 } 238 239 protected boolean hasInstanceClass() 240 { 241 return getFeatureType().getInstanceClass() != null; 242 } 243 244 protected Object resolve(int index, Object object) 245 { 246 if (isEObject() && hasProxies()) 247 { 248 EObject resolved = resolveProxy((EObject)object); 249 if (resolved != object) 250 { 251 Object oldObject = delegateGet(index); 252 delegateSet(index, validate(index, resolved)); 253 didSet(index, resolved, oldObject); 254 255 if (isNotificationRequired()) 256 { 257 owner.eNotify(createNotification(Notification.RESOLVE, object, resolved, index, false)); 258 } 259 260 return resolved; 261 } 262 } 263 return object; 264 } 265 266 protected EObject resolveProxy(EObject eObject) 267 { 268 return eObject.eIsProxy() ? owner.eResolveProxy((InternalEObject)eObject) : eObject; 269 } 270 271 public Object [] toArray() 272 { 273 if (hasProxies()) 274 { 275 for (int i = size() - 1; i >= 0; --i) 276 { 277 get(i); 278 } 279 } 280 return super.toArray(); 281 } 282 283 public Object [] toArray(Object array[]) 284 { 285 if (hasProxies()) 286 { 287 for (int i = size() - 1; i >= 0; --i) 288 { 289 get(i); 290 } 291 } 292 return super.toArray(array); 293 } 294 295 protected NotificationImpl createNotification(int eventType, Object oldObject, Object newObject, int index, boolean wasSet) 296 { 297 return new ENotificationImpl(owner, eventType, getFeatureID(), oldObject, newObject, index, wasSet); 298 } 299 300 protected NotificationImpl createNotification(int eventType, boolean oldValue, boolean newValue) 301 { 302 return new ENotificationImpl(owner, eventType, getFeatureID(), oldValue, newValue); 303 } 304 305 308 protected void dispatchNotification(Notification notification) 309 { 310 owner.eNotify(notification); 311 } 312 313 public Object basicGet(int index) 314 { 315 return super.basicGet(index); 316 } 317 318 public List basicList() 319 { 320 return super.basicList(); 321 } 322 323 protected boolean isNotificationRequired() 324 { 325 return owner.eNotificationRequired(); 326 } 327 328 public NotificationChain inverseAdd(Object object, NotificationChain notifications) 329 { 330 InternalEObject internalEObject = (InternalEObject) object; 331 if (hasNavigableInverse()) 332 { 333 if (!hasInstanceClass()) 334 { 335 return 336 internalEObject.eInverseAdd 337 (owner, 338 internalEObject.eClass().getFeatureID(getInverseEReference()), 339 null, 340 notifications); 341 } 342 else 343 { 344 return 345 internalEObject.eInverseAdd 346 (owner, 347 getInverseFeatureID(), 348 getInverseFeatureClass(), 349 notifications); 350 } 351 } 352 else 353 { 354 return 355 internalEObject.eInverseAdd 356 (owner, 357 InternalEObject.EOPPOSITE_FEATURE_BASE - getFeatureID(), 358 null, 359 notifications); 360 } 361 } 362 363 public NotificationChain inverseRemove(Object object, NotificationChain notifications) 364 { 365 InternalEObject internalEObject = (InternalEObject) object; 366 if (hasNavigableInverse()) 367 { 368 if (!hasInstanceClass()) 369 { 370 return 371 internalEObject.eInverseRemove 372 (owner, 373 internalEObject.eClass().getFeatureID(getInverseEReference()), 374 null, 375 notifications); 376 } 377 else 378 { 379 return 380 internalEObject.eInverseRemove 381 (owner, 382 getInverseFeatureID(), 383 getInverseFeatureClass(), 384 notifications); 385 } 386 } 387 else 388 { 389 return 390 internalEObject.eInverseRemove 391 (owner, 392 InternalEObject.EOPPOSITE_FEATURE_BASE - getFeatureID(), 393 null, 394 notifications); 395 } 396 } 397 398 401 public boolean contains(Object object) 402 { 403 if (isEObject()) 404 { 405 int size = size(); 406 if (size > 4) 407 { 408 if (isContainment()) 409 { 410 if (!(object instanceof EObject)) return false; 411 InternalEObject eObject = (InternalEObject)object; 412 return 413 eObject.eContainer() == owner && 414 (hasNavigableInverse() ? 415 eObject.eContainerFeatureID() == getInverseFeatureID() : 416 InternalEObject.EOPPOSITE_FEATURE_BASE - eObject.eContainerFeatureID() == getFeatureID()); 417 } 418 else if (hasNavigableInverse() && !hasManyInverse()) 421 { 422 return object instanceof EObject && ((EObject)object).eGet(getInverseEReference()) == owner; 423 } 424 } 425 426 boolean result = super.contains(object); 427 if (hasProxies() && !result) 428 { 429 for (int i = 0; i < size; ++i) 430 { 431 EObject eObject = resolveProxy((EObject)delegateGet(i)); 432 if (eObject == object) 433 { 434 return true; 435 } 436 } 437 } 438 return result; 439 } 440 else 441 { 442 return super.contains(object); 443 } 444 } 445 446 public int indexOf(Object object) 447 { 448 int index = super.indexOf(object); 449 if (index >= 0) 450 return index; 451 452 if (isEObject()) 455 { 456 for (int i = 0, size = size(); i < size; ++i) 457 { 458 EObject eObject = resolveProxy((EObject)delegateGet(i)); 459 if (eObject == object) 460 { 461 return i; 462 } 463 } 464 } 465 466 return -1; 467 } 468 469 public int lastIndexOf(Object object) 470 { 471 int result = super.lastIndexOf(object); 472 if (isEObject () && result == -1) 473 { 474 for (int i = size() - 1; i >= 0; --i) 475 { 476 EObject eObject = resolveProxy((EObject)delegateGet(i)); 477 if (eObject == object) 478 { 479 return i; 480 } 481 } 482 } 483 484 return result; 485 } 486 487 public Iterator basicIterator() 488 { 489 return super.basicIterator(); 490 } 491 492 public ListIterator basicListIterator() 493 { 494 return super.basicListIterator(); 495 } 496 497 public ListIterator basicListIterator(int index) 498 { 499 return super.basicListIterator(index); 500 } 501 502 public EObject getEObject() 503 { 504 return owner; 505 } 506 507 public Object get(boolean resolve) 508 { 509 return this; 510 } 511 512 public void set(Object newValue) 513 { 514 clear(); 515 addAll((List )newValue); 516 } 517 518 public boolean isSet() 519 { 520 return !isEmpty(); 521 } 522 523 public void unset() 524 { 525 clear(); 526 } 527 528 public static class UnmodifiableEList 529 extends DelegatingEList.UnmodifiableEList 530 implements InternalEList.Unsettable, EStructuralFeature.Setting 531 { 532 protected final InternalEObject owner; 533 protected final EStructuralFeature eStructuralFeature; 534 535 public UnmodifiableEList(InternalEObject owner, EStructuralFeature eStructuralFeature, List underlyingList) 536 { 537 super(underlyingList); 538 this.owner = owner; 539 this.eStructuralFeature = eStructuralFeature; 540 } 541 542 public Object basicGet(int index) 543 { 544 return super.basicGet(index); 545 } 546 547 public List basicList() 548 { 549 return super.basicList(); 550 } 551 552 public Iterator basicIterator() 553 { 554 return super.basicIterator(); 555 } 556 557 public ListIterator basicListIterator() 558 { 559 return super.basicListIterator(); 560 } 561 562 public ListIterator basicListIterator(int index) 563 { 564 return super.basicListIterator(index); 565 } 566 567 public EObject getEObject() 568 { 569 return owner; 570 } 571 572 public EStructuralFeature getEStructuralFeature() 573 { 574 return eStructuralFeature; 575 } 576 577 public Object get(boolean resolve) 578 { 579 return this; 580 } 581 582 public void set(Object newValue) 583 { 584 throw new UnsupportedOperationException (); 585 } 586 587 public boolean isSet() 588 { 589 return !isEmpty(); 590 } 591 592 public void unset() 593 { 594 throw new UnsupportedOperationException (); 595 } 596 597 public NotificationChain basicRemove(Object object, NotificationChain notifications) 598 { 599 throw new UnsupportedOperationException (); 600 } 601 602 public NotificationChain basicAdd(Object object, NotificationChain notifications) 603 { 604 throw new UnsupportedOperationException (); 605 } 606 } 607 608 public static abstract class Generic extends DelegatingEcoreEList 609 { 610 public static final int IS_SET = EcoreEList.Generic.IS_SET; 611 public static final int IS_UNSETTABLE = EcoreEList.Generic.IS_UNSETTABLE; 612 public static final int HAS_INSTANCE_CLASS = EcoreEList.Generic.HAS_INSTANCE_CLASS; 613 public static final int HAS_NAVIGABLE_INVERSE = EcoreEList.Generic.HAS_NAVIGABLE_INVERSE; 614 public static final int HAS_MANY_INVERSE = EcoreEList.Generic.HAS_MANY_INVERSE; 615 public static final int IS_CONTAINMENT = EcoreEList.Generic.IS_CONTAINMENT; 616 public static final int IS_CONTAINER = EcoreEList.Generic.IS_CONTAINER; 617 public static final int IS_UNIQUE = EcoreEList.Generic.IS_UNIQUE; 618 public static final int IS_PRIMITIVE = EcoreEList.Generic.IS_PRIMITIVE; 619 public static final int IS_ENUM = EcoreEList.Generic.IS_ENUM; 620 public static final int IS_EOBJECT = EcoreEList.Generic.IS_EOBJECT; 621 public static final int HAS_PROXIES = EcoreEList.Generic.HAS_PROXIES; 622 623 public static int kind(EStructuralFeature eStructuralFeature) 624 { 625 return EcoreEList.Generic.kind(eStructuralFeature); 626 } 627 628 protected int kind; 629 630 public Generic(int kind, InternalEObject owner) 631 { 632 super(owner); 633 this.kind = kind; 634 } 635 636 protected boolean useEquals() 637 { 638 return (kind & (IS_EOBJECT | IS_ENUM)) == 0; 641 } 642 643 protected boolean canContainNull() 644 { 645 return (kind & (IS_EOBJECT | IS_PRIMITIVE | IS_ENUM)) == 0; 646 } 647 648 protected boolean isUnique() 649 { 650 return (kind & IS_UNIQUE) != 0; 651 } 652 653 protected boolean hasInverse() 654 { 655 return (kind & (HAS_NAVIGABLE_INVERSE | IS_CONTAINMENT)) != 0; 656 } 657 658 protected boolean hasManyInverse() 659 { 660 return (kind & HAS_MANY_INVERSE) != 0; 661 } 662 663 protected boolean hasNavigableInverse() 664 { 665 return (kind & HAS_NAVIGABLE_INVERSE) != 0; 666 } 667 668 protected boolean isEObject() 669 { 670 return (kind & IS_EOBJECT) != 0; 671 } 672 673 protected boolean isContainment() 674 { 675 return (kind & IS_CONTAINMENT) != 0; 676 } 677 678 protected boolean hasProxies() 679 { 680 return (kind & HAS_PROXIES) != 0; 681 } 682 683 protected boolean hasInstanceClass() 684 { 685 return (kind & HAS_INSTANCE_CLASS) != 0; 686 } 687 688 protected boolean isContainer() 689 { 690 return (kind & IS_CONTAINER) != 0; 691 } 692 693 protected boolean isUnsettable() 694 { 695 return (kind & IS_UNSETTABLE) != 0; 696 } 697 698 public boolean isSet() 699 { 700 return isUnsettable() ? (kind & IS_SET) != 0 : !isEmpty(); 701 } 702 703 public void unset() 704 { 705 super.unset(); 706 if (isUnsettable()) 707 { 708 if (isNotificationRequired()) 709 { 710 boolean oldIsSet = (kind & IS_SET) != 0; 711 kind &= ~IS_SET; 712 owner.eNotify(createNotification(Notification.UNSET, oldIsSet, false)); 713 } 714 else 715 { 716 kind &= ~IS_SET; 717 } 718 } 719 } 720 721 protected void didChange() 722 { 723 kind |= IS_SET; 724 } 725 } 726 727 public static abstract class Dynamic extends Generic 728 { 729 protected EStructuralFeature eStructuralFeature; 730 731 public Dynamic(InternalEObject owner, EStructuralFeature eStructuralFeature) 732 { 733 super(kind(eStructuralFeature), owner); 734 this.eStructuralFeature = eStructuralFeature; 735 } 736 737 public Dynamic(int kind, InternalEObject owner, EStructuralFeature eStructuralFeature) 738 { 739 super(kind, owner); 740 this.eStructuralFeature = eStructuralFeature; 741 } 742 743 public EStructuralFeature getEStructuralFeature() 744 { 745 return eStructuralFeature; 746 } 747 } 748 } 749 | Popular Tags |