Updates for enabling the association of sparql queries with OWL classes and allowing the individual response builder to retrieve data (using data getters) and make that data available to the templates. Additionally, I'm adding a new data post processor that allows 'duplicate' results (or results with the same object uri for the main subject uri) to be returned - this relates to work being done by Frances for Vitro. This post processor will need to be explicitly included for it to be used.
This commit is contained in:
parent
4f7e6d0ee4
commit
0b3d14ebab
5 changed files with 213 additions and 2 deletions
|
@ -31,6 +31,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.QueryUtils;
|
|||
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.dataGetter.ExecuteDataRetrieval;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.beanswrappers.ReadOnlyBeansWrapper;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.IndividualTemplateModel;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individuallist.ListedIndividual;
|
||||
|
@ -59,6 +60,7 @@ class IndividualResponseBuilder {
|
|||
private final WebappDaoFactory wadf;
|
||||
private final IndividualDao iDao;
|
||||
private final ObjectPropertyDao opDao;
|
||||
private final ExecuteDataRetrieval eDataRetrieval;
|
||||
|
||||
private final Individual individual;
|
||||
|
||||
|
@ -69,6 +71,8 @@ class IndividualResponseBuilder {
|
|||
this.opDao = wadf.getObjectPropertyDao();
|
||||
|
||||
this.individual = individual;
|
||||
//initializing execute data retrieval
|
||||
this.eDataRetrieval = new ExecuteDataRetrieval(this.vreq, this.vreq.getDisplayModel(), this.individual);
|
||||
}
|
||||
|
||||
ResponseValues assembleResponse() throws TemplateModelException {
|
||||
|
@ -80,6 +84,14 @@ class IndividualResponseBuilder {
|
|||
body.put("temporalVisualizationEnabled", getTemporalVisualizationFlag());
|
||||
body.put("verbosePropertySwitch", getVerbosePropertyValues());
|
||||
|
||||
//Execute data getters that might apply to this individual, e.g. because of the class of the individual
|
||||
try{
|
||||
this.eDataRetrieval.executeDataGetters(body);
|
||||
} catch(Exception ex) {
|
||||
log.error("Data retrieval for individual lead to error", ex);
|
||||
}
|
||||
|
||||
//Individual template model
|
||||
IndividualTemplateModel itm = getIndividualTemplateModel(individual);
|
||||
/* We need to expose non-getters in displaying the individual's property list,
|
||||
* since it requires calls to methods with parameters.
|
||||
|
|
|
@ -74,6 +74,25 @@ public class DataGetterUtils {
|
|||
return dgList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of DataGetter objects that are associated with a JAVA class.
|
||||
* This allows the individual profile for an individual of a specific class to be returned .
|
||||
*/
|
||||
public static List<DataGetter> getDataGettersForClass( VitroRequest vreq, Model displayModel, String classURI)
|
||||
throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, SecurityException, InvocationTargetException, NoSuchMethodException{
|
||||
//get data getter uris for pageURI
|
||||
List<String> dgUris = getDataGetterURIsForClassURI( displayModel, classURI);
|
||||
|
||||
List<DataGetter> dgList = new ArrayList<DataGetter>();
|
||||
for( String dgURI: dgUris){
|
||||
DataGetter dg =dataGetterForURI(vreq, displayModel, dgURI) ;
|
||||
if( dg != null )
|
||||
dgList.add(dg);
|
||||
}
|
||||
log.debug("getDataGettersForClass: " + dgList);
|
||||
return dgList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a DataGetter using information in the
|
||||
* displayModel for the individual with the URI given by dataGetterURI
|
||||
|
@ -163,7 +182,7 @@ public class DataGetterUtils {
|
|||
|
||||
private static List<String> getDataGetterURIsForPageURI(Model displayModel, String pageURI) {
|
||||
String query = prefixes +
|
||||
"SELECT ?dataGetter WHERE { ?pageURI display:hasDataGetter ?dataGetter }";
|
||||
"SELECT ?dataGetter WHERE { ?pageURI display:hasDataGetter ?dataGetter. }";
|
||||
Query dgForPageQuery = QueryFactory.create(query);
|
||||
|
||||
QuerySolutionMap initialBindings = new QuerySolutionMap();
|
||||
|
@ -188,6 +207,35 @@ public class DataGetterUtils {
|
|||
return dgURIs;
|
||||
}
|
||||
|
||||
//Get data getters for a specific JAVA class - associates data getters with individuals for a specific JAVA class
|
||||
private static List<String> getDataGetterURIsForClassURI(Model displayModel, String classURI) {
|
||||
//Class URI will be substituted in so this is for a specific class uri
|
||||
String query = prefixes +
|
||||
"SELECT ?dataGetter WHERE { ?classURI display:hasDataGetter ?dataGetter }";
|
||||
Query dgForPageQuery = QueryFactory.create(query);
|
||||
|
||||
QuerySolutionMap initialBindings = new QuerySolutionMap();
|
||||
initialBindings.add("classURI", ResourceFactory.createResource( classURI ));
|
||||
|
||||
List<String> dgURIs = new ArrayList<String>();
|
||||
displayModel.enterCriticalSection(false);
|
||||
try{
|
||||
QueryExecution qexec = QueryExecutionFactory.create(dgForPageQuery,displayModel,initialBindings );
|
||||
try{
|
||||
ResultSet results = qexec.execSelect();
|
||||
while (results.hasNext()) {
|
||||
QuerySolution soln = results.nextSolution();
|
||||
Resource dg = soln.getResource("dataGetter");
|
||||
if( dg != null && dg.getURI() != null){
|
||||
dgURIs.add( dg.getURI());
|
||||
}
|
||||
}
|
||||
}finally{ qexec.close(); }
|
||||
}finally{ displayModel.leaveCriticalSection(); }
|
||||
|
||||
return dgURIs;
|
||||
}
|
||||
|
||||
private static String chooseType(List<String> types, Model displayModel, String dataGetterURI) throws IllegalAccessException {
|
||||
//currently just get the first one that is not owl:Thing
|
||||
for(String type : types){
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.dataGetter;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
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.QueryExecution;
|
||||
import com.hp.hpl.jena.query.QueryExecutionFactory;
|
||||
import com.hp.hpl.jena.query.QueryFactory;
|
||||
import com.hp.hpl.jena.query.QuerySolution;
|
||||
import com.hp.hpl.jena.query.QuerySolutionMap;
|
||||
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.RDFNode;
|
||||
import com.hp.hpl.jena.rdf.model.Resource;
|
||||
import com.hp.hpl.jena.rdf.model.ResourceFactory;
|
||||
import com.hp.hpl.jena.shared.Lock;
|
||||
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.beans.VClassGroup;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
|
||||
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.IndividualListController.PageRecord;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.json.JsonServlet;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache;
|
||||
|
||||
|
||||
public class ExecuteDataRetrieval {
|
||||
|
||||
final static Log log = LogFactory.getLog(ExecuteDataRetrieval.class);
|
||||
Individual individual = null;
|
||||
VitroRequest vreq = null;
|
||||
Model displayModel = null;
|
||||
|
||||
/**
|
||||
* Constructor with display model and data getter URI that will be called by reflection.
|
||||
*/
|
||||
public ExecuteDataRetrieval(VitroRequest vreq, Model displayModel, Individual individual){
|
||||
//not sure if we need display model or vreq for this?
|
||||
this.individual = individual;
|
||||
this.vreq = vreq;
|
||||
this.displayModel = displayModel;
|
||||
}
|
||||
|
||||
public List<DataGetter> retrieveDataGetters() {
|
||||
//Using a hashset to prevent duplicates
|
||||
//Would this work with interfaces? In this case, all of them would be interfaces?
|
||||
HashSet<DataGetter> dataGetters = new HashSet<DataGetter>();
|
||||
List<VClass> vclasses = this.individual.getVClasses();
|
||||
//For any of the vclasses that apply to this individual, check whether
|
||||
//there are any datagetter assigned for that class
|
||||
try {
|
||||
for(VClass v: vclasses) {
|
||||
String classURI = v.getURI();
|
||||
//How to handle duplicates?
|
||||
dataGetters.addAll(DataGetterUtils.getDataGettersForClass(vreq, displayModel, classURI));
|
||||
}
|
||||
}
|
||||
catch(Exception ex) {
|
||||
log.error("Error occurred in retrieving datagetters for vclasses", ex);
|
||||
}
|
||||
List<DataGetter> dgList = new ArrayList<DataGetter>(dataGetters);
|
||||
return dgList;
|
||||
}
|
||||
|
||||
//retrieve data getters for the classes that apply to this individual
|
||||
//execute the data getters, and return the data in a map
|
||||
public void executeDataGetters(Map<String, Object> mapForTemplate)
|
||||
throws Exception {
|
||||
List<DataGetter> dgList = retrieveDataGetters();
|
||||
//Put in individual URI in map for template - e.g. sparql query can then use that information and add bindings
|
||||
mapForTemplate.put("individualURI", this.individual.getURI());
|
||||
for( DataGetter dg : dgList){
|
||||
Map<String,Object> moreData = dg.getData(mapForTemplate);
|
||||
if( moreData != null ){
|
||||
mapForTemplate.putAll(moreData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||
|
||||
/** The object property data postprocessor that is used if the view does not specify another postprocessor */
|
||||
public class MaintainDuplicatesObjectPropertyDataPostProcessor extends BaseObjectPropertyDataPostProcessor {
|
||||
|
||||
private static final Log log = LogFactory.getLog(DefaultObjectPropertyDataPostProcessor.class);
|
||||
|
||||
public MaintainDuplicatesObjectPropertyDataPostProcessor(ObjectPropertyTemplateModel optm,
|
||||
WebappDaoFactory wdf) {
|
||||
super(optm, wdf);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void process(Map<String, String> map) {
|
||||
// no default data postprocessing defined yet
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(List<Map<String, String>> data) {
|
||||
if (data.isEmpty()) {
|
||||
log.debug("No data to postprocess for property " + objectPropertyTemplateModel.getUri());
|
||||
return;
|
||||
}
|
||||
|
||||
//Process list is not called as it removes duplicates
|
||||
|
||||
for (Map<String, String> map : data) {
|
||||
process(map);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -53,7 +53,6 @@ owl:ObjectProperty
|
|||
<java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.SparqlQueryDataGetter>
|
||||
a owl:Class .
|
||||
|
||||
|
||||
########Data Properties#########
|
||||
|
||||
###Basic
|
||||
|
|
Loading…
Add table
Reference in a new issue