blob: 4a45ff772b9378991d44d93e9afe88a30a59f759 [file] [log] [blame]
/*
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
*
* $Id: ChangeCommand.java,v 1.5 2004/06/23 17:12:19 khussey Exp $
*/
package org.eclipse.uml2.edit.util;
import java.util.Collections;
import java.util.Iterator;
import java.util.ListIterator;
import org.eclipse.emf.common.command.AbstractCommand;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.change.ChangeDescription;
import org.eclipse.emf.ecore.change.ChangeKind;
import org.eclipse.emf.ecore.change.FeatureChange;
import org.eclipse.emf.ecore.change.ListChange;
import org.eclipse.emf.ecore.change.impl.ListChangeImpl;
import org.eclipse.emf.ecore.change.util.ChangeRecorder;
import org.eclipse.emf.edit.domain.EditingDomain;
/**
*
*/
public class ChangeCommand
extends AbstractCommand {
private static class UniqueListChangeImpl
extends ListChangeImpl {
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.ecore.change.ListChange#apply(org.eclipse.emf.common.util.EList)
*/
public void apply(EList originalList) {
switch (getKind().getValue()) {
case ChangeKind.ADD :
if (-1 == index) {
for (Iterator values = getValues().iterator(); values
.hasNext();) {
Object value = values.next();
if (!originalList.contains(value)) {
originalList.add(value);
}
}
} else {
for (ListIterator values = getValues().listIterator(
getValues().size()); values.hasPrevious();) {
Object value = values.previous();
if (!originalList.contains(value)) {
originalList.add(index, value);
}
}
}
break;
case ChangeKind.REMOVE :
for (Iterator values = getValues().iterator(); values
.hasNext();) {
originalList.remove(values.next());
}
break;
default :
super.apply(originalList);
}
}
}
private static final ChangeRecorder CHANGE_RECORDER = new ChangeRecorder() {
private boolean featureIsUnique = false;
protected ListChange createListChange(EList changesList,
ChangeKind kind, int index) {
if (featureIsUnique) {
ListChange listChange = new UniqueListChangeImpl();
listChange.setKind(kind);
listChange.setIndex(index);
changesList.add(listChange);
return listChange;
} else {
return super.createListChange(changesList, kind, index);
}
}
protected void createRemoveListChange(EList oldList, EList changesList,
Object newObject, int index) {
if (featureIsUnique) {
ListChange listChange = createListChange(changesList,
ChangeKind.REMOVE_LITERAL, index);
listChange.getValues().add(oldList.remove(index));
} else {
super.createRemoveListChange(oldList, changesList, newObject,
index);
}
}
protected void finalizeChange(FeatureChange change, EObject eObject) {
featureIsUnique = change.getFeature().isUnique();
super.finalizeChange(change, eObject);
}
};
private final EditingDomain editingDomain;
private final Runnable runnable;
private ChangeDescription changeDescription = null;
public ChangeCommand(EditingDomain editingDomain, Runnable runnable) {
this(editingDomain, runnable, null);
}
public ChangeCommand(EditingDomain editingDomain, Runnable runnable,
String label) {
this(editingDomain, runnable, label, null);
}
public ChangeCommand(EditingDomain editingDomain, Runnable runnable,
String label, String description) {
super(label, description);
if (null == editingDomain) {
throw new IllegalArgumentException(String.valueOf(editingDomain));
}
if (null == runnable) {
throw new IllegalArgumentException(String.valueOf(runnable));
}
this.editingDomain = editingDomain;
this.runnable = runnable;
}
public EditingDomain getEditingDomain() {
return editingDomain;
}
protected Runnable getRunnable() {
return runnable;
}
protected ChangeDescription getChangeDescription() {
return changeDescription;
}
protected void setChangeDescription(ChangeDescription changeDescription) {
this.changeDescription = changeDescription;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.common.command.AbstractCommand#prepare()
*/
protected boolean prepare() {
return null == getChangeDescription();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.common.command.Command#canUndo()
*/
public boolean canUndo() {
return null != getChangeDescription();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.common.command.Command#execute()
*/
public void execute() {
synchronized (CHANGE_RECORDER) {
CHANGE_RECORDER.beginRecording(Collections
.singleton(getEditingDomain().getResourceSet()));
try {
getRunnable().run();
} finally {
setChangeDescription(CHANGE_RECORDER.endRecording());
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.common.command.Command#undo()
*/
public void undo() {
synchronized (CHANGE_RECORDER) {
CHANGE_RECORDER.beginRecording(Collections
.singleton(getEditingDomain().getResourceSet()));
try {
getChangeDescription().apply();
} finally {
setChangeDescription(CHANGE_RECORDER.endRecording());
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.common.command.Command#redo()
*/
public void redo() {
synchronized (CHANGE_RECORDER) {
CHANGE_RECORDER.beginRecording(Collections
.singleton(getEditingDomain().getResourceSet()));
try {
getChangeDescription().apply();
} finally {
setChangeDescription(CHANGE_RECORDER.endRecording());
}
}
}
}