Revision: 1813
Author: [email protected]
Date: Fri Jan  8 08:23:04 2010
Log: Basic backend SPARQL query support (Issue 116)     
http://code.google.com/p/simal/source/detail?r=1813

Added:
/trunk/uk.ac.osswatch.simal.core/src/main/java/uk/ac/osswatch/simal/model/jena/SparqlResult.java
 /trunk/uk.ac.osswatch.simal.core/src/test/java/uk/ac/osswatch/simal/model
/trunk/uk.ac.osswatch.simal.core/src/test/java/uk/ac/osswatch/simal/model/jena /trunk/uk.ac.osswatch.simal.core/src/test/java/uk/ac/osswatch/simal/model/jena/simal /trunk/uk.ac.osswatch.simal.core/src/test/java/uk/ac/osswatch/simal/model/jena/simal/TestJenaSimalRepository.java
Modified:
 /trunk/uk.ac.osswatch.simal.core
/trunk/uk.ac.osswatch.simal.core/src/main/java/uk/ac/osswatch/simal/model/jena/simal/JenaSimalRepository.java

=======================================
--- /dev/null
+++ /trunk/uk.ac.osswatch.simal.core/src/main/java/uk/ac/osswatch/simal/model/jena/SparqlResult.java Fri Jan 8 08:23:04 2010
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2010 University of Oxford
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package uk.ac.osswatch.simal.model.jena;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.hp.hpl.jena.rdf.model.RDFNode;
+
+/**
+ * Holds the result of a SPARQL query in tabular form
+ * for easy display. This is meant as a transient data class
+ * to store a query result set for use at the front end.
+ * Exposes the list iterator, which makes the caller responsible
+ * for first adding all results before displaying results.
+ * Intended for single-threaded use because of ArrayLists.
+ *
+ * @author svanderwaal
+ *
+ */
+public class SparqlResult {
+  public static final Logger LOGGER = LoggerFactory
+      .getLogger(SparqlResult.class);
+
+  private List<String> varNames;
+
+  private List<List<RDFNode>> sparqlResults;
+
+  /**
+   * Create a new SparqlResult for given variable names.
+   * @param varNames
+   */
+  public SparqlResult(List<String> varNames) {
+    this.varNames = varNames;
+    this.sparqlResults = new ArrayList<List<RDFNode>>();
+  }
+
+  /**
+   * Add a result to the query result set. Corresponds to
+   * a row in a regular SQL result set.
+   * @param result
+   */
+  public void addResult(List<RDFNode> result) {
+    this.sparqlResults.add(result);
+  }
+
+  /**
+   * Return the variable names that are bound for this
+   * query result.
+   * @return
+   */
+  public List<String> getVarNames() {
+    return this.varNames;
+  }
+
+  /**
+   * Expose iterator to let caller iterate over the result.
+   * @return iterator
+   */
+  public Iterator<List<RDFNode>> getResultsIterator() {
+    return sparqlResults.iterator();
+  }
+
+}
=======================================
--- /dev/null
+++ /trunk/uk.ac.osswatch.simal.core/src/test/java/uk/ac/osswatch/simal/model/jena/simal/TestJenaSimalRepository.java Fri Jan 8 08:23:04 2010
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2010 University of Oxford
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package uk.ac.osswatch.simal.model.jena.simal;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.fail;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.junit.Test;
+
+import uk.ac.osswatch.simal.integrationTest.model.repository.BaseRepositoryTest;
+import uk.ac.osswatch.simal.model.jena.SparqlResult;
+import uk.ac.osswatch.simal.rdf.ISimalRepository;
+import uk.ac.osswatch.simal.rdf.SimalRepositoryException;
+
+import com.hp.hpl.jena.rdf.model.RDFNode;
+
+/**
+ * Test Jena specific functionality of JenaSimalRepository.
+ *
+ * @author svanderwaal
+ *
+ */
+public class TestJenaSimalRepository extends BaseRepositoryTest {
+
+ private static final String QUERY_PREFIX = " PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> "
+      + " PREFIX  rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
+      + " PREFIX  doap: <http://usefulinc.com/ns/doap#> "
+      + " PREFIX  simal: <http://oss-watch.ac.uk/ns/0.2/simal#> ";
+
+  private static final String QUERY_ALL_PROJECTS = QUERY_PREFIX
+      + "SELECT DISTINCT  ?project" + " WHERE "
+      + " { ?project  rdf:type   doap:Project ;" + "  }";
+
+  private static final String QUERY_INVALID = QUERY_PREFIX + "SELECT *";
+
+  @Test
+  public void testSparqlQuery() {
+    SparqlResult projects;
+    String expectedVarName = "project";
+    int expectedNrProjects = 10;
+
+    try {
+      projects = getJenaSimalRepository().getSparqlQueryResult(
+          QUERY_ALL_PROJECTS);
+      List<String> actualVarNames = projects.getVarNames();
+      assertEquals(1, actualVarNames.size());
+      assertEquals(expectedVarName, actualVarNames.get(0));
+
+      Iterator<List<RDFNode>> projIter  = projects.getResultsIterator();
+      int actualNrProjects =0;
+      while (projIter.hasNext()) {
+        List<RDFNode> curResult = projIter.next();
+        assertEquals(1, curResult.size());
+        assertNotNull(curResult.get(0));
+        actualNrProjects++;
+      }
+      assertEquals(expectedNrProjects, actualNrProjects);
+    } catch (SimalRepositoryException e) {
+      fail("Could not query repository");
+    }
+  }
+
+  @Test
+  public void testInvalidSparqlQuery() {
+    SparqlResult projects = null;
+    try {
+ projects = getJenaSimalRepository().getSparqlQueryResult(QUERY_INVALID);
+      fail("Query was invalid so should fail without results.");
+    } catch (SimalRepositoryException e) {
+ assertNull("Query was invalid so should fail without results.", projects);
+    }
+  }
+
+  private JenaSimalRepository getJenaSimalRepository() {
+    ISimalRepository repo = getRepository();
+    if (!(repo instanceof JenaSimalRepository)) {
+ fail("Configuration problem; testing Jena when repo is not of Jena type");
+    }
+    return (JenaSimalRepository) repo;
+  }
+}
=======================================
--- /trunk/uk.ac.osswatch.simal.core/src/main/java/uk/ac/osswatch/simal/model/jena/simal/JenaSimalRepository.java Tue Dec 15 16:31:12 2009 +++ /trunk/uk.ac.osswatch.simal.core/src/main/java/uk/ac/osswatch/simal/model/jena/simal/JenaSimalRepository.java Fri Jan 8 08:23:04 2010
@@ -30,8 +30,10 @@
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
+import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Random;
 import java.util.Set;

@@ -64,6 +66,7 @@
 import uk.ac.osswatch.simal.model.jena.Homepage;
 import uk.ac.osswatch.simal.model.jena.Project;
 import uk.ac.osswatch.simal.model.jena.Resource;
+import uk.ac.osswatch.simal.model.jena.SparqlResult;
 import uk.ac.osswatch.simal.model.simal.SimalOntology;
 import uk.ac.osswatch.simal.rdf.AbstractSimalRepository;
 import uk.ac.osswatch.simal.rdf.ISimalRepository;
@@ -73,10 +76,18 @@

 import com.hp.hpl.jena.db.DBConnection;
 import com.hp.hpl.jena.db.IDBConnection;
+import com.hp.hpl.jena.query.Query;
+import com.hp.hpl.jena.query.QueryException;
+import com.hp.hpl.jena.query.QueryExecution;
+import com.hp.hpl.jena.query.QueryExecutionFactory;
+import com.hp.hpl.jena.query.QueryFactory;
+import com.hp.hpl.jena.query.QuerySolution;
+import com.hp.hpl.jena.query.ResultSet;
 import com.hp.hpl.jena.rdf.model.Model;
 import com.hp.hpl.jena.rdf.model.ModelFactory;
 import com.hp.hpl.jena.rdf.model.ModelMaker;
 import com.hp.hpl.jena.rdf.model.Property;
+import com.hp.hpl.jena.rdf.model.RDFNode;
 import com.hp.hpl.jena.rdf.model.Statement;
 import com.hp.hpl.jena.rdf.model.StmtIterator;
 import com.hp.hpl.jena.vocabulary.RDF;
@@ -265,6 +276,51 @@
              return null;
       }
   }
+
+  /**
+   * Generic method for querying the RDF backend.
+   *
+   * @param queryStr
+   *          valid SPARQL query
+   * @return
+   * @throws SimalRepositoryException
+   */
+  @SuppressWarnings("unchecked")
+  public SparqlResult getSparqlQueryResult(String queryStr)
+      throws SimalRepositoryException {
+    SparqlResult sparqlResult = null;
+    QueryExecution qe = null;
+
+    try {
+      Query query = QueryFactory.create(queryStr);
+      qe = QueryExecutionFactory.create(query, model);
+      ResultSet results = qe.execSelect();
+      sparqlResult = new SparqlResult(results.getResultVars());
+
+      while (results.hasNext()) {
+        QuerySolution soln = results.nextSolution();
+        List<RDFNode> result = new ArrayList<RDFNode>();
+        Iterator<Object> varNamesIter = soln.varNames();
+        while (varNamesIter.hasNext()) {
+          String varName = (String) varNamesIter.next();
+          result.add(soln.get(varName));
+        }
+        sparqlResult.addResult(result);
+      }
+
+    } catch (QueryException e) {
+ String message = "QueryException when trying to SPARQLquery with query: "
+          + queryStr;
+      logger.warn(message + "; message: " + e.getMessage());
+      throw new SimalRepositoryException(message, e);
+    } finally {
+      if (qe != null) {
+        qe.close();
+      }
+    }
+
+    return sparqlResult;
+  }

   /**
    * @refactor should be moved to ProjectService class
-- 
You received this message because you are subscribed to the Google Groups 
"Simal Commits" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/simal-commits?hl=en.


Reply via email to