1 17 package org.eclipse.emf.edit.command; 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.command.Command; 27 import org.eclipse.emf.common.command.CommandWrapper; 28 import org.eclipse.emf.common.command.CompoundCommand; 29 import org.eclipse.emf.common.command.IdentityCommand; 30 import org.eclipse.emf.common.util.BasicEList; 31 import org.eclipse.emf.common.util.EList; 32 import org.eclipse.emf.ecore.EAttribute; 33 import org.eclipse.emf.ecore.EClass; 34 import org.eclipse.emf.ecore.EClassifier; 35 import org.eclipse.emf.ecore.EObject; 36 import org.eclipse.emf.ecore.EReference; 37 import org.eclipse.emf.ecore.EStructuralFeature; 38 import org.eclipse.emf.ecore.EcorePackage; 39 import org.eclipse.emf.edit.EMFEditPlugin; 40 import org.eclipse.emf.edit.domain.EditingDomain; 41 42 43 72 public class SetCommand extends AbstractOverrideableCommand 73 { 74 77 public static Command create(EditingDomain domain, final Object owner, Object feature, Object value) 78 { 79 return create(domain, owner, feature, value, CommandParameter.NO_INDEX); 80 } 81 82 85 public static Command create(EditingDomain domain, final Object owner, Object feature, Object value, int index) 86 { 87 if (owner instanceof EObject && ((EObject)owner).eClass().getEAllReferences().contains(feature)) 92 { 93 EReference eReference = (EReference)feature; 94 if (eReference.isMany() && index == CommandParameter.NO_INDEX) 95 { 96 List values = (List )value; 101 List oldValues = (List )((EObject)owner).eGet(eReference); 102 103 if (values.isEmpty() && oldValues.isEmpty()) 104 { 105 return 106 new IdentityCommand(LABEL, DESCRIPTION, owner) 107 { 108 public Collection getAffectedObjects() 109 { 110 return Collections.singleton(owner); 111 } 112 }; 113 } 114 else 115 { 116 CompoundCommand compound = 117 new CompoundCommand(CompoundCommand.LAST_COMMAND_ALL, LABEL, DESCRIPTION) 118 { 119 public Collection getAffectedObjects() 120 { 121 return Collections.singleton(owner); 122 } 123 }; 124 125 if (!oldValues.isEmpty()) 126 { 127 if (!values.isEmpty()) 128 { 129 List removedValues = new BasicEList.FastCompare(oldValues); 130 removedValues.removeAll(values); 131 132 if (!removedValues.equals(oldValues)) 135 { 136 if (!removedValues.isEmpty()) 139 { 140 compound.append(RemoveCommand.create(domain, owner, feature, new BasicEList(removedValues))); 141 } 142 143 List remainingValues = new BasicEList.FastCompare(oldValues); 146 remainingValues.removeAll(removedValues); 147 int count = -1; 148 for (Iterator i = values.iterator(); i.hasNext(); ) 149 { 150 Object object = i.next(); 151 int position = remainingValues.indexOf(object); 152 if (position != -1 && position != ++count) 153 { 154 compound.append(MoveCommand.create(domain, owner, feature, object, count)); 155 } 156 } 157 158 List addedValues = new BasicEList.FastCompare(values); 161 addedValues.removeAll(remainingValues); 162 for (ListIterator i = values.listIterator(); i.hasNext(); ) 163 { 164 Object object = i.next(); 165 if (addedValues.contains(object)) 166 { 167 compound.append(AddCommand.create(domain, owner, feature, object, i.previousIndex())); 168 } 169 } 170 return compound; 171 } 172 } 173 174 compound.append(RemoveCommand.create(domain, owner, feature, new BasicEList(oldValues))); 175 } 176 if (!values.isEmpty()) 177 { 178 compound.append(AddCommand.create(domain, owner, feature, values)); 179 } 180 return compound; 181 } 182 } 183 else if (eReference.getEOpposite() != null) 184 { 185 EReference eOtherEnd = eReference.getEOpposite(); 186 if (eOtherEnd.isMany()) 187 { 188 if (eReference.isMany()) 189 { 190 EList list = (EList)((EObject)owner).eGet(eReference); 196 if (index == list.size() - 1) 197 { 198 EObject oldValue = (EObject)list.get(index); 199 EList oppositeList = (EList)oldValue.eGet(eOtherEnd); 200 if (oppositeList.get(oppositeList.size() - 1) != owner) 201 { 202 CompoundCommand compound = 203 new CompoundCommand(CompoundCommand.LAST_COMMAND_ALL, LABEL, DESCRIPTION) 204 { 205 public Collection getAffectedObjects() 206 { 207 return Collections.singleton(owner); 208 } 209 }; 210 compound.append(RemoveCommand.create(domain, oldValue, eOtherEnd, owner)); 211 compound.append(AddCommand.create(domain, owner, feature, value)); 212 return compound; 213 } 214 } 215 } 216 else 217 { 218 Object oldValue = ((EObject)owner).eGet(eReference); 223 if (value == null) 224 { 225 if (oldValue == null) 226 { return domain.createCommand(SetCommand.class, new CommandParameter(owner, eReference, value)); 230 } 231 else 232 { return RemoveCommand.create(domain, oldValue, eOtherEnd, Collections.singleton(owner)); 236 } 237 } 238 else 239 { Command addCommand = 241 new CommandWrapper(AddCommand.create(domain, value, eOtherEnd, Collections.singleton(owner))) 242 { 243 public Collection getAffectedObjects() 244 { 245 return Collections.singleton(owner); 246 } 247 }; 248 249 if (oldValue == null) 250 { return addCommand; 254 } 255 else 256 { CompoundCommand compound = new CompoundCommand(CompoundCommand.LAST_COMMAND_ALL, LABEL, DESCRIPTION); 260 compound.append(RemoveCommand.create(domain, oldValue, eOtherEnd, Collections.singleton(owner))); 261 compound.append(addCommand); 262 return compound; 263 } 264 } 265 } 266 } 267 else if (eOtherEnd.isContainment()) 268 { 269 if (value != null) 270 { 271 return 274 new CommandWrapper(SetCommand.create(domain, value, eOtherEnd, owner)) 275 { 276 public Collection getResult() 277 { 278 return Collections.singleton(owner); 279 } 280 public Collection getAffectedObjects() 281 { 282 return Collections.singleton(owner); 283 } 284 }; 285 } 286 } 287 else 288 { 289 if (value instanceof EObject && ((EObject)value).eGet(eOtherEnd) != null) 294 { 295 CompoundCommand compound = 296 new CompoundCommand(CompoundCommand.LAST_COMMAND_ALL) 297 { 298 public boolean canUndo() 299 { 300 return true; 301 } 302 }; 303 if (eReference.isMany()) 304 { 305 compound.append(SetCommand.create(domain, value, eOtherEnd, null)); 309 } 310 else 311 { 312 compound.append(domain.createCommand(SetCommand.class, new CommandParameter(value, eOtherEnd, null))); 315 } 316 compound.append(domain.createCommand(SetCommand.class, new CommandParameter(owner, eReference, value, index))); 317 return compound; 318 } 319 } 320 } 321 } 322 return domain.createCommand(SetCommand.class, new CommandParameter(owner, feature, value, index)); 323 } 324 325 328 protected static final String LABEL = EMFEditPlugin.INSTANCE.getString("_UI_SetCommand_label"); 329 330 333 protected static final String DESCRIPTION = EMFEditPlugin.INSTANCE.getString("_UI_SetCommand_description"); 334 335 338 protected EObject owner; 339 340 343 protected EStructuralFeature feature; 344 345 349 protected EList ownerList; 350 351 354 protected Object value; 355 356 359 protected Object oldValue; 360 361 364 protected int index; 365 366 369 protected boolean canUndo = true; 370 371 374 public SetCommand(EditingDomain domain, EObject owner, EStructuralFeature feature, Object value) 375 { 376 super(domain, LABEL, DESCRIPTION); 377 378 this.owner = owner; 381 this.feature = feature; 382 this.value = value; 383 this.index = CommandParameter.NO_INDEX; 384 } 385 386 389 public SetCommand(EditingDomain domain, EObject owner, EStructuralFeature feature, Object value, int index) 390 { 391 super(domain, LABEL, DESCRIPTION); 392 393 this.owner = owner; 396 this.feature = feature; 397 this.value = value; 398 this.index = index; 399 400 if (index != CommandParameter.NO_INDEX) 401 { 402 ownerList = getOwnerList(owner, feature); 403 } 404 } 405 406 409 public EObject getOwner() 410 { 411 return owner; 412 } 413 414 417 public EStructuralFeature getFeature() 418 { 419 return feature; 420 } 421 422 425 public EList getOwnerList() 426 { 427 return ownerList; 428 } 429 430 433 public int getIndex() 434 { 435 return index; 436 } 437 438 441 public Object getValue() 442 { 443 return value; 444 } 445 446 449 public Object getOldValue() 450 { 451 return oldValue; 452 } 453 454 protected static final EcorePackage ecorePackage = EcorePackage.eINSTANCE; 455 456 protected boolean prepare() 457 { 458 boolean result = false; 459 460 if (owner != null) 463 { 464 if (domain.isReadOnly(owner.eResource())) 465 { 466 return false; 467 } 468 469 EClass eMetaObject = owner.eClass(); 472 473 if (eMetaObject.getEAllAttributes().contains(feature)) 476 { 477 EAttribute eAttribute = (EAttribute)feature; 480 EClassifier eType = eAttribute.getEType(); 481 482 if (ownerList != null) 483 { 484 if (index >= 0 && index < ownerList.size() && eType.isInstance(value) && 488 (!eAttribute.isUnique() || !ownerList.contains(value))) 489 { 490 oldValue = ownerList.get(index); 491 result = true; 492 } 493 } 494 else if (eAttribute.isMany()) 495 { 496 if (owner.eIsSet(eAttribute)) 499 { 500 oldValue = new BasicEList((EList)owner.eGet(feature)); 501 } 502 503 if (value == null) 504 { 505 result = true; 506 } 507 else if (value instanceof Collection ) 508 { 509 Collection collection = (Collection )value; 510 result = true; 511 for (Iterator objects = collection.iterator(); objects.hasNext(); ) 512 { 513 if (!eType.isInstance(objects.next())) 514 { 515 result = false; 516 break; 517 } 518 } 519 } 520 } 521 else 522 { 523 if (owner.eIsSet(eAttribute)) 526 { 527 oldValue = owner.eGet(feature); 528 } 529 530 result = value == null || eType.isInstance(value); 531 } 532 } 533 else if (eMetaObject.getEAllReferences().contains(feature)) 536 { 537 EReference eReference = (EReference)feature; 540 541 if (ownerList != null) 545 { 546 if (index >= 0 && index < ownerList.size() && eReference.getEType().isInstance(value) && 547 (!eReference.isUnique() || !ownerList.contains(value))) 548 { 549 oldValue = ownerList.get(index); 550 result = true; 551 } 552 } 553 else if (!eReference.isMany()) 554 { 555 oldValue = owner.eGet(feature); 556 557 if (value == null || eReference.getEType().isInstance(value)) 558 { 559 result = true; 560 } 561 } 562 563 if (result && eReference.isContainment()) 566 { 567 for (EObject container = owner; container != null; container = container.eContainer()) 568 { 569 if (value == container) 570 { 571 result = false; 572 break; 573 } 574 } 575 } 576 577 if (result && eReference.getEOpposite() != null) 580 { 581 EReference eOtherEnd = eReference.getEOpposite(); 582 if (eOtherEnd.isMany()) 583 { 584 if (oldValue != null) 589 { 590 EList oppositeList = (EList)((EObject)oldValue).eGet(eOtherEnd); 591 canUndo = oppositeList.get(oppositeList.size() - 1) == owner; 592 } 593 } 594 else 595 { 596 canUndo = (value == null || ((EObject)value).eGet(eOtherEnd) == null); 600 } 601 602 } 603 } 604 } 605 606 return result; 607 } 608 609 public void doExecute() 610 { 611 if (ownerList != null) 614 { 615 ownerList.set(index, value); 616 } 617 else if (value == null) 618 { 619 owner.eUnset(feature); 620 } 621 else 622 { 623 owner.eSet(feature, value); 624 } 625 } 626 627 public boolean doCanUndo() 628 { 629 return canUndo; 630 } 631 632 public void doUndo() 633 { 634 if (ownerList != null) 637 { 638 ownerList.set(index, oldValue); 639 } 640 else if (oldValue == null) 641 { 642 owner.eUnset(feature); 643 } 644 else 645 { 646 owner.eSet(feature, oldValue); 647 } 648 } 649 650 public void doRedo() 651 { 652 if (ownerList != null) 655 { 656 ownerList.set(index, value); 657 } 658 else if (value == null) 659 { 660 owner.eUnset(feature); 661 } 662 else 663 { 664 owner.eSet(feature, value); 665 } 666 } 667 668 public Collection doGetResult() 669 { 670 return Collections.singleton(owner); 671 } 672 673 public Collection doGetAffectedObjects() 674 { 675 return Collections.singleton(owner); 676 } 677 678 682 public String toString() 683 { 684 StringBuffer result = new StringBuffer (super.toString()); 685 result.append(" (owner: " + owner + ")"); 686 result.append(" (feature: " + feature + ")"); 687 if (ownerList != null) 688 { 689 result.append(" (ownerList: " + ownerList + ")"); 690 result.append(" (index: " + index + ")"); 691 } 692 result.append(" (value: " + value + ")"); 693 result.append(" (oldValue: " + oldValue + ")"); 694 695 return result.toString(); 696 } 697 } 698 | Popular Tags |