/emf-2.8.0/org.eclipse.emf.edit/src/org/eclipse/emf/edit/command/ReplaceCommand.java
Java | 353 lines | 154 code | 48 blank | 151 comment | 15 complexity | 283947e4b13e7f25d444c477f7b15f3f MD5 | raw file
- /**
- * Copyright (c) 2002-2006 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM - Initial API and implementation
- */
- package org.eclipse.emf.edit.command;
- import java.util.Collection;
- import java.util.Collections;
- import org.eclipse.emf.common.command.Command;
- import org.eclipse.emf.common.util.EList;
- import org.eclipse.emf.ecore.EObject;
- import org.eclipse.emf.ecore.EStructuralFeature;
- import org.eclipse.emf.edit.EMFEditPlugin;
- import org.eclipse.emf.edit.domain.EditingDomain;
- /**
- * The replace command logically acts upon an owner object that has a collection-type feature
- * in which an object can be replaced by a collection of other objects.
- * The static create methods delegate command creation to {@link EditingDomain#createCommand EditingDomain.createCommand},
- * which may or may not result in the actual creation of an instance of this class.
- *
- * <p>
- * The implementation of this class is low-level and EMF specific;
- * it allows an object from a many-valued feature of an owner to be replaced by a collection of other objects.
- * i.e., it is equivalent of the call
- * <pre>
- * int index = ((EList)((EObject)owner).eGet((EStructuralFeature)feature)).indexOf(value);
- * ((EList)((EObject)owner).eGet((EStructuralFeature)feature)).remove(value);
- * ((EList)((EObject)owner).eGet((EStructuralFeature)feature)).addAll(index, (Collection)collection);
- * </pre>
- *
- * <p>
- * It can also be used as an equivalent to the call
- * <pre>
- * int index = ((EList)extent).indexOf(value);
- * ((EList)extent).remove(value);
- * ((EList)extent).addAll(index, (Collection)collection);
- * </pre>
- * which is how root objects are replaced in the contents of a resource.
- * Like all the low level commands in this package, the replace command is undoable.
- *
- * <p>
- * A replace command is an {@link OverrideableCommand}.
- */
- public class ReplaceCommand extends AbstractOverrideableCommand
- {
- /**
- * This creates a command to replace an object with a collection of replacements.
- */
- public static Command create(EditingDomain domain, Object value, Collection<?> collection)
- {
- return create(domain, null, null, value, collection);
- }
- /**
- * This creates a command to replace a particular value in the specified feature of the owner with a collection replacements objects.
- */
- public static Command create(EditingDomain domain, Object owner, Object feature, Object value, Collection<?> collection)
- {
- return domain.createCommand(ReplaceCommand.class, new CommandParameter(owner, feature, value, collection));
- }
- /**
- * This caches the label.
- */
- protected static final String LABEL = EMFEditPlugin.INSTANCE.getString("_UI_ReplaceCommand_label");
- /**
- * This caches the description.
- */
- protected static final String DESCRIPTION = EMFEditPlugin.INSTANCE.getString("_UI_ReplaceCommand_description");
- /**
- * This is the owner object upon which the command will act.
- * It could be null, in the case that we are dealing with an {@link org.eclipse.emf.common.util.EList}.
- */
- protected EObject owner;
- /**
- * This is the feature of the owner object upon the command will act.
- * It could be null, in the case that we are dealing with an {@link org.eclipse.emf.common.util.EList}.
- */
- protected EStructuralFeature feature;
- /**
- * This is the list from which the command will replace.
- */
- protected EList<Object> ownerList;
- /**
- * This is value that is being replaced.
- */
- protected Object value;
- /**
- * This is the collection of replacements.
- */
- protected Collection<?> collection;
- /**
- * This is the index at which to reinsert the replaced object during an undo so as to achieve the original list order.
- */
- protected int index;
- /**
- * The is the value returned by {@link Command#getAffectedObjects}.
- * The affected objects are different after an execute than after an undo, so we record it.
- */
- protected Collection<?> affectedObjects;
- /**
- * This constructs a primitive command to replace a particular value in the specified feature of the owner
- * with the specified replacement.
- */
- public ReplaceCommand(EditingDomain domain, EObject owner, EStructuralFeature feature, Object value, Object replacement)
- {
- this(domain, owner, feature, value, Collections.singleton(replacement));
- }
- /**
- * This constructs a primitive command to replace a particular value in the specified feature of the owner
- * with the specified collection of replacements.
- */
- public ReplaceCommand(EditingDomain domain, EObject owner, EStructuralFeature feature, Object value, Collection<?> collection)
- {
- super(domain, LABEL, DESCRIPTION);
- // Initialize all the fields from the command parameter.
- //
- this.owner = owner;
- this.feature = feature;
- this.value = value;
- this.collection = collection;
- ownerList = getOwnerList(this.owner, feature);
- }
- /**
- * This constructs a primitive command to replace a particular value in the specified extent with the given replacement.
- */
- public ReplaceCommand(EditingDomain domain, EList<?> list, Object value, Object replacement)
- {
- this(domain, list, value, Collections.singleton(replacement));
- }
- /**
- * This constructs a primitive command to replace a particular value in the specified extent with the given collection of replacements.
- */
- public ReplaceCommand(EditingDomain domain, EList<?> list, Object value, Collection<?> collection)
- {
- super(domain, LABEL, DESCRIPTION);
- // Initialize all the fields from the command parameter.
- //
- this.value = value;
- this.collection = collection;
- @SuppressWarnings("unchecked")
- EList<Object> untypedList = (EList<Object>)list;
- ownerList = untypedList;
- }
- /**
- * This returns the owner object upon which the command will act.
- * It could be null, in the case that we are dealing with an {@link org.eclipse.emf.common.util.EList}.
- */
- public EObject getOwner()
- {
- return owner;
- }
- /**
- * This returns the feature of the owner object upon the command will act.
- * It could be null, in the case that we are dealing with an {@link org.eclipse.emf.common.util.EList}.
- */
- public EStructuralFeature getFeature()
- {
- return feature;
- }
- /**
- * This returns the list in which the command will replace.
- */
- public EList<Object> getOwnerList()
- {
- return ownerList;
- }
- /**
- * This returns the value being replaced.
- */
- public Object getValue()
- {
- return value;
- }
- /**
- * This returns the collection of replacement objects.
- */
- public Collection<?> getCollection()
- {
- return collection;
- }
- /**
- * This returns the index at which to reinsert the replace objects during an undo so as to achieve the original list order.
- */
- public int getIndex()
- {
- return index;
- }
- @Override
- protected boolean prepare()
- {
- // This can't execute if there is no owner list
- // or the owner list doesn't contain the value being replaced or
- // there are not replacements.
- //
- if (ownerList == null || !ownerList.contains(value) || collection == null || collection.isEmpty())
- {
- return false;
- }
- else if (owner != null && domain.isReadOnly(owner.eResource()))
- {
- return false;
- }
- else if (feature == null)
- {
- // An extent allows anything to be added.
- //
- return true;
- }
- else
- {
- // Make sure each object conforms to the type of the feature.
- //
- for (Object replacement : collection)
- {
- if (!feature.getEType().isInstance(replacement))
- {
- return false;
- }
- }
- return true;
- }
- }
- @Override
- public void doExecute()
- {
- // Record the position of the value in the owner list.
- //
- index = ownerList.indexOf(value);
-
- // Simply remove the object from the owner list.
- //
- ownerList.remove(value);
- // Insert the collection at the right place.
- //
- ownerList.addAll(index, collection);
-
- // Update the containing map, if necessary.
- //
- updateEMap(owner, feature);
- // We'd like the collection of replacements selected after this replace completes.
- //
- affectedObjects = collection;
- }
- @Override
- public void doUndo()
- {
- // Remove the collection of replacements.
- //
- ownerList.removeAll(collection);
- // Add the value back in the right place.
- //
- ownerList.add(index, value);
- // Update the containing map, if necessary.
- //
- updateEMap(owner, feature);
- // We'd like the replaced selected after this undo replace completes.
- //
- affectedObjects = Collections.singleton(value);
- }
-
- @Override
- public void doRedo()
- {
- // Simply remove the object from the owner list.
- //
- ownerList.remove(value);
- // Insert the collection at the right place.
- //
- ownerList.addAll(index, collection);
-
- // Update the containing map, if necessary.
- //
- updateEMap(owner, feature);
- // We'd like the collection of replacements selected after this replace completes.
- //
- affectedObjects = collection;
- }
- @Override
- public Collection<?> doGetResult()
- {
- return collection;
- }
- @Override
- public Collection<?> doGetAffectedObjects()
- {
- return affectedObjects;
- }
- /**
- * This gives an abbreviated name using this object's own class' name, without package qualification,
- * followed by a space separated list of <tt>field:value</tt> pairs.
- */
- @Override
- public String toString()
- {
- StringBuffer result = new StringBuffer(super.toString());
- result.append(" (owner: " + owner + ")");
- result.append(" (feature: " + feature + ")");
- result.append(" (ownerList: " + ownerList + ")");
- result.append(" (value: " + value + ")");
- result.append(" (collection: " + collection + ")");
- result.append(" (index: " + index + ")");
- result.append(" (affectedObjects:" + affectedObjects + ")");
- return result.toString();
- }
- }