1 17 package org.eclipse.emf.ecore.change.impl; 18 19 20 import java.util.ArrayList ; 21 import java.util.Collection ; 22 import java.util.HashMap ; 23 import java.util.Iterator ; 24 import java.util.List ; 25 import java.util.Map ; 26 27 import org.eclipse.emf.common.notify.NotificationChain; 28 import org.eclipse.emf.common.util.BasicEList; 29 import org.eclipse.emf.common.util.EList; 30 import org.eclipse.emf.common.util.EMap; 31 import org.eclipse.emf.common.util.UniqueEList; 32 import org.eclipse.emf.ecore.EClass; 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.change.ChangeDescription; 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.change.ResourceChange; 42 import org.eclipse.emf.ecore.impl.EObjectImpl; 43 import org.eclipse.emf.ecore.resource.Resource; 44 import org.eclipse.emf.ecore.util.EObjectContainmentEList; 45 import org.eclipse.emf.ecore.util.EObjectEList; 46 import org.eclipse.emf.ecore.util.EcoreEMap; 47 import org.eclipse.emf.ecore.util.FeatureMap; 48 import org.eclipse.emf.ecore.util.FeatureMapUtil; 49 import org.eclipse.emf.ecore.util.InternalEList; 50 51 52 68 public class ChangeDescriptionImpl extends EObjectImpl implements ChangeDescription 69 { 70 78 protected EMap objectChanges = null; 79 80 90 protected EList objectsToDetach = null; 91 92 100 protected EList objectsToAttach = null; 101 102 110 protected EList resourceChanges = null; 111 112 117 protected ChangeDescriptionImpl() 118 { 119 super(); 120 } 121 122 127 protected EClass eStaticClass() 128 { 129 return ChangePackage.eINSTANCE.getChangeDescription(); 130 } 131 132 137 public EMap getObjectChanges() 138 { 139 if (objectChanges == null) 140 { 141 objectChanges = new EcoreEMap(ChangePackage.eINSTANCE.getEObjectToChangesMapEntry(), EObjectToChangesMapEntryImpl.class, this, ChangePackage.CHANGE_DESCRIPTION__OBJECT_CHANGES); 142 } 143 return objectChanges; 144 } 145 146 151 public EList getObjectsToDetachGen() 152 { 153 if (objectsToDetach == null) 154 { 155 objectsToDetach = new EObjectEList(EObject.class, this, ChangePackage.CHANGE_DESCRIPTION__OBJECTS_TO_DETACH); 156 } 157 return objectsToDetach; 158 } 159 160 protected static List getContainedEObjects(List featureMapEntries) 161 { 162 List result = new ArrayList (); 163 for (Iterator i = featureMapEntries.iterator(); i.hasNext(); ) 164 { 165 FeatureMap.Entry entry = (FeatureMap.Entry)i.next(); 166 EStructuralFeature feature = entry.getEStructuralFeature(); 167 if (feature instanceof EReference && ((EReference)feature).isContainment()) 168 { 169 result.add(entry.getValue()); 170 } 171 } 172 return result; 173 } 174 175 public EList getObjectsToDetach() 176 { 177 List objectsBeforeChange = new UniqueEList.FastCompare(); 178 List objectsAfterChange = new UniqueEList.FastCompare(); 179 180 if (!getObjectChanges().isEmpty()) 181 { 182 preApply(false); 183 184 for (Iterator i = getObjectChanges().iterator(); i.hasNext();) 185 { 186 EObjectToChangesMapEntryImpl entry = (EObjectToChangesMapEntryImpl)i.next(); 187 EObject objectToChange = entry.getTypedKey(); 188 for (Iterator j = entry.getTypedValue().iterator(); j.hasNext();) 189 { 190 FeatureChange featureChange = (FeatureChange)j.next(); 191 EStructuralFeature feature = featureChange.getFeature(); 192 if (FeatureMapUtil.isFeatureMap(feature)) 193 { 194 objectsBeforeChange.addAll(getContainedEObjects((List )featureChange.getValue())); 195 objectsAfterChange.addAll(getContainedEObjects((List )objectToChange.eGet(feature))); 196 } 197 else if (feature instanceof EReference && ((EReference)feature).isContainment()) 198 { 199 if (feature.isMany()) 200 { 201 objectsBeforeChange.addAll((List )featureChange.getValue()); 202 objectsAfterChange.addAll((List )objectToChange.eGet(feature)); 203 } 204 else 205 { 206 Object value = featureChange.getValue(); 207 if (value != null) objectsBeforeChange.add(value); 208 value = objectToChange.eGet(feature); 209 if (value != null) objectsAfterChange.add(value); 210 } 211 } 212 } 213 } 214 } 215 216 if (!getResourceChanges().isEmpty()) 217 { 218 for (Iterator i = getResourceChanges().iterator(); i.hasNext();) 219 { 220 ResourceChange resourceChange = (ResourceChange)i.next(); 221 Resource resource = resourceChange.getResource(); 222 if (resource == null) 223 { 224 resource = eResource(); 225 } 226 227 if (resource != null) 228 { 229 EList currentContentCopy = new BasicEList(resource.getContents()); 230 for (Iterator j = resourceChange.getListChanges().iterator(); j.hasNext();) 231 { 232 ListChange listChange = (ListChange)j.next(); 233 ((ListChangeImpl)listChange).apply(currentContentCopy); 234 } 235 236 objectsBeforeChange.addAll(currentContentCopy); 237 objectsAfterChange.addAll(resource.getContents()); 238 } 239 } 240 } 241 242 objectsAfterChange.removeAll(objectsBeforeChange); 244 245 getObjectsToDetachGen().retainAll(objectsAfterChange); 247 getObjectsToDetachGen().addAll(objectsAfterChange); 248 249 return getObjectsToDetachGen(); 250 } 251 252 257 public EList getObjectsToAttach() 258 { 259 if (objectsToAttach == null) 260 { 261 objectsToAttach = new EObjectContainmentEList(EObject.class, this, ChangePackage.CHANGE_DESCRIPTION__OBJECTS_TO_ATTACH); 262 } 263 return objectsToAttach; 264 } 265 266 271 public EList getResourceChanges() 272 { 273 if (resourceChanges == null) 274 { 275 resourceChanges = new EObjectContainmentEList(ResourceChange.class, this, ChangePackage.CHANGE_DESCRIPTION__RESOURCE_CHANGES); 276 } 277 return resourceChanges; 278 } 279 280 285 public void apply() 286 { 287 preApply(false); 288 289 for (Iterator iter = getObjectChanges().iterator(); iter.hasNext(); ) 292 { 293 EObjectToChangesMapEntryImpl entry = (EObjectToChangesMapEntryImpl)iter.next(); 294 EObject objectToChange = entry.getTypedKey(); 295 for (Iterator fIter = entry.getTypedValue().iterator(); fIter.hasNext(); ) 296 { 297 FeatureChange featureChange = (FeatureChange)fIter.next(); 298 featureChange.apply(objectToChange); 299 } 300 } 301 302 for (Iterator iter = getResourceChanges().iterator(); iter.hasNext(); ) 303 { 304 ResourceChange resourceChange = (ResourceChange)iter.next(); 305 resourceChange.apply(); 306 } 307 308 getObjectsToAttach().clear(); 311 getObjectChanges().clear(); 312 getResourceChanges().clear(); 313 oldContainmentInformation = null; 314 } 315 316 321 public void applyAndReverse() 322 { 323 preApply(true); 324 325 List objectsBeforeApply = new UniqueEList.FastCompare(); 326 List objectsAfterApply = new UniqueEList.FastCompare(); 327 328 for (Iterator iter = getObjectChanges().iterator(); iter.hasNext(); ) 331 { 332 EObjectToChangesMapEntryImpl entry = (EObjectToChangesMapEntryImpl)iter.next(); 333 EObject objectToChange = entry.getTypedKey(); 334 for (Iterator fIter = entry.getTypedValue().iterator(); fIter.hasNext(); ) 335 { 336 FeatureChange featureChange = (FeatureChange)fIter.next(); 337 EStructuralFeature feature = featureChange.getFeature(); 338 339 int featureKind = 340 FeatureMapUtil.isFeatureMap(feature) ? 341 3 : 342 feature instanceof EReference && ((EReference)feature).isContainment() ? 343 feature.isMany() ? 344 1 : 345 2 : 346 0; 347 switch (featureKind) 348 { 349 case 1: 350 { 351 objectsBeforeApply.addAll((List )objectToChange.eGet(feature)); 352 break; 353 } 354 case 2: 355 { 356 Object value = objectToChange.eGet(feature); 357 if (value != null) 358 { 359 objectsBeforeApply.add(objectToChange.eGet(feature)); 360 } 361 break; 362 } 363 case 3: 364 { 365 objectsBeforeApply.addAll(getContainedEObjects((List )objectToChange.eGet(feature))); 366 break; 367 } 368 } 369 370 featureChange.applyAndReverse(objectToChange); 371 372 switch (featureKind) 373 { 374 case 1: 375 { 376 objectsAfterApply.addAll((List )objectToChange.eGet(feature)); 377 break; 378 } 379 case 2: 380 { 381 Object value = objectToChange.eGet(feature); 382 if (value != null) 383 { 384 objectsAfterApply.add(objectToChange.eGet(feature)); 385 } 386 break; 387 } 388 case 3: 389 { 390 objectsAfterApply.addAll(getContainedEObjects((List )objectToChange.eGet(feature))); 391 break; 392 } 393 } 394 } 395 } 396 397 for (Iterator iter = getResourceChanges().iterator(); iter.hasNext(); ) 398 { 399 ResourceChange resourceChange = (ResourceChange)iter.next(); 400 Resource resource = resourceChange.getResource(); 401 if (resource != null) 402 { 403 objectsBeforeApply.addAll(resource.getContents()); 404 } 405 resourceChange.applyAndReverse(); 406 if (resource != null) 407 { 408 objectsAfterApply.addAll(resource.getContents()); 409 } 410 } 411 412 objectsBeforeApply.removeAll(objectsAfterApply); 415 416 getObjectsToAttach().clear(); 419 for (Iterator iter = objectsBeforeApply.iterator(); iter.hasNext(); ) 420 { 421 EObject eObject = (EObject)iter.next(); 422 if (eObject.eContainer() == null && eObject.eResource() == null) 423 { 424 getObjectsToAttach().add(eObject); 425 } 426 } 427 oldContainmentInformation = null; 428 } 429 430 protected void preApply(boolean reverse) 431 { 432 for (Iterator iter = getObjectChanges().iterator(); iter.hasNext(); ) 436 { 437 EObjectToChangesMapEntryImpl entry = (EObjectToChangesMapEntryImpl)iter.next(); 438 EObject objectToChange = entry.getTypedKey(); 439 for (Iterator fIter = entry.getTypedValue().iterator(); fIter.hasNext(); ) 440 { 441 FeatureChangeImpl featureChange = (FeatureChangeImpl)fIter.next(); 442 featureChange.preApply(objectToChange, reverse); 443 if (reverse || featureChange.isSet()) 444 { 445 EStructuralFeature feature = featureChange.getFeature(); 446 if (FeatureMapUtil.isFeatureMap(feature) || 447 feature != null && 448 feature.isMany() && 449 feature instanceof EReference && 450 (((EReference)feature).getEOpposite() != null || ((EReference)feature).isContainment())) 451 { 452 if (reverse) 453 { 454 EList applyToList = new BasicEList((EList)objectToChange.eGet(feature)); 457 for (Iterator k = featureChange.getListChanges().iterator(); k.hasNext(); ) 458 { 459 ListChange listChange = (ListChange)k.next(); 460 listChange.applyAndReverse(applyToList); 461 } 462 featureChange.setValue(applyToList); } 464 else 465 { 466 featureChange.getValue(); } 468 } 469 } 470 } 471 } 472 } 473 474 protected Map oldContainmentInformation; 475 476 protected static class OldContainmentInformation 477 { 478 public EObject container; 479 public EReference containmentFeature; 480 481 public OldContainmentInformation(EObject container, EReference containmentFeature) 482 { 483 this.container = container; 484 this.containmentFeature = containmentFeature; 485 } 486 } 487 488 protected Map getOldContainmentInformation() 489 { 490 if (oldContainmentInformation == null) 491 { 492 oldContainmentInformation = new HashMap (); 493 for (Iterator i = getObjectChanges().iterator(); i.hasNext(); ) 494 { 495 Map.Entry entry = (Map.Entry )i.next(); 496 List featureChanges = (List )entry.getValue(); 497 for (Iterator j = featureChanges.iterator(); j.hasNext(); ) 498 { 499 FeatureChange featureChange = (FeatureChange)j.next(); 500 EStructuralFeature feature = featureChange.getFeature(); 501 if (feature instanceof EReference && ((EReference)feature).isContainment()) 502 { 503 EObject container = (EObject)entry.getKey(); 504 if (feature.isMany()) 505 { 506 for (Iterator k = ((List )featureChange.getValue()).iterator(); k.hasNext(); ) 507 { 508 EObject eObject = (EObject)k.next(); 509 if (eObject.eContainer() != container || eObject.eContainmentFeature() != feature) 510 { 511 oldContainmentInformation.put(eObject, new OldContainmentInformation(container, (EReference)feature)); 512 } 513 } 514 } 515 else 516 { 517 EObject eObject = (EObject)featureChange.getValue(); 518 if (eObject != null && (eObject.eContainer() != container || eObject.eContainmentFeature() != feature)) 519 { 520 oldContainmentInformation.put(eObject, new OldContainmentInformation(container, (EReference)feature)); 521 } 522 } 523 } 524 } 525 } 526 } 527 528 for (Iterator i= getObjectsToDetach().iterator(); i.hasNext(); ) 529 { 530 EObject eObject = (EObject)i.next(); 531 oldContainmentInformation.put(eObject, new OldContainmentInformation(null, null)); 532 } 533 534 return oldContainmentInformation; 535 } 536 537 public EObject getOldContainer(EObject eObject) 538 { 539 OldContainmentInformation oldContainmentInformation = (OldContainmentInformation)getOldContainmentInformation().get(eObject); 540 if (oldContainmentInformation == null) 541 { 542 return eObject.eContainer(); 543 } 544 else 545 { 546 return oldContainmentInformation.container; 547 } 548 } 549 550 public EReference getOldContainmentFeature(EObject eObject) 551 { 552 OldContainmentInformation oldContainmentInformation = (OldContainmentInformation)getOldContainmentInformation().get(eObject); 553 if (oldContainmentInformation == null) 554 { 555 return eObject.eContainmentFeature(); 556 } 557 else 558 { 559 return oldContainmentInformation.containmentFeature; 560 } 561 } 562 567 public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, Class baseClass, NotificationChain msgs) 568 { 569 if (featureID >= 0) 570 { 571 switch (eDerivedStructuralFeatureID(featureID, baseClass)) 572 { 573 case ChangePackage.CHANGE_DESCRIPTION__OBJECT_CHANGES: 574 return ((InternalEList)getObjectChanges()).basicRemove(otherEnd, msgs); 575 case ChangePackage.CHANGE_DESCRIPTION__OBJECTS_TO_ATTACH: 576 return ((InternalEList)getObjectsToAttach()).basicRemove(otherEnd, msgs); 577 case ChangePackage.CHANGE_DESCRIPTION__RESOURCE_CHANGES: 578 return ((InternalEList)getResourceChanges()).basicRemove(otherEnd, msgs); 579 default: 580 return eDynamicInverseRemove(otherEnd, featureID, baseClass, msgs); 581 } 582 } 583 return eBasicSetContainer(null, featureID, msgs); 584 } 585 586 591 public Object eGet(EStructuralFeature eFeature, boolean resolve) 592 { 593 switch (eDerivedStructuralFeatureID(eFeature)) 594 { 595 case ChangePackage.CHANGE_DESCRIPTION__OBJECT_CHANGES: 596 return getObjectChanges(); 597 case ChangePackage.CHANGE_DESCRIPTION__OBJECTS_TO_DETACH: 598 return getObjectsToDetach(); 599 case ChangePackage.CHANGE_DESCRIPTION__OBJECTS_TO_ATTACH: 600 return getObjectsToAttach(); 601 case ChangePackage.CHANGE_DESCRIPTION__RESOURCE_CHANGES: 602 return getResourceChanges(); 603 } 604 return eDynamicGet(eFeature, resolve); 605 } 606 607 612 public void eSet(EStructuralFeature eFeature, Object newValue) 613 { 614 switch (eDerivedStructuralFeatureID(eFeature)) 615 { 616 case ChangePackage.CHANGE_DESCRIPTION__OBJECT_CHANGES: 617 getObjectChanges().clear(); 618 getObjectChanges().addAll((Collection )newValue); 619 return; 620 case ChangePackage.CHANGE_DESCRIPTION__OBJECTS_TO_DETACH: 621 getObjectsToDetach().clear(); 622 getObjectsToDetach().addAll((Collection )newValue); 623 return; 624 case ChangePackage.CHANGE_DESCRIPTION__OBJECTS_TO_ATTACH: 625 getObjectsToAttach().clear(); 626 getObjectsToAttach().addAll((Collection )newValue); 627 return; 628 case ChangePackage.CHANGE_DESCRIPTION__RESOURCE_CHANGES: 629 getResourceChanges().clear(); 630 getResourceChanges().addAll((Collection )newValue); 631 return; 632 } 633 eDynamicSet(eFeature, newValue); 634 } 635 636 641 public void eUnset(EStructuralFeature eFeature) 642 { 643 switch (eDerivedStructuralFeatureID(eFeature)) 644 { 645 case ChangePackage.CHANGE_DESCRIPTION__OBJECT_CHANGES: 646 getObjectChanges().clear(); 647 return; 648 case ChangePackage.CHANGE_DESCRIPTION__OBJECTS_TO_DETACH: 649 getObjectsToDetach().clear(); 650 return; 651 case ChangePackage.CHANGE_DESCRIPTION__OBJECTS_TO_ATTACH: 652 getObjectsToAttach().clear(); 653 return; 654 case ChangePackage.CHANGE_DESCRIPTION__RESOURCE_CHANGES: 655 getResourceChanges().clear(); 656 return; 657 } 658 eDynamicUnset(eFeature); 659 } 660 661 666 public boolean eIsSet(EStructuralFeature eFeature) 667 { 668 switch (eDerivedStructuralFeatureID(eFeature)) 669 { 670 case ChangePackage.CHANGE_DESCRIPTION__OBJECT_CHANGES: 671 return objectChanges != null && !objectChanges.isEmpty(); 672 case ChangePackage.CHANGE_DESCRIPTION__OBJECTS_TO_DETACH: 673 return objectsToDetach != null && !objectsToDetach.isEmpty(); 674 case ChangePackage.CHANGE_DESCRIPTION__OBJECTS_TO_ATTACH: 675 return objectsToAttach != null && !objectsToAttach.isEmpty(); 676 case ChangePackage.CHANGE_DESCRIPTION__RESOURCE_CHANGES: 677 return resourceChanges != null && !resourceChanges.isEmpty(); 678 } 679 return eDynamicIsSet(eFeature); 680 } 681 682 } | Popular Tags |