1 17 package org.eclipse.emf.edit.command; 18 19 20 import java.util.ArrayList ; 21 import java.util.Collection ; 22 import java.util.Collections ; 23 import java.util.Iterator ; 24 import java.util.List ; 25 import java.util.ListIterator ; 26 27 import org.eclipse.emf.common.command.Command; 28 import org.eclipse.emf.common.util.EList; 29 import org.eclipse.emf.ecore.EObject; 30 import org.eclipse.emf.ecore.EStructuralFeature; 31 import org.eclipse.emf.edit.EMFEditPlugin; 32 import org.eclipse.emf.edit.domain.EditingDomain; 33 34 35 67 public class RemoveCommand extends AbstractOverrideableCommand 68 { 69 72 public static Command create(EditingDomain domain, Object value) 73 { 74 return create(domain, Collections.singleton(value)); 75 } 76 77 80 public static Command create(EditingDomain domain, Object owner, Object feature, Object value) 81 { 82 return create(domain, owner, feature, Collections.singleton(value)); 83 } 84 85 88 public static Command create(final EditingDomain domain, final Collection collection) 89 { 90 return create(domain, null, null, collection); 91 } 92 93 96 public static Command create(final EditingDomain domain, final Object owner, final Object feature, final Collection collection) 97 { 98 return domain.createCommand(RemoveCommand.class, new CommandParameter(owner, feature, collection)); 99 } 100 101 104 protected static final String LABEL = EMFEditPlugin.INSTANCE.getString("_UI_RemoveCommand_label"); 105 106 109 protected static final String DESCRIPTION = EMFEditPlugin.INSTANCE.getString("_UI_RemoveCommand_description"); 110 111 114 protected static final String DESCRIPTION_FOR_LIST = EMFEditPlugin.INSTANCE.getString("_UI_RemoveCommand_description_for_list"); 115 116 120 protected EObject owner; 121 122 126 protected EStructuralFeature feature; 127 128 131 protected EList ownerList; 132 133 136 protected Collection collection; 137 138 141 protected int[] indices; 142 143 147 protected Collection affectedObjects; 148 149 152 public RemoveCommand(EditingDomain domain, EObject owner, EStructuralFeature feature, Object value) 153 { 154 this(domain, owner, feature, Collections.singleton(value)); 155 } 156 157 160 public RemoveCommand(EditingDomain domain, EObject owner, EStructuralFeature feature, Collection collection) 161 { 162 super(domain, LABEL, DESCRIPTION); 163 164 this.owner = owner; 167 this.feature = feature; 168 this.collection = collection == null ? null : new ArrayList (collection); 169 170 ownerList = getOwnerList(this.owner, feature); 171 } 172 173 176 public RemoveCommand(EditingDomain domain, EList list, Object value) 177 { 178 this(domain, list, Collections.singleton(value)); 179 } 180 181 184 public RemoveCommand(EditingDomain domain, EList list, Collection collection) 185 { 186 super(domain, LABEL, DESCRIPTION_FOR_LIST); 187 188 this.collection = collection == null ? null : new ArrayList (collection); 191 192 ownerList = list; 193 } 194 195 199 public EObject getOwner() 200 { 201 return owner; 202 } 203 204 208 public EStructuralFeature getFeature() 209 { 210 return feature; 211 } 212 213 216 public EList getOwnerList() 217 { 218 return ownerList; 219 } 220 221 224 public Collection getCollection() 225 { 226 return collection; 227 } 228 229 232 public int[] getIndices() 233 { 234 return indices; 235 } 236 237 protected boolean prepare() 238 { 239 boolean result = 242 ownerList != null && 243 collection != null && 244 ownerList.containsAll(collection) && 245 (owner == null || !domain.isReadOnly(owner.eResource())); 246 247 return result; 248 } 249 250 public void doExecute() 251 { 252 List identity = new ArrayList (collection.size()); 260 int[] identityIndices = new int[collection.size()]; 261 262 int i = 0; 263 264 for (ListIterator ownedObjects = ownerList.listIterator(); ownedObjects.hasNext(); ) 265 { 266 Object ownedObject = ownedObjects.next(); 267 268 if (containsExact(collection, ownedObject)) 271 { 272 removeExact(collection, ownedObject); 275 identity.add(ownedObject); 276 277 identityIndices[i++] = ownedObjects.previousIndex(); 280 } 281 } 282 283 List equality = new ArrayList (collection.size()); 286 int[] equalityIndices = new int[collection.size()]; 287 i = 0; 288 289 for (ListIterator ownedObjects = ownerList.listIterator(); ownedObjects.hasNext(); ) 290 { 291 Object ownedObject = ownedObjects.next(); 292 int index = ownedObjects.previousIndex(); 293 294 if (collection.contains(ownedObject) && !contains(identityIndices, index)) 297 { 298 collection.remove(ownedObject); 301 equality.add(ownedObject); 302 303 equalityIndices[i++] = index; 306 } 307 } 308 309 merge(identity, identityIndices, equality, equalityIndices); 312 313 for (i = indices.length - 1; i >= 0; i--) 316 { 317 ownerList.remove(indices[i]); 318 } 319 320 affectedObjects = owner == null ? Collections.EMPTY_SET : Collections.singleton(owner); 323 } 324 325 328 protected boolean containsExact(Collection collection, Object target) 329 { 330 for (Iterator i = collection.iterator(); i.hasNext(); ) 331 { 332 if (i.next() == target) return true; 333 } 334 return false; 335 } 336 337 340 protected boolean contains(int[] values, int target) 341 { 342 for (int i = 0, len = values.length; i < len; i++) 343 { 344 if (values[i] == target) return true; 345 } 346 return false; 347 } 348 349 352 protected boolean removeExact(Collection collection, Object target) 353 { 354 for (Iterator i = collection.iterator(); i.hasNext(); ) 355 { 356 if (i.next() == target) 357 { 358 i.remove(); 359 return true; 360 } 361 } 362 return false; 363 } 364 365 370 protected void merge(List objects1, int[] indices1, List objects2, int[] indices2) 371 { 372 if (objects2.isEmpty()) 375 { 376 collection = objects1; 377 indices = indices1; 378 return; 379 } 380 381 if (objects1.isEmpty()) 382 { 383 collection = objects2; 384 indices = indices2; 385 return; 386 } 387 388 int size = objects1.size() + objects2.size(); 391 collection = new ArrayList (size); 392 indices = new int[size]; 393 394 int i1 = 0; 397 int i2 = 0; 398 int i = 0; 399 400 Iterator iter1 = objects1.iterator(); 403 Iterator iter2 = objects2.iterator(); 404 405 Object o1 = iter1.hasNext() ? iter1.next() : null; 406 Object o2 = iter2.hasNext() ? iter2.next() : null; 407 408 while (o1 != null && o2 != null) 411 { 412 if (indices1[i1] < indices2[i2]) 413 { 414 indices[i++] = indices1[i1++]; 415 collection.add(o1); 416 o1 = iter1.hasNext() ? iter1.next() : null; 417 } 418 else 419 { 420 indices[i++] = indices2[i2++]; 421 collection.add(o2); 422 o2 = iter2.hasNext() ? iter2.next() : null; 423 } 424 } 425 426 while (o1 != null) 429 { 430 indices[i++] = indices1[i1++]; 431 collection.add(o1); 432 o1 = iter1.hasNext() ? iter1.next() : null; 433 } 434 435 while (o2 != null) 436 { 437 indices[i++] = indices2[i2++]; 438 collection.add(o2); 439 o2 = iter2.hasNext() ? iter2.next() : null; 440 } 441 } 442 443 public void doUndo() 444 { 445 int i = 0; 454 for (Iterator objects = collection.iterator(); objects.hasNext(); ) 455 { 456 ownerList.add(indices[i++], objects.next()); 457 } 458 459 affectedObjects = collection; 462 } 463 464 public void doRedo() 465 { 466 for (int i = indices.length - 1; i >= 0; i--) 469 { 470 ownerList.remove(indices[i]); 471 } 472 473 affectedObjects = owner == null ? (Collection )Collections.EMPTY_SET : Collections.singleton(owner); 476 } 477 478 public Collection doGetResult() 479 { 480 return collection; 481 } 482 483 public Collection doGetAffectedObjects() 484 { 485 return affectedObjects; 486 } 487 488 492 public String toString() 493 { 494 StringBuffer result = new StringBuffer (super.toString()); 495 result.append(" (owner: " + owner + ")"); 496 result.append(" (feature: " + feature + ")"); 497 result.append(" (ownerList: " + ownerList + ")"); 498 result.append(" (collection: " + collection + ")"); 499 result.append(" (indices: " + indices + ")"); 500 result.append(" (affectedObjects: " + affectedObjects + ")"); 501 502 return result.toString(); 503 } 504 } 505 | Popular Tags |