blob: 327e5a7f2f1904ae07ff42d2eead692033f14685 [file] [log] [blame]
package net.sf.taverna.t2.workbench.file.importworkflow;
import java.util.ArrayList;
import java.util.List;
import net.sf.taverna.t2.workbench.edits.CompoundEdit;
import net.sf.taverna.t2.workbench.edits.Edit;
import net.sf.taverna.t2.workflow.edits.AddChildEdit;
import net.sf.taverna.t2.workflow.edits.AddDataLinkEdit;
import net.sf.taverna.t2.workflow.edits.AddProcessorEdit;
import net.sf.taverna.t2.workflow.edits.AddWorkflowInputPortEdit;
import net.sf.taverna.t2.workflow.edits.AddWorkflowOutputPortEdit;
import uk.org.taverna.scufl2.api.common.AbstractCloneable;
import uk.org.taverna.scufl2.api.container.WorkflowBundle;
import uk.org.taverna.scufl2.api.core.ControlLink;
import uk.org.taverna.scufl2.api.core.DataLink;
import uk.org.taverna.scufl2.api.core.Processor;
import uk.org.taverna.scufl2.api.core.Workflow;
import uk.org.taverna.scufl2.api.port.InputWorkflowPort;
import uk.org.taverna.scufl2.api.port.OutputWorkflowPort;
/**
* A tool that allows merging of two workflow.
* <p>
* The merge is performed as a series of edit, inserting a copy of the source
* workflow into the destination workflow.
*
* @author Stian Soiland-Reyes
* @author David Withers
*/
public class DataflowMerger {
/**
* Make a copy of a workflow.
*
* @param source
* workflow to copy
* @return A copy of the workflow.
*/
public static Workflow copyWorkflow(Workflow source) {
WorkflowBundle workflowBundle = AbstractCloneable.cloneWorkflowBean(source.getParent());
return workflowBundle.getWorkflows().getByName(source.getName());
}
private final Workflow destinationWorkflow;
/**
* Construct a {@link DataflowMerger} for the given destination workflow.
*
* @param destinationWorkflow
* Workflow to be merged into
*/
public DataflowMerger(Workflow destinationWorkflow) {
this.destinationWorkflow = destinationWorkflow;
}
/**
* Make an {@link Edit} that when performed merges the given source dataflow
* into the destination dataflow.
* <p>
* Internally a copy is made of the source dataflow, to avoid modifying the
* links and processors.
*
* @param sourceDataflow
* Dataflow to merge from
* @return An edit that can perform and undo the insertion of the components
* from the source dataflow.
* @throws MergeException
* If the merge cannot be performed.
*/
public CompoundEdit getMergeEdit(Workflow sourceDataflow)
throws MergeException {
return getMergeEdit(sourceDataflow, "");
}
/**
* Make an {@link Edit} that when performed merges the given source dataflow
* into the destination dataflow.
* <p>
* Internally a copy is made of the source dataflow, to avoid modifying the
* links and processors.
*
* @param sourceWorkflow
* Dataflow to merge from
* @param prefix
* A prefix which will be inserted in front of the names for the
* merged workflow components.
* @return An edit that can perform and undo the insertion of the components
* from the source dataflow.
* @throws MergeException
* If the merge cannot be performed.
*/
public CompoundEdit getMergeEdit(Workflow sourceWorkflow, String prefix)
throws MergeException {
List<Edit<?>> compoundEdit = new ArrayList<>();
Workflow workflow = copyWorkflow(sourceWorkflow);
for (InputWorkflowPort input : workflow.getInputPorts()) {
destinationWorkflow.getInputPorts().addWithUniqueName(input);
destinationWorkflow.getInputPorts().remove(input);
compoundEdit.add(new AddWorkflowInputPortEdit(destinationWorkflow, input));
}
for (OutputWorkflowPort output : workflow.getOutputPorts()) {
destinationWorkflow.getOutputPorts().addWithUniqueName(output);
destinationWorkflow.getOutputPorts().remove(output);
compoundEdit.add(new AddWorkflowOutputPortEdit(destinationWorkflow, output));
}
for (Processor processor : workflow.getProcessors()) {
processor.setName(prefix + processor.getName());
compoundEdit.add(new AddProcessorEdit(destinationWorkflow, processor));
}
for (DataLink dataLink : workflow.getDataLinks()) {
compoundEdit.add(new AddDataLinkEdit(destinationWorkflow, dataLink));
}
for (ControlLink controlLink : workflow.getControlLinks()) {
compoundEdit.add(new AddChildEdit<Workflow>(destinationWorkflow, controlLink));
}
return new CompoundEdit(compoundEdit);
}
}