1 17 package org.eclipse.emf.ecore.change.impl; 18 19 20 import java.util.Collection ; 21 import java.util.Iterator ; 22 import java.util.Map ; 23 24 import org.eclipse.emf.common.notify.Notification; 25 import org.eclipse.emf.common.notify.NotificationChain; 26 import org.eclipse.emf.common.util.BasicEList; 27 import org.eclipse.emf.common.util.ECollections; 28 import org.eclipse.emf.common.util.EList; 29 import org.eclipse.emf.ecore.EAttribute; 30 import org.eclipse.emf.ecore.EClass; 31 import org.eclipse.emf.ecore.EDataType; 32 import org.eclipse.emf.ecore.EObject; 33 import org.eclipse.emf.ecore.EReference; 34 import org.eclipse.emf.ecore.EStructuralFeature; 35 import org.eclipse.emf.ecore.InternalEObject; 36 import org.eclipse.emf.ecore.change.ChangeFactory; 37 import org.eclipse.emf.ecore.change.ChangeKind; 38 import org.eclipse.emf.ecore.change.ChangePackage; 39 import org.eclipse.emf.ecore.change.FeatureChange; 40 import org.eclipse.emf.ecore.change.ListChange; 41 import org.eclipse.emf.ecore.impl.ENotificationImpl; 42 import org.eclipse.emf.ecore.impl.EObjectImpl; 43 import org.eclipse.emf.ecore.util.EObjectContainmentEList; 44 import org.eclipse.emf.ecore.util.EcoreUtil; 45 import org.eclipse.emf.ecore.util.FeatureMapUtil; 46 import org.eclipse.emf.ecore.util.InternalEList; 47 48 49 68 public class FeatureChangeImpl extends EObjectImpl implements FeatureChange 69 { 70 73 protected static final int EPROXY_FEATURECHANGE = ELAST_EOBJECT_FLAG << 1; 74 75 83 protected static final String FEATURE_NAME_EDEFAULT = null; 84 85 93 protected static final String DATA_VALUE_EDEFAULT = null; 94 95 103 protected static final boolean SET_EDEFAULT = true; 104 105 113 protected boolean set = SET_EDEFAULT; 114 115 123 protected static final Object VALUE_EDEFAULT = null; 124 125 133 protected EList listChanges = null; 134 135 protected EStructuralFeature feature = null; 136 137 protected String featureName = null; 138 139 protected Object value = null; 140 141 protected String valueString = null; 142 143 148 protected FeatureChangeImpl() 149 { 150 super(); 151 } 152 153 protected FeatureChangeImpl(EStructuralFeature feature, Object value, boolean isSet) 154 { 155 this(); 156 this.feature = feature; 157 setValue(value); 158 this.set = isSet; 159 } 160 161 166 protected EClass eStaticClass() 167 { 168 return ChangePackage.eINSTANCE.getFeatureChange(); 169 } 170 171 176 public String getFeatureName() 177 { 178 return feature == null ? featureName : feature.getName(); 179 } 180 181 186 public void setFeatureName(String newFeatureName) 187 { 188 featureName = newFeatureName; 189 feature = null; 190 eFlags &= ~EPROXY_FEATURECHANGE; 191 } 192 193 198 public void unsetFeatureName() 199 { 200 setFeatureName(null); 201 } 202 203 208 public boolean isSetFeatureName() 209 { 210 return (feature != null || featureName != null) && eContainer() instanceof EObjectToChangesMapEntryImpl; 211 } 212 213 218 public String getDataValue() 219 { 220 if (valueString == null) 221 { 222 EStructuralFeature feature = getFeature(); 223 if (feature instanceof EAttribute && !feature.isMany()) 224 { 225 EDataType type = (EDataType)feature.getEType(); 226 valueString = EcoreUtil.convertToString(type, value); 227 } 228 } 229 return valueString; 230 } 231 232 237 public void setDataValue(String newDataValue) 238 { 239 String oldDataValue = getDataValue(); 240 valueString = newDataValue; 241 value = null; 242 if (eNotificationRequired()) 243 eNotify(new ENotificationImpl(this, Notification.SET, ChangePackage.FEATURE_CHANGE__DATA_VALUE, oldDataValue, newDataValue)); 244 } 245 246 251 public boolean isSet() 252 { 253 return set; 254 } 255 256 261 public void setSet(boolean newSet) 262 { 263 boolean oldSet = set; 264 set = newSet; 265 if (eNotificationRequired()) 266 eNotify(new ENotificationImpl(this, Notification.SET, ChangePackage.FEATURE_CHANGE__SET, oldSet, set)); 267 } 268 269 274 public EStructuralFeature getFeature() 275 { 276 if (feature == null) 277 { 278 if (eContainer() instanceof EObjectToChangesMapEntryImpl) 279 { 280 feature = ((EObject)((Map.Entry )eContainer()).getKey()).eClass().getEStructuralFeature(featureName); 281 } 282 } 283 else if ((eFlags & EPROXY_FEATURECHANGE) !=0) 284 { 285 EStructuralFeature oldFeature = feature; 286 feature = (EStructuralFeature)EcoreUtil.resolve(feature, this); 287 if (feature != oldFeature) 288 { 289 if (eNotificationRequired()) 290 eNotify(new ENotificationImpl(this, Notification.RESOLVE, ChangePackage.FEATURE_CHANGE__FEATURE, oldFeature, feature)); 291 } 292 eFlags &= ~ EPROXY_FEATURECHANGE; 293 } 294 return feature; 295 } 296 297 302 public EStructuralFeature basicGetFeature() 303 { 304 return feature; 305 } 306 307 312 public void setFeature(EStructuralFeature newFeature) 313 { 314 EStructuralFeature oldFeature = basicGetFeature(); 315 feature = newFeature; 316 featureName = null; 317 if (feature != null && feature.eIsProxy()) 318 eFlags |= EPROXY_FEATURECHANGE; 319 else 320 eFlags &= ~EPROXY_FEATURECHANGE; 321 if (eNotificationRequired()) 322 eNotify(new ENotificationImpl(this, Notification.SET, ChangePackage.FEATURE_CHANGE__FEATURE, oldFeature, newFeature)); 323 } 324 325 330 public void unsetFeature() 331 { 332 setFeature(null); 333 } 334 335 340 public boolean isSetFeature() 341 { 342 return feature != null && !(eContainer() instanceof EObjectToChangesMapEntryImpl); 343 } 344 345 350 public EObject getReferenceValue() 351 { 352 EObject referenceValue = basicGetReferenceValue(); 353 if (referenceValue != null && referenceValue.eIsProxy()) 354 { 355 EObject oldReferenceValue = referenceValue; 356 referenceValue = EcoreUtil.resolve(referenceValue, this); 357 if (referenceValue != oldReferenceValue) 358 { 359 if (eNotificationRequired()) 360 eNotify(new ENotificationImpl(this, Notification.RESOLVE, ChangePackage.FEATURE_CHANGE__REFERENCE_VALUE, oldReferenceValue, referenceValue)); 361 } 362 } 363 return referenceValue; 364 } 365 366 371 public EObject basicGetReferenceValue() 372 { 373 return (feature instanceof EReference && value instanceof EObject) ? (EObject)value : null; 374 } 375 376 381 public void setReferenceValue(EObject newReferenceValue) 382 { 383 EObject oldReferenceValue = basicGetReferenceValue(); 384 value = newReferenceValue; 385 valueString = null; 386 if (eNotificationRequired()) 387 eNotify(new ENotificationImpl(this, Notification.SET, ChangePackage.FEATURE_CHANGE__REFERENCE_VALUE, oldReferenceValue, newReferenceValue)); 388 } 389 390 395 public EList getListChanges() 396 { 397 if (listChanges == null) 398 { 399 listChanges = new EObjectContainmentEList(ListChange.class, this, ChangePackage.FEATURE_CHANGE__LIST_CHANGES); 400 } 401 return listChanges; 402 } 403 404 409 public Object getValue() 410 { 411 EStructuralFeature feature = getFeature(); 412 if (feature.getUpperBound() < 0) 413 { 414 if (value == null && eContainer() instanceof EObjectToChangesMapEntryImpl) 415 { 416 value = getListValue((EList)((EObject)((Map.Entry )eContainer()).getKey()).eGet(feature)); 417 } 418 } 419 else if (feature instanceof EReference) 420 { 421 return getReferenceValue(); 422 } 423 else if (value == null) { 425 EDataType type = (EDataType)feature.getEType(); 426 value = EcoreUtil.createFromString(type, valueString); 427 } 428 return value; 429 } 430 431 protected void setValue(Object value) 432 { 433 EStructuralFeature feature = getFeature(); 434 if (!eNotificationRequired() || feature.isMany()) 435 { 436 valueString = null; 437 this.value = value; 438 } 439 else 440 { 441 if (feature instanceof EAttribute) 442 { 443 EDataType type = (EDataType)feature.getEType(); 444 setDataValue(EcoreUtil.convertToString(type, value)); 445 this.value = value; 446 } 447 else 448 { 449 setReferenceValue((EObject)value); 450 } 451 } 452 } 453 454 protected EList getListValue(EList originalList) 455 { 456 if (isSet() && getFeature().getUpperBound() < 0) 457 { 458 if (value instanceof EList) { 460 return (EList)value; 461 } 462 463 EList changedList = new BasicEList(originalList); 464 apply(changedList); 465 value = changedList; return changedList; 467 } 468 return ECollections.EMPTY_ELIST; 469 } 470 471 476 public void apply(EObject originalObject) 477 { 478 EStructuralFeature feature = getFeature(); 479 if (feature != null && feature.isChangeable()) 480 { 481 if (!isSet()) 482 { 483 originalObject.eUnset(feature); 484 } 485 else if (feature.isMany()) 486 { 487 if (listChanges != null) 488 { 489 if (FeatureMapUtil.isFeatureMap(feature) || 490 feature instanceof EReference && (((EReference)feature).getEOpposite() != null || ((EReference)feature).isContainment())) 491 { 492 ECollections.setEList((EList)originalObject.eGet(feature), (EList)getValue()); 496 } 497 else 498 { 499 apply((EList)originalObject.eGet(feature)); 500 } 501 } 502 } 503 else 504 { 505 originalObject.eSet(feature, getValue()); 506 } 507 } 508 } 509 510 515 public void applyAndReverse(EObject originalObject) 516 { 517 EStructuralFeature feature = getFeature(); 518 boolean isEReference = feature instanceof EReference; 519 520 if (feature != null && feature.isChangeable() && (!isEReference || !((EReference)feature).isContainer())) 521 { 522 if (!isSet()) 523 { 524 if (feature.isMany()) 525 { 526 ListChange listChange = createListChange(getListChanges(), ChangeKind.ADD_LITERAL, 0); 527 if (isEReference && (((EReference)feature).getEOpposite() != null || ((EReference)feature).isContainment())) 528 { 529 listChange.getValues().addAll((EList)getValue()); 530 } 531 else 532 { 533 listChange.getValues().addAll((EList)originalObject.eGet(feature)); 534 } 535 } 536 originalObject.eUnset(feature); 537 } 538 else if (feature.isMany()) 539 { 540 if (listChanges != null) 541 { 542 if (FeatureMapUtil.isFeatureMap(feature) || 543 isEReference && (((EReference)feature).getEOpposite() != null || ((EReference)feature).isContainment())) 544 { 545 ECollections.setEList((EList)originalObject.eGet(feature), (EList)getValue()); 549 } 550 else 551 { 552 EList applyToList = (EList)originalObject.eGet(feature); 553 for (Iterator iter = getListChanges().iterator(); iter.hasNext(); ) 554 { 555 ListChange listChange = (ListChange)iter.next(); 556 listChange.applyAndReverse(applyToList); 557 } 558 } 559 ECollections.reverse(getListChanges()); 560 } 561 } 562 else 563 { 564 originalObject.eSet(feature, getValue()); 565 } 566 567 setSet(newIsSet); 568 setValue(newValue); 569 570 if (!isSet()) 571 { 572 getListChanges().clear(); 573 } 574 } 575 } 576 577 protected boolean newIsSet; 578 protected Object newValue; 579 580 public void preApply(EObject originalObject, boolean reverse) 581 { 582 if (reverse) 583 { 584 EStructuralFeature feature = getFeature(); 585 if (feature != null) 586 { 587 newIsSet = originalObject.eIsSet(feature); 588 newValue = feature.isMany() ? null : originalObject.eGet(feature); 589 } 590 } 591 } 592 593 protected void apply(EList toList) 594 { 595 for (Iterator iter = getListChanges().iterator(); iter.hasNext(); ) 596 { 597 ListChange listChange = (ListChange)iter.next(); 598 listChange.apply(toList); 599 } 600 } 601 602 607 public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, Class baseClass, NotificationChain msgs) 608 { 609 if (featureID >= 0) 610 { 611 switch (eDerivedStructuralFeatureID(featureID, baseClass)) 612 { 613 case ChangePackage.FEATURE_CHANGE__LIST_CHANGES: 614 return ((InternalEList)getListChanges()).basicRemove(otherEnd, msgs); 615 default: 616 return eDynamicInverseRemove(otherEnd, featureID, baseClass, msgs); 617 } 618 } 619 return eBasicSetContainer(null, featureID, msgs); 620 } 621 622 627 public Object eGet(EStructuralFeature eFeature, boolean resolve) 628 { 629 switch (eDerivedStructuralFeatureID(eFeature)) 630 { 631 case ChangePackage.FEATURE_CHANGE__FEATURE_NAME: 632 return getFeatureName(); 633 case ChangePackage.FEATURE_CHANGE__DATA_VALUE: 634 return getDataValue(); 635 case ChangePackage.FEATURE_CHANGE__SET: 636 return isSet() ? Boolean.TRUE : Boolean.FALSE; 637 case ChangePackage.FEATURE_CHANGE__VALUE: 638 return getValue(); 639 case ChangePackage.FEATURE_CHANGE__FEATURE: 640 if (resolve) return getFeature(); 641 return basicGetFeature(); 642 case ChangePackage.FEATURE_CHANGE__REFERENCE_VALUE: 643 if (resolve) return getReferenceValue(); 644 return basicGetReferenceValue(); 645 case ChangePackage.FEATURE_CHANGE__LIST_CHANGES: 646 return getListChanges(); 647 } 648 return eDynamicGet(eFeature, resolve); 649 } 650 651 656 public void eSet(EStructuralFeature eFeature, Object newValue) 657 { 658 switch (eDerivedStructuralFeatureID(eFeature)) 659 { 660 case ChangePackage.FEATURE_CHANGE__FEATURE_NAME: 661 setFeatureName((String )newValue); 662 return; 663 case ChangePackage.FEATURE_CHANGE__DATA_VALUE: 664 setDataValue((String )newValue); 665 return; 666 case ChangePackage.FEATURE_CHANGE__SET: 667 setSet(((Boolean )newValue).booleanValue()); 668 return; 669 case ChangePackage.FEATURE_CHANGE__FEATURE: 670 setFeature((EStructuralFeature)newValue); 671 return; 672 case ChangePackage.FEATURE_CHANGE__REFERENCE_VALUE: 673 setReferenceValue((EObject)newValue); 674 return; 675 case ChangePackage.FEATURE_CHANGE__LIST_CHANGES: 676 getListChanges().clear(); 677 getListChanges().addAll((Collection )newValue); 678 return; 679 } 680 eDynamicSet(eFeature, newValue); 681 } 682 683 688 public void eUnset(EStructuralFeature eFeature) 689 { 690 switch (eDerivedStructuralFeatureID(eFeature)) 691 { 692 case ChangePackage.FEATURE_CHANGE__FEATURE_NAME: 693 unsetFeatureName(); 694 return; 695 case ChangePackage.FEATURE_CHANGE__DATA_VALUE: 696 setDataValue(DATA_VALUE_EDEFAULT); 697 return; 698 case ChangePackage.FEATURE_CHANGE__SET: 699 setSet(SET_EDEFAULT); 700 return; 701 case ChangePackage.FEATURE_CHANGE__FEATURE: 702 unsetFeature(); 703 return; 704 case ChangePackage.FEATURE_CHANGE__REFERENCE_VALUE: 705 setReferenceValue((EObject)null); 706 return; 707 case ChangePackage.FEATURE_CHANGE__LIST_CHANGES: 708 getListChanges().clear(); 709 return; 710 } 711 eDynamicUnset(eFeature); 712 } 713 714 719 public boolean eIsSet(EStructuralFeature eFeature) 720 { 721 switch (eDerivedStructuralFeatureID(eFeature)) 722 { 723 case ChangePackage.FEATURE_CHANGE__FEATURE_NAME: 724 return isSetFeatureName(); 725 case ChangePackage.FEATURE_CHANGE__DATA_VALUE: 726 return DATA_VALUE_EDEFAULT == null ? getDataValue() != null : !DATA_VALUE_EDEFAULT.equals(getDataValue()); 727 case ChangePackage.FEATURE_CHANGE__SET: 728 return set != SET_EDEFAULT; 729 case ChangePackage.FEATURE_CHANGE__VALUE: 730 return VALUE_EDEFAULT == null ? getValue() != null : !VALUE_EDEFAULT.equals(getValue()); 731 case ChangePackage.FEATURE_CHANGE__FEATURE: 732 return isSetFeature(); 733 case ChangePackage.FEATURE_CHANGE__REFERENCE_VALUE: 734 return basicGetReferenceValue() != null; 735 case ChangePackage.FEATURE_CHANGE__LIST_CHANGES: 736 return listChanges != null && !listChanges.isEmpty(); 737 } 738 return eDynamicIsSet(eFeature); 739 } 740 741 746 public String toString() 747 { 748 if (eIsProxy()) return super.toString(); 749 750 StringBuffer result = new StringBuffer (super.toString()); 751 result.append(" (set: "); 752 result.append(set); 753 result.append(')'); 754 return result.toString(); 755 } 756 757 protected ListChange createListChange(EList changesList, ChangeKind kind, int index) 758 { 759 ListChange listChange = ChangeFactory.eINSTANCE.createListChange(); 760 listChange.setKind(kind); 761 listChange.setIndex(index); 762 changesList.add(listChange); 763 return listChange; 764 } 765 } | Popular Tags |