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 2016/10/31 17:37:53 UTC

[3/3] incubator-taverna-language git commit: TAVERNA-1017 Use Commons RDF API instead of Jena

TAVERNA-1017 Use Commons RDF API instead of Jena


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/a748e824
Tree: http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/tree/a748e824
Diff: http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/diff/a748e824

Branch: refs/heads/TAVERNA-1017
Commit: a748e824fb43616bedf60c299934744c8eec98e1
Parents: 3002424
Author: Stian Soiland-Reyes <st...@apache.org>
Authored: Mon Oct 31 17:37:11 2016 +0000
Committer: Stian Soiland-Reyes <st...@apache.org>
Committed: Mon Oct 31 17:37:37 2016 +0000

----------------------------------------------------------------------
 pom.xml                                         |  21 ++-
 taverna-scufl2-annotation/pom.xml               |  11 +-
 .../scufl2/annotation/AnnotationTools.java      | 154 ++++++++++---------
 taverna-scufl2-api/pom.xml                      |   5 +
 .../taverna/scufl2/api/common/URITools.java     |  15 ++
 5 files changed, 126 insertions(+), 80 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/a748e824/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index d5acb9b..43132cb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,10 +28,14 @@
     <version>0.16.0-incubating-SNAPSHOT</version>
     <packaging>pom</packaging>
 
-    <name>Apache Taverna Language APIs (Scufl2, Databundle)</name>
+    <name>Apache Taverna Language APIs (Scufl2, Databundle)</name>    
     <description>Taverna Language API for workflow definitions (SCUFL2)
         and workflow inputs/outputs/run (DataBundle).
     </description>
+    <properties>
+    	<!--  TODO: Use 0.3.0-incubating once it is released -->
+    	<commons.rdf.version>0.4.0-incubating-SNAPSHOT</commons.rdf.version>
+    </properties>
     <build>
         <plugins>
             <plugin>
@@ -252,11 +256,12 @@
                 <artifactId>commons-beanutils</artifactId>
                 <version>${commons.beanutils.version}</version>
             </dependency>
+            
         </dependencies>
     </dependencyManagement>
     <dependencies>
         <!-- Common dependencies on jena-osgi, which requires some additional dependencies 
-            to be a happy OSGi bundle -->
+            to be a happy OSGi bundle 
 
         <dependency>
             <groupId>org.apache.jena</groupId>
@@ -268,17 +273,23 @@
             <artifactId>org.apache.servicemix.bundles.xerces</artifactId>
             <version>${servicemix.xerces.version}</version>
         </dependency>
-        <!-- JENA-1178 workaround: Upgrade jsonlld-java -->
+        -->
+        <!-- JENA-1178 workaround: Upgrade jsonlld-java 
         <dependency>
             <groupId>com.github.jsonld-java</groupId>
             <artifactId>jsonld-java</artifactId>
             <version>${jsonldjava.version}</version>
-        </dependency>
-        <!-- Needed by Jena -->
+        </dependency>-->
+        <!-- Needed by Jena 
         <dependency>
             <groupId>com.github.andrewoma.dexx</groupId>
             <artifactId>collection</artifactId>
             <version>${dexx.collection.version}</version>
+        </dependency>-->
+        <dependency>
+        	<groupId>org.apache.commons</groupId>
+        	<artifactId>commons-rdf-api</artifactId>
+        	<version>${commons.rdf.version}</version>        	
         </dependency>
     </dependencies>
     <profiles>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/a748e824/taverna-scufl2-annotation/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-scufl2-annotation/pom.xml b/taverna-scufl2-annotation/pom.xml
index b5d7ea2..23e2875 100644
--- a/taverna-scufl2-annotation/pom.xml
+++ b/taverna-scufl2-annotation/pom.xml
@@ -44,12 +44,11 @@
 			<version>${project.version}</version>
 			<scope>test</scope>
 		</dependency>
-		<dependency>
-			<groupId>org.apache.jena</groupId>
-			<artifactId>jena-osgi</artifactId>
-			<version>${jena.version}</version>
-		</dependency>
-
+        <dependency>
+        	<groupId>org.apache.commons</groupId>
+        	<artifactId>commons-rdf-jena</artifactId>
+        	<version>${commons.rdf.version}</version>        	
+        </dependency>
 
 	</dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/a748e824/taverna-scufl2-annotation/src/main/java/org/apache/taverna/scufl2/annotation/AnnotationTools.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-annotation/src/main/java/org/apache/taverna/scufl2/annotation/AnnotationTools.java b/taverna-scufl2-annotation/src/main/java/org/apache/taverna/scufl2/annotation/AnnotationTools.java
index 9e8a157..4a5de12 100644
--- a/taverna-scufl2-annotation/src/main/java/org/apache/taverna/scufl2/annotation/AnnotationTools.java
+++ b/taverna-scufl2-annotation/src/main/java/org/apache/taverna/scufl2/annotation/AnnotationTools.java
@@ -26,12 +26,19 @@ import java.io.InputStream;
 import java.net.URI;
 import java.util.Calendar;
 import java.util.GregorianCalendar;
-import java.util.Iterator;
+import java.util.Optional;
+import java.util.concurrent.ExecutionException;
 import java.util.logging.Logger;
 
-import org.apache.jena.riot.Lang;
-import org.apache.jena.riot.RDFDataMgr;
-import org.apache.jena.riot.RDFLanguages;
+import org.apache.commons.rdf.api.Dataset;
+import org.apache.commons.rdf.api.Graph;
+import org.apache.commons.rdf.api.IRI;
+import org.apache.commons.rdf.api.Literal;
+import org.apache.commons.rdf.api.Quad;
+import org.apache.commons.rdf.jena.JenaIRI;
+import org.apache.commons.rdf.jena.JenaLiteral;
+import org.apache.commons.rdf.jena.JenaRDF;
+import org.apache.commons.rdf.jena.experimental.JenaRDFParser;
 import org.apache.taverna.scufl2.api.annotation.Annotation;
 import org.apache.taverna.scufl2.api.common.Child;
 import org.apache.taverna.scufl2.api.common.Scufl2Tools;
@@ -39,24 +46,14 @@ import org.apache.taverna.scufl2.api.common.URITools;
 import org.apache.taverna.scufl2.api.container.WorkflowBundle;
 import org.apache.taverna.scufl2.ucfpackage.UCFPackage.ResourceEntry;
 
-
-import org.apache.jena.graph.Node;
-import org.apache.jena.graph.NodeFactory;
-import org.apache.jena.query.Dataset;
-import org.apache.jena.query.DatasetFactory;
-import org.apache.jena.rdf.model.Model;
-import org.apache.jena.rdf.model.ModelFactory;
-import org.apache.jena.sparql.core.Quad;
-
 public class AnnotationTools {
-	private static final String EXAMPLE_DATA_PREDICATE = "http://biocatalogue.org/attribute/exampleData";
-	public static final URI EXAMPLE_DATA = URI.create(EXAMPLE_DATA_PREDICATE);
-	private static final String TITLE_PREDICATE = "http://purl.org/dc/terms/title";
-	public static final URI TITLE = URI.create(TITLE_PREDICATE);
-	private static final String DESCRIPTION_PREDICATE = "http://purl.org/dc/terms/description";
-	public static final URI DESCRIPTION = URI.create(DESCRIPTION_PREDICATE);
-	private static final String CREATOR_PREDICATE = "http://purl.org/dc/elements/1.1/creator";
-	public static final URI CREATOR = URI.create(CREATOR_PREDICATE);
+    
+    private static JenaRDF rdf = new JenaRDF();
+    	
+	public static final IRI EXAMPLE_DATA = rdf.createIRI("http://biocatalogue.org/attribute/exampleData");
+	public static final IRI TITLE = rdf.createIRI("http://purl.org/dc/terms/title");
+	public static final IRI DESCRIPTION = rdf.createIRI("http://purl.org/dc/terms/description");
+	public static final IRI CREATOR = rdf.createIRI("http://purl.org/dc/elements/1.1/creator");
 
 	private static Logger logger = Logger.getLogger(AnnotationTools.class
 			.getCanonicalName());
@@ -65,7 +62,7 @@ public class AnnotationTools {
 	private URITools uritools = new URITools();
 
 	public Dataset annotationDatasetFor(Child<?> workflowBean) {
-		Dataset dataset = DatasetFactory.createMem();
+		Dataset dataset = rdf.createDataset();
 		for (Annotation ann : scufl2Tools.annotationsFor(workflowBean)) {
 			WorkflowBundle bundle = ann.getParent();
 			URI annUri = uritools.uriForBean(ann);
@@ -87,57 +84,79 @@ public class AnnotationTools {
 				continue;
 			}
 			String contentType = resourceEntry.getMediaType();
-			Lang lang = RDFLanguages.contentTypeToLang(contentType);
-			if (lang == null) {
-				lang = RDFLanguages.filenameToLang(path);
-			}
-			if (lang == null) {
-				logger.warning("Can't find media type of annotation body: "
-						+ ann.getBody());
-				continue;
-			}
-			Model model = ModelFactory.createDefaultModel();
+			
 			try (InputStream inStream = bundle.getResources()
 					.getResourceAsInputStream(path)) {
-				RDFDataMgr.read(model, inStream, bodyUri, lang);
+			    
+			    Optional<Graph> graph = graphForAnnotation(dataset, annUri);
+			    
+			            
+			    JenaRDFParser parser = new JenaRDFParser()
+			            .base(bodyUri).source(inStream)
+			            .contentType(contentType)
+			            .target(graph.get());
+                // TODO: Do multiple parsings in one go to speed up outer
+                // for-loop? Would need thread-safe Dataset backed by say TDB in memory			    
+			    try {
+                    parser.parse().get();
+                } catch (IllegalStateException | InterruptedException | ExecutionException e) {
+                    logger.warning("Can't parse annotation body: " + path);
+                    continue;
+                }
 			} catch (IOException e) {
 				logger.warning("Can't read annotation body: " + path);
 				continue;
 			}
-			dataset.addNamedModel(annUri.toString(), model);
 		}
 
 		return dataset;
 	}
 
+    private Optional<Graph> graphForAnnotation(Dataset dataset, URI annUri) {
+        IRI graphUri = uritools.asIRI(annUri);
+        Optional<Graph> graph = dataset.getGraph(graphUri);
+        
+        if (! graph.isPresent()) {
+            // Need a dummy quad first? 
+            JenaIRI example = rdf.createIRI("http://example.com/");
+            dataset.add(graphUri, example, example, example);
+            graph = dataset.getGraph(graphUri);
+            if (! graph.isPresent()) {
+                logger.severe("Can't create named graph: " + graphUri.getIRIString());
+            }
+            // Remove dummy triple :)  This will crash if the above can't create graph. 
+            graph.get().remove(example, example, example);
+        }
+        
+        return graph;
+    }
+
 	public String getTitle(Child<?> workflowBean) {
-		return getLiteral(workflowBean, TITLE_PREDICATE);
+		return getLiteral(workflowBean, TITLE).orElse(null);
 	}
 
-	private String getLiteral(Child<?> workflowBean, String propertyUri) {
+	private Optional<String> getLiteral(Child<?> workflowBean, IRI property) {
+	    // TODO: Cache dataset PARSING!
 		Dataset annotations = annotationDatasetFor(workflowBean);
-		URI beanUri = uritools.uriForBean(workflowBean);
-		Node subject = NodeFactory.createURI(beanUri.toString());
-		Node property = NodeFactory.createURI(propertyUri);
-
-		Iterator<Quad> found = annotations.asDatasetGraph().find(null, subject,
-				property, null);
-		if (!found.hasNext()) {
-			return null;
-		}
-		return found.next().getObject().toString(false);
+		IRI beanIRI = uritools.asIRI(uritools.uriForBean(workflowBean));		
+		return annotations.stream(null, beanIRI, property, null).map(Quad::getObject)
+		        // Pick any Literal property value, if it exist
+		    .filter(Literal.class::isInstance).map(Literal.class::cast)
+		    .map(Literal::getLexicalForm).findAny();	
 	}
 
 	public String getCreator(Child<?> workflowBean) {
-		return getLiteral(workflowBean, CREATOR_PREDICATE);
+	    // TODO: Also support dcterms:creator and foaf:name ?
+		return getLiteral(workflowBean, CREATOR).orElse(null);
 	}
 
 	public String getExampleValue(Child<?> workflowBean) {
-		return getLiteral(workflowBean, EXAMPLE_DATA_PREDICATE);
+	    // TODO: Also support example value as a path?
+		return getLiteral(workflowBean, EXAMPLE_DATA).orElse(null);
 	}
 
-	public String getDescription(Child<?> workflowBean) {
-		return getLiteral(workflowBean, DESCRIPTION_PREDICATE);
+	public String getDescription(Child<?> workflowBean) {	    
+		return getLiteral(workflowBean, DESCRIPTION).orElse(null);
 	}
 
 	/**
@@ -150,7 +169,7 @@ public class AnnotationTools {
 	 * @throws IOException
 	 */
 	public Annotation createNewAnnotation(WorkflowBundle workflowBundle,
-			Child<?> subject, URI predicate, String value) throws IOException {
+			Child<?> subject, IRI predicate, String value) throws IOException {
 		Object parent = subject.getParent();
 		while (parent instanceof Child)
 			parent = ((Child<?>) parent).getParent();
@@ -176,25 +195,22 @@ public class AnnotationTools {
 		annotation.setAnnotatedAt(now);
 		// annotation.setAnnotator();//FIXME
 		annotation.setSerializedAt(now);
-		URI annotatedSubject = uritools.relativeUriForBean(subject, annotation);
+		IRI annotatedSubject = uritools.asIRI(uritools.relativeUriForBean(subject, annotation));
+		
+		
 		StringBuilder turtle = new StringBuilder();
-		turtle.append("<");
-		turtle.append(annotatedSubject.toASCIIString());
-		turtle.append("> ");
-
-		turtle.append("<");
-		turtle.append(predicate.toASCIIString());
-		turtle.append("> ");
-
-		// A potentially multi-line string
-		turtle.append("\"\"\"");
-		// Escape existing \ to \\
-		String escaped = value.replace("\\", "\\\\");
-		// Escape existing " to \" (beware Java's escaping of \ and " below)
-		escaped = escaped.replace("\"", "\\\"");
-		turtle.append(escaped);
-		turtle.append("\"\"\"");
-		turtle.append(" .");
+		turtle.append(annotatedSubject.ntriplesString());
+
+		turtle.append(" ");
+		turtle.append(predicate.ntriplesString());
+
+		turtle.append(" ");
+		JenaLiteral literal = rdf.createLiteral(value);
+		turtle.append(literal.ntriplesString());
+		
+		turtle.append(" .\n");
+		
+		// TODO: Save with Jena instead
 		try {
 			workflowBundle.getResources().addResource(turtle.toString(), path,
 					"text/turtle");

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/a748e824/taverna-scufl2-api/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-scufl2-api/pom.xml b/taverna-scufl2-api/pom.xml
index 4c0052a..a7ea442 100644
--- a/taverna-scufl2-api/pom.xml
+++ b/taverna-scufl2-api/pom.xml
@@ -50,6 +50,11 @@
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-databind</artifactId>
         </dependency>
+        <dependency>
+        	<groupId>org.apache.commons</groupId>
+        	<artifactId>commons-rdf-simple</artifactId>
+        	<version>${commons.rdf.version}</version>        	
+        </dependency>        
     </dependencies>
     <build>
         <plugins>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/a748e824/taverna-scufl2-api/src/main/java/org/apache/taverna/scufl2/api/common/URITools.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-api/src/main/java/org/apache/taverna/scufl2/api/common/URITools.java b/taverna-scufl2-api/src/main/java/org/apache/taverna/scufl2/api/common/URITools.java
index 85d96ac..dff04b4 100644
--- a/taverna-scufl2-api/src/main/java/org/apache/taverna/scufl2/api/common/URITools.java
+++ b/taverna-scufl2-api/src/main/java/org/apache/taverna/scufl2/api/common/URITools.java
@@ -27,6 +27,9 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.rdf.api.IRI;
+import org.apache.commons.rdf.api.RDF;
+import org.apache.commons.rdf.simple.SimpleRDF;
 import org.apache.taverna.scufl2.api.annotation.Annotation;
 import org.apache.taverna.scufl2.api.annotation.Revision;
 import org.apache.taverna.scufl2.api.common.Visitor.VisitorWithPath;
@@ -53,6 +56,18 @@ public class URITools {
 	private static final String DATALINK = "datalink";
 	private static final URI DOT = URI.create(".");
 
+	private RDF rdf = new SimpleRDF();
+	
+	public IRI asIRI(URI uri) {
+	    // TODO: Handle internationalization?
+	    return rdf.createIRI(uri.toString());
+	}
+	
+	public URI asURI(IRI iri) {
+        // TODO: Handle internationalization?
+	    return URI.create(iri.getIRIString());
+	}
+	
 	public URI relativePath(URI base, URI uri) {
 		URI root = base.resolve("/");
 		if (!root.equals(uri.resolve("/")))