updates for sparql data getter and updates to data getter utils
This commit is contained in:
parent
eb1ff58879
commit
558985d542
5 changed files with 274 additions and 7 deletions
|
@ -3,12 +3,20 @@ package edu.cornell.mannlib.vitro.webapp.utils.dataGetter;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Enumeration;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import com.hp.hpl.jena.query.Query;
|
import com.hp.hpl.jena.query.Query;
|
||||||
import com.hp.hpl.jena.query.QueryExecution;
|
import com.hp.hpl.jena.query.QueryExecution;
|
||||||
|
@ -17,13 +25,26 @@ import com.hp.hpl.jena.query.QueryFactory;
|
||||||
import com.hp.hpl.jena.query.QuerySolution;
|
import com.hp.hpl.jena.query.QuerySolution;
|
||||||
import com.hp.hpl.jena.query.QuerySolutionMap;
|
import com.hp.hpl.jena.query.QuerySolutionMap;
|
||||||
import com.hp.hpl.jena.query.ResultSet;
|
import com.hp.hpl.jena.query.ResultSet;
|
||||||
|
import com.hp.hpl.jena.rdf.model.Literal;
|
||||||
import com.hp.hpl.jena.rdf.model.Model;
|
import com.hp.hpl.jena.rdf.model.Model;
|
||||||
|
import com.hp.hpl.jena.rdf.model.RDFNode;
|
||||||
import com.hp.hpl.jena.rdf.model.Resource;
|
import com.hp.hpl.jena.rdf.model.Resource;
|
||||||
import com.hp.hpl.jena.rdf.model.ResourceFactory;
|
import com.hp.hpl.jena.rdf.model.ResourceFactory;
|
||||||
|
import com.hp.hpl.jena.shared.Lock;
|
||||||
import com.hp.hpl.jena.vocabulary.OWL;
|
import com.hp.hpl.jena.vocabulary.OWL;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.JsonServlet;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController.PageRecord;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
|
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.PageDataGetterUtils;
|
import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.PageDataGetterUtils;
|
||||||
|
|
||||||
public class DataGetterUtils {
|
public class DataGetterUtils {
|
||||||
|
@ -180,13 +201,205 @@ public class DataGetterUtils {
|
||||||
}
|
}
|
||||||
throw new IllegalAccessException("No useful type defined for <" + dataGetterURI + ">");
|
throw new IllegalAccessException("No useful type defined for <" + dataGetterURI + ">");
|
||||||
}
|
}
|
||||||
|
//Copied from PageDaoJena
|
||||||
|
static protected String nodeToString( RDFNode node ){
|
||||||
|
if( node == null ){
|
||||||
|
return "";
|
||||||
|
}else if( node.isLiteral() ){
|
||||||
|
Literal literal = node.asLiteral();
|
||||||
|
return literal.getLexicalForm();
|
||||||
|
}else if( node.isURIResource() ){
|
||||||
|
Resource resource = node.asResource();
|
||||||
|
return resource.getURI();
|
||||||
|
}else if( node.isAnon() ){
|
||||||
|
Resource resource = node.asResource();
|
||||||
|
return resource.getId().getLabelString(); //get b-node id
|
||||||
|
}else{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static final String prefixes =
|
static final String prefixes =
|
||||||
"PREFIX rdf: <" + VitroVocabulary.RDF +"> \n" +
|
"PREFIX rdf: <" + VitroVocabulary.RDF +"> \n" +
|
||||||
"PREFIX rdfs: <" + VitroVocabulary.RDFS +"> \n" +
|
"PREFIX rdfs: <" + VitroVocabulary.RDFS +"> \n" +
|
||||||
"PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> \n" +
|
"PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> \n" +
|
||||||
"PREFIX display: <" + DisplayVocabulary.DISPLAY_NS +"> \n";
|
"PREFIX display: <" + DisplayVocabulary.DISPLAY_NS +"> \n";
|
||||||
|
|
||||||
|
//This query is used in more than one place, so can be placed here
|
||||||
|
//An alternative is to have individuals for classes data getter extend classgroupdatagetter
|
||||||
|
//This currently assumes one class group uri per data getter, but this can be extended
|
||||||
|
/**
|
||||||
|
* For page data getter conversions
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Get Individual count for Solr query for intersection of multiple classes
|
||||||
|
*/
|
||||||
|
public static long getIndividualCountForIntersection(VitroRequest vreq, ServletContext context, List<String> classUris) {
|
||||||
|
return IndividualListController.getIndividualCount(classUris, vreq.getWebappDaoFactory().getIndividualDao(), context);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Return data getter type to be employed in display model
|
||||||
|
public static String generateDataGetterTypeURI(String dataGetterClassName) {
|
||||||
|
return "java:" + dataGetterClassName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String getClassGroupForDataGetter(Model displayModel, String dataGetterURI) {
|
||||||
|
String classGroupUri = null;
|
||||||
|
QuerySolutionMap initBindings = new QuerySolutionMap();
|
||||||
|
initBindings.add("dataGetterURI", ResourceFactory.createResource(dataGetterURI));
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
//Get the class group
|
||||||
|
Query dataGetterConfigurationQuery = QueryFactory.create(classGroupForDataGetterQuery) ;
|
||||||
|
displayModel.enterCriticalSection(Lock.READ);
|
||||||
|
try{
|
||||||
|
QueryExecution qexec = QueryExecutionFactory.create(
|
||||||
|
dataGetterConfigurationQuery, displayModel, initBindings) ;
|
||||||
|
ResultSet res = qexec.execSelect();
|
||||||
|
try{
|
||||||
|
while( res.hasNext() ){
|
||||||
|
count++;
|
||||||
|
QuerySolution soln = res.next();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//model is OPTIONAL
|
||||||
|
RDFNode node = soln.getResource("classGroupUri");
|
||||||
|
if( node != null && node.isURIResource() ){
|
||||||
|
classGroupUri = node.asResource().getURI();
|
||||||
|
}else{
|
||||||
|
classGroupUri = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}finally{ qexec.close(); }
|
||||||
|
}finally{ displayModel.leaveCriticalSection(); }
|
||||||
|
return classGroupUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process results related to VClass or vclasses. Handles both single and multiple vclasses being sent.
|
||||||
|
*/
|
||||||
|
public static JSONObject processVclassResultsJSON(Map<String, Object> map, VitroRequest vreq, boolean multipleVclasses) {
|
||||||
|
JSONObject rObj = new JSONObject();
|
||||||
|
VClass vclass=null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
// Properties from ontologies used by VIVO - should not be in vitro
|
||||||
|
DataProperty fNameDp = (new DataProperty());
|
||||||
|
fNameDp.setURI("http://xmlns.com/foaf/0.1/firstName");
|
||||||
|
DataProperty lNameDp = (new DataProperty());
|
||||||
|
lNameDp.setURI("http://xmlns.com/foaf/0.1/lastName");
|
||||||
|
DataProperty preferredTitleDp = (new DataProperty());
|
||||||
|
preferredTitleDp.setURI("http://vivoweb.org/ontology/core#preferredTitle");
|
||||||
|
|
||||||
|
if( log.isDebugEnabled() ){
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Enumeration<String> e = vreq.getParameterNames();
|
||||||
|
while(e.hasMoreElements()){
|
||||||
|
String name = (String)e.nextElement();
|
||||||
|
log.debug("parameter: " + name);
|
||||||
|
for( String value : vreq.getParameterValues(name) ){
|
||||||
|
log.debug("value for " + name + ": '" + value + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//need an unfiltered dao to get firstnames and lastnames
|
||||||
|
WebappDaoFactory fullWdf = vreq.getFullWebappDaoFactory();
|
||||||
|
|
||||||
|
String[] vitroClassIdStr = vreq.getParameterValues("vclassId");
|
||||||
|
if ( vitroClassIdStr != null && vitroClassIdStr.length > 0){
|
||||||
|
for(String vclassId: vitroClassIdStr) {
|
||||||
|
vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vclassId);
|
||||||
|
if (vclass == null) {
|
||||||
|
log.error("Couldn't retrieve vclass ");
|
||||||
|
throw new Exception ("Class " + vclassId + " not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
log.error("parameter vclassId URI parameter expected ");
|
||||||
|
throw new Exception("parameter vclassId URI parameter expected ");
|
||||||
|
}
|
||||||
|
List<String> vclassIds = Arrays.asList(vitroClassIdStr);
|
||||||
|
//if single vclass expected, then include vclass. This relates to what the expected behavior is, not size of list
|
||||||
|
if(!multipleVclasses) {
|
||||||
|
//currently used for ClassGroupPage
|
||||||
|
rObj.put("vclass",
|
||||||
|
new JSONObject().put("URI",vclass.getURI())
|
||||||
|
.put("name",vclass.getName()));
|
||||||
|
} else {
|
||||||
|
//For now, utilize very last VClass (assume that that is the one to be employed)
|
||||||
|
//TODO: Find more general way of dealing with this
|
||||||
|
//put multiple ones in?
|
||||||
|
if(vclassIds.size() > 0) {
|
||||||
|
int numberVClasses = vclassIds.size();
|
||||||
|
vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vclassIds.get(numberVClasses - 1));
|
||||||
|
rObj.put("vclass", new JSONObject().put("URI",vclass.getURI())
|
||||||
|
.put("name",vclass.getName()));
|
||||||
|
}
|
||||||
|
// rObj.put("vclasses", new JSONObject().put("URIs",vitroClassIdStr)
|
||||||
|
// .put("name",vclass.getName()));
|
||||||
|
}
|
||||||
|
if (vclass != null) {
|
||||||
|
|
||||||
|
rObj.put("totalCount", map.get("totalCount"));
|
||||||
|
rObj.put("alpha", map.get("alpha"));
|
||||||
|
|
||||||
|
List<Individual> inds = (List<Individual>)map.get("entities");
|
||||||
|
log.debug("Number of individuals returned from request: " + inds.size());
|
||||||
|
JSONArray jInds = new JSONArray();
|
||||||
|
for(Individual ind : inds ){
|
||||||
|
JSONObject jo = new JSONObject();
|
||||||
|
jo.put("URI", ind.getURI());
|
||||||
|
jo.put("label",ind.getRdfsLabel());
|
||||||
|
jo.put("name",ind.getName());
|
||||||
|
jo.put("thumbUrl", ind.getThumbUrl());
|
||||||
|
jo.put("imageUrl", ind.getImageUrl());
|
||||||
|
jo.put("profileUrl", UrlBuilder.getIndividualProfileUrl(ind, vreq));
|
||||||
|
|
||||||
|
jo.put("mostSpecificTypes", JsonServlet.getMostSpecificTypes(ind,fullWdf));
|
||||||
|
jo.put("preferredTitle", JsonServlet.getDataPropertyValue(ind, preferredTitleDp, fullWdf));
|
||||||
|
|
||||||
|
jInds.put(jo);
|
||||||
|
}
|
||||||
|
rObj.put("individuals", jInds);
|
||||||
|
|
||||||
|
JSONArray wpages = new JSONArray();
|
||||||
|
//Made sure that PageRecord here is SolrIndividualListController not IndividualListController
|
||||||
|
List<PageRecord> pages = (List<PageRecord>)map.get("pages");
|
||||||
|
for( PageRecord pr: pages ){
|
||||||
|
JSONObject p = new JSONObject();
|
||||||
|
p.put("text", pr.text);
|
||||||
|
p.put("param", pr.param);
|
||||||
|
p.put("index", pr.index);
|
||||||
|
wpages.put( p );
|
||||||
|
}
|
||||||
|
rObj.put("pages",wpages);
|
||||||
|
|
||||||
|
JSONArray jletters = new JSONArray();
|
||||||
|
List<String> letters = Controllers.getLetters();
|
||||||
|
for( String s : letters){
|
||||||
|
JSONObject jo = new JSONObject();
|
||||||
|
jo.put("text", s);
|
||||||
|
jo.put("param", "alpha=" + URLEncoder.encode(s, "UTF-8"));
|
||||||
|
jletters.put( jo );
|
||||||
|
}
|
||||||
|
rObj.put("letters", jletters);
|
||||||
|
}
|
||||||
|
} catch(Exception ex) {
|
||||||
|
log.error("Error occurred in processing JSON object", ex);
|
||||||
|
}
|
||||||
|
return rObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String forClassGroupURI = "<" + DisplayVocabulary.FOR_CLASSGROUP + ">";
|
||||||
|
|
||||||
|
private static final String classGroupForDataGetterQuery =
|
||||||
|
"PREFIX display: <" + DisplayVocabulary.DISPLAY_NS +"> \n" +
|
||||||
|
"SELECT ?classGroupUri WHERE { \n" +
|
||||||
|
" ?dataGetterUri "+forClassGroupURI+" ?classGroupUri . \n" +
|
||||||
|
"}";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -206,14 +206,14 @@ public class SparqlQueryDataGetter extends DataGetterBase implements DataGetter{
|
||||||
public static final String defaultVarNameForResults = "results";
|
public static final String defaultVarNameForResults = "results";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query to get the definition of the SparqlDataGetter for a given URI.
|
* Query to get the definition of the SparqlDataGetter for a given data getter URI.
|
||||||
*/
|
*/
|
||||||
private static final String dataGetterQuery =
|
private static final String dataGetterQuery =
|
||||||
"PREFIX display: <" + DisplayVocabulary.DISPLAY_NS +"> \n" +
|
"PREFIX display: <" + DisplayVocabulary.DISPLAY_NS +"> \n" +
|
||||||
"SELECT ?query ?saveToVar ?model WHERE { \n" +
|
"SELECT ?query ?saveToVar ?model WHERE { \n" +
|
||||||
" ?pageUri "+queryPropertyURI+" ?query . \n" +
|
" ?dataGetterUri "+queryPropertyURI+" ?query . \n" +
|
||||||
" OPTIONAL{ ?pageUri "+saveToVarPropertyURI+" ?saveToVar } \n " +
|
" OPTIONAL{ ?dataGetterUri "+saveToVarPropertyURI+" ?saveToVar } \n " +
|
||||||
" OPTIONAL{ ?pageUri "+queryModelPropertyURI+" ?queryModel } \n" +
|
" OPTIONAL{ ?dataGetterUri "+queryModelPropertyURI+" ?model } \n" +
|
||||||
"}";
|
"}";
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,13 @@ owl:versionInfo
|
||||||
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#usesDataGetterClass>
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#usesDataGetterClass>
|
||||||
a owl:DatatypeProperty .
|
a owl:DatatypeProperty .
|
||||||
|
|
||||||
|
###Custom data getters that may or may not be associated with a page use the following relationships
|
||||||
|
###E.g. sparql data getters can specify the query to be used as well as what variable in the template
|
||||||
|
###should store the results
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#saveToVar>
|
||||||
|
a owl:DatatypeProperty .
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#query>
|
||||||
|
a owl:DatatypeProperty .
|
||||||
######### Object Properties#########
|
######### Object Properties#########
|
||||||
###Basic
|
###Basic
|
||||||
rdfs:range
|
rdfs:range
|
||||||
|
@ -173,4 +179,7 @@ owl:topObjectProperty
|
||||||
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#restrictResultsByClass>
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#restrictResultsByClass>
|
||||||
a owl:ObjectProperty .
|
a owl:ObjectProperty .
|
||||||
|
|
||||||
|
###Custom data getters that may or may not be associated with a page use the following relationships
|
||||||
|
###E.g. sparql data getters can specify what model to use for querying
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#queryModel>
|
||||||
|
a owl:ObjectProperty .
|
||||||
|
|
13
webapp/web/css/menupage/sparqlresults.css
Normal file
13
webapp/web/css/menupage/sparqlresults.css
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
.resultRow {
|
||||||
|
float:none;
|
||||||
|
clear:both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resultCell {
|
||||||
|
float:left;
|
||||||
|
border:1px solid #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resultHeading {
|
||||||
|
font-weight:bold;
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
<#--Save to variable is sparqlResults -->
|
||||||
|
<#assign resultsExist = false/>
|
||||||
|
<#if sparqlResults?has_content>
|
||||||
|
<#assign resultsExist = true/>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<h3>Sparql Query Results</h3>
|
||||||
|
<#if resultsExist>
|
||||||
|
<#assign numberRows = sparqlResults?size/>
|
||||||
|
<#assign firstRow = false/>
|
||||||
|
<#list sparqlResults as resultRow>
|
||||||
|
<#assign resultKeys = resultRow?keys />
|
||||||
|
<#if firstRow = false>
|
||||||
|
<div class="resultHeading resultRow">
|
||||||
|
<#list resultKeys as resultKey>
|
||||||
|
<div class="resultCell">${resultKey}</div>
|
||||||
|
</#list>
|
||||||
|
</div>
|
||||||
|
<#assign firstRow = true/>
|
||||||
|
</#if>
|
||||||
|
<div class="resultRow">
|
||||||
|
<#list resultKeys as resultKey>
|
||||||
|
<div class="resultCell">${resultRow[resultKey]}</div>
|
||||||
|
</#list>
|
||||||
|
</div>
|
||||||
|
</#list>
|
||||||
|
<#else>
|
||||||
|
No results were returned.
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/css/menupage/sparqlresults.css" />')}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue