Package LONI.visitor

Source Code of LONI.visitor.LoniToTavernaConverter

package LONI.visitor;

import java.util.ArrayList;
import java.util.UUID;
import java.util.List;

import org.apache.commons.lang3.StringEscapeUtils;

import Core.Pair;
import LONI.tree.*;
import LONI.tree.GraphObject.DataModule;
import LONI.tree.GraphObject.GraphObject;
import LONI.tree.GraphObject.Module;
import LONI.tree.GraphObject.ModuleGroup;
import LONI.tree.module.Output;
import LONI.tree.module.Parameter;
import LONI.tree.module.Value;
import LONI.tree.module.Values;
import LONI.tree.workflow.Connection;
import LONI.tree.workflow.Connections;
import LONI.tree.workflow.Pipeline;
import Taverna.Tree.Annotation.*;
import Taverna.Tree.Annotation.Annotations;
import Taverna.Tree.DataFlowImpl.AnnotatedGranularDepthInputPorts;
import Taverna.Tree.DataFlowImpl.AnnotatedGranularDepthOutputPorts;
import Taverna.Tree.DataFlowImpl.AnnotatedGranularDepthPort;
import Taverna.Tree.DataFlowImpl.AnnotatedGranularDepthInputPorts;
import Taverna.Tree.DataFlowImpl.AnnotatedGranularDepthOutputPorts;
import Taverna.Tree.DataFlowImpl.AnnotatedPort;
import Taverna.Tree.DataFlowImpl.AnnotatedPorts;
import Taverna.Tree.DataFlowImpl.DataLink;
import Taverna.Tree.DataFlowImpl.Dataflow;
import Taverna.Tree.DataFlowImpl.Datalinks;
import Taverna.Tree.DataFlowImpl.DepthPort;
import Taverna.Tree.DataFlowImpl.GranularDepthPort;
import Taverna.Tree.DataFlowImpl.Link;
import Taverna.Tree.DataFlowImpl.PortProduct;
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.InputPorts;
import Taverna.Tree.Processor.LocalWorkerActivityConfigurationBean;
import Taverna.Tree.Processor.Mapping;
import Taverna.Tree.Processor.MimeTypes;
import Taverna.Tree.Processor.Null;
import Taverna.Tree.Processor.ParallelizeConfig;
import Taverna.Tree.Processor.Processor;
import Taverna.Tree.Processor.Processors;
import Taverna.Tree.Processor.RetryConfig;
import Taverna.Tree.Processor.lWACBInputs;
import Taverna.Tree.Processor.lWACBOutputs;
import Taverna.Tree.Conditions;
import Taverna.Tree.Cross;
import Taverna.Tree.DispatchLayer;
import Taverna.Tree.DispatchStack;
import Taverna.Tree.Iteration;
import Taverna.Tree.IterationNode;
import Taverna.Tree.IterationStrategyStack;
import Taverna.Tree.Raven;
import Taverna.Tree.TavMap;
import Taverna.Tree.Workflow;

public class LoniToTavernaConverter extends DFSVisitor {

  /**
   * Converts a Loni Pipeline Workflow into corresponding Taverna Workflow object.
   */
  public Object visit(Pipeline pipeline){
    this.pipeline = pipeline;
    Workflow workflow;
    String producedBy="taverna-2.3.0";
    String version = "1";    //Taverna wouldn't open the file with the version less than 1
    String xmlns="http://taverna.sf.net/2008/xml/t2flow";
   
    Dataflow dataflow = (Dataflow) visit(pipeline.getPipelineModuleGroup());
    workflow = new Workflow( dataflow,  producedBy,  version,  xmlns);
    this.workflow = workflow;
    return workflow;

  }

  /**
   * Visits Loni Pipeline ModuleGroup and converts into corresponding Taverna Dataflow object.
   */
  public Object visit(ModuleGroup moduleGroup){
    this.moduleGroup = moduleGroup;
    Dataflow dataflow;
   
    // Initialize parameters to construct Dataflow object
    String name = moduleGroup.getName();
    AnnotatedGranularDepthInputPorts inputPorts = new AnnotatedGranularDepthInputPorts();
    AnnotatedGranularDepthOutputPorts outputPorts = new AnnotatedGranularDepthOutputPorts();
    Processors processors = new Processors();
    Conditions conditions = new Conditions();
    Datalinks datalinks = (Datalinks) visit(pipeline.getConnections());
    Annotations annotations = new Annotations();
    String id = UUID.randomUUID().toString();
    String role = "top";
   
    dataflow = new Dataflow(name, inputPorts, outputPorts, processors, conditions, datalinks, annotations, id, role);
    this.dataflow = dataflow; // set environment variable for visitor
   
    // Add Title and Description
    annotations.addAnnotationChain("DescriptiveTitle", moduleGroup.getName(), null);
    annotations.addAnnotationChain("FreeTextDescription", moduleGroup.getDescription(), null);
   
    // Add Authors
    List<Author> authors = moduleGroup.getAuthors().getAuthors();
    for(Author author : authors)
    {
      String authorText = author.getFullName() + " Email: " + author.getEmail() + " Website: " + author.getWebsite();
      annotations.addAnnotationChain("Author", authorText, null);
    }
   
    // Add Modules/Graph Objects
    for(GraphObject module : moduleGroup.getModules())
    {
      moduleVisitor.visit(module, null);
    }
    return dataflow; 
  }
 
  /**
   * Visits Connections in Loni Pipeline xml file to create corresponding Datalinks in Taverna.
   */
    public Object visit(Connections connections){
      Datalinks datalinks = new Datalinks();
     
      // For each connection in between modules, create a corresponding Datalink for Taverna workflow.
      for (Connection c : connections.getConnections())
      {
          Link src = null;
          Link snk = null;
        String source[] = c.getSource().split("\\.");
        for(GraphObject module : moduleGroup.getModules())
        {
          if(source[0].equals(module.getId())){
            src = module.getSource(source[1]);
          }
        }
        String sink[] = c.getSink().split("\\.");
        for(GraphObject module : moduleGroup.getModules())
        {
          if(sink[0].equals(module.getId())){
            snk = module.getSink(sink[1]);
          }
        }
        DataLink datalink = new DataLink(snk, src);
        datalinks.addDataLink(datalink);
      }
      return datalinks;
    }

    /*
     *  Visitor for different modules in Loni Pipeline. Currently only DataModules and
     *  Modules (executable modules) are supported. In order to extend the converter to
     *  handle more types of modules, add a new method to ModuleVisitor as such:
     *  public Pair<Object, Object> visit(<moduleType> module, Object o);
     */
  {
        moduleVisitor = new ModuleVisitor(){
          // Visit DataModule to create data sources/sinks
        public Pair<Object, Object> visit(DataModule dataModule, Object o){
          String name = dataModule.getId();
          String description = dataModule.getDescription();
          String value = " Input/Output file(s) can be found at: ";
          Values values = dataModule.getValues();
          if(values != null){
              for(Value v : values.getValues())
                value += v.getValue();
          }
          description += value;
         
          Annotations annotations = new Annotations();
          annotations.addAnnotationChain("FreeTextDescription", description, null);

          // DataModule is data source
          if(dataModule.getInputs() == null)
          {
            AnnotatedGranularDepthPort port = new AnnotatedGranularDepthPort(name, 0, 0);
            port.setAnnotations(annotations);
            dataflow.getInputPorts().addPorts(port)
          }
         
          // DataModule is data sink
          else if(dataModule.getOutputs() == null)
          {
            AnnotatedGranularDepthPort port = new AnnotatedGranularDepthPort(name, 0,0);
            port.setAnnotations(annotations);
            dataflow.getOutputPorts().addPorts(port);
          }
          return null;
        }
       
        // Visit [executable] Module to create Processors
        public Pair<Object, Object> visit(Module module, Object o){
          String name = module.getId();
          String location = module.getLocation();
          String description = "Location of executable: " + location + ". When prompted to input data values, enter this path for the command input.";
         
          Processor processor = new Processor(null, null, null, name);
         
          // Create annotations
          Annotations annotations = new Annotations();
          annotations.addAnnotationChain("FreeTextDescription", description, null);
         
          // Add inputs/outputs
          int depth = 0;
          for(Parameter p : module.getInputs())
          {
            depth++;
          }
          processor.getInputPorts().addPorts(new AnnotatedGranularDepthPort("args", depth-1, 0));

          processor.getOutputPorts().addPorts(new AnnotatedGranularDepthPort("result", 0, 0));
         
          /*
           * Next few steps are procedural steps to create a predefined
           * type of module in Taverna that allows the user to run an
           * executable command line app on data, effectively emulating
           * executable modules in Loni Pipeline.
           */
         
          // Add activities
          Raven raven = new Raven("net.sf.taverna.t2.activities", "localworker-activity", "1.3");
         
          Mapping input1 = new Mapping("args", "args");
          Mapping input2 = new Mapping("command", "command");
          TavMap inputMap = new TavMap();
          inputMap.addMapping(input1);
          inputMap.addMapping(input2);
         
          Mapping output = new Mapping("result", "result");
          TavMap outputMap = new TavMap();
          outputMap.addMapping(output);
         
          lWACBInputs lWACBIn = new lWACBInputs();
          MimeTypes m1 = new MimeTypes("'text/plain'");
          lWACBIn.addInput(new ActivityInputPortDefinitionBean("command", "0", m1, "", "java.lang.String", "true", null));
          MimeTypes m2 = new MimeTypes("l('text/plain')");
          lWACBIn.addInput(new ActivityInputPortDefinitionBean("args", "1", m2, "", "java.lang.String", "true", null));
         
          lWACBOutputs lWACBOut = new lWACBOutputs();
          MimeTypes m3 = new MimeTypes("'text/plain'");
          lWACBOut.addOutput(new ActivityOutputPortDefinitionBean("result", "0", m3, null, null, null, "0"));
         
          String script = StringEscapeUtils.unescapeXml("if (command == void || command.equals(\"\")) {\r\n\tthrow new RuntimeException(\"The 'command' port cannot be null.\");\r\n}\r\nProcess proc = null;\r\nRuntime rt = Runtime.getRuntime();\r\n\r\nString osName = System.getProperty(\"os.name\");\r\nString[] cmdArray = null;\r\nif (osName.equals(\"Windows NT\") || osName.equals(\"Windows XP\")) {\r\n\tcmdArray = new String[] { \"cmd.exe\", \"/c\", command };\r\n} else if (osName.equals(\"Windows 95\")) {\r\n\tcmdArray = new String[] { \"command.exe\", \"/c\", command };\r\n} else {// TODO: investigate if this will work in Linux and OSX\r\n\tcmdArray = new String[] { command };\r\n}\r\n\r\n// concatenate the arrays\r\nif ((args == void) || (args == null)) {\r\n\targs = new ArrayList();\r\n}\r\n\r\nint argSize = cmdArray.length + args.size();\r\nArrayList appArray = new ArrayList(argSize);\r\nfor (int i = 0; i &lt; cmdArray.length; i++) {\r\n\tappArray.add(cmdArray[i]);\r\n}\r\n\r\nfor (int i = 0; i &lt; args.size(); i++) {\r\n\tappArray.add(args.get(i));\r\n}\r\n\r\nString[] applist = new String[argSize];\r\nappArray.toArray(applist);\r\nproc = rt.exec(applist);\r\n\r\n// Get the input stream and read from it\r\nInputStream in = proc.getInputStream();\r\n\r\nint c;\r\nStringBuffer sb = new StringBuffer();\r\nwhile ((c = in.read()) != -1) {\r\n\tsb.append((char) c);\r\n}\r\nin.close();\r\nresult = sb.toString();\r\n");
          LocalWorkerActivityConfigurationBean lwacb = new LocalWorkerActivityConfigurationBean("", lWACBIn, lWACBOut, "workflow", null, null, script, null, "net.sourceforge.taverna.scuflworkers.io.LocalCommand");
          ConfigBean configBean = new ConfigBean("xstream", lwacb, null, null, null);
         
          Activity activity = new Activity(raven, "net.sf.taverna.t2.activities.localworker.LocalworkerActivity", inputMap, outputMap, configBean);
          Activities activities = new Activities();
          activities.addActivity(activity);
          processor.setActivities(activities);
         
          // Add Dispatch Stack
          DispatchStack ds = new DispatchStack();
          Raven dispatchRaven = new Raven("net.sf.taverna.t2.core", "workflowmodel-impl", "1.3");
          DispatchLayer layer1 = new DispatchLayer(dispatchRaven, "net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Parallelize", new ConfigBean("xstream", null, new ParallelizeConfig("", "1"), null, null));
          DispatchLayer layer2 = new DispatchLayer(dispatchRaven, "net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.ErrorBounce", new ConfigBean("xstream", null, null, new Null(""), null));
          DispatchLayer layer3 = new DispatchLayer(dispatchRaven, "net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Failover", new ConfigBean("xstream", null, null, new Null(""), null));
          DispatchLayer layer4 = new DispatchLayer(dispatchRaven, "net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Retry", new ConfigBean("xstream", null, null, null, new RetryConfig("", "1.0", "1000", "5000", "0")));
          DispatchLayer layer5 = new DispatchLayer(dispatchRaven, "net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Invoke", new ConfigBean("xstream", null, null, new Null(""), null));
          ds.addDispatchLayer(layer1);
          ds.addDispatchLayer(layer2);
          ds.addDispatchLayer(layer3);
          ds.addDispatchLayer(layer4);
          ds.addDispatchLayer(layer5);
          processor.setDispatchStack(ds);
         
          // Add Iteration Strategy Stack
          IterationStrategyStack iss = new IterationStrategyStack();
         
          IterationNode in = new IterationNode();
          in.setCross(new Cross());
          in.getCross().addPort(new PortProduct("args", 1));
          in.getCross().addPort(new PortProduct("command", 0));
         
          Iteration i = new Iteration();
          i.addStrategy(in);
         
          iss.addIteration(i);
          processor.setIterationStrategyStack(iss);
         
          // Add processor to Processors
          dataflow.getProcessors().addProcessor(processor);
         
          // Create Data Input with command-line app
          AnnotatedGranularDepthPort command = new AnnotatedGranularDepthPort("Command: " + processor.getProcessorName(), 0, 0);
          command.setAnnotations(annotations);
          dataflow.getInputPorts().addPorts(command);
          processor.getInputPorts().addPorts(new AnnotatedGranularDepthPort("command", 0, 0));
         
         
          // Create connection from command-line app to processor
          Link snk = new Link("processor", name, "command");
          Link src = new Link("dataflow", null, "Command: " + processor.getProcessorName());
          DataLink datalink = new DataLink(snk, src);
          dataflow.getDatalinks().addDataLink(datalink);
         
          return null;
        }
        };
       

  }
 
  // Environment variables
  Workflow workflow;
  Dataflow dataflow;
  Pipeline pipeline;
  ModuleGroup moduleGroup;
}
TOP

Related Classes of LONI.visitor.LoniToTavernaConverter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.