blob: b66991c0d2dae4d2cca19d096972940fe23c6a1e [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.taverna.scufl2.cwl;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
import java.lang.NullPointerException;
import org.yaml.snakeyaml.Yaml;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.taverna.scufl2.api.core.Workflow;
import org.apache.taverna.scufl2.api.core.Processor;
import org.apache.taverna.scufl2.api.core.DataLink;
import org.apache.taverna.scufl2.api.port.InputWorkflowPort;
import org.apache.taverna.scufl2.api.port.OutputWorkflowPort;
import org.apache.taverna.scufl2.api.port.InputProcessorPort;
import org.apache.taverna.scufl2.api.port.OutputProcessorPort;
import org.apache.taverna.scufl2.api.port.SenderPort;
import org.apache.taverna.scufl2.api.port.ReceiverPort;
import org.apache.taverna.scufl2.api.container.WorkflowBundle;
import org.apache.taverna.scufl2.api.io.WorkflowBundleIO;
import org.apache.taverna.scufl2.api.io.WriterException;
public class WorkflowParser {
private static final String FILE_NAME = "/hello_world.cwl";
private CWLParser cwlParser;
private Converter converter = new Converter();
private Map<String, InputWorkflowPort> workflowInputs = new HashMap<>();
private Map<String, OutputWorkflowPort> workflowOutputs = new HashMap<>();
private Map<String, Processor> workflowProcessors = new HashMap<>();
private Map<String, InputProcessorPort> processorInputs = new HashMap<>();
private Map<String, OutputProcessorPort> processorOutputs = new HashMap<>();
private Set<DataLink> dataLinks = new HashSet<DataLink>();
public WorkflowParser() {
Yaml reader = new Yaml();
ObjectMapper mapper = new ObjectMapper();
JsonNode cwlFile = mapper.valueToTree(reader.load(WorkflowParser.class.getResourceAsStream(FILE_NAME)));
this.cwlParser = new CWLParser(cwlFile);
}
public WorkflowParser(JsonNode cwlFile) {
this.cwlParser = new CWLParser(cwlFile);
}
public Workflow buildWorkflow() {
parseInputs();
parseOutputs();
Set<Step> cwlSteps = cwlParser.parseSteps();
parseProcessors(cwlSteps);
parseDataLinks(cwlSteps);
Workflow workflow = new Workflow();
Set<InputWorkflowPort> inputs = new HashSet<>(workflowInputs.values());
Set<OutputWorkflowPort> outputs = new HashSet<>(workflowOutputs.values());
Set<Processor> processors = new HashSet<>(workflowProcessors.values());
workflow.setInputPorts(inputs);
workflow.setOutputPorts(outputs);
workflow.setProcessors(processors);
workflow.setDataLinks(dataLinks);
// writeWorkflowToFile(workflow);
return workflow;
}
public void writeWorkflowToFile(Workflow workflow) {
try {
WorkflowBundleIO io = new WorkflowBundleIO();
File scufl2File = new File("workflow.wfbundle");
WorkflowBundle bundle = io.createBundle();
Set<Workflow> workflowSet = new HashSet<>();
workflowSet.add(workflow);
bundle.setWorkflows(workflowSet);
bundle.setMainWorkflow(workflow);
io.writeBundle(bundle, scufl2File, "application/vnd.taverna.scufl2.workflow-bundle");
} catch(WriterException e) {
System.out.println("Exception writing the workflow bundle");
} catch(IOException e) {
System.out.println("IOException");
}
}
public void parseInputs() {
Set<PortDetail> cwlInputs = cwlParser.parseInputs();
if(cwlInputs != null) {
for (PortDetail port : cwlInputs) {
String portId = port.getId();
InputWorkflowPort workflowPort = converter.convertInputWorkflowPort(port);
workflowInputs.put(portId, workflowPort);
}
}
}
public void parseOutputs() {
Set<PortDetail> cwlOutputs = cwlParser.parseOutputs();
for(PortDetail port: cwlOutputs) {
String portId = port.getId();
OutputWorkflowPort workflowPort = converter.convertOutputWorkflowPort(port);
workflowOutputs.put(portId, workflowPort);
}
}
public void parseProcessors(Set<Step> cwlSteps) {
for(Step step: cwlSteps) {
Processor processor = converter.convertStepToProcessor(step);
workflowProcessors.put(step.getId(), processor);
for(StepInput stepInput: step.getInputs()) {
InputProcessorPort processorPort = new InputProcessorPort(processor, stepInput.getId());
processorInputs.put(stepInput.getId(), processorPort);
}
for(StepOutput stepOutput: step.getOutputs()) {
OutputProcessorPort processorPort = new OutputProcessorPort(processor, stepOutput.getId());
processorOutputs.put(stepOutput.getId(), processorPort);
}
}
}
public void parseDataLinks(Set<Step> cwlSteps) {
for(Step step: cwlSteps) {
for(StepInput stepInput: step.getInputs()) {
String[] sourcePath = stepInput.getSource().split("/");
String source = sourcePath[sourcePath.length-1];
source = source.replace("#", "");
DataLink dataLink = new DataLink();
SenderPort sender = workflowInputs.get(source);
if(sender == null) {
sender = processorOutputs.get(source);
}
if(sender == null) {
throw new NullPointerException("Cannot find sender port with name: " + source);
}
String receiverId = stepInput.getId();
ReceiverPort receiver = workflowOutputs.get(receiverId);
if(receiver == null) {
receiver = processorInputs.get(receiverId);
}
if(receiver == null) {
throw new NullPointerException("Cannot find receiver port with name: " + receiverId);
}
dataLink.setSendsTo(receiver);
dataLink.setReceivesFrom(sender);
dataLinks.add(dataLink);
}
}
}
public Map<String, InputWorkflowPort> getWorkflowInputs() {
return workflowInputs;
}
public void setWorkflowInputs(Map<String, InputWorkflowPort> workflowInputs) {
this.workflowInputs = workflowInputs;
}
public Map<String, OutputWorkflowPort> getWorkflowOutputs() {
return workflowOutputs;
}
public void setWorkflowOutputs(Map<String, OutputWorkflowPort> workflowOutputs) {
this.workflowOutputs = workflowOutputs;
}
public Map<String, Processor> getWorkflowProcessors() {
return workflowProcessors;
}
public void setWorkflowProcessors(Map<String, Processor> workflowProcessors) {
this.workflowProcessors = workflowProcessors;
}
public Map<String, InputProcessorPort> getProcessorInputs() {
return processorInputs;
}
public void setProcessorInputs(Map<String, InputProcessorPort> processorInputs) {
this.processorInputs = processorInputs;
}
public Map<String, OutputProcessorPort> getProcessorOutputs() {
return processorOutputs;
}
public void setProcessorOutputs(Map<String, OutputProcessorPort> processorOutputs) {
this.processorOutputs = processorOutputs;
}
public Set<DataLink> getDataLinks() {
return dataLinks;
}
public void setDataLinks(Set<DataLink> dataLinks) {
this.dataLinks = dataLinks;
}
}