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 <[email protected]>
Authored: Mon Oct 31 17:37:11 2016 +0000
Committer: Stian Soiland-Reyes <[email protected]>
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("/")))

Reply via email to