Skip to content

Commit b4dd88d

Browse files
authored
Merge pull request #35 from common-workflow-language/draft-2-fix
Remove hash from start of IDs to support draft-2 ID/source notation
2 parents 7dcd926 + 496ac72 commit b4dd88d

File tree

1 file changed

+82
-38
lines changed

1 file changed

+82
-38
lines changed

src/main/java/org/commonwl/viewer/domain/CWLCollection.java

Lines changed: 82 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,33 @@ public class CWLCollection {
4646
// The main workflow
4747
private String mainWorkflowKey;
4848

49+
// Extension of CWL files
50+
private final String CWL_EXTENSION = "cwl";
51+
52+
// Github API specific strings
53+
private final String DIR = "dir";
54+
private final String FILE = "file";
55+
56+
// CWL specific strings
57+
private final String DOC_GRAPH = "$graph";
58+
private final String CLASS = "class";
59+
private final String WORKFLOW = "Workflow";
60+
private final String STEPS = "steps";
61+
private final String INPUTS = "inputs";
62+
private final String IN = "in";
63+
private final String OUTPUTS = "outputs";
64+
private final String OUT = "out";
65+
private final String ID = "id";
66+
private final String TYPE = "type";
67+
private final String LABEL = "label";
68+
private final String DEFAULT = "default";
69+
private final String OUTPUT_SOURCE = "outputSource";
70+
private final String SOURCE = "source";
71+
private final String DOC = "doc";
72+
private final String DESCRIPTION = "description";
73+
private final String ARRAY = "array";
74+
private final String ARRAY_ITEMS = "items";
75+
4976
/**
5077
* Creates a new collection of CWL files from a Github repository
5178
* @param githubService Service to provide the Github API functionality
@@ -70,7 +97,7 @@ private void addDocs(List<RepositoryContents> repoContents) throws IOException {
7097
for (RepositoryContents repoContent : repoContents) {
7198

7299
// Parse subdirectories if they exist
73-
if (repoContent.getType().equals("dir")) {
100+
if (repoContent.getType().equals(DIR)) {
74101

75102
// Get the contents of the subdirectory
76103
GithubDetails githubSubdir = new GithubDetails(githubInfo.getOwner(),
@@ -81,15 +108,15 @@ private void addDocs(List<RepositoryContents> repoContents) throws IOException {
81108
addDocs(subdirectory);
82109

83110
// Otherwise this is a file so add to the bundle
84-
} else if (repoContent.getType().equals("file")) {
111+
} else if (repoContent.getType().equals(FILE)) {
85112

86113
// Get the file extension
87114
int eIndex = repoContent.getName().lastIndexOf('.') + 1;
88115
if (eIndex > 0) {
89116
String extension = repoContent.getName().substring(eIndex);
90117

91118
// If this is a cwl file which needs to be parsed
92-
if (extension.equals("cwl")) {
119+
if (extension.equals(CWL_EXTENSION)) {
93120

94121
// Get the content of this file from Github
95122
GithubDetails githubFile = new GithubDetails(githubInfo.getOwner(),
@@ -117,9 +144,9 @@ private void addDocs(List<RepositoryContents> repoContents) throws IOException {
117144
*/
118145
private void addDoc(JsonNode newDoc, String fileName) {
119146
// Make sure that this document is only one object and not multiple under a $graph directive
120-
if (newDoc.has("$graph")) {
147+
if (newDoc.has(DOC_GRAPH)) {
121148
// Add each of the sub documents
122-
for (JsonNode jsonNode : newDoc.get("$graph")) {
149+
for (JsonNode jsonNode : newDoc.get(DOC_GRAPH)) {
123150
cwlDocs.put(extractID(jsonNode), jsonNode);
124151
}
125152
} else {
@@ -135,7 +162,7 @@ private void findMainWorkflow() {
135162
// Find the first workflow we come across
136163
// TODO: Consider relationship between run: parameters to better discover this
137164
for (Map.Entry<String, JsonNode> doc : cwlDocs.entrySet()) {
138-
if (doc.getValue().get("class").asText().equals("Workflow")) {
165+
if (doc.getValue().get(CLASS).asText().equals(WORKFLOW)) {
139166
mainWorkflowKey = doc.getKey();
140167
return;
141168
}
@@ -174,10 +201,10 @@ public Workflow getWorkflow() {
174201
* @return A map of step IDs and details related to them
175202
*/
176203
private Map<String, CWLStep> getSteps(JsonNode cwlDoc) {
177-
if (cwlDoc != null && cwlDoc.has("steps")) {
204+
if (cwlDoc != null && cwlDoc.has(STEPS)) {
178205
Map<String, CWLStep> returnMap = new HashMap<>();
179206

180-
JsonNode steps = cwlDoc.get("steps");
207+
JsonNode steps = cwlDoc.get(STEPS);
181208
if (steps.getClass() == ArrayNode.class) {
182209
// Explicit ID and other fields within each input list
183210
for (JsonNode step : steps) {
@@ -208,8 +235,14 @@ private Map<String, CWLStep> getSteps(JsonNode cwlDoc) {
208235
* @return A map of input IDs and details related to them
209236
*/
210237
private Map<String, CWLElement> getInputs(JsonNode cwlDoc) {
211-
if (cwlDoc != null && cwlDoc.has("inputs")) {
212-
return getInputsOutputs(cwlDoc.get("inputs"));
238+
if (cwlDoc != null) {
239+
if (cwlDoc.has(INPUTS)) {
240+
// For workflow
241+
return getInputsOutputs(cwlDoc.get(INPUTS));
242+
} else if (cwlDoc.has(IN)) {
243+
// For steps
244+
return getInputsOutputs(cwlDoc.get(IN));
245+
}
213246
}
214247
return null;
215248
}
@@ -220,8 +253,14 @@ private Map<String, CWLElement> getInputs(JsonNode cwlDoc) {
220253
* @return A map of output IDs and details related to them
221254
*/
222255
private Map<String, CWLElement> getOutputs(JsonNode cwlDoc) {
223-
if (cwlDoc != null && cwlDoc.has("outputs")) {
224-
return getInputsOutputs(cwlDoc.get("outputs"));
256+
if (cwlDoc != null) {
257+
if (cwlDoc.has(OUTPUTS)) {
258+
// For workflow
259+
return getInputsOutputs(cwlDoc.get(OUTPUTS));
260+
} else if (cwlDoc.has(OUT)) {
261+
// For steps
262+
return getInputsOutputs(cwlDoc.get(OUT));
263+
}
225264
}
226265
return null;
227266
}
@@ -235,9 +274,9 @@ private Map<String, CWLElement> getInputsOutputs(JsonNode inputsOutputs) {
235274
Map<String, CWLElement> returnMap = new HashMap<>();
236275

237276
if (inputsOutputs.getClass() == ArrayNode.class) {
238-
// Explicit ID and other fields within each ilist
277+
// Explicit ID and other fields within each list
239278
for (JsonNode inputOutput : inputsOutputs) {
240-
String id = inputOutput.get("id").asText();
279+
String id = inputOutput.get(ID).asText();
241280
returnMap.put(id, getDetails(inputOutput));
242281
}
243282
} else if (inputsOutputs.getClass() == ObjectNode.class) {
@@ -271,8 +310,8 @@ private CWLElement getDetails(JsonNode inputOutput) {
271310
details.setDefaultVal(extractDefault(inputOutput));
272311

273312
// Type is only for inputs
274-
if (inputOutput.has("type")) {
275-
details.setType(extractTypes(inputOutput.get("type")));
313+
if (inputOutput.has(TYPE)) {
314+
details.setType(extractTypes(inputOutput.get(TYPE)));
276315
}
277316
}
278317

@@ -287,8 +326,12 @@ private CWLElement getDetails(JsonNode inputOutput) {
287326
* @return The string for the id of the node
288327
*/
289328
private String extractID(JsonNode node) {
290-
if (node != null && node.has("id")) {
291-
return node.get("id").asText();
329+
if (node != null && node.has(ID)) {
330+
String id = node.get(ID).asText();
331+
if (id.startsWith("#")) {
332+
return id.substring(1);
333+
}
334+
return id;
292335
}
293336
return null;
294337
}
@@ -299,8 +342,8 @@ private String extractID(JsonNode node) {
299342
* @return The string for the label of the node
300343
*/
301344
private String extractLabel(JsonNode node) {
302-
if (node != null && node.has("label")) {
303-
return node.get("label").asText();
345+
if (node != null && node.has(LABEL)) {
346+
return node.get(LABEL).asText();
304347
}
305348
return null;
306349
}
@@ -311,8 +354,8 @@ private String extractLabel(JsonNode node) {
311354
* @return The string for the default value of the node
312355
*/
313356
private String extractDefault(JsonNode node) {
314-
if (node != null && node.has("default")) {
315-
return node.get("default").asText();
357+
if (node != null && node.has(DEFAULT)) {
358+
return node.get(DEFAULT).asText();
316359
}
317360
return null;
318361
}
@@ -328,10 +371,10 @@ private List<String> extractOutputSource(JsonNode node) {
328371
JsonNode sourceNode = null;
329372

330373
// outputSource and source treated the same
331-
if (node.has("outputSource")) {
332-
sourceNode = node.get("outputSource");
333-
} else if (node.has("source")) {
334-
sourceNode = node.get("source");
374+
if (node.has(OUTPUT_SOURCE)) {
375+
sourceNode = node.get(OUTPUT_SOURCE);
376+
} else if (node.has(SOURCE)) {
377+
sourceNode = node.get(SOURCE);
335378
}
336379

337380
if (sourceNode != null) {
@@ -353,7 +396,7 @@ private List<String> extractOutputSource(JsonNode node) {
353396
}
354397

355398
/**
356-
* Gets just the step ID from source of format 'stepID/outputID'
399+
* Gets just the step ID from source of format 'stepID</ or .>outputID'
357400
* @param source The source
358401
* @return The step ID
359402
*/
@@ -364,14 +407,15 @@ private String stepIDFromSource(String source) {
364407
source = source.substring(1);
365408
}
366409

367-
// Get segment before / (step ID)
410+
// Draft 3/V1 notation is 'stepID/outputID'
368411
int slashSplit = source.indexOf("/");
369412
if (slashSplit != -1) {
370413
source = source.substring(0, slashSplit);
371414
} else {
415+
// Draft 2 notation was 'stepID.outputID'
372416
int dotSplit = source.indexOf(".");
373417
if (dotSplit != -1) {
374-
source = "#" + source.substring(0, dotSplit);
418+
source = source.substring(0, dotSplit);
375419
}
376420
}
377421
}
@@ -385,11 +429,11 @@ private String stepIDFromSource(String source) {
385429
*/
386430
private String extractDoc(JsonNode node) {
387431
if (node != null) {
388-
if (node.has("doc")) {
389-
return node.get("doc").asText();
390-
} else if (node.has("description")) {
432+
if (node.has(DOC)) {
433+
return node.get(DOC).asText();
434+
} else if (node.has(DESCRIPTION)) {
391435
// This is to support older standards of cwl which use description instead of doc
392-
return node.get("description").asText();
436+
return node.get(DESCRIPTION).asText();
393437
}
394438
}
395439
return null;
@@ -422,11 +466,11 @@ private String extractTypes(JsonNode typeNode) {
422466
}
423467
} else if (typeNode.getClass() == ArrayNode.class) {
424468
// This is a verbose type with sub-fields broken down into type: and other params
425-
if (type.get("type").asText().equals("array")) {
426-
typeDetails.append(type.get("items").asText());
469+
if (type.get(TYPE).asText().equals(ARRAY)) {
470+
typeDetails.append(type.get(ARRAY_ITEMS).asText());
427471
typeDetails.append("[], ");
428472
} else {
429-
typeDetails.append(type.get("type").asText());
473+
typeDetails.append(type.get(TYPE).asText());
430474
}
431475
}
432476
}
@@ -444,8 +488,8 @@ private String extractTypes(JsonNode typeNode) {
444488

445489
} else if (typeNode.getClass() == ObjectNode.class) {
446490
// Type: array and items:
447-
if (typeNode.has("items")) {
448-
return typeNode.get("items").asText() + "[]";
491+
if (typeNode.has(ARRAY_ITEMS)) {
492+
return typeNode.get(ARRAY_ITEMS).asText() + "[]";
449493
}
450494
}
451495
}

0 commit comments

Comments
 (0)