blob: fe8708559b4718e7567e6349e6cae618841fdb26 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.taverna.workbench.edits;
import org.apache.taverna.scufl2.api.container.WorkflowBundle;
import org.apache.taverna.lang.observer.Observable;
import org.apache.taverna.lang.observer.Observer;
import org.apache.taverna.workbench.edits.EditManager.EditManagerEvent;
/**
* Manager that can handle {@link Edit edits} for a {@link WorkflowBundle}.
* <p>
* Edits to a workflow that are to be undoable or redoable should be created by
* using {@link EditManager#getEdits()} to get an {@link Edits} object. Using
* this to create {@link Edit}s, instead of calling {@link Edit#doEdit()}, use
* {@link EditManager#doDataflowEdit(WorkflowBundle, Edit)} to associate the
* edit with the specified Dataflow.
* <p>
* It is possible to undo a series of edits done on a particular dataflow in
* this way by using {@link #undoDataflowEdit(WorkflowBundle)}. If one or more
* undoes have been performed, they can be redone step by step using
* {@link #redoDataflowEdit(WorkflowBundle)}. Note that it is no longer possible
* to call {@link #redoDataflowEdit(WorkflowBundle)} after a
* {@link #doDataflowEdit(WorkflowBundle, Edit)}.
* <p>
* The EditManager is {@link Observable}. If you
* {@linkplain Observable#addObserver(net.sf.taverna.t2.lang.observer.Observer)
* add an observer} you can be notified on {@linkplain DataflowEditEvent edits},
* {@linkplain DataFlowUndoEvent undoes} and {@linkplain DataFlowRedoEvent
* redoes}.
*
* @author Stian Soiland-Reyes
*/
public interface EditManager extends Observable<EditManagerEvent> {
/**
* <code>true</code> if {@link #redoDataflowEdit(WorkflowBundle)} on the
* given dataflow would redo the last undone edit. If there are no previous
* edits, return <code>false</code>.
*
* @param dataflow
* {@link WorkflowBundle} which last affecting edit is to be
* undone
* @return <code>true</code if and only if
* {@link #redoDataflowEdit(WorkflowBundle)} would undo
*/
boolean canRedoDataflowEdit(WorkflowBundle dataflow);
/**
* <code>true</code> if {@link #undoDataflowEdit(WorkflowBundle)} on the
* given dataflow would undo the last edit. If there are no previous edits,
* return <code>false</code>.
*
* @param dataflow
* {@link WorkflowBundle} which last affecting edit is to be
* undone
* @return <code>true</code if {@link #undoDataflowEdit(WorkflowBundle)}
* would undo
*/
boolean canUndoDataflowEdit(WorkflowBundle dataflow);
/**
* Do an {@link Edit} affecting the given {@link WorkflowBundle}.
* <p>
* The edit is {@link Edit#doEdit() performed} and the edit can later be
* undone using {@link EditManager#undoDataflowEdit(WorkflowBundle)}.
* <p>
* Note that any events previously undone with
* {@link EditManager#undoDataflowEdit(WorkflowBundle)} for the given
* dataflow can no longer be
* {@link EditManager#redoDataflowEdit(WorkflowBundle) redone} after calling
* this method.
*
* @see EditManager#undoDataflowEdit(WorkflowBundle)
* @param dataflow
* {@link WorkflowBundle} this edit is affecting
* @param edit
* {@link Edit} that should be done using {@link Edit#doEdit()}.
* @throws EditException
* If {@link Edit#doEdit()} fails
*/
void doDataflowEdit(WorkflowBundle dataflow, Edit<?> edit)
throws EditException;
/**
* Redo the last {@link Edit} that was undone using
* {@link #undoDataflowEdit(WorkflowBundle)}.
* <p>
* Note that the {@link EditManager} might only be able to redo a reasonable
* number of steps.
* <p>
* It is not possible to use {@link #redoDataflowEdit(WorkflowBundle)} after
* a {@link #doDataflowEdit(WorkflowBundle, Edit)} affecting the same
* {@link WorkflowBundle}, or if no edits have been undone yet. No action
* would be taken in these cases.
*
* @param dataflow
* {@link WorkflowBundle} which last affecting edit is to be
* redone
* @throws EditException
* If {@link Edit#doEdit()} fails
*/
void redoDataflowEdit(WorkflowBundle dataflow) throws EditException;
/**
* Undo the last {@link Edit} affecting the given {@link WorkflowBundle}.
* <p>
* This can be called in succession until there are no more known undoes.
* Note that the {@link EditManager} might only be able to undo a reasonable
* number of steps.
* <p>
* The last edit must have been performed using
* {@link EditManager#doDataflowEdit(WorkflowBundle, Edit)} or
* {@link EditManager#redoDataflowEdit(WorkflowBundle)}. The undo is done
* using {@link Edit#undo()}. If no edits have been performed for the
* dataflow yet, no action is taken.
* <p>
* Undoes can be redone using {@link #redoDataflowEdit(WorkflowBundle)}.
*
* @param dataflow
* {@link WorkflowBundle} which last affecting edit is to be
* undone
*/
void undoDataflowEdit(WorkflowBundle dataflow);
/**
* An event about an {@link Edit} on a {@link WorkflowBundle}, accessible
* through {@link AbstractDataflowEditEvent#getEdit()} and
* {@link AbstractDataflowEditEvent#getDataFlow()}.
*/
public static abstract class AbstractDataflowEditEvent implements
EditManagerEvent {
private final WorkflowBundle dataFlow;
private final Edit<?> edit;
public AbstractDataflowEditEvent(WorkflowBundle dataFlow, Edit<?> edit) {
if (dataFlow == null || edit == null)
throw new NullPointerException(
"Dataflow and/or Edit can't be null");
this.dataFlow = dataFlow;
this.edit = edit;
}
/**
* The {@link WorkflowBundle} this event affected.
*
* @return A {@link WorkflowBundle}
*/
public WorkflowBundle getDataFlow() {
return dataFlow;
}
/**
* The {@link Edit} that was performed, undoed or redone on the
* {@link #getDataFlow() dataflow}.
*
* @return An {@link Edit}
*/
@Override
public Edit<?> getEdit() {
return edit;
}
}
/**
* An event sent when an {@link Edit} has been performed on a
* {@link WorkflowBundle}.
*
*/
public static class DataflowEditEvent extends AbstractDataflowEditEvent {
public DataflowEditEvent(WorkflowBundle dataFlow, Edit<?> edit) {
super(dataFlow, edit);
}
}
/**
* An event sent when a previously undone {@link Edit} has been redone on a
* {@link WorkflowBundle}.
*
*/
public static class DataFlowRedoEvent extends AbstractDataflowEditEvent {
public DataFlowRedoEvent(WorkflowBundle dataFlow, Edit<?> edit) {
super(dataFlow, edit);
}
}
/**
* An event sent when an {@link Edit} has been undone on a
* {@link WorkflowBundle}.
*
*/
public static class DataFlowUndoEvent extends AbstractDataflowEditEvent {
public DataFlowUndoEvent(WorkflowBundle dataFlow, Edit<?> edit) {
super(dataFlow, edit);
}
}
/**
* An event given to {@link Observer}s registered with
* {@link Observable#addObserver(Observer)}.
*/
public interface EditManagerEvent {
public Edit<?> getEdit();
}
}