package org.eclipse.emf.emfstore.client.model.impl;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.emf.emfstore.client.model.CompositeOperationHandle;
import org.eclipse.emf.emfstore.client.model.ProjectSpace;
import org.eclipse.emf.emfstore.client.model.observers.OperationListener;
import org.eclipse.emf.emfstore.server.model.versioning.operations.AbstractOperation;
import org.eclipse.emf.emfstore.server.model.versioning.operations.CompositeOperation;
import org.eclipse.emf.emfstore.server.model.versioning.operations.semantic.SemanticCompositeOperation;
public class OperationManager implements OperationRecorderListener {
private OperationRecorder operationRecorder;
private List<OperationListener> operationListeners;
// private CompositeOperation compositeOperation;
private ProjectSpace projectSpace;
public OperationManager(OperationRecorder operationRecorder, ProjectSpace projectSpace) {
this.operationRecorder = operationRecorder;
operationRecorder.addOperationRecorderListener(this);
operationListeners = new ArrayList<OperationListener>();
this.projectSpace = projectSpace;
}
/**
* Undo the last operation of the projectSpace.
*/
public void undoLastOperation() {
if (!projectSpace.getOperations().isEmpty()) {
List<AbstractOperation> operations = projectSpace.getOperations();
AbstractOperation lastOperation = operations.get(operations.size() - 1);
operationRecorder.stopChangeRecording();
try {
lastOperation.reverse().apply(operationRecorder.getCollection());
notifyOperationUndone(lastOperation);
} finally {
operationRecorder.startChangeRecording();
}
operations.remove(lastOperation);
}
// TODO: EM, update dirty state
// updateDirtyState();
}
/**
*
* @param operationListener
*/
public void addOperationListener(OperationListener operationListener) {
operationListeners.add(operationListener);
}
/**
* {@inheritDoc}
*
* @param operationListner
*/
public void removeOperationListener(OperationListener operationListner) {
operationListeners.remove(operationListner);
}
// TODO: EM, changed to public
public void notifyOperationUndone(AbstractOperation operation) {
for (OperationListener operationListener : operationListeners) {
operationListener.operationUnDone(operation);
}
}
/**
* Notify the operation observer that an operation has just completed.
*
* @param operation
* the operation
*/
void notifyOperationExecuted(AbstractOperation operation) {
// do not notify on composite start, wait until completion
if (operation instanceof CompositeOperation) {
// check of automatic composite, if yes then continue
if (((CompositeOperation) operation).getMainOperation() == null) {
return;
}
}
for (OperationListener operationListener : operationListeners) {
operationListener.operationExecuted(operation);
}
}
// public CompositeOperationHandle beginCompositeOperation() {
// // notificationRecorder.newRecording();
// if (this.compositeOperation != null) {
// throw new IllegalStateException(
// "Can only have one composite at once!");
// }
// this.compositeOperation = OperationsFactory.eINSTANCE
// .createCompositeOperation();
// operationRecorder.addOperation(this.compositeOperation);
// CompositeOperationHandle handle = new CompositeOperationHandle(this,
// compositeOperation);
// return handle;
// }
/**
* Aborts the current composite operation.
*/
public void abortCompositeOperation() {
undoLastOperation();
operationRecorder.abortCompositeOperation();
}
/**
* Complete the current composite operation.
*/
public void endCompositeOperation() {
notifyOperationExecuted(operationRecorder.getCompositeOperation());
operationRecorder.endCompositeOperation();
}
/**
* Replace and complete the current composite operation.
*
* @param semanticCompositeOperation
* the semantic operation that replaces the composite operation
*/
public void endCompositeOperation(SemanticCompositeOperation semanticCompositeOperation) {
List<AbstractOperation> operations = projectSpace.getOperations();
operations.remove(operations.size() - 1);
operations.add(semanticCompositeOperation);
endCompositeOperation();
}
public CompositeOperationHandle beginCompositeOperation() {
return operationRecorder.beginCompositeOperation();
}
// TODO: EM
// private void notifyPostCreationListeners(EObject modelElement) {
// // do not record changes since the creation listeners may only change
// // attributes
// boolean wasRecording = isRecording;
// if (isRecording) {
// stopChangeRecording();
// }
// for (PostCreationListener l : postCreationListeners) {
// l.onCreation(projectSpace, modelElement);
// }
// if (wasRecording) {
// startChangeRecording();
// }
// }
public void operationsRecorded(List<? extends AbstractOperation> operations) {
projectSpace.addOperations(operations);
}
public void clearOperations() {
operationRecorder.clearOperations();
}
}