Repository: ontodev/robot
Pull request #164 (2017-05-02 20:43:32)

added a --construct option to query, to allow for CONSTRUCT type sparql queries
As an example to test, you can use the SPARQL:

    PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
    PREFIX owl: <http://www.w3.org/2002/07/owl#>
    prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    PREFIX part_of: <http://purl.obolibrary.org/obo/BFO_0000050>
    CONSTRUCT {
        ?part part_of: ?whole
    }
    WHERE {
        ?part rdfs:subClassOf [	rdf:type owl:Restriction ;
							owl:onProperty part_of: ;
							owl:someValuesFrom ?whole ]
    }

And use the command:
`bin/robot query -i examples/edit.owl --construct query.rq output -f ttl`

This produces a ttl file called output with direct "part of" assertions. 


Patch:
diff --git a/.gitignore b/.gitignore
index 768cd236..c6c5549b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,8 @@
 .classpath
 .project
 .settings
+.idea
+*.iml
 bin/original-robot.jar
 bin/owltools2.jar
 bin/robot.jar
diff --git a/robot-command/src/main/java/org/obolibrary/robot/QueryCommand.java b/robot-command/src/main/java/org/obolibrary/robot/QueryCommand.java
index eada0f1d..fb32fad4 100644
--- a/robot-command/src/main/java/org/obolibrary/robot/QueryCommand.java
+++ b/robot-command/src/main/java/org/obolibrary/robot/QueryCommand.java
@@ -2,6 +2,7 @@ package org.obolibrary.robot;
 
 import java.io.File;
 import java.util.List;
+import java.util.StringJoiner;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -45,6 +46,10 @@ public class QueryCommand implements Command {
             "run a SPARQL select query and output result");
         select.setArgs(2);
         o.addOption(select);
+        Option construct = new Option("c", "construct", true,
+            "run a SPARQL construct query and output result");
+        construct.setArgs(2);
+        o.addOption(construct);
         options = o;
     }
 
@@ -118,7 +123,7 @@ public class QueryCommand implements Command {
             return null;
         }
         String formatName = CommandLineHelper.getOptionalValue(line, "format");
-        Lang outputFormat = org.apache.jena.riot.Lang.CSV;
+        Lang outputFormat = Lang.CSV;
         if (formatName != null) {
             formatName = formatName.toLowerCase();
             if (formatName.equals("tsv")) {
@@ -136,9 +141,7 @@ public class QueryCommand implements Command {
             else if (formatName.equals("nq")) {
                 outputFormat = Lang.NQ;
             }
-            else {
-               
-            }
+
         }
         IOHelper ioHelper = CommandLineHelper.getIOHelper(line);
         state = CommandLineHelper.updateInputOntology(ioHelper, state, line);
@@ -150,11 +153,18 @@ public class QueryCommand implements Command {
                 CommandLineHelper.getOptionValues(line, "select");
 
             for (int i = 0; i < select.size(); i = i + 2) {
-                String query =
-                    FileUtils.readFileToString(new File(select.get(i)));
+                String query = FileUtils.readFileToString(new File(select.get(i)));
                 File output = new File(select.get(i + 1));
                 QueryOperation.runQuery(dsg, query, output, outputFormat);
             }
+        } else if (line.hasOption("construct")) {
+            List<String> select = CommandLineHelper.getOptionalValues(line, "construct");
+
+            for (int i=0; i<select.size(); i += 2) {
+                String query = FileUtils.readFileToString(new File(select.get(i)));
+                File output = new File(select.get(i + 1));
+                QueryOperation.runConstruct(dsg, query, output, outputFormat);
+            }
         }
 
         return state;
diff --git a/robot-core/src/main/java/org/obolibrary/robot/QueryOperation.java b/robot-core/src/main/java/org/obolibrary/robot/QueryOperation.java
index f69ad001..b3a6c04e 100644
--- a/robot-core/src/main/java/org/obolibrary/robot/QueryOperation.java
+++ b/robot-core/src/main/java/org/obolibrary/robot/QueryOperation.java
@@ -6,6 +6,7 @@ import java.io.File;
 import java.io.FileOutputStream;
 import java.io.FileNotFoundException;
 
+import com.hp.hpl.jena.rdf.model.Model;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -53,9 +54,7 @@ public class QueryOperation {
         ontology.getOWLOntologyManager().saveOntology(ontology,
             new TurtleDocumentFormat(), out);
         DatasetGraph dsg = DatasetGraphFactory.createMem();
-        RDFDataMgr.read(dsg.getDefaultGraph(),
-            new ByteArrayInputStream(out.toByteArray()),
-            org.apache.jena.riot.Lang.TURTLE);
+        RDFDataMgr.read(dsg.getDefaultGraph(), new ByteArrayInputStream(out.toByteArray()), Lang.TURTLE);
         return dsg;
     }
 
@@ -67,11 +66,17 @@ public class QueryOperation {
      * @return the result set
      */
     public static ResultSet execQuery(DatasetGraph dsg, String query) {
-        QueryExecution qexec =
-            QueryExecutionFactory.create(query, DatasetFactory.create(dsg));
+        QueryExecution qexec = QueryExecutionFactory.create(query, DatasetFactory.create(dsg));
         return qexec.execSelect();
     }
 
+    public static Model execConstruct(DatasetGraph dsg, String query) {
+        QueryExecution exec = QueryExecutionFactory.create(query, DatasetFactory.create(dsg));
+        return exec.execConstruct();
+    }
+
+
+
     /**
      * Run a query and write the result to a file.
      *
@@ -82,12 +87,15 @@ public class QueryOperation {
      */
     public static void runQuery(DatasetGraph dsg, String query, File output, Lang outputFormat)
             throws FileNotFoundException {
-        if (outputFormat == null)
-            outputFormat = org.apache.jena.riot.Lang.CSV;
-        ResultSetMgr.write(
-            new FileOutputStream(output),
-            execQuery(dsg, query),
-            outputFormat);
+        if (outputFormat == null) {
+            outputFormat = Lang.CSV;
+        }
+        ResultSetMgr.write(new FileOutputStream(output), execQuery(dsg, query), outputFormat);
+    }
+
+    public static void runConstruct(DatasetGraph dsg, String query, File output, Lang outputFormat)
+        throws FileNotFoundException {
+        RDFDataMgr.write(new FileOutputStream(output), execConstruct(dsg, query), outputFormat);
     }
 
     /**


Test patch:
diff --git a/robot-core/src/test/java/org/obolibrary/robot/QueryOperationTest.java b/robot-core/src/test/java/org/obolibrary/robot/QueryOperationTest.java
index 23d2e45e..3e20063b 100644
--- a/robot-core/src/test/java/org/obolibrary/robot/QueryOperationTest.java
+++ b/robot-core/src/test/java/org/obolibrary/robot/QueryOperationTest.java
@@ -3,6 +3,9 @@ package org.obolibrary.robot;
 import java.io.IOException;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.hp.hpl.jena.rdf.model.*;
 import org.junit.Test;
 
 import com.hp.hpl.jena.query.ResultSet;
@@ -37,4 +40,28 @@ public class QueryOperationTest extends CoreTest {
         assertEquals(6, QueryOperation.countResults(results));
     }
 
+    @Test
+    public void testConstruct() throws IOException, OWLOntologyStorageException {
+        OWLOntology ontology = loadOntology("/bot.owl");
+        DatasetGraph dsg = QueryOperation.loadOntology(ontology);
+        String query =
+            "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n" +
+            "PREFIX owl: <http://www.w3.org/2002/07/owl#>\n" +
+            "prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n" +
+            "PREFIX part_of: <http://purl.obolibrary.org/obo/BFO_0000050>\n" +
+            "CONSTRUCT {\n" +
+            "    ?part part_of: ?whole\n" +
+            "}\n" +
+            "WHERE {\n" +
+            "    ?part rdfs:subClassOf [\trdf:type owl:Restriction ;\n" +
+            "\t\t\t\t\t\towl:onProperty part_of: ;\n" +
+            "\t\t\t\t\t\towl:someValuesFrom ?whole ]\n" +
+            "}";
+        Model model = QueryOperation.execConstruct(dsg, query);
+        Resource s = ResourceFactory.createResource("http://purl.obolibrary.org/obo/UBERON_0000062");
+        Property p = ResourceFactory.createProperty("http://purl.obolibrary.org/obo/BFO_0000050");
+        RDFNode o = ResourceFactory.createResource("http://purl.obolibrary.org/obo/UBERON_0000467");
+        assertTrue(model.contains(s, p, o));
+    }
+
 }