blob: 42f0d12ea16fea6ded6e6bb18f7c0e689632455a [file] [log] [blame]
/**
*
*/
package net.sf.taverna.t2.visit.fragility;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.sf.taverna.t2.visit.VisitReport;
import net.sf.taverna.t2.workflowmodel.Dataflow;
import net.sf.taverna.t2.workflowmodel.Datalink;
import net.sf.taverna.t2.workflowmodel.Merge;
import net.sf.taverna.t2.workflowmodel.MergeInputPort;
import net.sf.taverna.t2.workflowmodel.MergeOutputPort;
import net.sf.taverna.t2.workflowmodel.Port;
import net.sf.taverna.t2.workflowmodel.Processor;
import net.sf.taverna.t2.workflowmodel.ProcessorInputPort;
import net.sf.taverna.t2.workflowmodel.ProcessorOutputPort;
import net.sf.taverna.t2.workflowmodel.ProcessorPort;
import net.sf.taverna.t2.workflowmodel.processor.dispatch.DispatchLayer;
import net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Retry;
import net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.RetryConfig;
/**
* @author alanrw
*
*/
public class ProcessorFragilityChecker implements FragilityChecker<Processor> {
/* (non-Javadoc)
* @see net.sf.taverna.t2.annotation.Visitor#canVisit(java.lang.Object)
*/
public boolean canVisit(Object o) {
return o instanceof Processor;
}
/* (non-Javadoc)
* @see net.sf.taverna.t2.annotation.Visitor#visit(java.lang.Object, java.util.List)
*/
public VisitReport visit(Processor o, List<Object> ancestry) {
VisitReport result = null;
Set<VisitReport> reports = new HashSet<VisitReport>();
Dataflow d = (Dataflow) ancestry.get(0);
for (ProcessorInputPort pip : o.getInputPorts()) {
if (pip.getDepth() == -1) {
result = new VisitReport(FragilityCheck.getInstance(), o, "Invalid depth of list", FragilityCheck.INVALID_DEPTH, VisitReport.Status.SEVERE);
}
else {
int viaMerge = 0;
for (Datalink dl : d.getLinks()) {
if (dl.getSink().equals(pip)) {
Port source = dl.getSource();
if (source instanceof MergeOutputPort) {
viaMerge = 1;
}
break;
}
}
for (ProcessorPort sourceProcessorPort : getSourceProcessorPorts(d, pip)) {
boolean sourceRetries = false;
Processor sourceProcessor = sourceProcessorPort.getProcessor();
int resolvedDepth = ((ProcessorOutputPort) sourceProcessorPort).getOutgoingLinks().iterator().next().getResolvedDepth();
boolean sourceIterates = resolvedDepth != sourceProcessorPort.getDepth();
List<DispatchLayer<?>> layers = sourceProcessor.getDispatchStack().getLayers();
for (DispatchLayer l : layers) {
if (l instanceof Retry) {
Retry retry = (Retry) l;
RetryConfig config = retry.getConfiguration();
sourceRetries = config.getMaxRetries() != 0;
break;
}
}
boolean listCreation = (sourceProcessorPort.getDepth() < pip.getDepth());
if ((sourceIterates || (viaMerge != 0)) && listCreation && !sourceRetries) {
VisitReport report = new VisitReport(FragilityCheck.getInstance(), o, "Breaks on single error", FragilityCheck.SOURCE_FRAGILE, VisitReport.Status.WARNING);
report.setProperty("sinkPort", pip);
report.setProperty("sourceProcessor", sourceProcessor);
reports.add(report);
}
}
}
}
if (reports.isEmpty()) {
return null;
} else if (reports.size() == 1) {
return (reports.iterator().next());
} else {
return new VisitReport(FragilityCheck.getInstance(), o, "Breaks on single error", FragilityCheck.SOURCE_FRAGILE, VisitReport.Status.WARNING, reports);
}
}
private Set<ProcessorPort> getSourceProcessorPorts(Dataflow d, Port pip) {
Set<ProcessorPort> result = new HashSet<ProcessorPort>();
for (Datalink dl : d.getLinks()) {
if (dl.getSink().equals(pip)) {
Port source = dl.getSource();
if (source instanceof ProcessorPort) {
result.add((ProcessorPort)source);
} else if (source instanceof MergeOutputPort) {
Merge merge = ((MergeOutputPort) source).getMerge();
for (MergeInputPort mip : merge.getInputPorts()) {
result.addAll(getSourceProcessorPorts(d, mip));
}
}
}
}
return result;
}
public boolean isTimeConsuming() {
return false;
}
}