package Galaxy.Visitor.Local;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import CLInterface.ConverterConfig;
import Core.Pair;
import Core.Triple;
import Galaxy.Tree.Tool.Tool;
import Galaxy.Tree.Tool.Command.Command;
import Galaxy.Tree.Tool.Input.Input;
import Galaxy.Tree.Tool.Input.Inputs;
import Galaxy.Tree.Tool.Input.Param.Parameter;
import Galaxy.Tree.Tool.Output.Data;
import Galaxy.Tree.Tool.Output.Output;
import Galaxy.Tree.Tool.Output.Outputs;
import Galaxy.Tree.Workflow.Action;
import Galaxy.Tree.Workflow.ExternalInput;
import Galaxy.Tree.Workflow.ExternalOutput;
import Galaxy.Tree.Workflow.InputConnection;
import Galaxy.Tree.Workflow.Position;
import Galaxy.Tree.Workflow.Step;
import Galaxy.Tree.Workflow.Workflow;
import Galaxy.Visitor.DFSWorkflowVisitor;
import Galaxy.Visitor.DFSWorkflowVisitor.StepVisitor.StepImplVisitor;
import Galaxy.Visitor.util.LoniContext;
import Galaxy.Visitor.util.LoniEnvironment;
import LONI.tree.LoniNode;
import LONI.tree.GraphObject.DataModule;
import LONI.tree.GraphObject.GraphObject;
import LONI.tree.GraphObject.Module;
import LONI.tree.GraphObject.ModuleGroup;
import LONI.tree.module.Value;
import LONI.tree.module.format.FileType;
import LONI.tree.module.format.FileTypes;
import LONI.tree.module.format.Format;
import LONI.tree.module.metadata.Metadata;
import LONI.tree.workflow.Connection;
import LONI.tree.workflow.Connections;
import LONI.tree.workflow.Pipeline;
import LONI.tree.workflow.Variable;
import Specification.GalaxySpecification;
public class GalaxyToLoniWorkflowConverter extends DFSWorkflowVisitor
{
private static int MGROUP_COUNT=0;
private GalaxyToLoniToolConverter GtoLTool = new GalaxyToLoniToolConverter();
public String getModuleGroup(){
String s = "mgrp" + MGROUP_COUNT;
MGROUP_COUNT++;
return s;
}
public Object visit(Workflow workflow)
{
Pipeline pipeline;
ModuleGroup mgroup;
LoniEnvironment stepEnv;
LoniContext context = new LoniContext();
String annotation = workflow.getAnnotation();
String version = workflow.getFormatVersion();
String name = workflow.getName();
mgroup = new ModuleGroup();
mgroup.setName(name);
mgroup.setVersion("version");
mgroup.setDescription(annotation);
mgroup.setPosX(0);
mgroup.setPosY(0);
/* Add the Galaxy directory global to the loni file*/
String varName="GALAXY_DIR";
String varDescription="directory of galaxy installation. Used to find galaxy scripts.";
boolean secret = false;
int order = 0;
boolean required=true;
mgroup.getVariables().addVariable(new Variable(varName, varDescription, required,
secret, order, ConverterConfig.GALAXY_INPUT_DIR) );
varName="OUTPUT_FILE_DIR";
varDescription="directory of galaxy installation. Used to find galaxy scripts.";
mgroup.getVariables().addVariable(new Variable(varName, varDescription, required,
secret, order, ConverterConfig.GALAXY_OUTPUT_DIR) );
/* Record environmental variable in context for future use*/
/*TODO: Migrate these globals to some sort of configuration file*/
Connections connections = new Connections();
for(Step s : workflow.getSteps()){
Pair<GraphObject, LoniEnvironment> dat;
dat = (Pair<GraphObject, LoniEnvironment>) stepVisitor.visit(s, context);
connections.addConnections(dat.getElem2().getConnections());
mgroup.getModules().addAll(dat.getElem2().getModules());
if(dat.getElem1() != null)
mgroup.getModules().add(dat.getElem1());
}
pipeline = new Pipeline(version, mgroup, connections);
return pipeline;
}
{
stepVisitor = new StepVisitor() {
public Pair<GraphObject, LoniEnvironment> visit(Step step, LoniContext context){
if(step.getType().equals("tool"))
return visitModuleGroupToolStep(step, context);
else if(step.getType().equals("data_input"))
return visitDataStep(step, context);
/*
if(step.getType().equals("tool"))
return visitToolStep(step, context);
*/
return new Pair<GraphObject, LoniEnvironment>(null, new LoniEnvironment());
}
public Pair<GraphObject, LoniEnvironment> visitModuleGroupToolStep(Step step, LoniContext context){
ModuleGroup moduleGroup=new ModuleGroup();
LoniEnvironment env = new LoniEnvironment();
final String PREFIX = "Step";
LoniContext childContext = context.copy();
String id;
id = PREFIX + step.getId();
/*
* Add the step numbers as a prefix to all children.
*/
childContext.getPathContext().addContext(id);
childContext.getPositionContext().addContext(new Pair<Integer, Integer>(100,100));
childContext.getStateContext().setContext(step.getToolState());
/*
* Set the basic properties of each modulegoup
*/
moduleGroup.setPosX(step.getPosition().getFromLeft());
moduleGroup.setPosY(step.getPosition().getFromTop());
moduleGroup.setId(context.getPathContext().getAbsoluteContext(id));
moduleGroup.setRotation(4);
moduleGroup.setName(step.getName());
moduleGroup.setVersion(step.getToolVersion());
/*
* Get the tool from the database
*/
String toolid = step.getToolId();
Tool toolStep = null; //initialize tool to null
Pair<Module,LoniEnvironment> toolModuleGrp; //resulting module
toolStep = GalaxySpecification.getDatabase().getTool(step.getToolId());
//TODO: change to fatal exception.
if(toolStep == null)
throw new RuntimeException("GALAXY: Tool "+toolid+" does not exist in galaxy database.");
/*
* Get list of external inputs, formats
*/
//Visit retrieved tool.
toolModuleGrp= (Pair<Module,LoniEnvironment>)
GtoLTool.toolVisitor.visit(toolStep, childContext.copy());
Module toolModule = (Module) toolModuleGrp.getElem1();
LoniEnvironment toolEnv = toolModuleGrp.getElem2();
moduleGroup.getModules().add(toolModule);
LoniContext actionContext = childContext.copy();
actionContext.getPathContext().addContext("Action");
for(String actionName : step.getPostJobActions()){
Action action = step.getPostJobAction(actionName);
Pair<Object, LoniEnvironment> visitedAction;
visitedAction = stepImplVisitor.visit(action, actionContext);
Module actionModule = (Module) visitedAction.getElem1();
if(actionModule != null){
Connection toAction;
toAction = new Connection(
toolEnv.getOutputAliases().get(action.getOutputName()),
actionModule.getInputs().get(0).getId());
moduleGroup.getModules().add(actionModule);
toolEnv.addConnection(toAction);
actionContext.getPositionContext().addContext(
new Pair<Integer, Integer>(actionModule.getPosX(),actionModule.getPosY()));
}
toolEnv.addEnvironment(visitedAction.getElem2());
}
env.addEnvironment(toolEnv);
/*
* Get list of external outputs, formats
*/
/*
* Visit the list of external outputs, and link each external output
* To the aliased id.
*/
for(ExternalOutput e : step.getExternalOutputs()){
Pair<Object, LoniEnvironment> le = stepImplVisitor.visit(e, childContext.copy());
LONI.tree.module.Output extOutput = (LONI.tree.module.Output) le.getElem1();
extOutput.setLink(env.getOutputAliases().get(e.getName()));
moduleGroup.getOutputs().add(extOutput);
}
/*
* Create an external input for each of the sinks, link the external input
* to the aliased id, and visit the connection, add connection to environment.
*/
for(String sink : step.getConnectionSinks()){
LONI.tree.module.Parameter extInput = new LONI.tree.module.Parameter();
extInput.setLink(env.getInputAliases().get(sink));
extInput.setId(childContext.getPathContext().getAbsoluteContext(sink));
extInput.setName(sink);
moduleGroup.getInputs().add(extInput);
Pair<Object, LoniEnvironment> le= stepImplVisitor.visit(step.getConnectionSource(sink), sink, childContext.copy());
env.addConnection(((Connection)le.getElem1()));
env.addEnvironment(le.getElem2());
}
return new Pair<GraphObject, LoniEnvironment>(moduleGroup, env);
}
public Pair<GraphObject, LoniEnvironment> visitDataStep(Step step, LoniContext context){
final String ID_PREFIX = "Step";
LoniEnvironment stepEnv = new LoniEnvironment();
LoniContext childContext = context.copy();
DataModule genModule;
//Update the child context to include this path, position
childContext.getPathContext().addContext(ID_PREFIX + step.getId());
childContext.getPositionContext().addContext(new Pair<Integer,Integer>
(step.getPosition().getFromLeft(),
step.getPosition().getFromTop()));
//Set all the parameters for creating the object.
final String id =context.getPathContext().getAbsoluteContext(ID_PREFIX + step.getId());
final String name=step.getName();
final String myPackage = "";
final String version=step.getToolVersion();
final String description = step.getAnnotation();
final int posX=step.getPosition().getFromLeft();
final int posY=step.getPosition().getFromTop();
final int rotation=4;
final String type="File";
final boolean source=true;
final boolean dirSource=false;
final boolean dirDump=false;
final boolean useDirSourceFilters = false;
int dirSourceFilterType = 0;
boolean recursive=false;
Format format = null;
Metadata metadata = null;
genModule = new DataModule(id,name,myPackage, version,
description, posX, posY, rotation, type,
source, dirSource, dirDump,
useDirSourceFilters, dirSourceFilterType,
recursive, metadata);
/*
* Create a loni output connection by creating a galaxy
* data object and visiting it.
*/
Data mydata;
Pair<Object, LoniEnvironment> outputDat;
mydata = new Data("File",context.getPathContext().getAbsoluteContext("output"));
outputDat = (Pair<Object, LoniEnvironment>) GtoLTool.toolImplVisitor.visit(mydata, childContext.copy());
genModule.addOutput((LONI.tree.module.Output)outputDat.getElem1());
stepEnv.addEnvironment(outputDat.getElem2());
//return updated environment and module.
return new Pair(genModule, stepEnv);
}
final String ID_PREFIX = "Step";
{
stepImplVisitor = new StepImplVisitor(){
public Pair<Object, LoniEnvironment> visit(Action action, LoniContext context){
int OFFSET_X = 200;
int OFFSET_Y = 100;
LoniEnvironment actionEnv=new LoniEnvironment();
LoniContext childContext = context.copy();
String actionType= action.getActionType();
String outputName = action.getOutputName();
Map<String,String> args = action.getActionArguments();
Module module = new Module();
module.setId(context.getPathContext().getAbsoluteContext(actionType));
module.setName(actionType);
Pair<Integer, Integer> pos = context.getPositionContext().getAbsoluteContext(
new Pair<Integer, Integer>(OFFSET_X, OFFSET_Y));
module.setPosX(pos.getElem1());
module.setPosY(pos.getElem2());
module.setRotation(4);
module.setLocation("pipeline://localhost//usr/bin/python");
//Set the binary location to the python directory.
/*
String BIN_PATH = context.getGlobalVariableContext().getAbsoluteContext(
new Pair("BINARY_DIR","")
).getElem2();
module.setLocation(context.getGlobalVariableContext().getAbsoluteContext(
new Pair("PYTHON_DIR",BIN_PATH+"python")
).getElem2());
*/
//create a parameter that holds the script location
LONI.tree.module.Parameter cmdparam =new LONI.tree.module.Parameter();
cmdparam.setId(context.getPathContext().getAbsoluteContext(actionType+"Command"));
cmdparam.setName(actionType+"Command");
Format cmdFormat = new Format();
cmdFormat.setCardinality(1);
cmdFormat.setType("String");
cmdparam.setFileFormat(cmdFormat);
cmdparam.setEnabled(true);
cmdparam.setOrder(0);
//set the script location in the command parameter.
String val="dummy.py";
String toolid = context.getToolId();
String dir = GalaxySpecification.getDatabase().getDirectory(toolid);
val = "{GALAXY_DIR}"+dir+ val;
Value value = new Value(null,val);
cmdparam.getValues().addValue(value);
LONI.tree.module.Parameter param =new LONI.tree.module.Parameter();
param.setId(context.getPathContext().getAbsoluteContext(actionType+"Input"));
param.setName(actionType+"Input");
param.setEnabled(true);
param.setRequired(true);
param.setOrder(1);
LONI.tree.module.Output output = new LONI.tree.module.Output();
output.setEnabled(true);
output.setOrder(2);
module.addInput(param);
module.addInput(cmdparam);
module.addOutput(output);
if(actionType.equals("RenameDatasetAction")){
String newname = args.get("newname");
output.setId(context.getPathContext().getAbsoluteContext(newname));
output.setName(newname);
actionEnv.addExternalOutput(action.getOutputName(), output.getId());
}
else if(actionType.equals("ChangeDatatypeAction")){
String newtype = args.get("newtype");
Format outputFormat = new Format();
outputFormat.setCardinality(1);
outputFormat.setType("File");
FileType filetype;
filetype = new FileType(newtype,"",newtype);
outputFormat.getFileTypes().addFileType(filetype);
output.setFormat(outputFormat);
output.setId(context.getPathContext().getAbsoluteContext(newtype));
output.setName(newtype);
actionEnv.addExternalOutput(action.getOutputName(), output.getId());
}
else
module = null;
return new Pair<Object, LoniEnvironment>(module, actionEnv);
}
public Pair<Object, LoniEnvironment> visit(InputConnection source, String sink, LoniContext context){
Connection connection;
LoniContext otherContext= new LoniContext();
otherContext.getPathContext().addContext(ID_PREFIX + source.getSourceId());
connection = new Connection(
otherContext.getPathContext().getAbsoluteContext(source.getSourceName()),
context.getPathContext().getAbsoluteContext(sink));
return new Pair<Object, LoniEnvironment>(connection, new LoniEnvironment());
}
public Pair<Object, LoniEnvironment> visit(ExternalOutput externalOutput, LoniContext context){
/*Internal link*/
LONI.tree.module.Output output = new LONI.tree.module.Output();
LoniEnvironment env = new LoniEnvironment();
output.setId(context.getPathContext().getAbsoluteContext(externalOutput.getName()));
output.setName(externalOutput.getName());
return new Pair<Object, LoniEnvironment>(output, env);
}
};
}
};
}
}