NIHVIVO-2343 Move the SPARQL query execution boilerplate into a utility class so it can be used elsewhere.

This commit is contained in:
j2blake 2011-10-25 19:38:31 +00:00
parent 91a483a788
commit b0b2fb98e1
2 changed files with 117 additions and 71 deletions

View file

@ -3,7 +3,6 @@
package edu.cornell.mannlib.vitro.webapp.controller.accounts; package edu.cornell.mannlib.vitro.webapp.controller.accounts;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -13,10 +12,6 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.query.Query;
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.QuerySolution;
import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.Syntax; import com.hp.hpl.jena.query.Syntax;
@ -26,6 +21,8 @@ import com.hp.hpl.jena.rdf.model.Resource;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status;
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsOrdering.Field; import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsOrdering.Field;
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner;
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner.QueryParser;
/** /**
* Pull some UserAccounts from the model, based on a set of criteria. * Pull some UserAccounts from the model, based on a set of criteria.
@ -72,8 +69,6 @@ public class UserAccountsSelector {
+ " <%uri%> auth:hasPermissionSet ?ps \n" // + " <%uri%> auth:hasPermissionSet ?ps \n" //
+ "} \n"; + "} \n";
private static final Syntax SYNTAX = Syntax.syntaxARQ;
/** /**
* If the user enters any of these characters in a search term, escape it * If the user enters any of these characters in a search term, escape it
* with a backslash. * with a backslash.
@ -123,8 +118,8 @@ public class UserAccountsSelector {
.replace("%offset%", offset()); .replace("%offset%", offset());
log.debug("main query: " + qString); log.debug("main query: " + qString);
List<UserAccount> accounts = executeQuery(qString, List<UserAccount> accounts = new SparqlQueryRunner<List<UserAccount>>(
new MainQueryParser()); model, new MainQueryParser()).executeQuery(qString);
log.debug("query returns: " + accounts); log.debug("query returns: " + accounts);
return accounts; return accounts;
} }
@ -138,7 +133,8 @@ public class UserAccountsSelector {
.replace("%filterClauses%", filterClauses()); .replace("%filterClauses%", filterClauses());
log.debug("count query: " + qString); log.debug("count query: " + qString);
int count = executeQuery(qString, new CountQueryParser()); int count = new SparqlQueryRunner<Integer>(model,
new CountQueryParser()).executeQuery(qString);
log.debug("result count: " + count); log.debug("result count: " + count);
return count; return count;
} }
@ -150,8 +146,8 @@ public class UserAccountsSelector {
PREFIX_LINES).replace("%uri%", uri); PREFIX_LINES).replace("%uri%", uri);
log.debug("permissions query: " + qString); log.debug("permissions query: " + qString);
Collection<String> permissions = executeQuery(qString, Set<String> permissions = new SparqlQueryRunner<Set<String>>(model,
new PermissionsQueryParser()); new PermissionsQueryParser()).executeQuery(qString);
log.debug("permissions for '" + uri + "': " + permissions); log.debug("permissions for '" + uri + "': " + permissions);
account.setPermissionSetUris(permissions); account.setPermissionSetUris(permissions);
} }
@ -245,67 +241,15 @@ public class UserAccountsSelector {
return String.valueOf(offset); return String.valueOf(offset);
} }
private <T> T executeQuery(String queryStr, QueryParser<T> parser) {
QueryExecution qe = null;
try {
Query query = QueryFactory.create(queryStr, SYNTAX);
qe = QueryExecutionFactory.create(query, model);
return parser.parseResults(queryStr, qe.execSelect());
} catch (Exception e) {
log.error("Failed to execute the query: " + queryStr, e);
return parser.defaultValue();
} finally {
if (qe != null) {
qe.close();
}
}
}
private static abstract class QueryParser<T> {
abstract T parseResults(String queryStr, ResultSet results);
abstract T defaultValue();
protected String ifLiteralPresent(QuerySolution solution,
String variableName, String defaultValue) {
Literal literal = solution.getLiteral(variableName);
if (literal == null) {
return defaultValue;
} else {
return literal.getString();
}
}
protected long ifLongPresent(QuerySolution solution,
String variableName, long defaultValue) {
Literal literal = solution.getLiteral(variableName);
if (literal == null) {
return defaultValue;
} else {
return literal.getLong();
}
}
protected int ifIntPresent(QuerySolution solution, String variableName,
int defaultValue) {
Literal literal = solution.getLiteral(variableName);
if (literal == null) {
return defaultValue;
} else {
return literal.getInt();
}
}
}
private static class MainQueryParser extends QueryParser<List<UserAccount>> { private static class MainQueryParser extends QueryParser<List<UserAccount>> {
@Override @Override
public List<UserAccount> defaultValue() { protected List<UserAccount> defaultValue() {
return Collections.emptyList(); return Collections.emptyList();
} }
@Override @Override
public List<UserAccount> parseResults(String queryStr, ResultSet results) { protected List<UserAccount> parseResults(String queryStr,
ResultSet results) {
List<UserAccount> accounts = new ArrayList<UserAccount>(); List<UserAccount> accounts = new ArrayList<UserAccount>();
while (results.hasNext()) { while (results.hasNext()) {
try { try {
@ -359,12 +303,12 @@ public class UserAccountsSelector {
private static class CountQueryParser extends QueryParser<Integer> { private static class CountQueryParser extends QueryParser<Integer> {
@Override @Override
public Integer defaultValue() { protected Integer defaultValue() {
return 0; return 0;
} }
@Override @Override
public Integer parseResults(String queryStr, ResultSet results) { protected Integer parseResults(String queryStr, ResultSet results) {
int count = 0; int count = 0;
if (!results.hasNext()) { if (!results.hasNext()) {
@ -384,12 +328,12 @@ public class UserAccountsSelector {
private static class PermissionsQueryParser extends private static class PermissionsQueryParser extends
QueryParser<Set<String>> { QueryParser<Set<String>> {
@Override @Override
Set<String> defaultValue() { protected Set<String> defaultValue() {
return Collections.emptySet(); return Collections.emptySet();
} }
@Override @Override
Set<String> parseResults(String queryStr, ResultSet results) { protected Set<String> parseResults(String queryStr, ResultSet results) {
Set<String> permissions = new HashSet<String>(); Set<String> permissions = new HashSet<String>();
while (results.hasNext()) { while (results.hasNext()) {

View file

@ -0,0 +1,102 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.utils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.query.Query;
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.query.Syntax;
import com.hp.hpl.jena.rdf.model.Literal;
/**
* Execute a SPARQL query.
*
* Take the model and a parser in the constructor. Then execute as many queries
* as desired, with the query contained in a String.
*
* If there is an exception while parsing the query, executing the query, or
* parsing the results, log the exception and return the parser's default value.
* The query enbvironment is closed properly in any case.
*/
public class SparqlQueryRunner<T> {
private static final Log log = LogFactory.getLog(SparqlQueryRunner.class);
private static final Syntax SYNTAX = Syntax.syntaxARQ;
private final OntModel model;
private final QueryParser<T> parser;
public SparqlQueryRunner(OntModel model, QueryParser<T> parser) {
this.model = model;
this.parser = parser;
}
/**
* Execute the query and parse the results, closing and cleaning up
* afterward. If an exception occurs, return the parser's default value.
*/
public T executeQuery(String queryStr) {
QueryExecution qe = null;
try {
Query query = QueryFactory.create(queryStr, SYNTAX);
qe = QueryExecutionFactory.create(query, model);
return parser.parseResults(queryStr, qe.execSelect());
} catch (Exception e) {
log.error("Failed to execute the query: " + queryStr, e);
return parser.defaultValue();
} finally {
if (qe != null) {
qe.close();
}
}
}
/**
* This template class provides some parsing methods to help in the
* parseResults() method.
*/
public static abstract class QueryParser<T> {
protected abstract T parseResults(String queryStr, ResultSet results);
protected abstract T defaultValue();
protected String ifLiteralPresent(QuerySolution solution,
String variableName, String defaultValue) {
Literal literal = solution.getLiteral(variableName);
if (literal == null) {
return defaultValue;
} else {
return literal.getString();
}
}
protected long ifLongPresent(QuerySolution solution,
String variableName, long defaultValue) {
Literal literal = solution.getLiteral(variableName);
if (literal == null) {
return defaultValue;
} else {
return literal.getLong();
}
}
protected int ifIntPresent(QuerySolution solution, String variableName,
int defaultValue) {
Literal literal = solution.getLiteral(variableName);
if (literal == null) {
return defaultValue;
} else {
return literal.getInt();
}
}
}
}