Skip to content

Commit 3a98b5d

Browse files
committed
Schema.org/creator parsing for author information in RO manifest
1 parent c49e60d commit 3a98b5d

File tree

7 files changed

+99
-18
lines changed

7 files changed

+99
-18
lines changed

src/main/java/org/commonwl/view/cwl/RDFService.java

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ public class RDFService {
3737
"PREFIX sld: <https://w3id.org/cwl/salad#>\n" +
3838
"PREFIX Workflow: <https://w3id.org/cwl/cwl#Workflow/>\n" +
3939
"PREFIX DockerRequirement: <https://w3id.org/cwl/cwl#DockerRequirement/>\n" +
40-
"PREFIX rdfs: <rdfs:>";
40+
"PREFIX rdfs: <rdfs:>\n" +
41+
"PREFIX s: <http://schema.org/>";
4142

4243
private String rdfService;
4344

@@ -103,6 +104,7 @@ public boolean ontPropertyExists(String ontUri) {
103104

104105
/**
105106
* Get the label and doc strings for a workflow resource
107+
* @param path The path within the Git repository to the workflow
106108
* @param workflowURI The URI of the workflow
107109
* @return Result set with label and doc strings
108110
*/
@@ -112,6 +114,7 @@ public ResultSet getLabelAndDoc(String path, String workflowURI) {
112114
"SELECT ?label ?doc\n" +
113115
"WHERE {\n" +
114116
" GRAPH ?graphName {" +
117+
" ?wf rdf:type ?type .\n" +
115118
" OPTIONAL { ?wf sld:label|rdfs:label ?label }\n" +
116119
" OPTIONAL { ?wf sld:doc|rdfs:comment ?doc }\n" +
117120
" FILTER(regex(str(?wf), ?wfFilter, \"i\" ))" +
@@ -148,6 +151,7 @@ public String getOntLabel(String ontologyURI) {
148151

149152
/**
150153
* Get the inputs for the workflow in the model
154+
* @param path The path within the Git repository to the workflow
151155
* @param workflowURI URI of the workflow
152156
* @return The result set of inputs
153157
*/
@@ -173,6 +177,7 @@ public ResultSet getInputs(String path, String workflowURI) {
173177

174178
/**
175179
* Get the outputs for the workflow in the model
180+
* @param path The path within the Git repository to the workflow
176181
* @param workflowURI URI of the workflow
177182
* @return The result set of outputs
178183
*/
@@ -198,6 +203,7 @@ public ResultSet getOutputs(String path, String workflowURI) {
198203

199204
/**
200205
* Get the steps for the workflow in the model
206+
* @param path The path within the Git repository to the workflow
201207
* @param workflowURI URI of the workflow
202208
* @return The result set of steps
203209
*/
@@ -270,6 +276,7 @@ public ResultSet getOutputLinks(String path, String workflowURI) {
270276

271277
/**
272278
* Gets the docker requirement and pull link for a workflow
279+
* @param path The path within the Git repository to the workflow
273280
* @param workflowURI URI of the workflow
274281
* @return Result set of docker hint and pull link
275282
*/
@@ -291,6 +298,41 @@ public ResultSet getDockerLink(String path, String workflowURI) {
291298
return runQuery(dockerQuery);
292299
}
293300

301+
/**
302+
* Get authors from schema.org creator fields for a file
303+
* @param path The path within the Git repository to the file
304+
* @param fileUri URI of the file
305+
* @return The result set of step links
306+
*/
307+
public ResultSet getAuthors(String path, String fileUri) {
308+
ParameterizedSparqlString linkQuery = new ParameterizedSparqlString();
309+
linkQuery.setCommandText(queryCtx +
310+
"SELECT ?email ?name ?orcid\n" +
311+
"WHERE {\n" +
312+
" GRAPH ?graphName {" +
313+
" ?file s:creator ?creator .\n" +
314+
" {\n" +
315+
" ?creator rdf:type s:Person .\n" +
316+
" OPTIONAL { ?creator s:email ?email }\n" +
317+
" OPTIONAL { ?creator s:name ?name }\n" +
318+
" OPTIONAL { ?creator s:sameAs ?orcid }\n" +
319+
" } UNION {\n" +
320+
" ?creator rdf:type s:Organization .\n" +
321+
" ?creator s:department* ?dept .\n" +
322+
" ?dept s:member ?member\n" +
323+
" OPTIONAL { ?member s:email ?email }\n" +
324+
" OPTIONAL { ?member s:name ?name }\n" +
325+
" OPTIONAL { ?member s:sameAs ?orcid }\n" +
326+
" }\n" +
327+
" FILTER(regex(str(?orcid), \"^https?://orcid.org/\" ))\n" +
328+
" FILTER(regex(str(?file), ?wfFilter, \"i\" ))\n" +
329+
" }" +
330+
"}");
331+
linkQuery.setLiteral("wfFilter", path + "$");
332+
linkQuery.setIri("graphName", rdfService + fileUri);
333+
return runQuery(linkQuery);
334+
}
335+
294336
/**
295337
* Gets the step name from a full URI
296338
* @param baseUrl the URL of the workflow

src/main/java/org/commonwl/view/git/GitDetails.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,7 @@ public GitDetails(String repoUrl, String branch, String path) {
4747
}
4848

4949
// Default to root path
50-
if (path == null || path.isEmpty()) {
51-
this.path = "/";
52-
} else {
53-
this.path = path;
54-
}
50+
setPath(path);
5551
}
5652

5753

@@ -76,7 +72,13 @@ public String getPath() {
7672
}
7773

7874
public void setPath(String path) {
79-
this.path = path;
75+
if (path == null || path.isEmpty()) {
76+
this.path = "/";
77+
} else if (path.startsWith("/") && path.length() > 1) {
78+
this.path = path.substring(1);
79+
} else {
80+
this.path = path;
81+
}
8082
}
8183

8284
/**

src/main/java/org/commonwl/view/researchobject/ROBundleService.java

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,14 @@
2121

2222
import org.apache.commons.io.FileUtils;
2323
import org.apache.commons.io.FilenameUtils;
24+
import org.apache.jena.query.QuerySolution;
25+
import org.apache.jena.query.ResultSet;
2426
import org.apache.taverna.robundle.Bundle;
2527
import org.apache.taverna.robundle.Bundles;
2628
import org.apache.taverna.robundle.manifest.*;
2729
import org.commonwl.view.cwl.CWLTool;
2830
import org.commonwl.view.cwl.CWLValidationException;
31+
import org.commonwl.view.cwl.RDFService;
2932
import org.commonwl.view.git.GitDetails;
3033
import org.commonwl.view.git.GitService;
3134
import org.commonwl.view.git.GitType;
@@ -66,6 +69,7 @@ public class ROBundleService {
6669
// Services
6770
private GraphVizService graphVizService;
6871
private GitService gitService;
72+
private RDFService rdfService;
6973
private CWLTool cwlTool;
7074

7175
// Configuration variables
@@ -92,13 +96,15 @@ public ROBundleService(@Value("${bundleStorage}") Path bundleStorage,
9296
@Value("${singleFileSizeLimit}") int singleFileSizeLimit,
9397
GraphVizService graphVizService,
9498
GitService gitService,
99+
RDFService rdfService,
95100
CWLTool cwlTool) throws URISyntaxException {
96101
this.bundleStorage = bundleStorage;
97102
this.appAgent = new Agent(appName);
98103
appAgent.setUri(new URI(appURL));
99104
this.singleFileSizeLimit = singleFileSizeLimit;
100105
this.graphVizService = graphVizService;
101106
this.gitService = gitService;
107+
this.rdfService = rdfService;
102108
this.cwlTool = cwlTool;
103109
}
104110

@@ -134,7 +140,7 @@ public Bundle createBundle(Workflow workflow, GitDetails gitInfo) throws IOExcep
134140
Git gitRepo = gitService.getRepository(workflow.getRetrievedFrom());
135141
Path relativePath = Paths.get(FilenameUtils.getPath(gitInfo.getPath()));
136142
Path gitPath = gitRepo.getRepository().getWorkTree().toPath().resolve(relativePath);
137-
addFilesToBundle(gitInfo, bundle, bundlePath, gitRepo, gitPath, authors);
143+
addFilesToBundle(gitInfo, bundle, bundlePath, gitRepo, gitPath, authors, workflow);
138144

139145
// Add combined authors
140146
manifest.setAuthoredBy(new ArrayList<>(authors));
@@ -175,6 +181,7 @@ public Bundle createBundle(Workflow workflow, GitDetails gitInfo) throws IOExcep
175181
try {
176182
addAggregation(bundle, manifestAnnotations,
177183
"workflow.ttl", cwlTool.getRDF(rawUrl));
184+
178185
} catch (CWLValidationException ex) {
179186
logger.error("Could not get RDF for workflow from raw URL", ex.getMessage());
180187
}
@@ -208,7 +215,8 @@ public Bundle createBundle(Workflow workflow, GitDetails gitInfo) throws IOExcep
208215
* @param authors The combined set of authors for al the files
209216
*/
210217
private void addFilesToBundle(GitDetails gitDetails, Bundle bundle, Path bundlePath,
211-
Git gitRepo, Path repoPath, Set<HashableAgent> authors)
218+
Git gitRepo, Path repoPath, Set<HashableAgent> authors,
219+
Workflow workflow)
212220
throws IOException {
213221
File[] files = repoPath.toFile().listFiles();
214222
for (File file : files) {
@@ -225,7 +233,7 @@ private void addFilesToBundle(GitDetails gitDetails, Bundle bundle, Path bundleP
225233

226234
// Add all files in the subdirectory to this new folder
227235
addFilesToBundle(subfolderGitDetails, bundle, newBundlePath, gitRepo,
228-
repoPath.resolve(file.getName()), authors);
236+
repoPath.resolve(file.getName()), authors, workflow);
229237

230238
} else {
231239
try {
@@ -271,7 +279,8 @@ private void addFilesToBundle(GitDetails gitDetails, Bundle bundle, Path bundleP
271279
}
272280

273281
// Special handling for cwl files
274-
if (FilenameUtils.getExtension(file.getName()).equals("cwl")) {
282+
boolean cwl = FilenameUtils.getExtension(file.getName()).equals("cwl");
283+
if (cwl) {
275284
// Correct mime type (no official standard for yaml)
276285
aggregation.setMediatype("text/x-yaml");
277286

@@ -284,10 +293,35 @@ private void addFilesToBundle(GitDetails gitDetails, Bundle bundle, Path bundleP
284293
}
285294
}
286295

287-
// Add authors from git commits to the file
288296
try {
297+
Path gitPath = Paths.get(gitDetails.getPath()).resolve(file.getName());
298+
String url = workflow.getRetrievedFrom()
299+
.getUrl(workflow.getLastCommit()).replace("https://", "");
300+
301+
// Add authors from git commits to the file
289302
Set<HashableAgent> fileAuthors = gitService.getAuthors(gitRepo,
290-
Paths.get(gitDetails.getPath()).resolve(file.getName()).toString());
303+
gitPath.toString());
304+
305+
if (cwl) {
306+
// Attempt to get authors from cwl description
307+
ResultSet descAuthors = rdfService.getAuthors(bundlePath
308+
.resolve(file.getName()).toString().substring(10), url);
309+
if (descAuthors.hasNext()) {
310+
QuerySolution authorSoln = descAuthors.nextSolution();
311+
HashableAgent newAuthor = new HashableAgent();
312+
if (authorSoln.contains("name")) {
313+
newAuthor.setName(authorSoln.get("name").toString());
314+
}
315+
if (authorSoln.contains("email")) {
316+
newAuthor.setUri(new URI(authorSoln.get("email").toString()));
317+
}
318+
if (authorSoln.contains("orcid")) {
319+
newAuthor.setOrcid(new URI(authorSoln.get("orcid").toString()));
320+
}
321+
fileAuthors.add(newAuthor);
322+
}
323+
}
324+
291325
authors.addAll(fileAuthors);
292326
aggregation.setAuthoredBy(new ArrayList<>(fileAuthors));
293327
} catch (GitAPIException ex) {

src/main/java/org/commonwl/view/workflow/WorkflowRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,5 @@ public interface WorkflowRepository extends PagingAndSortingRepository<Workflow,
5050
* @param doc The string to search for in the doc
5151
* @param pageable The details of the page to be retrieved
5252
*/
53-
Page<Workflow> findByLabelContainingOrDocContaining(String label, String doc, Pageable pageable);
53+
Page<Workflow> findByLabelContainingOrDocContainingIgnoreCase(String label, String doc, Pageable pageable);
5454
}

src/main/java/org/commonwl/view/workflow/WorkflowService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public Page<Workflow> getPageOfWorkflows(Pageable pageable) {
9393
* @return The resulting page of the workflow entries
9494
*/
9595
public Page<Workflow> searchPageOfWorkflows(String searchString, Pageable pageable) {
96-
return workflowRepository.findByLabelContainingOrDocContaining(searchString, searchString, pageable);
96+
return workflowRepository.findByLabelContainingOrDocContainingIgnoreCase(searchString, searchString, pageable);
9797
}
9898

9999
/**

src/main/resources/templates/workflow.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@ <h4 class="modal-title" id="fullScreenGraphLabel">Workflow Graph</h4>
125125
<div class="row">
126126
<div class="col-md-12" role="main" id="main">
127127
<h2>Workflow: <span th:text="${workflow.label}">Workflow Name</span></h2>
128-
<p th:text="${workflow.doc}">Workflow Doc</p>
129128
</div>
130129
<div class="col-md-6">
131130
<a th:href="@{${workflow.retrievedFrom.getUrl()}}" href="#" rel="noopener" target="_blank" style="text-decoration:none;">
@@ -143,6 +142,9 @@ <h2>Workflow: <span th:text="${workflow.label}">Workflow Name</span></h2>
143142
<div class="col-md-6 text-right">
144143
<img class="verification_icon" src="../static/img/tick.svg" th:src="@{/img/tick.svg}" width="20" height="22" /> Verified with cwltool version <span th:text="${workflow.cwltoolVersion}">1.0.20170622090721</span>
145144
</div>
145+
<div class="col-md-12" style="margin-top:5px;" th:if="${workflow.doc != null}">
146+
<p th:text="${workflow.doc}">Workflow Doc</p>
147+
</div>
146148
</div>
147149
<div class="row">
148150
<div class="col-md-12">

src/test/java/org/commonwl/view/researchobject/ROBundleServiceTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.apache.taverna.robundle.manifest.PathAnnotation;
2626
import org.apache.taverna.robundle.manifest.PathMetadata;
2727
import org.commonwl.view.cwl.CWLTool;
28+
import org.commonwl.view.cwl.RDFService;
2829
import org.commonwl.view.git.GitDetails;
2930
import org.commonwl.view.git.GitService;
3031
import org.commonwl.view.graphviz.GraphVizService;
@@ -110,7 +111,7 @@ public void generateAndSaveROBundle() throws Exception {
110111
// Create new RO bundle
111112
ROBundleService bundleService = new ROBundleService(roBundleFolder.getRoot().toPath(),
112113
"CWL Viewer", "https://view.commonwl.org", 5242880,
113-
mockGraphvizService, mockGitService, mockCwlTool);
114+
mockGraphvizService, mockGitService, Mockito.mock(RDFService.class), mockCwlTool);
114115
Bundle bundle = bundleService.createBundle(lobSTRv1, lobSTRv1RODetails);
115116
Path bundleRoot = bundle.getRoot().resolve("workflow");
116117

@@ -207,7 +208,7 @@ public void filesOverLimit() throws Exception {
207208
// Create new RO bundle
208209
ROBundleService bundleService = new ROBundleService(roBundleFolder.getRoot().toPath(),
209210
"CWL Viewer", "https://view.commonwl.org", 0, mockGraphvizService,
210-
mockGitService, mockCwlTool);
211+
mockGitService, Mockito.mock(RDFService.class), mockCwlTool);
211212
Bundle bundle = bundleService.createBundle(lobSTRv1, lobSTRv1RODetails);
212213

213214
Manifest manifest = bundle.getManifest();

0 commit comments

Comments
 (0)