blob: 06fa75310ecdd6c78a9c47f52dd21e32043f675d [file] [log] [blame]
/*******************************************************************************
* Copyright (C) 2007 The University of Manchester
*
* Modifications to the initial code base are copyright of their
* respective authors, or their employers as appropriate.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
******************************************************************************/
package net.sf.taverna.t2.workflowmodel.impl;
import net.sf.taverna.t2.workflowmodel.Datalink;
import net.sf.taverna.t2.workflowmodel.Edit;
import net.sf.taverna.t2.workflowmodel.EditException;
import net.sf.taverna.t2.workflowmodel.Edits;
import net.sf.taverna.t2.workflowmodel.EventForwardingOutputPort;
import net.sf.taverna.t2.workflowmodel.EventHandlingInputPort;
import net.sf.taverna.t2.workflowmodel.Merge;
import net.sf.taverna.t2.workflowmodel.utils.Tools;
/**
* <p>
* An edit that connects an EventForwardingOutputPort sourcePort and EventHandlingInputPort sinkPort together
* via an intermediary {@link Merge} instance, which is provided to the constructor.
* The connections are made using {@link Datalink}. Using a Merge facilitates multiple incoming Datalinks connect to a single
* input port.
* </p>
* <p>
* If an connection already exists between a sinkPort and a sourcePort, then then an new datalink is provided
* for the incoming link but the outgoing link remains as is (since there can only be 1). In this case, if the
* sink port differs from the existing one then an EditException is thrown.
* </p>
*
* @author Stuart Owen
*
*/
public class ConnectMergedDatalinkEdit extends AbstractMergeEdit {
private EventHandlingInputPort sinkPort;
private EventForwardingOutputPort sourcePort;
private Datalink inLink;
private Datalink outLink;
private Edit<Datalink> connectInLinkEdit;
private Edit<Datalink> connectOutLinkEdit;
private MergeInputPortImpl mergeInputPort;
/**
* Constructs the ConnectMergedDatalinkEdit with an existing Merge instance, and the source and sink ports that are to
* be connected.
*
* @param merge
* @param sourcePort
* @param sinkPort
*/
public ConnectMergedDatalinkEdit(Merge merge, EventForwardingOutputPort sourcePort, EventHandlingInputPort sinkPort) {
super(merge);
if (sinkPort==null) throw new RuntimeException("The sinkport cannot be null");
this.sinkPort=sinkPort;
if (sourcePort==null) throw new RuntimeException("The sourceport cannot be null");
this.sourcePort=sourcePort;
}
@Override
protected void doEditAction(MergeImpl mergeImpl) throws EditException {
Edits edits = new EditsImpl();
String name = Tools.getUniqueMergeInputPortName(mergeImpl, sourcePort.getName()+"To" + merge.getLocalName() + "_input", 0);
mergeInputPort = new MergeInputPortImpl(mergeImpl,name,sinkPort.getDepth());
inLink = edits.createDatalink(sourcePort, mergeInputPort);
connectInLinkEdit=edits.getConnectDatalinkEdit(inLink);
if (mergeImpl.getOutputPort().getOutgoingLinks().size()==0) {
outLink = edits.createDatalink(mergeImpl.getOutputPort(), sinkPort);
connectOutLinkEdit=edits.getConnectDatalinkEdit(outLink);
}
else if (mergeImpl.getOutputPort().getOutgoingLinks().size()==1){
if (mergeImpl.getOutputPort().getOutgoingLinks().toArray(new Datalink[]{})[0].getSink() != sinkPort) {
throw new EditException("Cannot add a different sinkPort to a Merge that already has one defined");
}
}
else {
throw new EditException("The merge instance cannot have more that 1 outgoing Datalink");
}
mergeImpl.addInputPort(mergeInputPort);
connectInLinkEdit.doEdit();
if (connectOutLinkEdit!=null) connectOutLinkEdit.doEdit();
}
@Override
protected void undoEditAction(MergeImpl mergeImpl) {
if (connectOutLinkEdit!=null) connectOutLinkEdit.undo();
connectInLinkEdit.undo();
mergeImpl.removeInputPort(mergeInputPort);
}
}