You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@taverna.apache.org by st...@apache.org on 2018/07/16 09:22:28 UTC
[1/2] incubator-taverna-language git commit: Merge branch
'haouech:convert' into cwlparser
Repository: incubator-taverna-language
Updated Branches:
refs/heads/cwlparser 48f7dd9f7 -> afcfd77c5
Merge branch 'haouech:convert' into cwlparser
Contributed by Majdi Haouech, CLA on file.
This closes #40
ts
Project: http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/commit/88c14c4a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/tree/88c14c4a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/diff/88c14c4a
Branch: refs/heads/cwlparser
Commit: 88c14c4a9112980330e99886b963184da20cd1bf
Parents: 48f7dd9
Author: Stian Soiland-Reyes <st...@apache.org>
Authored: Mon Jul 16 10:15:28 2018 +0100
Committer: Stian Soiland-Reyes <st...@apache.org>
Committed: Mon Jul 16 10:15:28 2018 +0100
----------------------------------------------------------------------
taverna-scufl2-cwl/pom.xml | 6 +
.../apache/taverna/scufl2/cwl/CWLParser.java | 13 +-
.../apache/taverna/scufl2/cwl/Converter.java | 91 +++++++-
.../org/apache/taverna/scufl2/cwl/Main.java | 58 +++++
.../taverna/scufl2/cwl/WorkflowParser.java | 8 +-
.../apache/taverna/scufl2/cwl/YAMLHelper.java | 64 +++---
.../scufl2/cwl/components/CommandLineTool.java | 78 +++++++
.../taverna/scufl2/cwl/components/Main.java | 0
.../taverna/scufl2/cwl/components/Process.java | 33 +++
.../scufl2/cwl/components/ProcessFactory.java | 65 ++++++
.../scufl2/cwl/components/Reference.java | 43 ++++
.../taverna/scufl2/cwl/components/Step.java | 6 +-
.../scufl2/cwl/components/WorkflowProcess.java | 230 +++++++++++++++++++
.../src/main/resources/hello_world.cwl | 37 +++
.../main/resources/workflow_with_command.cwl | 45 ++++
.../apache/taverna/scufl2/cwl/TestParser.java | 9 -
.../taverna/scufl2/cwl/TestWorkflowProcess.java | 99 ++++++++
.../src/test/resources/hello_world.cwl | 3 +-
18 files changed, 836 insertions(+), 52 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/88c14c4a/taverna-scufl2-cwl/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-scufl2-cwl/pom.xml b/taverna-scufl2-cwl/pom.xml
index 3b11dff..0f76ffd 100644
--- a/taverna-scufl2-cwl/pom.xml
+++ b/taverna-scufl2-cwl/pom.xml
@@ -48,6 +48,12 @@
</dependency>
<dependency>
+ <groupId>com.fasterxml.jackson.dataformat</groupId>
+ <artifactId>jackson-dataformat-yaml</artifactId>
+ <version>${jackson.version}</version>
+ </dependency>
+
+ <dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.17</version>
http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/88c14c4a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/CWLParser.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/CWLParser.java b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/CWLParser.java
index 5a4d6cf..382208d 100644
--- a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/CWLParser.java
+++ b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/CWLParser.java
@@ -51,7 +51,7 @@ public class CWLParser {
Map<String, Integer> inputDepths = yamlHelper.processInputDepths(cwlFile);
if(inputs == null || inputDepths == null) {
- return null;
+ return new HashSet<PortDetail>();
}
Set<PortDetail> result = new HashSet<PortDetail>();
for(String id: inputs.keySet()) {
@@ -66,14 +66,15 @@ public class CWLParser {
}
public Set<PortDetail> parseOutputs() {
- Map<String, PortDetail> inputs = yamlHelper.processOutputDetails(cwlFile);
+ Map<String, PortDetail> outputs = yamlHelper.processOutputDetails(cwlFile);
- if(inputs == null) {
- return null;
+ if(outputs == null) {
+ return new HashSet<PortDetail>();
}
Set<PortDetail> result = new HashSet<PortDetail>();
- for(String id: inputs.keySet()) {
- PortDetail port = inputs.get(id);
+ for(String id: outputs.keySet()) {
+ PortDetail port = outputs.get(id);
+ port.setId(id);
result.add(port);
}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/88c14c4a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/Converter.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/Converter.java b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/Converter.java
index 7ddf9de..eff7ef6 100644
--- a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/Converter.java
+++ b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/Converter.java
@@ -20,6 +20,8 @@ package org.apache.taverna.scufl2.cwl;
import java.util.Set;
import java.util.HashSet;
+import java.util.Map;
+import java.util.HashMap;
import org.apache.taverna.scufl2.api.core.Workflow;
import org.apache.taverna.scufl2.api.core.Processor;
@@ -30,11 +32,15 @@ import org.apache.taverna.scufl2.api.port.InputProcessorPort;
import org.apache.taverna.scufl2.api.port.OutputProcessorPort;
import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
public class Converter {
+ private JsonNodeFactory jsonNodeFactory;
public Converter() {
-
+ jsonNodeFactory = JsonNodeFactory.instance;
}
public InputWorkflowPort convertInputWorkflowPort(PortDetail input) {
@@ -73,4 +79,87 @@ public class Converter {
return processor;
}
+
+ public JsonNode convertWorkflowProcessToJsonNode(WorkflowProcess workflow) {
+ Map<String, Processor> workflowProcessors = workflow.getWorkflowProcessors();
+ Map<String, InputProcessorPort> processorInputs = workflow.getProcessorInputs();
+ Map<String, OutputProcessorPort> processorOutputs = workflow.getProcessorOutputs();
+
+ ObjectNode result = jsonNodeFactory.objectNode();
+ ObjectNode inputs = convertInputWorkflows(workflow.getWorkflowInputs());
+ ObjectNode outputs = convertOutputWorkflows(workflow.getWorkflowOutputs());
+ ObjectNode steps = convertProcessors(workflow);
+ result.put("inputs", inputs);
+ result.put("outputs", outputs);
+ result.put("steps", steps);
+
+ return result;
+ }
+
+ private ObjectNode convertInputWorkflows(Map<String, InputWorkflowPort> workflowInputs) {
+ ObjectNode node = jsonNodeFactory.objectNode();
+ for(Map.Entry<String, InputWorkflowPort> entry: workflowInputs.entrySet()) {
+ String name = entry.getKey();
+ node.put(name, "string"); // TODO: Put the correct input type and not just string
+ }
+
+ return node;
+ }
+
+ private ObjectNode convertOutputWorkflows(Map<String, OutputWorkflowPort> workflowOutputs) {
+ ObjectNode node = jsonNodeFactory.objectNode();
+ for(Map.Entry<String, OutputWorkflowPort> entry: workflowOutputs.entrySet()) {
+ String name = entry.getKey();
+ node.put(name, "string"); // TODO: Put the correct input type and not just string
+ }
+
+ return node;
+ }
+
+ private ObjectNode convertProcessors(WorkflowProcess workflow) {
+ ObjectNode node = jsonNodeFactory.objectNode();
+ Map<String, Processor> processors = workflow.getWorkflowProcessors();
+
+ for(Map.Entry<String, Processor> entry: processors.entrySet()) {
+ Processor processor = entry.getValue();
+ ObjectNode step = jsonNodeFactory.objectNode();
+ ArrayNode inputs = jsonNodeFactory.arrayNode();
+ ArrayNode outputs = jsonNodeFactory.arrayNode();
+ for(InputProcessorPort port: processor.getInputPorts()) {
+ ObjectNode input = jsonNodeFactory.objectNode();
+ input.put(port.getName(), "string");
+ input.put("source", "");
+ inputs.add(input);
+ }
+ for(OutputProcessorPort port: processor.getOutputPorts()) {
+ ObjectNode output = jsonNodeFactory.objectNode();
+ output.put(port.getName(), "string");
+ outputs.add(output);
+ }
+ step.put("run", "NotImplemented");
+ step.put("inputs", inputs);
+ step.put("outputs", outputs);
+ node.put(processor.getName(), step);
+ }
+
+ return node;
+ }
+
+ public PortDetail convertToPortDetail(InputWorkflowPort inPort) {
+ int depth = inPort.getDepth();
+ String id = inPort.getName();
+ PortDetail port = new PortDetail();
+ port.setId(id);
+ port.setDepth(depth);
+
+ return port;
+ }
+
+ public PortDetail convertToPortDetail(OutputWorkflowPort outPort) {
+ String id = outPort.getName();
+ PortDetail port = new PortDetail();
+ port.setId(id);
+
+ return port;
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/88c14c4a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/Main.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/Main.java b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/Main.java
new file mode 100644
index 0000000..e5f7159
--- /dev/null
+++ b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/Main.java
@@ -0,0 +1,58 @@
+/*
+ * 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 org.yaml.snakeyaml.Yaml;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+
+public class Main {
+
+ private static final String HELLO_WORLD_CWL = "/hello_world.cwl";
+ private static final String WORKFLOW_WITH_COMMAND = "/workflow_with_command.cwl";
+ private static JsonNode cwlFile;
+
+ public static void main(String[] args) {
+
+ Yaml reader = new Yaml();
+ ObjectMapper mapper = new ObjectMapper();
+ cwlFile = mapper.valueToTree(reader.load(Main.class.getResourceAsStream(WORKFLOW_WITH_COMMAND)));
+ System.out.println(cwlFile);
+
+ Process workflow = ProcessFactory.createProcess(cwlFile);
+ workflow.parse();
+ Converter converter = new Converter();
+ JsonNode node = converter.convertWorkflowProcessToJsonNode((WorkflowProcess) workflow);
+ printAsYaml(node);
+ }
+
+ private static void printAsYaml(JsonNode node) {
+ try {
+ String yaml = new YAMLMapper().writeValueAsString(node);
+ System.out.println("YAML DATA");
+ System.out.println(yaml);
+ } catch (JsonProcessingException e) {
+ System.err.println("Error writing JsonNode to YAML");
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/88c14c4a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/WorkflowParser.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/WorkflowParser.java b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/WorkflowParser.java
index 0b6c095..b18dc54 100644
--- a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/WorkflowParser.java
+++ b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/WorkflowParser.java
@@ -43,6 +43,7 @@ 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;
@@ -67,6 +68,12 @@ public class WorkflowParser {
JsonNode cwlFile = mapper.valueToTree(reader.load(WorkflowParser.class.getResourceAsStream(FILE_NAME)));
this.cwlParser = new CWLParser(cwlFile);
this.converter = new Converter();
+ workflowInputs = new HashMap<>();
+ workflowOutputs = new HashMap<>();
+ workflowProcessors = new HashMap<>();
+ processorInputs = new HashMap<>();
+ processorOutputs = new HashMap<>();
+ dataLinks = new HashSet<DataLink>();
}
public WorkflowParser(JsonNode cwlFile) {
@@ -144,7 +151,6 @@ public class WorkflowParser {
Processor processor = converter.convertStepToProcessor(step);
workflowProcessors.put(step.getId(), processor);
- DataLink datalink = new DataLink();
for(StepInput stepInput: step.getInputs()) {
InputProcessorPort processorPort = new InputProcessorPort(processor, stepInput.getId());
processorInputs.put(stepInput.getId(), processorPort);
http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/88c14c4a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/YAMLHelper.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/YAMLHelper.java b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/YAMLHelper.java
index dacdc4f..c9b10dc 100644
--- a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/YAMLHelper.java
+++ b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/YAMLHelper.java
@@ -108,42 +108,44 @@ public class YAMLHelper {
public Set<Step> processSteps(JsonNode file) {
Set<Step> result = new HashSet<>();
- if(file == null) {
+ if(file == null || !file.has(STEPS)) {
return result;
}
- if(file.has(STEPS)) {
- JsonNode steps = file.get(STEPS);
- if(steps.isArray()) {
- for (JsonNode stepNode : steps) {
- Step step = new Step();
- String id = stepNode.get(ID).asText();
+ JsonNode steps = file.get(STEPS);
+ if(steps.isArray()) {
+ for (JsonNode stepNode : steps) {
+ Step step = new Step();
+ String id = stepNode.get(ID).asText();
+
+ JsonNode runNode = stepNode.get(RUN);
+ Process run = ProcessFactory.createProcess(runNode);
+ run.parse(); // Recursively parse nested process
+ Set<StepInput> inputs = processStepInput(stepNode.get(INPUTS));
+ step.setId(id);
+ step.setRun(run);
+ step.setInputs(inputs);
+ result.add(step);
+ }
+ } else if(steps.isObject()) {
+ Iterator<Entry<String, JsonNode>> iterator = steps.fields();
+ while(iterator.hasNext()) {
+ Entry<String, JsonNode> entry = iterator.next();
+ Step step = new Step();
- String run = stepNode.get(RUN).asText();
- Set<StepInput> inputs = processStepInput(stepNode.get(INPUTS));
- step.setId(id);
+ String id = entry.getKey();
+ JsonNode value = entry.getValue();
+ if(value.has(RUN)) {
+ JsonNode runNode = value.get(RUN);
+ Process run = ProcessFactory.createProcess(runNode);
+ run.parse();
step.setRun(run);
- step.setInputs(inputs);
- result.add(step);
}
- } else if(steps.isObject()) {
- Iterator<Entry<String, JsonNode>> iterator = steps.fields();
- while(iterator.hasNext()) {
- Entry<String, JsonNode> entry = iterator.next();
- Step step = new Step();
-
- String id = entry.getKey();
- JsonNode value = entry.getValue();
- if(value.has(RUN)) {
- String run = entry.getValue().get(RUN).asText();
- step.setRun(run);
- }
- Set<StepInput> inputs = processStepInput(value.get(INPUTS));
- step.setId(id);
- step.setInputs(inputs);
+ Set<StepInput> inputs = processStepInput(value.get(INPUTS));
+ step.setId(id);
+ step.setInputs(inputs);
- result.add(step);
- }
+ result.add(step);
}
}
@@ -156,7 +158,7 @@ public class YAMLHelper {
if(inputs == null) {
return result;
}
- if (inputs.getClass() == ArrayNode.class) {
+ if (inputs.isArray()) {
for (JsonNode input : inputs) {
String id = input.get(ID).asText();
@@ -164,7 +166,7 @@ public class YAMLHelper {
result.add(new StepInput(id, source));
}
- } else if (inputs.getClass() == ObjectNode.class) {
+ } else if (inputs.isObject()) {
Iterator<Entry<String, JsonNode>> iterator = inputs.fields();
while (iterator.hasNext()) {
Entry<String, JsonNode> entry = iterator.next();
http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/88c14c4a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/CommandLineTool.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/CommandLineTool.java b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/CommandLineTool.java
new file mode 100644
index 0000000..450304a
--- /dev/null
+++ b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/CommandLineTool.java
@@ -0,0 +1,78 @@
+/*
+ * 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.util.Set;
+import java.util.Map;
+import java.util.HashMap;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import org.apache.taverna.scufl2.api.port.InputProcessorPort;
+import org.apache.taverna.scufl2.api.port.OutputProcessorPort;
+
+public class CommandLineTool implements Process {
+
+ private final static String BASE_COMMAND = "baseCommand";
+ private final static String ID = "id";
+ private final static String INPUT_BINDINDGS = "inputBinding";
+
+ private CWLParser cwlParser;
+
+ private JsonNode node;
+
+ private String baseCommand = null;
+ private Map<String, InputProcessorPort> processorInputs;
+ private Map<String, OutputProcessorPort> processorOutputs;
+
+ public CommandLineTool(JsonNode node) {
+ this.node = node;
+ this.cwlParser = new CWLParser(node);
+ this.processorInputs = new HashMap<>();
+ this.processorOutputs = new HashMap<>();
+ this.parse();
+ }
+
+ public void parse() {
+ baseCommand = node.get(BASE_COMMAND).asText();
+ parseInputs();
+ parseOutputs();
+ }
+
+ public void parseInputs() {
+ Set<PortDetail> cwlInputs = cwlParser.parseInputs();
+ for(PortDetail detail: cwlInputs) {
+ String portId = detail.getId();
+ InputProcessorPort port = new InputProcessorPort();
+ port.setName(portId);
+ processorInputs.put(portId, port);
+ }
+ }
+
+ public void parseOutputs() {
+ Set<PortDetail> cwlOutputs = cwlParser.parseOutputs();
+ for(PortDetail detail: cwlOutputs) {
+ String portId = detail.getId();
+ OutputProcessorPort port = new OutputProcessorPort();
+ port.setName(portId);
+ processorOutputs.put(portId, port);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/88c14c4a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/Main.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/Main.java b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/Main.java
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/88c14c4a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/Process.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/Process.java b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/Process.java
new file mode 100644
index 0000000..70e3669
--- /dev/null
+++ b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/Process.java
@@ -0,0 +1,33 @@
+/*
+ * 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.util.Map;
+import java.util.HashMap;
+import java.util.Set;
+import java.util.HashSet;
+import org.apache.taverna.scufl2.api.port.SenderPort;
+import org.apache.taverna.scufl2.api.port.ReceiverPort;
+
+public interface Process {
+
+ public void parse();
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/88c14c4a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/ProcessFactory.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/ProcessFactory.java b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/ProcessFactory.java
new file mode 100644
index 0000000..301d417
--- /dev/null
+++ b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/ProcessFactory.java
@@ -0,0 +1,65 @@
+/*
+ * 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 com.fasterxml.jackson.databind.JsonNode;
+
+public class ProcessFactory {
+
+ private final static String RUN = "run";
+ private final static String CLASS = "class";
+
+ public static Process createProcess(JsonNode node) {
+
+ Process process = null;
+
+ if(node.isValueNode()) {
+ return new Reference(node.asText());
+ }
+
+ JsonNode className = node.get(CLASS);
+ if(className != null) {
+ if(className.asText().equals("Workflow")) {
+ process = new WorkflowProcess(node);
+ } else if(className.asText().equals("CommandLineTool")) {
+ process = new CommandLineTool(node);
+ }
+ } else {
+ JsonNode runNode = node.get(RUN);
+ if(runNode.isValueNode()) {
+ process = new Reference(runNode.asText());
+ } else {
+ String runClass = runNode.get(CLASS).asText();
+ switch(runClass) {
+ case "CommandLineTool":
+ process = new CommandLineTool(runNode);
+ break;
+ case "Workflow":
+ process = new WorkflowProcess(runNode);
+ break;
+ }
+ }
+ }
+
+
+ return process;
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/88c14c4a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/Reference.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/Reference.java b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/Reference.java
new file mode 100644
index 0000000..7a25744
--- /dev/null
+++ b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/Reference.java
@@ -0,0 +1,43 @@
+/*
+ * 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 com.fasterxml.jackson.databind.JsonNode;
+
+public class Reference implements Process {
+
+ private String source;
+
+ public Reference() {
+ source = "";
+ }
+
+ public Reference(String src) {
+ this.source = src;
+ }
+
+ public void parse() {
+ // TODO: read source file and parse nested workflow
+ }
+
+ public String toString() {
+ return source;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/88c14c4a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/Step.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/Step.java b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/Step.java
index 3f3d653..cdcd46e 100644
--- a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/Step.java
+++ b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/Step.java
@@ -28,7 +28,7 @@ public class Step {
private String id;
- private String run;
+ private Process run;
private Set<StepInput> inputs;
private Set<StepOutput> outputs;
@@ -46,11 +46,11 @@ public class Step {
this.id = id;
}
- public String getRun() {
+ public Process getRun() {
return run;
}
- public void setRun(String run) {
+ public void setRun(Process run) {
this.run = run;
}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/88c14c4a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/WorkflowProcess.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/WorkflowProcess.java b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/WorkflowProcess.java
new file mode 100644
index 0000000..b41d054
--- /dev/null
+++ b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/WorkflowProcess.java
@@ -0,0 +1,230 @@
+/*
+ * 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.Set;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.HashMap;
+
+
+import org.apache.taverna.scufl2.api.core.Processor;
+import org.apache.taverna.scufl2.api.core.DataLink;
+import org.apache.taverna.scufl2.api.core.Workflow;
+
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+
+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.io.WorkflowBundleIO;
+import org.apache.taverna.scufl2.api.io.WriterException;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+public class WorkflowProcess implements Process {
+
+ private CWLParser cwlParser;
+
+ private Map<String, InputWorkflowPort> workflowInputs;
+ private Map<String, OutputWorkflowPort> workflowOutputs;
+ private Map<String, Processor> workflowProcessors;
+ private Map<String, InputProcessorPort> processorInputs;
+ private Map<String, OutputProcessorPort> processorOutputs;
+ private Set<DataLink> dataLinks;
+
+ private Converter converter;
+
+ public WorkflowProcess(JsonNode node) {
+ cwlParser = new CWLParser(node);
+ converter = new Converter();
+ workflowInputs = new HashMap<>();
+ workflowOutputs = new HashMap<>();
+ workflowProcessors = new HashMap<>();
+ processorInputs = new HashMap<>();
+ processorOutputs = new HashMap<>();
+ dataLinks = new HashSet<>();
+ this.parse();
+ }
+
+ public void parse() {
+ 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);
+
+// System.out.println(workflow);
+// writeWorkflowToFile(workflow);
+//
+// System.out.println("DEBUG WORKFLOW");
+// System.out.println(workflow.getInputPorts());
+// System.out.println(workflow.getOutputPorts());
+// System.out.println(workflow.getProcessors());
+
+ }
+
+ 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, "text/vnd.taverna.scufl2.structure");
+ } 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();
+ 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);
+
+ // TODO: Add only receiver and sender ports from the Process interface
+ 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;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/88c14c4a/taverna-scufl2-cwl/src/main/resources/hello_world.cwl
----------------------------------------------------------------------
diff --git a/taverna-scufl2-cwl/src/main/resources/hello_world.cwl b/taverna-scufl2-cwl/src/main/resources/hello_world.cwl
new file mode 100644
index 0000000..4207afa
--- /dev/null
+++ b/taverna-scufl2-cwl/src/main/resources/hello_world.cwl
@@ -0,0 +1,37 @@
+#!/usr/bin/env cwl-runner
+
+# 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.
+
+cwlVersion: v1.0
+class: Workflow
+
+inputs:
+ name: string
+
+outputs:
+ output1: string
+
+steps:
+ step1:
+ run: example.cwl
+
+ inputs:
+ - id: text
+ source: "#x/name"
+
+ outputs: []
http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/88c14c4a/taverna-scufl2-cwl/src/main/resources/workflow_with_command.cwl
----------------------------------------------------------------------
diff --git a/taverna-scufl2-cwl/src/main/resources/workflow_with_command.cwl b/taverna-scufl2-cwl/src/main/resources/workflow_with_command.cwl
new file mode 100644
index 0000000..e640ecc
--- /dev/null
+++ b/taverna-scufl2-cwl/src/main/resources/workflow_with_command.cwl
@@ -0,0 +1,45 @@
+#!/usr/bin/env cwl-runner
+
+# 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.
+
+cwlVersion: v1.0
+class: Workflow
+
+inputs:
+ name: string
+
+outputs: []
+
+steps:
+ step1:
+ run:
+ class: CommandLineTool
+ baseCommand: echo
+ inputs:
+ message:
+ type: string
+
+ inputBinding:
+ position: 1
+ outputs: []
+
+ inputs:
+ - id: text
+ source: "#x/name"
+
+ outputs: []
http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/88c14c4a/taverna-scufl2-cwl/src/test/java/org/apache/taverna/scufl2/cwl/TestParser.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-cwl/src/test/java/org/apache/taverna/scufl2/cwl/TestParser.java b/taverna-scufl2-cwl/src/test/java/org/apache/taverna/scufl2/cwl/TestParser.java
index 4e3e69e..20c494c 100644
--- a/taverna-scufl2-cwl/src/test/java/org/apache/taverna/scufl2/cwl/TestParser.java
+++ b/taverna-scufl2-cwl/src/test/java/org/apache/taverna/scufl2/cwl/TestParser.java
@@ -77,15 +77,6 @@ public class TestParser {
}
@Test
- public void testParseOutputs() throws Exception {
-
- NamedSet<OutputWorkflowPort> workflowOutputs = workflow.getOutputPorts();
- NamedSet<OutputWorkflowPort> expectedOutputs = new NamedSet<>();
-
- assertEquals(expectedOutputs, workflowOutputs);
- }
-
- @Test
public void testParseProcessors() throws Exception {
workflow.setParent(null);
http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/88c14c4a/taverna-scufl2-cwl/src/test/java/org/apache/taverna/scufl2/cwl/TestWorkflowProcess.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-cwl/src/test/java/org/apache/taverna/scufl2/cwl/TestWorkflowProcess.java b/taverna-scufl2-cwl/src/test/java/org/apache/taverna/scufl2/cwl/TestWorkflowProcess.java
new file mode 100644
index 0000000..015ded4
--- /dev/null
+++ b/taverna-scufl2-cwl/src/test/java/org/apache/taverna/scufl2/cwl/TestWorkflowProcess.java
@@ -0,0 +1,99 @@
+/*
+ * 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.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.HashMap;
+
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
+import org.yaml.snakeyaml.Yaml;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+
+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.common.NamedSet;
+
+import org.apache.taverna.scufl2.api.port.InputWorkflowPort;
+import org.apache.taverna.scufl2.api.port.OutputWorkflowPort;
+import org.apache.taverna.scufl2.api.port.InputProcessorPort;
+
+
+public class TestWorkflowProcess {
+ private static final String HELLO_WORLD_CWL = "/hello_world.cwl";
+ private static final String WORKFLOW_WITH_COMMAND = "/workflow_with_command.cwl";
+
+ private static JsonNode cwlFile;
+
+ public JsonNode loadYamlFile(String filename) {
+
+ Yaml reader = new Yaml();
+ ObjectMapper mapper = new ObjectMapper();
+ JsonNode node = mapper.valueToTree(reader.load(TestWorkflowProcess.class.getResourceAsStream(filename)));
+
+ return node;
+ }
+
+ @Test
+ public void testWorkflowInputs() {
+ cwlFile = loadYamlFile(HELLO_WORLD_CWL);
+ WorkflowProcess workflow = new WorkflowProcess(cwlFile);
+ workflow.parseInputs();
+
+ Map<String, InputWorkflowPort> expected = new HashMap<>();
+ InputWorkflowPort expectedInput = new InputWorkflowPort();
+ expectedInput.setName("name");
+ expected.put("name", expectedInput);
+
+ assertEquals(expected, workflow.getWorkflowInputs());
+ }
+
+ @Test
+ public void testWorkflowOutputs() {
+ cwlFile = loadYamlFile(HELLO_WORLD_CWL);
+ WorkflowProcess workflow = new WorkflowProcess(cwlFile);
+ workflow.parseOutputs();
+
+ Map<String, OutputWorkflowPort> expected = new HashMap<>();
+ OutputWorkflowPort expectedOutput = new OutputWorkflowPort();
+ expectedOutput.setName("output1");
+ expected.put("output1", expectedOutput);
+
+ assertEquals(expected, workflow.getWorkflowOutputs());
+ }
+
+ @Test
+ public void testWorkflowSteps() {
+ cwlFile = loadYamlFile(WORKFLOW_WITH_COMMAND);
+ WorkflowProcess workflow = new WorkflowProcess(cwlFile);
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/88c14c4a/taverna-scufl2-cwl/src/test/resources/hello_world.cwl
----------------------------------------------------------------------
diff --git a/taverna-scufl2-cwl/src/test/resources/hello_world.cwl b/taverna-scufl2-cwl/src/test/resources/hello_world.cwl
index 2172578..4207afa 100644
--- a/taverna-scufl2-cwl/src/test/resources/hello_world.cwl
+++ b/taverna-scufl2-cwl/src/test/resources/hello_world.cwl
@@ -23,7 +23,8 @@ class: Workflow
inputs:
name: string
-outputs: []
+outputs:
+ output1: string
steps:
step1:
[2/2] incubator-taverna-language git commit: add taverna-scufl2-cwl
to build
Posted by st...@apache.org.
add taverna-scufl2-cwl to build
Project: http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/commit/afcfd77c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/tree/afcfd77c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/diff/afcfd77c
Branch: refs/heads/cwlparser
Commit: afcfd77c58dc22d9e3c367f70741ae9116c5e9da
Parents: 88c14c4
Author: Stian Soiland-Reyes <st...@apache.org>
Authored: Mon Jul 16 10:21:35 2018 +0100
Committer: Stian Soiland-Reyes <st...@apache.org>
Committed: Mon Jul 16 10:21:35 2018 +0100
----------------------------------------------------------------------
README.md | 1 +
pom.xml | 1 +
2 files changed, 2 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/afcfd77c/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index 0e332d2..6d5ae2f 100644
--- a/README.md
+++ b/README.md
@@ -97,6 +97,7 @@ Official modules:
Experimental modules:
+* [taverna-scufl2-cwl](taverna-scufl2-cwl/) Load/save [Common Workflow Language](https://www.commonwl.org/)
* [taverna-scufl2-scufl](taverna-scufl2-scufl/) Load Taverna 1 `.xml` workflows (SCUFL 1)
* [taverna-scufl2-annotation](taverna-scufl2-annotation/) Annotation utillity functions
* [taverna-baclava-language](taverna-baclava-language) Load Taverna 2 data documents (workflow inputs/outputs)
http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/afcfd77c/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 44dc74f..8c813ba 100644
--- a/pom.xml
+++ b/pom.xml
@@ -309,6 +309,7 @@ additional dependencies to be a happy OSGi bundle -->
<module>taverna-scufl2-wfbundle</module>
<module>taverna-tavlang-tool</module>
<module>taverna-scufl2-wfdesc</module>
+ <module>taverna-scufl2-cwl</module>
</modules>
</profile>
<profile>