VIVO-1248 extend SparqlQueryRunner, and combine with older attempts. (#45)
* Ignore artifacts that Eclipse creates. * VIVO-1248 Create the utils.sparqlrunner package. This is a merge of most of the edu.cornell.mannlib.vitro.webapp.utils.sparql package with edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner Remove the references to those classes. * VIVO-1248 extend SparqlQueryRunner, and combine with older attempts.
This commit is contained in:
parent
a8ec633f71
commit
9cd5a1329a
31 changed files with 1799 additions and 438 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -17,3 +17,8 @@ utilities/sdb_to_tdb/.work
|
|||
**/target
|
||||
|
||||
**/overlays
|
||||
|
||||
# Eclipse artifacts
|
||||
**/.settings
|
||||
**/.classpath
|
||||
**/.project
|
||||
|
|
|
@ -20,9 +20,9 @@ import org.apache.jena.rdf.model.Resource;
|
|||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
||||
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.utils.SparqlQueryRunner;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner.QueryParser;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparql.SparqlQueryUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.ResultSetParser;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.SparqlQueryRunner;
|
||||
|
||||
/**
|
||||
* Pull some UserAccounts from the model, based on a set of criteria.
|
||||
|
@ -111,8 +111,9 @@ public class UserAccountsSelector {
|
|||
.replace("%offset%", offset());
|
||||
log.debug("main query: " + qString);
|
||||
|
||||
List<UserAccount> accounts = new SparqlQueryRunner(model)
|
||||
.executeSelect(new MainQueryParser(), qString);
|
||||
List<UserAccount> accounts = SparqlQueryRunner
|
||||
.createSelectQueryContext(model, qString).execute()
|
||||
.parse(new MainQueryParser());
|
||||
log.debug("query returns: " + accounts);
|
||||
return accounts;
|
||||
}
|
||||
|
@ -126,8 +127,8 @@ public class UserAccountsSelector {
|
|||
.replace("%filterClauses%", filterClauses());
|
||||
log.debug("count query: " + qString);
|
||||
|
||||
int count = new SparqlQueryRunner(model).executeSelect(
|
||||
new CountQueryParser(), qString);
|
||||
int count = SparqlQueryRunner.createSelectQueryContext(model, qString)
|
||||
.execute().parse(new CountQueryParser());
|
||||
log.debug("result count: " + count);
|
||||
return count;
|
||||
}
|
||||
|
@ -139,8 +140,9 @@ public class UserAccountsSelector {
|
|||
PREFIX_LINES).replace("%uri%", uri);
|
||||
log.debug("permissions query: " + qString);
|
||||
|
||||
Set<String> permissions = new SparqlQueryRunner(model)
|
||||
.executeSelect(new PermissionsQueryParser(), qString);
|
||||
Set<String> permissions = SparqlQueryRunner
|
||||
.createSelectQueryContext(model, qString).execute()
|
||||
.parse(new PermissionsQueryParser());
|
||||
log.debug("permissions for '" + uri + "': " + permissions);
|
||||
account.setPermissionSetUris(permissions);
|
||||
}
|
||||
|
@ -214,7 +216,8 @@ public class UserAccountsSelector {
|
|||
return String.valueOf(offset);
|
||||
}
|
||||
|
||||
private static class MainQueryParser extends QueryParser<List<UserAccount>> {
|
||||
private static class MainQueryParser extends
|
||||
ResultSetParser<List<UserAccount>> {
|
||||
@Override
|
||||
protected List<UserAccount> defaultValue() {
|
||||
return Collections.emptyList();
|
||||
|
@ -274,7 +277,7 @@ public class UserAccountsSelector {
|
|||
}
|
||||
}
|
||||
|
||||
private static class CountQueryParser extends QueryParser<Integer> {
|
||||
private static class CountQueryParser extends ResultSetParser<Integer> {
|
||||
@Override
|
||||
protected Integer defaultValue() {
|
||||
return 0;
|
||||
|
@ -299,7 +302,7 @@ public class UserAccountsSelector {
|
|||
}
|
||||
|
||||
private static class PermissionsQueryParser extends
|
||||
QueryParser<Set<String>> {
|
||||
ResultSetParser<Set<String>> {
|
||||
@Override
|
||||
protected Set<String> defaultValue() {
|
||||
return Collections.emptySet();
|
||||
|
|
|
@ -16,9 +16,9 @@ import org.apache.jena.query.ResultSet;
|
|||
import edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies.ProxyRelationshipSelectionBuilder.ItemInfo;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies.ProxyRelationshipSelectionBuilder.Relationship;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies.ProxyRelationshipSelectionCriteria.ProxyRelationshipView;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner.QueryParser;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparql.SparqlQueryUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.ResultSetParser;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.SparqlQueryRunner;
|
||||
|
||||
/**
|
||||
* A class which will accept a ProxyRelationshipSelectionCriteria and produce a
|
||||
|
@ -94,8 +94,9 @@ public class ProxyRelationshipSelector {
|
|||
PREFIX_LINES);
|
||||
qString = replaceFilterClauses(qString);
|
||||
|
||||
int count = new SparqlQueryRunner(context.userAccountsModel)
|
||||
.executeSelect(new CountQueryParser(), qString);
|
||||
int count = SparqlQueryRunner
|
||||
.createSelectQueryContext(context.userAccountsModel, qString)
|
||||
.execute().parse(new CountQueryParser());
|
||||
|
||||
log.debug("result count: " + count);
|
||||
builder.count = count;
|
||||
|
@ -136,9 +137,9 @@ public class ProxyRelationshipSelector {
|
|||
.replace("%offset%", offset());
|
||||
qString = replaceFilterClauses(qString);
|
||||
|
||||
List<Relationship> relationships = new SparqlQueryRunner(
|
||||
context.userAccountsModel).executeSelect(
|
||||
new ProxyBasicsParser(), qString);
|
||||
List<Relationship> relationships = SparqlQueryRunner
|
||||
.createSelectQueryContext(context.userAccountsModel, qString)
|
||||
.execute().parse(new ProxyBasicsParser());
|
||||
log.debug("getProxyBasics returns: " + relationships);
|
||||
builder.relationships.addAll(relationships);
|
||||
}
|
||||
|
@ -177,8 +178,9 @@ public class ProxyRelationshipSelector {
|
|||
.replace("%matchingProperty%", context.matchingProperty)
|
||||
.replace("%externalAuthId%", proxy.externalAuthId);
|
||||
|
||||
ItemInfo expansion = new SparqlQueryRunner(context.unionModel)
|
||||
.executeSelect(new ExpandProxyParser(), qString);
|
||||
ItemInfo expansion = SparqlQueryRunner
|
||||
.createSelectQueryContext(context.unionModel, qString)
|
||||
.execute().parse(new ExpandProxyParser());
|
||||
proxy.classLabel = expansion.classLabel;
|
||||
proxy.imageUrl = expansion.imageUrl;
|
||||
}
|
||||
|
@ -199,9 +201,10 @@ public class ProxyRelationshipSelector {
|
|||
String qString = QUERY_RELATIONSHIPS.replace("%prefixes%",
|
||||
PREFIX_LINES).replace("%proxyUri%", proxy.uri);
|
||||
|
||||
List<String> profileUris = new SparqlQueryRunner(
|
||||
context.userAccountsModel).executeSelect(
|
||||
new RelationshipsParser(), qString);
|
||||
List<String> profileUris = SparqlQueryRunner
|
||||
.createSelectQueryContext(context.userAccountsModel,
|
||||
qString).execute()
|
||||
.parse(new RelationshipsParser());
|
||||
|
||||
for (String profileUri : profileUris) {
|
||||
r.profileInfos
|
||||
|
@ -235,8 +238,9 @@ public class ProxyRelationshipSelector {
|
|||
String qString = QUERY_EXPAND_PROFILE.replace("%prefixes%",
|
||||
PREFIX_LINES).replace("%profileUri%", profile.uri);
|
||||
|
||||
ItemInfo expansion = new SparqlQueryRunner(context.unionModel)
|
||||
.executeSelect(new ExpandProfileParser(), qString);
|
||||
ItemInfo expansion = SparqlQueryRunner
|
||||
.createSelectQueryContext(context.unionModel, qString)
|
||||
.execute().parse(new ExpandProfileParser());
|
||||
profile.label = expansion.label;
|
||||
profile.classLabel = expansion.classLabel;
|
||||
profile.imageUrl = expansion.imageUrl;
|
||||
|
@ -285,7 +289,7 @@ public class ProxyRelationshipSelector {
|
|||
// ----------------------------------------------------------------------
|
||||
|
||||
private static class ProxyBasicsParser extends
|
||||
QueryParser<List<Relationship>> {
|
||||
ResultSetParser<List<Relationship>> {
|
||||
@Override
|
||||
protected List<Relationship> defaultValue() {
|
||||
return Collections.emptyList();
|
||||
|
@ -318,7 +322,7 @@ public class ProxyRelationshipSelector {
|
|||
}
|
||||
}
|
||||
|
||||
private static class CountQueryParser extends QueryParser<Integer> {
|
||||
private static class CountQueryParser extends ResultSetParser<Integer> {
|
||||
@Override
|
||||
protected Integer defaultValue() {
|
||||
return 0;
|
||||
|
@ -342,7 +346,7 @@ public class ProxyRelationshipSelector {
|
|||
}
|
||||
}
|
||||
|
||||
private static class ExpandProxyParser extends QueryParser<ItemInfo> {
|
||||
private static class ExpandProxyParser extends ResultSetParser<ItemInfo> {
|
||||
@Override
|
||||
protected ItemInfo defaultValue() {
|
||||
return new ItemInfo();
|
||||
|
@ -367,7 +371,8 @@ public class ProxyRelationshipSelector {
|
|||
}
|
||||
}
|
||||
|
||||
private static class RelationshipsParser extends QueryParser<List<String>> {
|
||||
private static class RelationshipsParser extends
|
||||
ResultSetParser<List<String>> {
|
||||
@Override
|
||||
protected List<String> defaultValue() {
|
||||
return Collections.emptyList();
|
||||
|
@ -388,7 +393,7 @@ public class ProxyRelationshipSelector {
|
|||
}
|
||||
}
|
||||
|
||||
private static class ExpandProfileParser extends QueryParser<ItemInfo> {
|
||||
private static class ExpandProfileParser extends ResultSetParser<ItemInfo> {
|
||||
@Override
|
||||
protected ItemInfo defaultValue() {
|
||||
return new ItemInfo();
|
||||
|
|
|
@ -24,8 +24,8 @@ import edu.cornell.mannlib.vitro.webapp.controller.ajax.AbstractAjaxResponder;
|
|||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparql.SparqlQueryUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.SparqlQueryRunner;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil;
|
||||
|
||||
/**
|
||||
|
@ -76,10 +76,10 @@ public class BasicProxiesGetter extends AbstractAjaxResponder {
|
|||
String cleanTerm = SparqlQueryUtils.escapeForRegex(term);
|
||||
String queryStr = QUERY_BASIC_PROXIES.replace("%term%", cleanTerm);
|
||||
|
||||
JSONArray jsonArray = new SparqlQueryRunner(userAccountsModel)
|
||||
.executeSelect(
|
||||
new BasicProxyInfoParser(placeholderImageUrl),
|
||||
queryStr);
|
||||
JSONArray jsonArray = SparqlQueryRunner
|
||||
.createSelectQueryContext(userAccountsModel, queryStr)
|
||||
.execute()
|
||||
.parse(new BasicProxyInfoParser(placeholderImageUrl));
|
||||
|
||||
String response = jsonArray.toString();
|
||||
log.debug(response);
|
||||
|
|
|
@ -36,9 +36,9 @@ import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao;
|
|||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.http.AcceptHeaderParsingException;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.http.NotAcceptableException;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparql.SparqlQueryUtils;
|
||||
|
||||
/**
|
||||
* Present the SPARQL Query form, and execute the queries.
|
||||
|
|
|
@ -24,7 +24,7 @@ import org.apache.jena.query.ResultSet;
|
|||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.ResultSetParser;
|
||||
|
||||
/**
|
||||
* A base class for AJAX responder objects, to be instantiated and invoked by
|
||||
|
@ -82,7 +82,7 @@ public abstract class AbstractAjaxResponder {
|
|||
*/
|
||||
protected String assembleJsonResponse(List<Map<String, String>> maps) {
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
for (Map<String, String> map: maps) {
|
||||
for (Map<String, String> map : maps) {
|
||||
jsonArray.put(map);
|
||||
}
|
||||
return jsonArray.toString();
|
||||
|
@ -93,7 +93,7 @@ public abstract class AbstractAjaxResponder {
|
|||
* implement "parseSolutionRow()"
|
||||
*/
|
||||
protected abstract static class JsonArrayParser extends
|
||||
SparqlQueryRunner.QueryParser<JSONArray> {
|
||||
ResultSetParser<JSONArray> {
|
||||
@Override
|
||||
protected JSONArray defaultValue() {
|
||||
return new JSONArray();
|
||||
|
|
|
@ -10,9 +10,9 @@ import org.apache.jena.query.QueryParseException;
|
|||
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.http.AcceptHeaderParsingException;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.http.NotAcceptableException;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparql.SparqlQueryUtils;
|
||||
|
||||
/**
|
||||
* The base class for the SPARQL query API.
|
||||
|
|
|
@ -73,12 +73,12 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet;
|
|||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.adapters.VitroModelFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaIngestUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaIngestUtils.MergeResult;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaIngestWorkflowProcessor;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaOutputUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.WorkflowOntology;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparql.SparqlQueryUtils;
|
||||
|
||||
public class JenaIngestController extends BaseEditController {
|
||||
private static final Log log = LogFactory.getLog(JenaIngestController.class);
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.dao.jena;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.SparqlQueryRunner.createSelectQueryContext;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.SparqlQueryRunner.queryHolder;
|
||||
import static org.apache.jena.rdf.model.ResourceFactory.createResource;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner.bindValues;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner.uriValue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
@ -16,7 +16,6 @@ import java.util.Set;
|
|||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.apache.jena.ontology.ObjectProperty;
|
||||
import org.apache.jena.ontology.OntModel;
|
||||
import org.apache.jena.ontology.OntModelSpec;
|
||||
|
@ -33,11 +32,11 @@ import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
|
|||
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.InsertException;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner.QueryParser;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockableOntModel;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockableOntModelSelector;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockedOntModel;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.QueryHolder;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.ResultSetParser;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
|
@ -522,7 +521,7 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
|
|||
+ "} \n"; //
|
||||
|
||||
private static class ParserLocateConfigContext extends
|
||||
QueryParser<Set<ConfigContext>> {
|
||||
ResultSetParser<Set<ConfigContext>> {
|
||||
private final String domainUri;
|
||||
private final String baseUri;
|
||||
private final String rangeUri;
|
||||
|
@ -561,30 +560,29 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
|
|||
LockableOntModel lockableDisplayModel, String domainUri,
|
||||
String baseUri, String rangeUri) {
|
||||
try (LockedOntModel displayModel = lockableDisplayModel.read()) {
|
||||
String queryString;
|
||||
QueryHolder qHolder;
|
||||
if (domainUri == null || domainUri.trim().isEmpty()
|
||||
|| domainUri.equals(OWL.Thing.getURI())) {
|
||||
queryString = bindValues(
|
||||
QUERY_LOCATE_CONFIG_CONTEXT_WITH_NO_DOMAIN,
|
||||
uriValue("baseUri", baseUri),
|
||||
uriValue("rangeUri", rangeUri));
|
||||
qHolder = queryHolder(
|
||||
QUERY_LOCATE_CONFIG_CONTEXT_WITH_NO_DOMAIN)
|
||||
.bindToUri("baseUri", baseUri).bindToUri(
|
||||
"rangeUri", rangeUri);
|
||||
} else {
|
||||
queryString = bindValues(
|
||||
QUERY_LOCATE_CONFIG_CONTEXT_WITH_DOMAIN,
|
||||
uriValue("baseUri", baseUri),
|
||||
uriValue("rangeUri", rangeUri),
|
||||
uriValue("domainUri", domainUri));
|
||||
qHolder = queryHolder(
|
||||
QUERY_LOCATE_CONFIG_CONTEXT_WITH_DOMAIN)
|
||||
.bindToUri("baseUri", baseUri)
|
||||
.bindToUri("rangeUri", rangeUri)
|
||||
.bindToUri("domainUri", domainUri);
|
||||
}
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("domainUri=" + domainUri + ", baseUri=" + baseUri
|
||||
+ ", rangeUri=" + rangeUri + ", queryString="
|
||||
+ queryString);
|
||||
+ ", rangeUri=" + rangeUri + ", qHolder=" + qHolder);
|
||||
}
|
||||
|
||||
ParserLocateConfigContext parser = new ParserLocateConfigContext(
|
||||
domainUri, baseUri, rangeUri);
|
||||
Set<ConfigContext> contexts = new SparqlQueryRunner(
|
||||
displayModel).executeSelect(parser, queryString);
|
||||
Set<ConfigContext> contexts = createSelectQueryContext(
|
||||
displayModel, qHolder).execute().parse(parser);
|
||||
|
||||
log.debug("found " + contexts.size() + " contexts: " + contexts);
|
||||
return contexts;
|
||||
|
|
|
@ -5,7 +5,7 @@ package edu.cornell.mannlib.vitro.webapp.searchindex.documentBuilding;
|
|||
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONTENT;
|
||||
import static edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames.ALLTEXT;
|
||||
import static edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames.ALLTEXTUNSTEMMED;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.sparql.SelectQueryRunner.createQueryContext;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.SparqlQueryRunner.createSelectQueryContext;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
@ -24,7 +24,7 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
|||
import edu.cornell.mannlib.vitro.webapp.utils.configuration.ContextModelsUser;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.configuration.Property;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.configuration.Validation;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparql.SelectQueryHolder;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.QueryHolder;
|
||||
|
||||
/**
|
||||
* Modify the document, adding the results of one or more select queries.
|
||||
|
@ -151,10 +151,10 @@ public class SelectQueryDocumentModifier implements DocumentModifier,
|
|||
|
||||
private List<String> getTextForQuery(String query, Individual ind) {
|
||||
try {
|
||||
SelectQueryHolder queryHolder = new SelectQueryHolder(query)
|
||||
.bindToUri("uri", ind.getURI());
|
||||
List<String> list = createQueryContext(rdfService, queryHolder)
|
||||
.execute().getStringFields().flatten();
|
||||
QueryHolder queryHolder = new QueryHolder(query).bindToUri("uri",
|
||||
ind.getURI());
|
||||
List<String> list = createSelectQueryContext(rdfService,
|
||||
queryHolder).execute().toStringFields().flatten();
|
||||
log.debug(label + " - query: '" + query + "' returns " + list);
|
||||
return list;
|
||||
} catch (Throwable t) {
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.searchindex.indexing;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONTENT;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.sparql.SelectQueryRunner.createQueryContext;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.sparql.SelectQueryRunner.selectQuery;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.SparqlQueryRunner.createSelectQueryContext;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.SparqlQueryRunner.queryHolder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
@ -23,7 +23,7 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
|||
import edu.cornell.mannlib.vitro.webapp.utils.configuration.ContextModelsUser;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.configuration.Property;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.configuration.Validation;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparql.SelectQueryHolder;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.QueryHolder;
|
||||
|
||||
/**
|
||||
* Find URIs based on one or more select queries.
|
||||
|
@ -118,7 +118,7 @@ public class SelectQueryUriFinder implements IndexingUriFinder,
|
|||
}
|
||||
|
||||
private List<String> getUrisForQuery(Statement stmt, String queryString) {
|
||||
SelectQueryHolder query = selectQuery(queryString);
|
||||
QueryHolder query = queryHolder(queryString);
|
||||
query = query.bindToUri("predicate", stmt.getPredicate().getURI());
|
||||
|
||||
query = tryToBindUri(query, "subject", stmt.getSubject());
|
||||
|
@ -127,12 +127,12 @@ public class SelectQueryUriFinder implements IndexingUriFinder,
|
|||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return createQueryContext(rdfService, query).execute()
|
||||
.getStringFields().flatten();
|
||||
return createSelectQueryContext(rdfService, query).execute()
|
||||
.toStringFields().flatten();
|
||||
}
|
||||
|
||||
private SelectQueryHolder tryToBindUri(SelectQueryHolder query,
|
||||
String name, RDFNode node) {
|
||||
private QueryHolder tryToBindUri(QueryHolder query, String name,
|
||||
RDFNode node) {
|
||||
if (query == null) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -1,125 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.sparql;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.apache.jena.query.QuerySolution;
|
||||
import org.apache.jena.query.ResultSet;
|
||||
import org.apache.jena.rdf.model.RDFNode;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparql.SelectQueryRunner.ExecutingSelectQueryContext;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparql.SelectQueryRunner.SelectQueryContext;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparql.SelectQueryRunner.StringResultsMapping;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparql.SelectQueryRunner.StringResultsMappingImpl;
|
||||
|
||||
/**
|
||||
* An implementation of QueryContext based on an RDFService.
|
||||
*
|
||||
* Package access. Instances should be created only by SelectQueryRunner, or by
|
||||
* a method on this class.
|
||||
*/
|
||||
class RdfServiceQueryContext implements SelectQueryContext {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(RdfServiceQueryContext.class);
|
||||
|
||||
private final RDFService rdfService;
|
||||
private final SelectQueryHolder query;
|
||||
|
||||
RdfServiceQueryContext(RDFService rdfService, SelectQueryHolder query) {
|
||||
this.rdfService = rdfService;
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RdfServiceQueryContext bindVariableToUri(String name, String uri) {
|
||||
return new RdfServiceQueryContext(rdfService,
|
||||
query.bindToUri(name, uri));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutingSelectQueryContext execute() {
|
||||
return new RdfServiceExecutingQueryContext(rdfService, query);
|
||||
}
|
||||
|
||||
private static class RdfServiceExecutingQueryContext implements
|
||||
ExecutingSelectQueryContext {
|
||||
private final RDFService rdfService;
|
||||
private final SelectQueryHolder query;
|
||||
|
||||
public RdfServiceExecutingQueryContext(RDFService rdfService,
|
||||
SelectQueryHolder query) {
|
||||
this.rdfService = rdfService;
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringResultsMapping getStringFields(String... names) {
|
||||
Set<String> fieldNames = new HashSet<>(Arrays.asList(names));
|
||||
StringResultsMappingImpl mapping = new StringResultsMappingImpl();
|
||||
try {
|
||||
ResultSet results = RDFServiceUtils.sparqlSelectQuery(
|
||||
query.getQueryString(), rdfService);
|
||||
return mapResultsForQuery(results, fieldNames);
|
||||
} catch (Exception e) {
|
||||
log.error(
|
||||
"problem while running query '"
|
||||
+ query.getQueryString() + "'", e);
|
||||
}
|
||||
return mapping;
|
||||
}
|
||||
|
||||
private StringResultsMapping mapResultsForQuery(ResultSet results,
|
||||
Set<String> fieldNames) {
|
||||
StringResultsMappingImpl mapping = new StringResultsMappingImpl();
|
||||
while (results.hasNext()) {
|
||||
Map<String, String> rowMapping = mapResultsForRow(
|
||||
results.nextSolution(), fieldNames);
|
||||
if (!rowMapping.isEmpty()) {
|
||||
mapping.add(rowMapping);
|
||||
}
|
||||
}
|
||||
return mapping;
|
||||
}
|
||||
|
||||
private Map<String, String> mapResultsForRow(QuerySolution row,
|
||||
Set<String> fieldNames) {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
for (Iterator<String> names = row.varNames(); names.hasNext();) {
|
||||
String name = names.next();
|
||||
RDFNode node = row.get(name);
|
||||
String text = getTextForNode(node);
|
||||
if (StringUtils.isNotBlank(text)) {
|
||||
map.put(name, text);
|
||||
}
|
||||
}
|
||||
if (!fieldNames.isEmpty()) {
|
||||
map.keySet().retainAll(fieldNames);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private String getTextForNode(RDFNode node) {
|
||||
if (node == null) {
|
||||
return "";
|
||||
} else if (node.isLiteral()) {
|
||||
return node.asLiteral().getString().trim();
|
||||
} else {
|
||||
return node.toString().trim();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.sparql;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Holds the text of a SPARQL Select query, and allows you to perform some lexical
|
||||
* operations on it.
|
||||
*
|
||||
* This is immutable, so don't forget to get the result of the operations.
|
||||
*/
|
||||
public class SelectQueryHolder {
|
||||
private final String queryString;
|
||||
|
||||
public SelectQueryHolder(String queryString) {
|
||||
this.queryString = queryString;
|
||||
}
|
||||
|
||||
public String getQueryString() {
|
||||
return queryString;
|
||||
}
|
||||
|
||||
public boolean hasVariable(String name) {
|
||||
String regex = "\\?" + name + "\\b";
|
||||
return Pattern.compile(regex).matcher(queryString).find();
|
||||
}
|
||||
|
||||
public SelectQueryHolder bindToUri(String name, String uri) {
|
||||
String regex = "\\?" + name + "\\b";
|
||||
String replacement = "<" + uri + ">";
|
||||
String bound = queryString.replaceAll(regex, replacement);
|
||||
return new SelectQueryHolder(bound);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.sparql;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||
|
||||
/**
|
||||
* A conversational tool for handling SPARQL queries.
|
||||
*
|
||||
* {@code
|
||||
* Examples:
|
||||
* List<String> values = createQueryContext(rdfService, queryString)
|
||||
* .bindVariableToUri("uri", uri)
|
||||
* .execute()
|
||||
* .getStringFields("partner")
|
||||
* .flatten();
|
||||
*
|
||||
* SelectQueryHolder q = selectQuery(queryString)
|
||||
* .bindToUri("uri", uri));
|
||||
* List<Map<String, String> map = createQueryContext(rdfService, q)
|
||||
* .execute()
|
||||
* .getStringFields();
|
||||
* }
|
||||
*
|
||||
* The execute() method does not actually execute the query: it merely sets it
|
||||
* up syntactically.
|
||||
*
|
||||
* If you don't supply any field names to getStringFields(), you get all of
|
||||
* them.
|
||||
*
|
||||
* Any string value that returns a blank or empty string is omitted from the
|
||||
* results. Any row that returns no values is omitted from the results.
|
||||
*/
|
||||
public final class SelectQueryRunner {
|
||||
private static final Log log = LogFactory.getLog(SelectQueryRunner.class);
|
||||
|
||||
private SelectQueryRunner() {
|
||||
// No need to create an instance.
|
||||
}
|
||||
|
||||
public static SelectQueryHolder selectQuery(String queryString) {
|
||||
return new SelectQueryHolder(queryString);
|
||||
}
|
||||
|
||||
public static SelectQueryContext createQueryContext(RDFService rdfService,
|
||||
String queryString) {
|
||||
return createQueryContext(rdfService, selectQuery(queryString));
|
||||
}
|
||||
|
||||
public static SelectQueryContext createQueryContext(RDFService rdfService,
|
||||
SelectQueryHolder query) {
|
||||
return new RdfServiceQueryContext(rdfService, query);
|
||||
}
|
||||
|
||||
public static interface SelectQueryContext {
|
||||
public SelectQueryContext bindVariableToUri(String name, String uri);
|
||||
|
||||
public ExecutingSelectQueryContext execute();
|
||||
}
|
||||
|
||||
public static interface ExecutingSelectQueryContext {
|
||||
public StringResultsMapping getStringFields(String... fieldNames);
|
||||
}
|
||||
|
||||
public static interface StringResultsMapping extends
|
||||
List<Map<String, String>> {
|
||||
public List<String> flatten();
|
||||
|
||||
public Set<String> flattenToSet();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Helper classes
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
static class StringResultsMappingImpl extends
|
||||
ArrayList<Map<String, String>> implements StringResultsMapping {
|
||||
|
||||
@Override
|
||||
public List<String> flatten() {
|
||||
List<String> flat = new ArrayList<>();
|
||||
for (Map<String, String> map : this) {
|
||||
flat.addAll(map.values());
|
||||
}
|
||||
return flat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> flattenToSet() {
|
||||
return new HashSet<>(flatten());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils;
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.sparql;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
|
@ -0,0 +1,87 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.jena.query.Query;
|
||||
import org.apache.jena.query.QueryExecution;
|
||||
import org.apache.jena.query.QueryExecutionFactory;
|
||||
import org.apache.jena.query.QueryFactory;
|
||||
import org.apache.jena.query.Syntax;
|
||||
import org.apache.jena.rdf.model.Model;
|
||||
import org.apache.jena.rdf.model.ModelFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.SparqlQueryRunner.ConstructQueryContext;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.SparqlQueryRunner.ExecutingConstructQueryContext;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
public class ModelConstructQueryContext implements ConstructQueryContext {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(ModelConstructQueryContext.class);
|
||||
|
||||
private static final Syntax SYNTAX = Syntax.syntaxARQ;
|
||||
|
||||
private final Model model;
|
||||
private final QueryHolder query;
|
||||
|
||||
public ModelConstructQueryContext(Model model, QueryHolder query) {
|
||||
this.model = model;
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstructQueryContext bindVariableToUri(String name, String uri) {
|
||||
return new ModelConstructQueryContext(model, query.bindToUri(name, uri));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstructQueryContext bindVariableToPlainLiteral(String name,
|
||||
String value) {
|
||||
return new ModelConstructQueryContext(model, query.bindToPlainLiteral(
|
||||
name, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ModelConstructQueryContext[query=" + query + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutingConstructQueryContext execute() {
|
||||
return new ModelExecutingConstructQueryContext(model, query);
|
||||
}
|
||||
|
||||
private static class ModelExecutingConstructQueryContext implements
|
||||
ExecutingConstructQueryContext {
|
||||
private final Model model;
|
||||
private final QueryHolder query;
|
||||
|
||||
public ModelExecutingConstructQueryContext(Model model, QueryHolder query) {
|
||||
this.model = model;
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model toModel() {
|
||||
QueryExecution qe = null;
|
||||
try {
|
||||
Query q = QueryFactory.create(query.getQueryString(), SYNTAX);
|
||||
qe = QueryExecutionFactory.create(q, model);
|
||||
return qe.execConstruct();
|
||||
} catch (Exception e) {
|
||||
log.error(
|
||||
"problem while running query '"
|
||||
+ query.getQueryString() + "'", e);
|
||||
return ModelFactory.createDefaultModel();
|
||||
} finally {
|
||||
if (qe != null) {
|
||||
qe.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.jena.query.Query;
|
||||
import org.apache.jena.query.QueryExecution;
|
||||
import org.apache.jena.query.QueryExecutionFactory;
|
||||
import org.apache.jena.query.QueryFactory;
|
||||
import org.apache.jena.query.ResultSet;
|
||||
import org.apache.jena.query.ResultSetFormatter;
|
||||
import org.apache.jena.query.Syntax;
|
||||
import org.apache.jena.rdf.model.Model;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.SparqlQueryRunner.ExecutingSelectQueryContext;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.SparqlQueryRunner.SelectQueryContext;
|
||||
|
||||
/**
|
||||
* An implementation of QueryContext based on a Model.
|
||||
*
|
||||
* Package access. Instances should be created only by SparqlQueryRunner, or by
|
||||
* a method on this class.
|
||||
*/
|
||||
class ModelSelectQueryContext implements SelectQueryContext {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(ModelSelectQueryContext.class);
|
||||
|
||||
private static final Syntax SYNTAX = Syntax.syntaxARQ;
|
||||
|
||||
private final Model model;
|
||||
private final QueryHolder query;
|
||||
|
||||
public ModelSelectQueryContext(Model model, QueryHolder query) {
|
||||
this.model = model;
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelSelectQueryContext bindVariableToUri(String name, String uri) {
|
||||
return new ModelSelectQueryContext(model, query.bindToUri(name, uri));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelSelectQueryContext bindVariableToPlainLiteral(String name,
|
||||
String value) {
|
||||
return new ModelSelectQueryContext(model, query.bindToPlainLiteral(
|
||||
name, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ModelSelectQueryContext[query=" + query + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutingSelectQueryContext execute() {
|
||||
return new ModelExecutingQueryContext(model, query);
|
||||
}
|
||||
|
||||
private static class ModelExecutingQueryContext implements
|
||||
ExecutingSelectQueryContext {
|
||||
private final Model model;
|
||||
private final QueryHolder query;
|
||||
|
||||
public ModelExecutingQueryContext(Model model, QueryHolder query) {
|
||||
this.model = model;
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringResultsMapping toStringFields(String... names) {
|
||||
String qString = query.getQueryString();
|
||||
Set<String> fieldNames = new HashSet<>(Arrays.asList(names));
|
||||
try {
|
||||
Query q = QueryFactory.create(qString, SYNTAX);
|
||||
QueryExecution qexec = QueryExecutionFactory.create(q, model);
|
||||
try {
|
||||
ResultSet results = qexec.execSelect();
|
||||
return new StringResultsMapping(results, fieldNames);
|
||||
} finally {
|
||||
qexec.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("problem while running query '" + qString + "'", e);
|
||||
return StringResultsMapping.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T parse(ResultSetParser<T> parser) {
|
||||
String qString = query.getQueryString();
|
||||
try {
|
||||
Query q = QueryFactory.create(qString, SYNTAX);
|
||||
QueryExecution qexec = QueryExecutionFactory.create(q, model);
|
||||
try {
|
||||
return parser.parseResults(qString, qexec.execSelect());
|
||||
} finally {
|
||||
qexec.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("problem while running query '" + qString + "'", e);
|
||||
return parser.defaultValue();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToOutput(OutputStream output) {
|
||||
String qString = query.getQueryString();
|
||||
try {
|
||||
Query q = QueryFactory.create(qString, SYNTAX);
|
||||
QueryExecution qexec = QueryExecutionFactory.create(q, model);
|
||||
try {
|
||||
ResultSetFormatter.outputAsJSON(output, qexec.execSelect());
|
||||
} finally {
|
||||
qexec.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("problem while running query '" + qString + "'", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Holds the text of a SPARQL query, and allows you to perform some lexical
|
||||
* operations on it.
|
||||
*
|
||||
* This is immutable, so don't forget to get the result of the operations.
|
||||
*/
|
||||
public class QueryHolder {
|
||||
private final String queryString;
|
||||
|
||||
public QueryHolder(String queryString) {
|
||||
this.queryString = Objects.requireNonNull(queryString);
|
||||
}
|
||||
|
||||
public String getQueryString() {
|
||||
return queryString;
|
||||
}
|
||||
|
||||
public boolean hasVariable(String name) {
|
||||
String regex = "\\?" + name + "\\b";
|
||||
return Pattern.compile(regex).matcher(queryString).find();
|
||||
}
|
||||
|
||||
public QueryHolder bindToUri(String name, String uri) {
|
||||
String regex = "\\?" + name + "\\b";
|
||||
String replacement = "<" + uri + ">";
|
||||
String bound = replaceWithinBraces(regex, replacement);
|
||||
return new QueryHolder(bound);
|
||||
}
|
||||
|
||||
public QueryHolder bindToPlainLiteral(String name, String value) {
|
||||
String regex = "\\?" + name + "\\b";
|
||||
String replacement = '"' + value + '"';
|
||||
String bound = replaceWithinBraces(regex, replacement);
|
||||
return new QueryHolder(bound);
|
||||
}
|
||||
|
||||
private String replaceWithinBraces(String regex, String replacement) {
|
||||
int openBrace = queryString.indexOf('{');
|
||||
int closeBrace = queryString.lastIndexOf('}');
|
||||
if (openBrace == -1 || closeBrace == -1) {
|
||||
return queryString;
|
||||
} else {
|
||||
String prefix = queryString.substring(0, openBrace);
|
||||
String suffix = queryString.substring(closeBrace);
|
||||
String patterns = queryString.substring(openBrace, closeBrace);
|
||||
return prefix + patterns.replaceAll(regex, replacement) + suffix;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return queryString.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
} else if (obj == null) {
|
||||
return false;
|
||||
} else if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
QueryHolder that = (QueryHolder) obj;
|
||||
return Objects.equals(this.queryString, that.queryString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "QueryHolder[" + queryString + "]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
# A conversational API for running SPARQL queries
|
||||
|
||||
`edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner` provides a syntactically simple
|
||||
way to manipulate and execute SPARQL queries. The query may be run against a Jena `Model`
|
||||
or a Vitro `RDFService`.
|
||||
|
||||
The API supports the most common tasks:
|
||||
|
||||
+ bind URI values to variables in the query.
|
||||
+ bind plain literal values to variables in the query.
|
||||
+ execute a CONSTRUCT query and return a Jena model.
|
||||
+ execute a SELECT query and return the results in a variety of formats:
|
||||
+ a List of String values
|
||||
+ a Set of String values
|
||||
+ a List of Maps of String values
|
||||
+ a JSON-formatted output stream
|
||||
+ the output of a custom parser class.
|
||||
|
||||
The API could reasonably be extended to perform other operations, or to produce
|
||||
additional forms of output. It currently provides only the functionality that
|
||||
was immediately useful at the time of writing.
|
||||
|
||||
## Usage Examples
|
||||
|
||||
In general, the usage pattern is to
|
||||
|
||||
+ create the query context
|
||||
+ optionally bind values to variables in the query
|
||||
+ execute
|
||||
+ transform the results
|
||||
|
||||
### SELECT to a List of Strings
|
||||
|
||||
Run a SELECT query, binding a value to the variable `?uri` and returning
|
||||
a List of the values that are returned for the variable `?partner`.
|
||||
|
||||
List<String> values = createSelectQueryContext(rdfService, queryString)
|
||||
.bindVariableToUri("uri", uri)
|
||||
.execute()
|
||||
.toStringFields("partner")
|
||||
.flatten();
|
||||
|
||||
### SELECT to a List of Maps
|
||||
|
||||
Example: Run a SELECT query, returning a list of maps of strings. Each map
|
||||
represents a record in the ResultSet, with variable names mapped to the
|
||||
value in that record, translated to a String.
|
||||
|
||||
List<Map<String, String>> maps = createSelectQueryContext(model, queryString)
|
||||
.execute()
|
||||
.toStringFields()
|
||||
.getListOfMaps();
|
||||
|
||||
>_Note: Null or empty values are omitted from the maps; empty maps are omitted from the list._
|
||||
|
||||
|
||||
### SELECT to a Parser
|
||||
|
||||
MyQueryResult mqr = createSelectQueryContext(model, queryString)
|
||||
.bindVariableToUri("uri", uri)
|
||||
.bindVariableToPlainLiteral("id", "PW-4250")
|
||||
.execute()
|
||||
.parse(new MyQueryParser());
|
||||
|
||||
### CONSTRUCT to a Model
|
||||
|
||||
Model m = createConstructQueryContext(rdfService, queryString)
|
||||
.execute()
|
||||
.toModel();
|
||||
|
||||
## Using the QueryHolder
|
||||
|
||||
The `QueryHolder` class can be useful in itself, for manipulating a query string.
|
||||
|
||||
### Bind variables in a query
|
||||
|
||||
String boundQuery = queryHolder(rawQuery)
|
||||
.bindToUri("uri", uri)
|
||||
.getQueryString();
|
||||
|
||||
### Inquire about unbound variables
|
||||
|
||||
boolean foundIt = queryHolder(rawQuery)
|
||||
.hasVariable("name");
|
||||
|
||||
### Prepare a query in advance of executing it.
|
||||
QueryHolder qh = queryHolder(queryString)
|
||||
.bindToUri("uri", uri));
|
||||
.bindVariableToPlainLiteral("id", "PW-4250")
|
||||
List<Map<String, String> map = createSelectQueryContext(model, qh)
|
||||
.execute()
|
||||
.toStringFields()
|
||||
.getListOfMaps();
|
||||
|
||||
## Parsing a ResultSet
|
||||
|
||||
By writing a parser, you can translate the `ResultSet` from a SPARQL query
|
||||
into any object, according to the translation algorithm you specify. You must
|
||||
provide the parser with both a parsing method and a default value. The parser
|
||||
will return the default value if the parsing method fails for any reason. In
|
||||
this way, you are assured that the parser will not throw an exception.
|
||||
|
||||
Here is an example of a simple parser. It inspects the first record in the
|
||||
result set and builds an `ItemInfo` object.
|
||||
|
||||
private static class ExpandProfileParser extends ResultSetParser<ItemInfo> {
|
||||
@Override
|
||||
protected ItemInfo defaultValue() {
|
||||
return new ItemInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemInfo parseResults(String queryStr, ResultSet results) {
|
||||
ItemInfo item = new ItemInfo();
|
||||
if (results.hasNext()) {
|
||||
QuerySolution solution = results.next();
|
||||
item.label = ifLiteralPresent(solution, "label", "");
|
||||
item.classLabel = ifLiteralPresent(solution, "classLabel", "");
|
||||
item.imageUrl = ifLiteralPresent(solution, "imageUrl", "");
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
This parser would be used in this way:
|
||||
|
||||
ItemInfo info = createSelectQueryContext(model, queryString)
|
||||
.execute()
|
||||
.parse(new ExpandProfileParser());
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ModelSerializationFormat.NTRIPLE;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.jena.query.QueryExecution;
|
||||
import org.apache.jena.rdf.model.Model;
|
||||
import org.apache.jena.rdf.model.ModelFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.SparqlQueryRunner.ConstructQueryContext;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.SparqlQueryRunner.ExecutingConstructQueryContext;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
public class RdfServiceConstructQueryContext implements ConstructQueryContext {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(RdfServiceConstructQueryContext.class);
|
||||
|
||||
private final RDFService rdfService;
|
||||
private final QueryHolder query;
|
||||
|
||||
public RdfServiceConstructQueryContext(RDFService rdfService,
|
||||
QueryHolder query) {
|
||||
this.rdfService = rdfService;
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstructQueryContext bindVariableToUri(String name, String uri) {
|
||||
return new RdfServiceConstructQueryContext(rdfService, query.bindToUri(
|
||||
name, uri));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstructQueryContext bindVariableToPlainLiteral(String name,
|
||||
String value) {
|
||||
return new RdfServiceConstructQueryContext(rdfService,
|
||||
query.bindToPlainLiteral(name, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutingConstructQueryContext execute() {
|
||||
return new RdfServiceExecutingConstructQueryContext(rdfService, query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RdfServiceConstructQueryContext[query=" + query + "]";
|
||||
}
|
||||
|
||||
private static class RdfServiceExecutingConstructQueryContext implements
|
||||
ExecutingConstructQueryContext {
|
||||
private final RDFService rdfService;
|
||||
private final QueryHolder query;
|
||||
|
||||
public RdfServiceExecutingConstructQueryContext(RDFService rdfService,
|
||||
QueryHolder query) {
|
||||
this.rdfService = rdfService;
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model toModel() {
|
||||
QueryExecution qe = null;
|
||||
try {
|
||||
return RDFServiceUtils.parseModel(rdfService
|
||||
.sparqlConstructQuery(query.getQueryString(), NTRIPLE),
|
||||
NTRIPLE);
|
||||
} catch (Exception e) {
|
||||
log.error(
|
||||
"problem while running query '"
|
||||
+ query.getQueryString() + "'", e);
|
||||
return ModelFactory.createDefaultModel();
|
||||
} finally {
|
||||
if (qe != null) {
|
||||
qe.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ResultFormat.JSON;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.jena.query.ResultSet;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.SparqlQueryRunner.ExecutingSelectQueryContext;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.SparqlQueryRunner.SelectQueryContext;
|
||||
|
||||
/**
|
||||
* An implementation of QueryContext based on an RDFService.
|
||||
*
|
||||
* Package access. Instances should be created only by SparqlQueryRunner, or by
|
||||
* a method on this class.
|
||||
*/
|
||||
class RdfServiceSelectQueryContext implements SelectQueryContext {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(RdfServiceSelectQueryContext.class);
|
||||
|
||||
private final RDFService rdfService;
|
||||
private final QueryHolder query;
|
||||
|
||||
RdfServiceSelectQueryContext(RDFService rdfService, QueryHolder query) {
|
||||
this.rdfService = rdfService;
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RdfServiceSelectQueryContext bindVariableToUri(String name,
|
||||
String uri) {
|
||||
return new RdfServiceSelectQueryContext(rdfService, query.bindToUri(
|
||||
name, uri));
|
||||
}
|
||||
|
||||
@Override
|
||||
public RdfServiceSelectQueryContext bindVariableToPlainLiteral(String name,
|
||||
String value) {
|
||||
return new RdfServiceSelectQueryContext(rdfService,
|
||||
query.bindToPlainLiteral(name, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RdfServiceSelectQueryContext[query=" + query + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutingSelectQueryContext execute() {
|
||||
return new RdfServiceExecutingQueryContext(rdfService, query);
|
||||
}
|
||||
|
||||
private static class RdfServiceExecutingQueryContext implements
|
||||
ExecutingSelectQueryContext {
|
||||
private final RDFService rdfService;
|
||||
private final QueryHolder query;
|
||||
|
||||
public RdfServiceExecutingQueryContext(RDFService rdfService,
|
||||
QueryHolder query) {
|
||||
this.rdfService = rdfService;
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringResultsMapping toStringFields(String... names) {
|
||||
Set<String> fieldNames = new HashSet<>(Arrays.asList(names));
|
||||
try {
|
||||
ResultSet results = RDFServiceUtils.sparqlSelectQuery(
|
||||
query.getQueryString(), rdfService);
|
||||
return new StringResultsMapping(results, fieldNames);
|
||||
} catch (Exception e) {
|
||||
log.error(
|
||||
"problem while running query '"
|
||||
+ query.getQueryString() + "'", e);
|
||||
return StringResultsMapping.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T parse(ResultSetParser<T> parser) {
|
||||
String qString = query.getQueryString();
|
||||
try {
|
||||
return parser.parseResults(qString,
|
||||
RDFServiceUtils.sparqlSelectQuery(qString, rdfService));
|
||||
} catch (Exception e) {
|
||||
log.error("problem while running query '" + qString + "'", e);
|
||||
return parser.defaultValue();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToOutput(OutputStream output) {
|
||||
try {
|
||||
InputStream resultStream = rdfService.sparqlSelectQuery(
|
||||
query.getQueryString(), JSON);
|
||||
IOUtils.copy(resultStream, output);
|
||||
} catch (Exception e) {
|
||||
log.error(
|
||||
"problem while running query '"
|
||||
+ query.getQueryString() + "'", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner;
|
||||
|
||||
import org.apache.jena.query.QuerySolution;
|
||||
import org.apache.jena.query.ResultSet;
|
||||
import org.apache.jena.rdf.model.Literal;
|
||||
import org.apache.jena.rdf.model.RDFNode;
|
||||
|
||||
/**
|
||||
* Define the interface for parsing a result set, and provide some helpful
|
||||
* methods as well.
|
||||
*/
|
||||
public abstract class ResultSetParser<T> {
|
||||
protected abstract T parseResults(String queryStr, ResultSet results);
|
||||
|
||||
protected abstract T defaultValue();
|
||||
|
||||
protected String ifResourcePresent(QuerySolution solution,
|
||||
String variableName, String defaultValue) {
|
||||
RDFNode node = solution.get(variableName);
|
||||
if (node == null || !node.isURIResource()) {
|
||||
return defaultValue;
|
||||
}
|
||||
return node.asResource().getURI();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.jena.rdf.model.Model;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||
|
||||
/**
|
||||
* A conversational tool for handling SPARQL queries.
|
||||
*
|
||||
* <pre>
|
||||
* Examples:
|
||||
* List<String> values = createSelectQueryContext(rdfService, queryString)
|
||||
* .bindVariableToUri("uri", uri)
|
||||
* .execute()
|
||||
* .toStringFields("partner")
|
||||
* .flatten();
|
||||
*
|
||||
* QueryHolder qh = queryHolder(queryString)
|
||||
* .bindToUri("uri", uri));
|
||||
* List<Map<String, String> map = createSelectQueryContext(model, qh)
|
||||
* .execute()
|
||||
* .toStringFields();
|
||||
* </pre>
|
||||
*
|
||||
* The query context can come from either an RDFService or a Model.
|
||||
*
|
||||
* The execute() method does not actually execute the query: it merely sets it
|
||||
* up syntactically.
|
||||
*
|
||||
* If you don't supply any field names to toStringFields(), you get all of
|
||||
* them.
|
||||
*
|
||||
* Any string value that returns a blank or empty string is omitted from the
|
||||
* results. Any row that returns no values is omitted from the results.
|
||||
*/
|
||||
public final class SparqlQueryRunner {
|
||||
private static final Log log = LogFactory.getLog(SparqlQueryRunner.class);
|
||||
|
||||
private SparqlQueryRunner() {
|
||||
// No need to create an instance.
|
||||
}
|
||||
|
||||
public static QueryHolder queryHolder(String queryString) {
|
||||
return new QueryHolder(queryString);
|
||||
}
|
||||
|
||||
// ------------- SELECT ----------- //
|
||||
|
||||
public static SelectQueryContext createSelectQueryContext(RDFService rdfService,
|
||||
String queryString) {
|
||||
return createSelectQueryContext(rdfService, queryHolder(queryString));
|
||||
}
|
||||
|
||||
public static SelectQueryContext createSelectQueryContext(RDFService rdfService,
|
||||
QueryHolder query) {
|
||||
return new RdfServiceSelectQueryContext(rdfService, query);
|
||||
}
|
||||
|
||||
public static SelectQueryContext createSelectQueryContext(Model model,
|
||||
String queryString) {
|
||||
return createSelectQueryContext(model, queryHolder(queryString));
|
||||
}
|
||||
|
||||
public static SelectQueryContext createSelectQueryContext(Model model,
|
||||
QueryHolder query) {
|
||||
return new ModelSelectQueryContext(model, query);
|
||||
}
|
||||
|
||||
public static interface SelectQueryContext {
|
||||
public SelectQueryContext bindVariableToUri(String name, String uri);
|
||||
|
||||
public SelectQueryContext bindVariableToPlainLiteral(String name,
|
||||
String value);
|
||||
|
||||
public ExecutingSelectQueryContext execute();
|
||||
}
|
||||
|
||||
public static interface ExecutingSelectQueryContext {
|
||||
public StringResultsMapping toStringFields(String... fieldNames);
|
||||
|
||||
public <T> T parse(ResultSetParser<T> parser);
|
||||
|
||||
public void writeToOutput(OutputStream output);
|
||||
}
|
||||
|
||||
// ------------- CONSTRUCT ----------- //
|
||||
|
||||
public static ConstructQueryContext createConstructQueryContext(RDFService rdfService,
|
||||
String queryString) {
|
||||
return createConstructQueryContext(rdfService, queryHolder(queryString));
|
||||
}
|
||||
|
||||
public static ConstructQueryContext createConstructQueryContext(RDFService rdfService,
|
||||
QueryHolder query) {
|
||||
return new RdfServiceConstructQueryContext(rdfService, query);
|
||||
}
|
||||
|
||||
public static ConstructQueryContext createConstructQueryContext(Model model,
|
||||
String queryString) {
|
||||
return createConstructQueryContext(model, queryHolder(queryString));
|
||||
}
|
||||
|
||||
public static ConstructQueryContext createConstructQueryContext(Model model,
|
||||
QueryHolder query) {
|
||||
return new ModelConstructQueryContext(model, query);
|
||||
}
|
||||
|
||||
public static interface ConstructQueryContext{
|
||||
public ConstructQueryContext bindVariableToUri(String name, String uri);
|
||||
|
||||
public ConstructQueryContext bindVariableToPlainLiteral(String name,
|
||||
String value);
|
||||
|
||||
public ExecutingConstructQueryContext execute();
|
||||
}
|
||||
|
||||
public static interface ExecutingConstructQueryContext {
|
||||
public Model toModel();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.jena.query.QuerySolution;
|
||||
import org.apache.jena.query.ResultSet;
|
||||
import org.apache.jena.rdf.model.RDFNode;
|
||||
|
||||
/**
|
||||
* Parse the set of fieldNames against the results of the query, and make the
|
||||
* extracted values available.
|
||||
*/
|
||||
public class StringResultsMapping {
|
||||
public static final StringResultsMapping EMPTY = new StringResultsMapping();
|
||||
private final List<Map<String, String>> listOfMaps;
|
||||
|
||||
public StringResultsMapping() {
|
||||
this.listOfMaps = Collections.emptyList();
|
||||
}
|
||||
|
||||
public StringResultsMapping(ResultSet results, Set<String> fieldNames) {
|
||||
this.listOfMaps = mapResultsForQuery(results, fieldNames);
|
||||
}
|
||||
|
||||
private List<Map<String, String>> mapResultsForQuery(ResultSet results,
|
||||
Set<String> fieldNames) {
|
||||
List<Map<String, String>> mapping = new ArrayList<>();
|
||||
while (results.hasNext()) {
|
||||
Map<String, String> rowMapping = mapResultsForRow(
|
||||
results.nextSolution(), fieldNames);
|
||||
if (!rowMapping.isEmpty()) {
|
||||
mapping.add(rowMapping);
|
||||
}
|
||||
}
|
||||
return mapping;
|
||||
}
|
||||
|
||||
private Map<String, String> mapResultsForRow(QuerySolution row,
|
||||
Set<String> fieldNames) {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
for (Iterator<String> names = row.varNames(); names.hasNext();) {
|
||||
String name = names.next();
|
||||
RDFNode node = row.get(name);
|
||||
String text = getTextForNode(node);
|
||||
if (StringUtils.isNotBlank(text)) {
|
||||
map.put(name, text);
|
||||
}
|
||||
}
|
||||
if (!fieldNames.isEmpty()) {
|
||||
map.keySet().retainAll(fieldNames);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private String getTextForNode(RDFNode node) {
|
||||
if (node == null) {
|
||||
return "";
|
||||
} else if (node.isLiteral()) {
|
||||
return node.asLiteral().getString().trim();
|
||||
} else {
|
||||
return node.toString().trim();
|
||||
}
|
||||
}
|
||||
|
||||
public List<Map<String, String>> getListOfMaps() {
|
||||
List<Map<String, String>> list = new ArrayList<>();
|
||||
for (Map<String, String> map: listOfMaps) {
|
||||
list.add(new HashMap<>(map));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<String> flatten() {
|
||||
List<String> flat = new ArrayList<>();
|
||||
for (Map<String, String> map : listOfMaps) {
|
||||
flat.addAll(map.values());
|
||||
}
|
||||
return flat;
|
||||
}
|
||||
|
||||
public Set<String> flattenToSet() {
|
||||
return new HashSet<>(flatten());
|
||||
}
|
||||
|
||||
}
|
|
@ -31,6 +31,11 @@ public class ModelUtilitiesTestHelper {
|
|||
createResource(classUri));
|
||||
}
|
||||
|
||||
public static Statement objectProperty(String subjectUri, String propertyUri) {
|
||||
return createStatement(createResource(subjectUri),
|
||||
createProperty(propertyUri), createResource());
|
||||
}
|
||||
|
||||
public static Statement objectProperty(String subjectUri,
|
||||
String propertyUri, String objectUri) {
|
||||
return createStatement(createResource(subjectUri),
|
||||
|
|
|
@ -16,7 +16,6 @@ import java.util.List;
|
|||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.log4j.Level;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
@ -29,7 +28,6 @@ import org.apache.jena.rdf.model.ModelFactory;
|
|||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies.ProxyRelationshipSelectionCriteria.ProxyRelationshipView;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies.ProxyRelationshipSelector.Context;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||
|
||||
/**
|
||||
* For now, just test the methods that manipulate the query string.
|
||||
*/
|
||||
public class SparqlQueryRunnerTest extends AbstractTestClass {
|
||||
@Test
|
||||
public void bindValuesNameNotFound() {
|
||||
String raw = "No such name here";
|
||||
String expected = raw;
|
||||
assertEquals(expected, bindValues(raw, uriValue("bogus", "BOGUS")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindOneUri() {
|
||||
String raw = "Replace both ?this and ?this also.";
|
||||
String expected = "Replace both <URI> and <URI> also.";
|
||||
assertEquals(expected, bindValues(raw, uriValue("this", "URI")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindTwoUris() {
|
||||
String raw = "Replace both ?this and ?that also.";
|
||||
String expected = "Replace both <URI> and <ANOTHER> also.";
|
||||
assertEquals(
|
||||
expected,
|
||||
bindValues(raw, uriValue("this", "URI"),
|
||||
uriValue("that", "ANOTHER")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void honorWordBoundary() {
|
||||
String raw = "Replace ?this but not ?thistle.";
|
||||
String expected = "Replace <URI> but not ?thistle.";
|
||||
assertEquals(expected, bindValues(raw, uriValue("this", "URI")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void honorStringLimit() {
|
||||
String raw = "?this";
|
||||
String expected = "<URI>";
|
||||
assertEquals(expected, bindValues(raw, uriValue("this", "URI")));
|
||||
}
|
||||
|
||||
private static final String REAL_WORLD_RAW = "" //
|
||||
+ "PREFIX : <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" //
|
||||
+ "\n" //
|
||||
+ "SELECT DISTINCT ?context ?config \n" //
|
||||
+ "WHERE { \n" //
|
||||
+ " ?context a :ConfigContext ; \n" //
|
||||
+ " :configContextFor ?baseUri ; \n" //
|
||||
+ " :qualifiedByDomain ?domainUri ; \n" //
|
||||
+ " :qualifiedBy ?rangeUri ; \n" //
|
||||
+ " :hasConfiguration ?config . \n" //
|
||||
+ "} \n"; //
|
||||
|
||||
private static final String REAL_WORLD_EXPECTED = "" //
|
||||
+ "PREFIX : <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" //
|
||||
+ "\n" //
|
||||
+ "SELECT DISTINCT ?context ?config \n" //
|
||||
+ "WHERE { \n" //
|
||||
+ " ?context a :ConfigContext ; \n" //
|
||||
+ " :configContextFor <http://vivoweb.org/ontology/core#relates> ; \n" //
|
||||
+ " :qualifiedByDomain <http://vivoweb.org/ontology/core#Contract> ; \n" //
|
||||
+ " :qualifiedBy <http://vivoweb.org/ontology/core#ResearcherRole> ; \n" //
|
||||
+ " :hasConfiguration ?config . \n" //
|
||||
+ "} \n"; //
|
||||
|
||||
@Test
|
||||
public void realWorldExample() {
|
||||
assertEquals(
|
||||
REAL_WORLD_EXPECTED,
|
||||
bindValues(
|
||||
REAL_WORLD_RAW,
|
||||
uriValue("baseUri",
|
||||
"http://vivoweb.org/ontology/core#relates"),
|
||||
uriValue("domainUri",
|
||||
"http://vivoweb.org/ontology/core#Contract"),
|
||||
uriValue("rangeUri",
|
||||
"http://vivoweb.org/ontology/core#ResearcherRole")));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||
|
||||
/**
|
||||
* Check the functionality of QueryHolder.
|
||||
*/
|
||||
public class QueryHolderTest extends AbstractTestClass {
|
||||
private static final String SOME_URI = "http://some.uri/";
|
||||
private static final String SOME_LITERAL = "abracadabra";
|
||||
|
||||
private static final String FIND_ONCE = "SELECT ?s ?p WHERE { ?s ?p ?bindMe }";
|
||||
private static final String URI_BOUND_ONCE = "SELECT ?s ?p WHERE { ?s ?p <"
|
||||
+ SOME_URI + "> }";
|
||||
private static final String LITERAL_BOUND_ONCE = "SELECT ?s ?p WHERE { ?s ?p \""
|
||||
+ SOME_LITERAL + "\" }";
|
||||
|
||||
private static final String FIND_TWICE = "CONSTRUCT { ?s ?p ?find_twice } WHERE { ?s ?p ?find_twice }";
|
||||
private static final String URI_BOUND_TWICE = "CONSTRUCT { ?s ?p <"
|
||||
+ SOME_URI + "> } WHERE { ?s ?p <" + SOME_URI + "> }";
|
||||
private static final String LITERAL_BOUND_TWICE = "CONSTRUCT { ?s ?p \""
|
||||
+ SOME_LITERAL + "\" } WHERE { ?s ?p \"" + SOME_LITERAL + "\" }";
|
||||
|
||||
private static final String SQUEEZED = "CONSTRUCT {?s ?p ?squeeze} WHERE {?s ?p ?squeeze}";
|
||||
private static final String URI_BOUND_SQUEEZED = "CONSTRUCT {?s ?p <"
|
||||
+ SOME_URI + ">} WHERE {?s ?p <" + SOME_URI + ">}";
|
||||
private static final String LITERAL_BOUND_SQUEEZED = "CONSTRUCT {?s ?p \""
|
||||
+ SOME_LITERAL + "\"} WHERE {?s ?p \"" + SOME_LITERAL + "\"}";
|
||||
|
||||
private static final String FIND_IN_SELECT_CLAUSE = "SELECT ?s ?p ?bindMe WHERE { ?s ?p ?bindMe }";
|
||||
private static final String URI_BOUND_IN_SELECT_CLAUSE = "SELECT ?s ?p ?bindMe WHERE { ?s ?p <"
|
||||
+ SOME_URI + "> }";
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// The tests
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
public void hasVariable_findsOne() {
|
||||
assertTrue(new QueryHolder(FIND_ONCE).hasVariable("bindMe"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasVariable_findsTwo() {
|
||||
assertTrue(new QueryHolder(FIND_TWICE).hasVariable("find_twice"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasVariable_doesntFindOne() {
|
||||
assertFalse(new QueryHolder(FIND_TWICE).hasVariable("notThere"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasVariable_notFooledByExtendedName() {
|
||||
assertFalse(new QueryHolder(FIND_ONCE).hasVariable("bind"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasVariable_notFooledByPunctuation() {
|
||||
assertTrue(new QueryHolder(SQUEEZED).hasVariable("squeeze"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindToUri_notFound_noComplaint() {
|
||||
bindToUri(FIND_ONCE, "notThere", SOME_URI).yields(FIND_ONCE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindToUri_findsOne_bindsIt() {
|
||||
bindToUri(FIND_ONCE, "bindMe", SOME_URI).yields(URI_BOUND_ONCE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindToUri_findsTwo_bindsBoth() {
|
||||
bindToUri(FIND_TWICE, "find_twice", SOME_URI).yields(URI_BOUND_TWICE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindToUri_notFooledByExtendedName() {
|
||||
bindToUri(FIND_ONCE, "bind", SOME_URI).yields(FIND_ONCE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindToUri_notFooledByPunctuation() {
|
||||
bindToUri(SQUEEZED, "squeeze", SOME_URI).yields(URI_BOUND_SQUEEZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindToPlainLiteral_notFound_noComplaint() {
|
||||
bindToLiteral(FIND_ONCE, "notThere", SOME_LITERAL).yields(FIND_ONCE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindToPlainLiteral_findsOne_bindsIt() {
|
||||
bindToLiteral(FIND_ONCE, "bindMe", SOME_LITERAL)
|
||||
.yields(LITERAL_BOUND_ONCE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindToPlainLiteral_findsTwo_bindsBoth() {
|
||||
bindToLiteral(FIND_TWICE, "find_twice", SOME_LITERAL)
|
||||
.yields(LITERAL_BOUND_TWICE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindToPlainLiteral_notFooledByExtendedName() {
|
||||
bindToLiteral(FIND_ONCE, "bind", SOME_LITERAL).yields(FIND_ONCE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindToPlainLiteral_notFooledByPunctuation() {
|
||||
bindToLiteral(SQUEEZED, "squeeze", SOME_LITERAL)
|
||||
.yields(LITERAL_BOUND_SQUEEZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void variableInSelectClauseIsLeftAlone() {
|
||||
bindToUri(FIND_IN_SELECT_CLAUSE, "bindMe", SOME_URI)
|
||||
.yields(URI_BOUND_IN_SELECT_CLAUSE);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Helper methods and classes
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private Yielder bindToUri(String query, String name, String uri) {
|
||||
QueryHolder holder = new QueryHolder(query);
|
||||
QueryHolder bound = holder.bindToUri(name, uri);
|
||||
return new Yielder(bound.getQueryString());
|
||||
}
|
||||
|
||||
private Yielder bindToLiteral(String query, String name, String value) {
|
||||
QueryHolder holder = new QueryHolder(query);
|
||||
QueryHolder bound = holder.bindToPlainLiteral(name, value);
|
||||
return new Yielder(bound.getQueryString());
|
||||
}
|
||||
|
||||
private class Yielder {
|
||||
private final String actual;
|
||||
|
||||
public Yielder(String actual) {
|
||||
this.actual = actual;
|
||||
}
|
||||
|
||||
void yields(String expected) {
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,331 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.testing.ModelUtilitiesTestHelper.dataProperty;
|
||||
import static edu.cornell.mannlib.vitro.testing.ModelUtilitiesTestHelper.model;
|
||||
import static edu.cornell.mannlib.vitro.testing.ModelUtilitiesTestHelper.objectProperty;
|
||||
import static org.apache.jena.datatypes.xsd.XSDDatatype.XSDinteger;
|
||||
import static org.apache.jena.datatypes.xsd.XSDDatatype.XSDlong;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.apache.jena.query.QuerySolution;
|
||||
import org.apache.jena.query.ResultSet;
|
||||
import org.apache.jena.rdf.model.Model;
|
||||
import org.apache.log4j.Level;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||
|
||||
public class ResultSetParserTest extends AbstractTestClass {
|
||||
|
||||
private static final String NAMESPACE = "http://namespace#";
|
||||
|
||||
private static final String SUBJECT = NAMESPACE + "subject";
|
||||
|
||||
private static final String PREDICATE_URI = NAMESPACE + "uri";
|
||||
private static final String OBJECT_URI = NAMESPACE + "objectUri";
|
||||
private static final String OBJECT_URI_DEFAULT = NAMESPACE
|
||||
+ "objectUriDefault";
|
||||
|
||||
private static final String PREDICATE_ANON = NAMESPACE + "anonymous";
|
||||
private static final String OBJECT_ANON_DEFAULT = NAMESPACE + "anonDefault";
|
||||
|
||||
private static final String PREDICATE_STRING = NAMESPACE + "string";
|
||||
private static final String OBJECT_STRING = "objectString";
|
||||
private static final String OBJECT_STRING_DEFAULT = "objectStringDefault";
|
||||
|
||||
private static final String PREDICATE_INT = NAMESPACE + "int";
|
||||
private static final Integer OBJECT_INT = 4;
|
||||
private static final Integer OBJECT_INT_DEFAULT = -1;
|
||||
|
||||
private static final String PREDICATE_LONG = NAMESPACE + "long";
|
||||
private static final Long OBJECT_LONG = 888L;
|
||||
private static final Long OBJECT_LONG_DEFAULT = -333L;
|
||||
|
||||
private static final Object PARSING_FAILURE = "PARSING_FAILURE";
|
||||
private static final Object NO_RECORDS_FOUND = "NO_RECORDS_FOUND";
|
||||
|
||||
private static final String SELECT_QUERY = "" //
|
||||
+ "SELECT ?uri ?anonymous ?string ?int ?long \n" //
|
||||
+ "WHERE { \n" //
|
||||
+ " ?s <" + PREDICATE_URI + "> ?uri . \n" //
|
||||
+ " ?s <" + PREDICATE_ANON + "> ?anon . \n" //
|
||||
+ " ?s <" + PREDICATE_STRING + "> ?string . \n" //
|
||||
+ " ?s <" + PREDICATE_INT + "> ?int . \n" //
|
||||
+ " ?s <" + PREDICATE_LONG + "> ?long . \n" //
|
||||
+ "} \n";
|
||||
|
||||
private Model model;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
setLoggerLevel(ModelSelectQueryContext.class, Level.OFF);
|
||||
|
||||
model = model(objectProperty(SUBJECT, PREDICATE_URI, OBJECT_URI),
|
||||
objectProperty(SUBJECT, PREDICATE_ANON),
|
||||
dataProperty(SUBJECT, PREDICATE_STRING, OBJECT_STRING),
|
||||
dataProperty(SUBJECT, PREDICATE_INT, OBJECT_INT, XSDinteger),
|
||||
dataProperty(SUBJECT, PREDICATE_LONG, OBJECT_LONG, XSDlong));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// The tests
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
public void errorInParse_yieldsDefaultValue() {
|
||||
assertParsingResult(PARSING_FAILURE, new BaseParser() {
|
||||
@Override
|
||||
Object parseOneLine(QuerySolution solution) {
|
||||
throw new RuntimeException("I refuse to parse this!");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
public void expectedUriFoundUri() {
|
||||
assertParsingResult(OBJECT_URI, new BaseParser() {
|
||||
@Override
|
||||
Object parseOneLine(QuerySolution solution) {
|
||||
return ifResourcePresent(solution, "uri", OBJECT_URI_DEFAULT);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expectedUriFoundNothing_returnsDefault() {
|
||||
assertParsingResult(OBJECT_URI_DEFAULT, new BaseParser() {
|
||||
@Override
|
||||
Object parseOneLine(QuerySolution solution) {
|
||||
return ifResourcePresent(solution, "nothing",
|
||||
OBJECT_URI_DEFAULT);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO Ignoring because the anonymous node isn't showing up in the
|
||||
* ResultSet. Why not? Anyway, this behaves like "foundNothing".
|
||||
*/
|
||||
@Test
|
||||
@Ignore
|
||||
public void expectedUriFoundAnonymous_returnsDefault() {
|
||||
assertParsingResult(OBJECT_URI_DEFAULT, new BaseParser() {
|
||||
@Override
|
||||
Object parseOneLine(QuerySolution solution) {
|
||||
return ifResourcePresent(solution, "anon", OBJECT_URI_DEFAULT);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expectedUriFoundString_returnsDefault() {
|
||||
assertParsingResult(OBJECT_URI_DEFAULT, new BaseParser() {
|
||||
@Override
|
||||
Object parseOneLine(QuerySolution solution) {
|
||||
return ifResourcePresent(solution, "string", OBJECT_URI_DEFAULT);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
public void expectedStringFoundString() {
|
||||
assertParsingResult(OBJECT_STRING, new BaseParser() {
|
||||
@Override
|
||||
Object parseOneLine(QuerySolution solution) {
|
||||
return ifLiteralPresent(solution, "string",
|
||||
OBJECT_STRING_DEFAULT);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expectedStringFoundNothing_returnsDefault() {
|
||||
assertParsingResult(OBJECT_STRING_DEFAULT, new BaseParser() {
|
||||
@Override
|
||||
Object parseOneLine(QuerySolution solution) {
|
||||
return ifLiteralPresent(solution, "nothing",
|
||||
OBJECT_STRING_DEFAULT);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expectedStringFoundResource_fails() {
|
||||
assertParsingResult(PARSING_FAILURE, new BaseParser() {
|
||||
@Override
|
||||
Object parseOneLine(QuerySolution solution) {
|
||||
return ifLiteralPresent(solution, "uri", OBJECT_STRING_DEFAULT);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expectedStringFoundInt_returnsStringValueOfInt() {
|
||||
assertParsingResult(OBJECT_INT.toString(), new BaseParser() {
|
||||
@Override
|
||||
Object parseOneLine(QuerySolution solution) {
|
||||
return ifLiteralPresent(solution, "int", OBJECT_STRING_DEFAULT);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
public void expectedIntFoundInt() {
|
||||
assertParsingResult(OBJECT_INT, new BaseParser() {
|
||||
@Override
|
||||
Object parseOneLine(QuerySolution solution) {
|
||||
return ifIntPresent(solution, "int", OBJECT_INT_DEFAULT);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expectedIntFoundNothing() {
|
||||
assertParsingResult(OBJECT_INT_DEFAULT, new BaseParser() {
|
||||
@Override
|
||||
Object parseOneLine(QuerySolution solution) {
|
||||
return ifIntPresent(solution, "nothing", OBJECT_INT_DEFAULT);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expectedIntFoundResource_fails() {
|
||||
assertParsingResult(PARSING_FAILURE, new BaseParser() {
|
||||
@Override
|
||||
Object parseOneLine(QuerySolution solution) {
|
||||
return ifIntPresent(solution, "uri", OBJECT_INT_DEFAULT);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expectedIntFoundString_fails() {
|
||||
assertParsingResult(PARSING_FAILURE, new BaseParser() {
|
||||
@Override
|
||||
Object parseOneLine(QuerySolution solution) {
|
||||
return ifIntPresent(solution, "string", OBJECT_INT_DEFAULT);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expectedIntFoundLong() {
|
||||
assertParsingResult(new Integer(OBJECT_LONG.intValue()),
|
||||
new BaseParser() {
|
||||
@Override
|
||||
Object parseOneLine(QuerySolution solution) {
|
||||
return ifIntPresent(solution, "long",
|
||||
OBJECT_INT_DEFAULT);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
public void expectedLongFoundLong() {
|
||||
assertParsingResult(OBJECT_LONG, new BaseParser() {
|
||||
@Override
|
||||
Object parseOneLine(QuerySolution solution) {
|
||||
return ifLongPresent(solution, "long", OBJECT_LONG_DEFAULT);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expectedLongFoundNothing() {
|
||||
assertParsingResult(OBJECT_LONG_DEFAULT, new BaseParser() {
|
||||
@Override
|
||||
Object parseOneLine(QuerySolution solution) {
|
||||
return ifLongPresent(solution, "nothing", OBJECT_LONG_DEFAULT);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expectedLongFoundResource_fails() {
|
||||
assertParsingResult(PARSING_FAILURE, new BaseParser() {
|
||||
@Override
|
||||
Object parseOneLine(QuerySolution solution) {
|
||||
return ifLongPresent(solution, "uri", OBJECT_LONG_DEFAULT);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expectedLongFoundString_fails() {
|
||||
assertParsingResult(PARSING_FAILURE, new BaseParser() {
|
||||
@Override
|
||||
Object parseOneLine(QuerySolution solution) {
|
||||
return ifLongPresent(solution, "string", OBJECT_LONG_DEFAULT);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expectedLongFoundInt() {
|
||||
assertParsingResult(new Long(OBJECT_INT), new BaseParser() {
|
||||
@Override
|
||||
Object parseOneLine(QuerySolution solution) {
|
||||
return ifLongPresent(solution, "int", OBJECT_LONG_DEFAULT);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* ifLongPresent, return value or default.
|
||||
* present, absent
|
||||
* </pre>
|
||||
*/
|
||||
// ----------------------------------------------------------------------
|
||||
// Helper methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private void assertParsingResult(Object expected, BaseParser parser) {
|
||||
Object actual = SparqlQueryRunner
|
||||
.createSelectQueryContext(model, SELECT_QUERY).execute()
|
||||
.parse(parser);
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
private abstract static class BaseParser extends ResultSetParser<Object> {
|
||||
@Override
|
||||
protected Object defaultValue() {
|
||||
return PARSING_FAILURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object parseResults(String queryStr, ResultSet results) {
|
||||
if (results.hasNext()) {
|
||||
return parseOneLine(results.next());
|
||||
} else {
|
||||
return NO_RECORDS_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
abstract Object parseOneLine(QuerySolution solution);
|
||||
}
|
||||
|
||||
// private String dumpSolution(QuerySolution solution) {
|
||||
// Map<String, Object> fields = new HashMap<>();
|
||||
// Iterator<String> names = solution.varNames();
|
||||
// while (names.hasNext()) {
|
||||
// String name = names.next();
|
||||
// fields.put(name, solution.get(name));
|
||||
// }
|
||||
// return fields.toString();
|
||||
// }
|
||||
//
|
||||
}
|
|
@ -0,0 +1,170 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.testing.ModelUtilitiesTestHelper.dataProperty;
|
||||
import static edu.cornell.mannlib.vitro.testing.ModelUtilitiesTestHelper.model;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.SparqlQueryRunner.createConstructQueryContext;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.SparqlQueryRunner.createSelectQueryContext;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.SparqlQueryRunner.queryHolder;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.jena.atlas.json.JSON;
|
||||
import org.apache.jena.atlas.json.JsonObject;
|
||||
import org.apache.jena.rdf.model.Model;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.model.RDFServiceModel;
|
||||
|
||||
/**
|
||||
* Top-level smoke tests for the SparqlQueryRunnerTest. Exercise all of the
|
||||
* methods that create contexts, and show that we can do the simplest of
|
||||
* operations against them.
|
||||
*/
|
||||
public class SparqlQueryRunnerTest extends AbstractTestClass {
|
||||
private static final String SUBJECT_URI = "http://namespace/subject_uri";
|
||||
private static final String PREDICATE_URI = "http://namespace/predicate_uri";
|
||||
private static final String OBJECT_VALUE = "object_value";
|
||||
|
||||
private static final String SELECT_QUERY = "SELECT ?s ?p ?o WHERE { ?s ?p ?o . }";
|
||||
private static final JsonObject EXPECTED_SELECT_RESULTS = JSON.parse(""
|
||||
+ "{ " //
|
||||
+ " 'head' : { " //
|
||||
+ " 'vars' : [ 's', 'p', 'o' ] " //
|
||||
+ " } , " //
|
||||
+ " 'results' : { " //
|
||||
+ " 'bindings' : [ " //
|
||||
+ " { " //
|
||||
+ " 'p' : { " //
|
||||
+ " 'type' : 'uri' , " //
|
||||
+ " 'value' : 'http://namespace/predicate_uri' " //
|
||||
+ " } , " //
|
||||
+ " 'o' : { " //
|
||||
+ " 'type' : 'literal' , " //
|
||||
+ " 'value' : 'object_value' " //
|
||||
+ " } , " //
|
||||
+ " 's' : { " //
|
||||
+ " 'type' : 'uri' , " //
|
||||
+ " 'value' : 'http://namespace/subject_uri' " //
|
||||
+ " } " //
|
||||
+ " } " //
|
||||
+ " ] " //
|
||||
+ " } " //
|
||||
+ "} ");
|
||||
|
||||
private static final String CONSTRUCT_QUERY = "CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }";
|
||||
|
||||
private Model model;
|
||||
private RDFService rdfService;
|
||||
private ByteArrayOutputStream buffer;
|
||||
private Model constructed;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
model = model(dataProperty(SUBJECT_URI, PREDICATE_URI, OBJECT_VALUE));
|
||||
rdfService = new RDFServiceModel(model);
|
||||
buffer = new ByteArrayOutputStream();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// SELECT tests
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
public void selectQueryAgainstModel() {
|
||||
createSelectQueryContext(model, SELECT_QUERY).execute().writeToOutput(
|
||||
buffer);
|
||||
assertExpectedSelectResults();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void selectQueryHolderAgainstModel() {
|
||||
createSelectQueryContext(model, queryHolder(SELECT_QUERY)).execute()
|
||||
.writeToOutput(buffer);
|
||||
assertExpectedSelectResults();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void selectQueryAgainstRDFService() {
|
||||
createSelectQueryContext(rdfService, SELECT_QUERY).execute()
|
||||
.writeToOutput(buffer);
|
||||
assertExpectedSelectResults();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void selectQueryHolderAgainstRDFService() {
|
||||
createSelectQueryContext(rdfService, queryHolder(SELECT_QUERY))
|
||||
.execute().writeToOutput(buffer);
|
||||
assertExpectedSelectResults();
|
||||
}
|
||||
|
||||
/**
|
||||
* We've shown that all select contexts work. It should suffice that one of
|
||||
* them can convert to string fields.
|
||||
*/
|
||||
@Test
|
||||
public void selectToStringFields() {
|
||||
List<String> objectValues = createSelectQueryContext(model,
|
||||
SELECT_QUERY).execute().toStringFields("o").flatten();
|
||||
assertEquals(Arrays.asList(OBJECT_VALUE), objectValues);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// CONSTRUCT tests
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
public void constructQueryAgainstModel() {
|
||||
constructed = createConstructQueryContext(model, CONSTRUCT_QUERY)
|
||||
.execute().toModel();
|
||||
assertExpectedConstructResults();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructQueryHolderAgainstModel() {
|
||||
constructed = createConstructQueryContext(model,
|
||||
queryHolder(CONSTRUCT_QUERY)).execute().toModel();
|
||||
assertExpectedConstructResults();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructQueryAgainstRDFService() {
|
||||
constructed = createConstructQueryContext(rdfService, CONSTRUCT_QUERY)
|
||||
.execute().toModel();
|
||||
assertExpectedConstructResults();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructQueryHolderAgainstRDFService() {
|
||||
constructed = createConstructQueryContext(rdfService,
|
||||
queryHolder(CONSTRUCT_QUERY)).execute().toModel();
|
||||
assertExpectedConstructResults();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Helper methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private void assertExpectedSelectResults() {
|
||||
try {
|
||||
JsonObject actual = JSON.parse(buffer.toString("UTF-8"));
|
||||
assertEquals(EXPECTED_SELECT_RESULTS, actual);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
fail(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void assertExpectedConstructResults() {
|
||||
assertEquals(model.listStatements().toSet(), constructed
|
||||
.listStatements().toSet());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.testing.ModelUtilitiesTestHelper.dataProperty;
|
||||
import static edu.cornell.mannlib.vitro.testing.ModelUtilitiesTestHelper.model;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.SparqlQueryRunner.createSelectQueryContext;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.jena.rdf.model.Model;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||
|
||||
public class StringResultsMappingTest extends AbstractTestClass {
|
||||
private static final String SUBJECT_URI_1 = "http://namespace/subject_uri_1";
|
||||
private static final String PREDICATE_URI_1 = "http://namespace/predicate_uri_1";
|
||||
private static final String OBJECT_VALUE_1 = "object_value_1";
|
||||
private static final String SUBJECT_URI_2 = "http://namespace/subject_uri_2";
|
||||
private static final String PREDICATE_URI_2 = "http://namespace/predicate_uri_2";
|
||||
private static final String OBJECT_VALUE_2 = "object_value_2";
|
||||
|
||||
private static final String SELECT_QUERY = "SELECT ?s ?p ?o WHERE { ?s ?p ?o . }";
|
||||
|
||||
private static final List<Map<String, String>> LIST_ALL_FIELDS = list(
|
||||
map(entry("s", SUBJECT_URI_1), entry("p", PREDICATE_URI_1),
|
||||
entry("o", OBJECT_VALUE_1)),
|
||||
map(entry("s", SUBJECT_URI_2), entry("p", PREDICATE_URI_2),
|
||||
entry("o", OBJECT_VALUE_2)));
|
||||
private static final List<Map<String, String>> LIST_ONE_FIELD = list(
|
||||
map(entry("o", OBJECT_VALUE_1)), map(entry("o", OBJECT_VALUE_2)));
|
||||
|
||||
private static final List<String> FLATTEN_ALL_FIELDS = list(SUBJECT_URI_1,
|
||||
PREDICATE_URI_1, OBJECT_VALUE_1, SUBJECT_URI_2, PREDICATE_URI_2,
|
||||
OBJECT_VALUE_2);
|
||||
private static final List<String> FLATTEN_ONE_FIELD = list(OBJECT_VALUE_1,
|
||||
OBJECT_VALUE_2);
|
||||
|
||||
private Model model;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
model = model(
|
||||
dataProperty(SUBJECT_URI_1, PREDICATE_URI_1, OBJECT_VALUE_1),
|
||||
dataProperty(SUBJECT_URI_2, PREDICATE_URI_2, OBJECT_VALUE_2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkMapsOfAllFields() {
|
||||
assertEquivalentUnorderedLists(LIST_ALL_FIELDS,
|
||||
createSelectQueryContext(model, SELECT_QUERY).execute()
|
||||
.toStringFields().getListOfMaps());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkMapsOfOneField() {
|
||||
assertEquivalentUnorderedLists(LIST_ONE_FIELD,
|
||||
createSelectQueryContext(model, SELECT_QUERY).execute()
|
||||
.toStringFields("o").getListOfMaps());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkFlattenAllFields() {
|
||||
assertEquivalentUnorderedLists(FLATTEN_ALL_FIELDS,
|
||||
createSelectQueryContext(model, SELECT_QUERY).execute()
|
||||
.toStringFields().flatten());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkFlattenOneField() {
|
||||
assertEquivalentUnorderedLists(FLATTEN_ONE_FIELD,
|
||||
createSelectQueryContext(model, SELECT_QUERY).execute()
|
||||
.toStringFields("o").flatten());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkFlattenToSet() {
|
||||
assertEquals(new HashSet<>(FLATTEN_ONE_FIELD),
|
||||
createSelectQueryContext(model, SELECT_QUERY).execute()
|
||||
.toStringFields("o").flattenToSet());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Helper methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private <T> void assertEquivalentUnorderedLists(List<T> list1, List<T> list2) {
|
||||
Collections.sort(list1, new ArbitraryOrder<>());
|
||||
Collections.sort(list2, new ArbitraryOrder<>());
|
||||
assertEquals(list1, list2);
|
||||
}
|
||||
|
||||
private static class ArbitraryOrder<T> implements Comparator<T> {
|
||||
@Override
|
||||
public int compare(T t1, T t2) {
|
||||
return t1.hashCode() - t2.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
private static <T> List<T> list(T... items) {
|
||||
List<T> l = new ArrayList<>();
|
||||
for (T item : items) {
|
||||
l.add(item);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
private static Map<String, String> map(Entry... entries) {
|
||||
Map<String, String> m = new HashMap<>();
|
||||
for (Entry entry : entries) {
|
||||
m.put(entry.key, entry.value);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
private static Entry entry(String key, String value) {
|
||||
return new Entry(key, value);
|
||||
}
|
||||
|
||||
private static class Entry {
|
||||
final String key;
|
||||
final String value;
|
||||
|
||||
Entry(String key, String value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue