package Taverna.Visitor;
import java.util.List;
import java.util.ArrayList;
import Taverna.Tree.Condition;
import Taverna.Tree.Conditions;
import Taverna.Tree.Annotation.AnnotationContent;
import Taverna.Tree.DataFlowImpl.AnnotatedGranularDepthOutputPorts;
import Taverna.Tree.DataFlowImpl.AnnotatedPort;
import Taverna.Tree.DataFlowImpl.AnnotatedPorts;
import Taverna.Tree.DataFlowImpl.AnnotatedGranularDepthPort;
import Taverna.Tree.DataFlowImpl.AnnotatedGranularDepthInputPorts;
import Taverna.Tree.DataFlowImpl.AnnotatedGranularDepthOutputPorts;
import Taverna.Tree.DataFlowImpl.DataLink;
import Taverna.Tree.DataFlowImpl.Datalinks;
import Taverna.Tree.DataFlowImpl.Link;
import Taverna.Tree.DataFlowImpl.OutputPorts;
import Taverna.Tree.DataFlowImpl.Port;
import Taverna.Tree.Processor.Activities;
import Taverna.Tree.Processor.Activity;
import Taverna.Tree.Processor.ActivityInputPortDefinitionBean;
import Taverna.Tree.Processor.ActivityOutputPortDefinitionBean;
import Taverna.Tree.Processor.ConfigBean;
import Taverna.Tree.Processor.Processor;
import Taverna.Tree.Processor.Processors;
import Taverna.Tree.Processor.lWACBInputs;
import Taverna.Tree.Processor.lWACBOutputs;
import LONI.tree.workflow.Connection;
import LONI.tree.workflow.Connections;
import LONI.tree.GraphObject.DataModule;
import LONI.tree.GraphObject.GraphObject;
import LONI.tree.GraphObject.Module;
import LONI.tree.GraphObject.ModuleGroup;
import LONI.tree.module.Data;
import LONI.tree.module.metadata.Metadata;
import LONI.tree.module.Output;
import LONI.tree.module.Parameter;
import LONI.tree.module.format.Format;
import LONI.tree.module.format.FileTypes;
import LONI.tree.module.format.FileType;
import LONI.tree.module.Values;
import LONI.tree.module.Value;
import CLInterface.ConverterConfig;
import CLInterface.ConverterConstants;
import CLInterface.Printer;
import Core.Pair;
import Core.Triple;
import Galaxy.Visitor.Webservice.GalaxyToLoniWorkflowConverter;
import Taverna.util.TavernaContext;
/**
* @author johnny5550822, Nick
* Taverna's DataFlowImp conversion
*
*/
public class DataFlowImplConverter extends DataFlowImplVisitor{
TavernaContext tavernaContext = new TavernaContext();
final static String TavernaType = "TavernaFile";
private int posX=0; //coordinates system of LONI
private int posY=0; //coordinates system of LONI modules
private int maxPosX=0; // current maximum value of posX
private int maxPosY=200; // current maximum value of posY
/* (non-Javadoc)
* @see Taverna.Visitor.DataFlowImplVisitor#changeCoordinateSystem()
*/
public void changeCoordinateSystem(){
if (posX+100<=600){
if (posY+100<=maxPosY){
posY+=100;
}else{
posX+=100;
posY-=100;
}
}else{
posY+=200;
maxPosY+=200;
}
}
public int getPosX(){
return posX;
}
public int getPosY(){
return posY;
}
/* (non-Javadoc)
* @see Taverna.Visitor.DataFlowImplVisitor#visit(Taverna.Tree.DataFlowImpl.AnnotatedGranularDepthInputPorts)
*/
public Object visit(AnnotatedGranularDepthInputPorts inputPorts){
List<AnnotatedGranularDepthPort> annotatedPorts = inputPorts.getPorts();
List<DataModule> dataModules = new ArrayList<DataModule>();
if(annotatedPorts != null){
for(AnnotatedGranularDepthPort p : annotatedPorts){
boolean sourceBoolean=true;
dataModules.add((DataModule)visit(p,sourceBoolean));
}
}
return dataModules;
}
/* (non-Javadoc)
* @see Taverna.Visitor.DataFlowImplVisitor#visit(Taverna.Tree.DataFlowImpl.AnnotatedGranularDepthOutputPorts)
*/
public Object visit(AnnotatedGranularDepthOutputPorts outputPorts){
List<AnnotatedGranularDepthPort> annotatedPorts = outputPorts.getPorts();
List<DataModule> dataModules = new ArrayList<DataModule>();
if(annotatedPorts != null){
for(AnnotatedGranularDepthPort p : annotatedPorts){
boolean sourceBoolean=false;
dataModules.add((DataModule)visit(p,sourceBoolean));
}
}
return dataModules;
}
/* (non-Javadoc)
* @see Taverna.Visitor.DataFlowImplVisitor#visit(Taverna.Tree.DataFlowImpl.AnnotatedGranularDepthPort, boolean)
*/
public Object visit(AnnotatedGranularDepthPort port, boolean sourceBoolean){
DataModule dataModule = new DataModule();
dataModule.setName(port.getName());
dataModule.setId(port.getName());
dataModule.setMyPackage("Default package");
dataModule.setVersion("Default version");
//Store Annotation of the ports
try{
AnnotationConverter annotationVisitor = new AnnotationConverter();
AnnotationContent annotationContent=new AnnotationContent();
annotationContent=(AnnotationContent) annotationVisitor.visit(port.getAnnotations());
if (annotationContent.description!=null){
dataModule.setDescription(annotationContent.description);
}
}catch (Exception e) {
Printer.log("DataFlowImplConverter.java---No Description in Ports");
dataModule.setDescription("");
}
changeCoordinateSystem();
Printer.log(port.getName()+":"+getPosX()+","+getPosY());
dataModule.setPosX(getPosX());
dataModule.setPosY(getPosY());
dataModule.setRotation(0);
// Hard coding this for now, the data module needs to go through all the data links
// in the dataflow and see what types of things the input parameter port is
// connected to, and determine what type of thing the data module needs
dataModule.setType("File");
// May want to change the code so that there is an input port and output port class
// to make it easier to tell what kind of Port that port is
//To make the distinguish the "shape" of sink and source in LONI. true=Source; false=Sink
dataModule.setSource(sourceBoolean);
dataModule.setDirSource(false);
dataModule.setDirDump(false);
dataModule.setUseDirSourceFilters(false);
dataModule.setRecursive(false);
dataModule.setMetadata(new Metadata(new Data()));
dataModule.getFileTypes().addFileType(new FileType(TavernaType,"",""));
// Figure out whether the data module will have inputs or outputs by going through the
// DataLinks and figuring out if one of their source or sink names matches the
// ports name. Then you can generate inputs or outputs for the data module depending
// on what you need
Datalinks dl = tavernaContext.getDatalinks();
List<DataLink> datalinks = dl.getDataLinks();
String inputPortName = port.getName();
String datalinkPortName = "";
String sourceLinkType = "";
String sourcePort = "";
String sourceProcessor = "";
String sinkLinkType = "";
String sinkPort = "";
String sinkProcessor = "";
Link source;
Link sink;
Parameter parameter = null;
Output output = null;
Format format;
FileTypes fileTypes;
for(DataLink d : datalinks){
source = d.getSource();
sourceLinkType = source.getLinkType();
sourcePort = source.getPort();
sourceProcessor = source.getProcessor();
sink = d.getSink();
sinkLinkType = sink.getLinkType();
sinkPort = sink.getPort();
sinkProcessor = sink.getProcessor();
// Even if the Taverna port is a SOURCE, that will correspond to Output.class in LONI. It's weird, but you have to be careful. In side the Input of LONI, the dataModule actually contains <output>, not <input>!
if(sinkPort == inputPortName){
parameter = new Parameter();
parameter.setId(dataModule.getId() +".Input");
parameter.setName(inputPortName);
parameter.setDescription("Input description");
parameter.setRequired(true);
parameter.setEnabled(true);
parameter.setOrder(tavernaContext.getNextOrder());
parameter.setLink("");
parameter.setValues(new Values());
// Create a new Format for parameter
format = new Format();
format.setType("File");
format.setCardinality(1);
format.setCardinalityBase("");
format.setTransformationBase("");
// Create and fill in file types for format
fileTypes = new FileTypes();
fileTypes.addFileType(new FileType(TavernaType, "", ""));
format.setFileTypes(fileTypes);
// Give parameter the newly created Format object
parameter.setFileFormat(format);
dataModule.addInput(parameter);
break;
}
else if(sourcePort == inputPortName){
output = new Output();
output.setId(dataModule.getId() +".Output");
output.setName(inputPortName);
output.setDescription("Output description");
output.setRequired(true);
output.setEnabled(true);
output.setOrder(tavernaContext.getNextOrder());
output.setLink("");
output.setValues(new Values());
// Create a new Format for output
output.setFormat(new Format());
output.getFormat().setType("File");
output.getFormat().setCardinality(1);
output.getFormat().setCardinalityBase("");
output.getFormat().setTransformationBase("");
// Create and fill in file types for format
output.getFormat().getFileTypes().addFileType(new FileType(TavernaType, "", ""));
output.getValues().addValue(new Value("hi", "there"));
dataModule.addOutput(output);
break;
}
}
return dataModule;
}
/*
* Returns the processor name of the Link l
*/
public Object visit(Link l){
if(l.getLinkType().equals("processor")){
return l.getProcessor();
}
else if(l.getLinkType().equals("dataflow")){
return l.getPort();
}
// Not sure what the default should be here, need to check other link type.
return "";
}
public Object visit(DataLink d){
String source = (String) visit(d.getSource())+".Output";
String sink = (String) visit(d.getSink())+".Input";
Pair<String, String> sourceAndSink = new Pair<String, String>(source, sink);
return sourceAndSink;
}
/*
* @see Taverna.Visitor.DataFlowImplVisitor#visit(Taverna.Tree.Datalinks)
*/
public Object visit(Datalinks d){
this.tavernaContext.setDatalinks(d);
Connections connections = new Connections();
Pair<String, String> sourceAndSink;
if(d.getDataLinks() != null){
List<DataLink> datalinkList = d.getDataLinks();
for(DataLink datalink : datalinkList){
sourceAndSink = (Pair) visit(datalink);
connections.addConnection(new Connection(sourceAndSink.getElem1(), sourceAndSink.getElem2()));
}
} else {
Printer.log("d.getDataLinks() is null");
}
return connections;
}
/* (non-Javadoc)
* @see Taverna.Visitor.DataFlowImplVisitor#visit(Taverna.Tree.Processor.Processors)
*/
public Object visit(Processors procs){
List<GraphObject> objs = new ArrayList<GraphObject>();
for(Processor p : procs.getProcessors()){
GraphObject gr = (GraphObject) visit(p);
if(gr != null) objs.add(gr);
}
return objs;
}
/* (non-Javadoc)
* @see Taverna.Visitor.DataFlowImplVisitor#visit(Taverna.Tree.Processor.Processor)
*/
public Object visit(Processor p){
ModuleGroup newgrp = new ModuleGroup();
List<DataModule> inputs = (List<DataModule>) visit(p.getInputPorts());
List<DataModule> outputs = (List<DataModule>) visit(p.getOutputPorts());
if(outputs != null)
newgrp.getModules().addAll(outputs);
if(inputs != null)
newgrp.getModules().addAll(inputs);
newgrp.setName(p.getProcessorName());
List<GraphObject> grActivities= (List<GraphObject>) visit(p.getActivities());
newgrp.getModules().addAll(grActivities);
return newgrp;
}
/* (non-Javadoc)
* @see Taverna.Visitor.DataFlowImplVisitor#visit(Taverna.Tree.Processor.ActivityInputPortDefinitionBean)
*/
public Object visit(ActivityInputPortDefinitionBean input){
Parameter p = new Parameter();
p.setName( input.getName());
p.setPrefix(input.getName()+"=");
p.setEnabled(true);
p.setOrder(1);
p.setPrefixSpaced(false);
p.setFileFormat(new Format());
p.getFormat().setCardinality(1);
p.getFormat().setType("File");
if(input.getTranslatedElementType() != null){
String elem_class = input.getTranslatedElementType();
if(elem_class.equals("java.lang.String")){
p.getFormat().setType("String");
}
}
return p;
}
/* (non-Javadoc)
* @see Taverna.Visitor.DataFlowImplVisitor#visit(Taverna.Tree.Processor.ActivityOutputPortDefinitionBean)
*/
public Object visit(ActivityOutputPortDefinitionBean output){
LONI.tree.module.Output out = new LONI.tree.module.Output();
out.setName( output.getName());
out.setPrefix("*"+output.getName()+"=");
out.setEnabled(true);
out.setOrder(1);
out.setPrefixSpaced(false);
out.setFormat(new Format());
out.getFormat().setType("File");
out.getFormat().setCardinality(1);
FileType ft =new FileType();
ft.setDescription("");
ft.setExtension("");
ft.setName(TavernaType);
out.getFormat().getFileTypes().addFileType(ft);
return out;
}
/* (non-Javadoc)
* @see Taverna.Visitor.DataFlowImplVisitor#visit(Taverna.Tree.Processor.lWACBInputs)
*/
public Object visit(lWACBInputs inputs){
List<Parameter> params = new ArrayList<Parameter>();
if(inputs.getiWACBInputs() != null){
for(ActivityInputPortDefinitionBean o : inputs.getiWACBInputs()){
Parameter p = (Parameter)visit(o);
if(p != null)
params.add(p);
}
}
return params;
}
/* (non-Javadoc)
* @see Taverna.Visitor.DataFlowImplVisitor#visit(Taverna.Tree.Processor.lWACBOutputs)
*/
public Object visit(lWACBOutputs outputs){
List<LONI.tree.module.Output> params = new ArrayList<LONI.tree.module.Output>();
if(outputs.getiWACBOutputs() != null){
for(ActivityOutputPortDefinitionBean o : outputs.getiWACBOutputs()){
LONI.tree.module.Output p = (LONI.tree.module.Output)visit(o);
if(p != null)
params.add(p);
}
}
return params;
}
/**
* String modification method for script conversion in Taverna to Loni
*/
public String cleanStringValue(String s){
String str;
str= s.replaceAll("[\\{]", "\\^paren\\^");
str= str.replaceAll("[\\}]", "\\$paren\\$");
return str;
}
/* (non-Javadoc)
* @see Taverna.Visitor.DataFlowImplVisitor#visit(Taverna.Tree.Processor.ConfigBean)
*/
public Object visit(ConfigBean c){
String location= ConverterConstants.LOCALHOST_PATH +
ConverterConfig.TAVERNA_BEANSHELL_LOCATION;
String wrapper = ConverterConfig.GALAXY_SCRIPT_DIR + ConverterConstants.BEANSHELL_WRAPPER;
List<Parameter> args = new ArrayList<Parameter>();
Parameter scriptParam = new Parameter();
scriptParam.setName("Beanshell wrapper script");
scriptParam.setEnabled(true);
scriptParam.setOrder(0);
scriptParam.setFileFormat(new Format());
scriptParam.getFileFormat().setType("String");
scriptParam.getFileFormat().setCardinality(1);
Value val = new Value();
val.setValue(wrapper);
scriptParam.getValues().addValue(val);
args.add(scriptParam);
if(c.getlWACB() != null){
Parameter scriptBody = new Parameter();
scriptBody.setName("Beanshell script body");
scriptBody.setEnabled(true);
scriptBody.setOrder(1);
scriptBody.setPrefix("@");
scriptBody.setPrefixSpaced(false);
scriptBody.setFileFormat(new Format());
scriptBody.getFileFormat().setType("String");
scriptBody.getFileFormat().setCardinality(1);
Value myval = new Value();
myval.setValue(cleanStringValue(c.getlWACB().getScript()));
scriptBody.getValues().addValue(myval);
args.add(scriptBody);
List<Parameter> inputs = (List<Parameter> ) visit(c.getlWACB().getIWACBIn());
List<Output> outputs = (List<Output>) visit(c.getlWACB().getiWACBOut());
if(inputs !=null)
args.addAll(inputs);
return new Triple<String, List<Parameter>, List<Output>>(location, args, outputs);
}
return null;
}
/* (non-Javadoc)
* @see Taverna.Visitor.DataFlowImplVisitor#visit(Taverna.Tree.Processor.Activity)
*/
public Object visit(Activity a){
Module m = new Module();
m.setName(a.getTheClass());
if(a.getConfigBean() != null){
Triple<String, List<Parameter>, List<Output>> info;
info= (Triple<String, List<Parameter>, List<Output>>) visit(a.getConfigBean());
m.setLocation(info.getElem1());
m.addInputs(info.getElem2());
m.addOutputs(info.getElem3());
}
return m;
}
/* (non-Javadoc)
* @see Taverna.Visitor.DataFlowImplVisitor#visit(Taverna.Tree.Processor.Activities)
*/
public Object visit(Activities a){
List<GraphObject> lst= new ArrayList<GraphObject>();
if(a.getActivities() != null){
for(Activity act : a.getActivities()){
GraphObject go = (GraphObject) visit(act);
if(go != null)
lst.add(go);
}
}
return lst;
}
}