Updates for adding a data getter that executes a solr query to retrieve individuals for a specific vclass and returns the results - the default template is a copy of the individual list controller template - some code refactoring also breaks out some of the individual controller methods into solr query utils for potential further reuse.
This commit is contained in:
parent
8c12deacec
commit
52314c4640
6 changed files with 419 additions and 89 deletions
|
@ -28,6 +28,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Tem
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames;
|
import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames;
|
||||||
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
|
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.utils.solr.SolrQueryUtils;
|
||||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individuallist.ListedIndividual;
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individuallist.ListedIndividual;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -143,22 +144,14 @@ public class IndividualListController extends FreemarkerHttpServlet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: Remove and update reference within JsonServlet
|
||||||
public static String getAlphaParameter(VitroRequest request){
|
public static String getAlphaParameter(VitroRequest request){
|
||||||
return request.getParameter("alpha");
|
return SolrQueryUtils.getAlphaParameter(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: Remove and update reference within JsonServlet
|
||||||
public static int getPageParameter(VitroRequest request) {
|
public static int getPageParameter(VitroRequest request) {
|
||||||
String pageStr = request.getParameter("page");
|
return SolrQueryUtils.getPageParameter(request);
|
||||||
if( pageStr != null ){
|
|
||||||
try{
|
|
||||||
return Integer.parseInt(pageStr);
|
|
||||||
}catch(NumberFormatException nfe){
|
|
||||||
log.debug("could not parse page parameter");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<String,Object> getResultsForVClass(String vclassURI, int page, String alpha, IndividualDao indDao, ServletContext context)
|
public static Map<String,Object> getResultsForVClass(String vclassURI, int page, String alpha, IndividualDao indDao, ServletContext context)
|
||||||
|
@ -166,7 +159,7 @@ public class IndividualListController extends FreemarkerHttpServlet {
|
||||||
Map<String,Object> rvMap = new HashMap<String,Object>();
|
Map<String,Object> rvMap = new HashMap<String,Object>();
|
||||||
try{
|
try{
|
||||||
List<String> classUris = Collections.singletonList(vclassURI);
|
List<String> classUris = Collections.singletonList(vclassURI);
|
||||||
IndividualListQueryResults results = buildAndExecuteVClassQuery(classUris, alpha, page, INDIVIDUALS_PER_PAGE, context, indDao);
|
IndividualListQueryResults results = SolrQueryUtils.buildAndExecuteVClassQuery(classUris, alpha, page, INDIVIDUALS_PER_PAGE, context, indDao);
|
||||||
rvMap = getResultsForVClassQuery(results, page, INDIVIDUALS_PER_PAGE, alpha);
|
rvMap = getResultsForVClassQuery(results, page, INDIVIDUALS_PER_PAGE, alpha);
|
||||||
} catch (SolrServerException e) {
|
} catch (SolrServerException e) {
|
||||||
String msg = "An error occurred retrieving results for vclass query";
|
String msg = "An error occurred retrieving results for vclass query";
|
||||||
|
@ -182,7 +175,7 @@ public class IndividualListController extends FreemarkerHttpServlet {
|
||||||
public static Map<String,Object> getResultsForVClassIntersections(List<String> vclassURIs, int page, int pageSize, String alpha, IndividualDao indDao, ServletContext context) {
|
public static Map<String,Object> getResultsForVClassIntersections(List<String> vclassURIs, int page, int pageSize, String alpha, IndividualDao indDao, ServletContext context) {
|
||||||
Map<String,Object> rvMap = new HashMap<String,Object>();
|
Map<String,Object> rvMap = new HashMap<String,Object>();
|
||||||
try{
|
try{
|
||||||
IndividualListQueryResults results = buildAndExecuteVClassQuery(vclassURIs, alpha, page, pageSize, context, indDao);
|
IndividualListQueryResults results = SolrQueryUtils.buildAndExecuteVClassQuery(vclassURIs, alpha, page, pageSize, context, indDao);
|
||||||
rvMap = getResultsForVClassQuery(results, page, pageSize, alpha);
|
rvMap = getResultsForVClassQuery(results, page, pageSize, alpha);
|
||||||
} catch(Throwable th) {
|
} catch(Throwable th) {
|
||||||
log.error("Error retrieving individuals corresponding to intersection multiple classes." + vclassURIs.toString(), th);
|
log.error("Error retrieving individuals corresponding to intersection multiple classes." + vclassURIs.toString(), th);
|
||||||
|
@ -190,18 +183,12 @@ public class IndividualListController extends FreemarkerHttpServlet {
|
||||||
return rvMap;
|
return rvMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IndividualListQueryResults buildAndExecuteVClassQuery(
|
|
||||||
List<String> vclassURIs, String alpha, int page, int pageSize,
|
//TODO: Get rid of this method and utilize SolrQueryUtils - currently appears to be referenced
|
||||||
ServletContext context, IndividualDao indDao)
|
//only within DataGetterUtils
|
||||||
throws SolrServerException {
|
public static long getIndividualCount(List<String> vclassUris, IndividualDao indDao, ServletContext context) {
|
||||||
SolrQuery query = getQuery(vclassURIs, alpha, page, pageSize);
|
return SolrQueryUtils.getIndividualCount(vclassUris, indDao, context);
|
||||||
IndividualListQueryResults results = IndividualListQueryResults.runQuery(query, indDao, context);
|
}
|
||||||
log.debug("Executed solr query for " + vclassURIs);
|
|
||||||
if (results.getIndividuals().isEmpty()) {
|
|
||||||
log.debug("entities list is null for vclass " + vclassURIs);
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Map<String,Object> getResultsForVClassQuery(IndividualListQueryResults results, int page, int pageSize, String alpha) {
|
private static Map<String,Object> getResultsForVClassQuery(IndividualListQueryResults results, int page, int pageSize, String alpha) {
|
||||||
Map<String,Object> rvMap = new HashMap<String,Object>();
|
Map<String,Object> rvMap = new HashMap<String,Object>();
|
||||||
|
@ -223,68 +210,6 @@ public class IndividualListController extends FreemarkerHttpServlet {
|
||||||
return rvMap;
|
return rvMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get count of individuals without actually getting the results
|
|
||||||
public static long getIndividualCount(List<String> vclassUris, IndividualDao indDao, ServletContext context) {
|
|
||||||
SolrQuery query = new SolrQuery(makeMultiClassQuery(vclassUris));
|
|
||||||
query.setRows(0);
|
|
||||||
try {
|
|
||||||
SolrServer solr = SolrSetup.getSolrServer(context);
|
|
||||||
QueryResponse response = null;
|
|
||||||
response = solr.query(query);
|
|
||||||
return response.getResults().getNumFound();
|
|
||||||
} catch(Exception ex) {
|
|
||||||
log.error("An error occured in retrieving individual count", ex);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* builds a query with a type clause for each type in vclassUris, NAME_LOWERCASE filetred by
|
|
||||||
* alpha, and just the hits for the page for pageSize.
|
|
||||||
*/
|
|
||||||
private static SolrQuery getQuery(List<String> vclassUris, String alpha, int page, int pageSize){
|
|
||||||
String queryText = "";
|
|
||||||
|
|
||||||
try {
|
|
||||||
queryText = makeMultiClassQuery(vclassUris);
|
|
||||||
|
|
||||||
// Add alpha filter if applicable
|
|
||||||
if ( alpha != null && !"".equals(alpha) && alpha.length() == 1) {
|
|
||||||
queryText += VitroSearchTermNames.NAME_LOWERCASE + ":" + alpha.toLowerCase() + "*";
|
|
||||||
}
|
|
||||||
|
|
||||||
SolrQuery query = new SolrQuery(queryText);
|
|
||||||
|
|
||||||
//page count starts at 1, row count starts at 0
|
|
||||||
int startRow = (page-1) * pageSize ;
|
|
||||||
query.setStart( startRow ).setRows( pageSize );
|
|
||||||
|
|
||||||
// Need a single-valued field for sorting
|
|
||||||
query.setSortField(VitroSearchTermNames.NAME_LOWERCASE_SINGLE_VALUED, SolrQuery.ORDER.asc);
|
|
||||||
|
|
||||||
log.debug("Query is " + query.toString());
|
|
||||||
return query;
|
|
||||||
|
|
||||||
} catch (Exception ex){
|
|
||||||
log.error("Could not make Solr query",ex);
|
|
||||||
return new SolrQuery();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String makeMultiClassQuery( List<String> vclassUris){
|
|
||||||
List<String> queryTypes = new ArrayList<String>();
|
|
||||||
try {
|
|
||||||
// query term for rdf:type - multiple types possible
|
|
||||||
for(String vclassUri: vclassUris) {
|
|
||||||
queryTypes.add(VitroSearchTermNames.RDFTYPE + ":\"" + vclassUri + "\" ");
|
|
||||||
}
|
|
||||||
return StringUtils.join(queryTypes, " AND ");
|
|
||||||
} catch (Exception ex){
|
|
||||||
log.error("Could not make Solr query",ex);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static List<PageRecord> makePagesList( long size, int pageSize, int selectedPage ) {
|
public static List<PageRecord> makePagesList( long size, int pageSize, int selectedPage ) {
|
||||||
|
|
||||||
|
|
|
@ -138,6 +138,11 @@ public class DisplayVocabulary {
|
||||||
/* URI of property for Fixed HTML Generator */
|
/* URI of property for Fixed HTML Generator */
|
||||||
public static final String FIXED_HTML_VALUE = DISPLAY_NS + "htmlValue";
|
public static final String FIXED_HTML_VALUE = DISPLAY_NS + "htmlValue";
|
||||||
|
|
||||||
|
|
||||||
|
/* URI of property for Solr Query Generator */
|
||||||
|
public static final String VCLASSID = DISPLAY_NS + "hasVClassId";
|
||||||
|
|
||||||
|
|
||||||
//public static final Individual EVENTS = m_model.createIndividual( NS + "Events", PAGE );
|
//public static final Individual EVENTS = m_model.createIndividual( NS + "Events", PAGE );
|
||||||
|
|
||||||
//public static final Individual EVENTS_MENU_ITEM = m_model.createIndividual( NS + "EventsMenuItem", NAVIGATION_ELEMENT );
|
//public static final Individual EVENTS_MENU_ITEM = m_model.createIndividual( NS + "EventsMenuItem", NAVIGATION_ELEMENT );
|
||||||
|
|
|
@ -0,0 +1,220 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.utils.dataGetter;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
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 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.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.SearchException;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.utils.solr.SolrQueryUtils;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individuallist.ListedIndividual;
|
||||||
|
|
||||||
|
public class SolrIndividualsDataGetter extends DataGetterBase implements DataGetter{
|
||||||
|
String dataGetterURI;
|
||||||
|
List<String> vclassUris = null;
|
||||||
|
String saveToVar;
|
||||||
|
VitroRequest vreq;
|
||||||
|
ServletContext context;
|
||||||
|
|
||||||
|
|
||||||
|
final static Log log = LogFactory.getLog(SolrIndividualsDataGetter.class);
|
||||||
|
//default template
|
||||||
|
private final static String defaultTemplate = "menupage--defaultSolrIndividuals.ftl";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor with display model and data getter URI that will be called by reflection.
|
||||||
|
*/
|
||||||
|
public SolrIndividualsDataGetter(VitroRequest vreq, Model displayModel, String dataGetterURI){
|
||||||
|
this.configure(vreq, displayModel,dataGetterURI);
|
||||||
|
}
|
||||||
|
|
||||||
|
//For now, vClassURI should be passed in within model
|
||||||
|
//We are also including ability to pass as parameter
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getData(Map<String, Object> pageData) {
|
||||||
|
// Merge the pageData with the request parameters. PageData overrides
|
||||||
|
Map<String, String[]> merged = new HashMap<String, String[]>();
|
||||||
|
merged.putAll(vreq.getParameterMap());
|
||||||
|
for (String key: pageData.keySet()) {
|
||||||
|
merged.put(key, new String[] {String.valueOf(pageData.get(key))});
|
||||||
|
}
|
||||||
|
|
||||||
|
return doSolrQuery( merged);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure this instance based on the URI and display model.
|
||||||
|
*/
|
||||||
|
protected void configure(VitroRequest vreq, Model displayModel, String dataGetterURI) {
|
||||||
|
if( vreq == null )
|
||||||
|
throw new IllegalArgumentException("VitroRequest may not be null.");
|
||||||
|
if( displayModel == null )
|
||||||
|
throw new IllegalArgumentException("Display Model may not be null.");
|
||||||
|
if( dataGetterURI == null )
|
||||||
|
throw new IllegalArgumentException("PageUri may not be null.");
|
||||||
|
|
||||||
|
this.vreq = vreq;
|
||||||
|
this.context = vreq.getSession().getServletContext();
|
||||||
|
this.dataGetterURI = dataGetterURI;
|
||||||
|
this.vclassUris = new ArrayList<String>();
|
||||||
|
QuerySolutionMap initBindings = new QuerySolutionMap();
|
||||||
|
initBindings.add("dataGetterURI", ResourceFactory.createResource(this.dataGetterURI));
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
Query dataGetterConfigurationQuery = QueryFactory.create(dataGetterQuery) ;
|
||||||
|
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();
|
||||||
|
|
||||||
|
//saveToVar is OPTIONAL
|
||||||
|
Literal saveTo = soln.getLiteral("saveToVar");
|
||||||
|
if( saveTo != null && saveTo.isLiteral() ){
|
||||||
|
this.saveToVar = saveTo.asLiteral().getLexicalForm();
|
||||||
|
}else{
|
||||||
|
this.saveToVar = defaultVarNameForResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
//vclass uri is OPTIONAL
|
||||||
|
//Right now, only anticipating one but will need to change this if this is in fact a list
|
||||||
|
String vclassUriStr = null;
|
||||||
|
Resource vclassUri = soln.getResource("vclassUri");
|
||||||
|
if( vclassUri != null && vclassUri.isResource() ){
|
||||||
|
vclassUriStr = vclassUri.getURI();
|
||||||
|
}
|
||||||
|
if(vclassUriStr != null) {
|
||||||
|
this.vclassUris.add(vclassUriStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}finally{ qexec.close(); }
|
||||||
|
}finally{ displayModel.leaveCriticalSection(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Partially copied from IndividualListController
|
||||||
|
private Map<String, Object> doSolrQuery( Map<String, String[]> merged) {
|
||||||
|
if(vclassUris.size() == 0) {
|
||||||
|
if(merged.containsKey("vclassuri")) {
|
||||||
|
this.vclassUris = Arrays.asList(merged.get("vclassuri"));
|
||||||
|
} else {
|
||||||
|
log.error("No vclass uri found. Solr query will not work");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> body = new HashMap<String, Object>();
|
||||||
|
|
||||||
|
//Right now, just getting the first vclass uri, but will have to review how to get intersections or multiple classes
|
||||||
|
if(vclassUris.size() > 0) {
|
||||||
|
String vClassURI = vclassUris.get(0);
|
||||||
|
//First, get the vclass object
|
||||||
|
VClass vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vClassURI);
|
||||||
|
if (vclass == null) {
|
||||||
|
log.error("Couldn't retrieve vclass " + vClassURI);
|
||||||
|
}
|
||||||
|
|
||||||
|
String vclassUri = vclass.getURI();
|
||||||
|
body.put("vclassId", vclassUri);
|
||||||
|
vreq.setAttribute("displayType", vclassUri); // used by the template model object
|
||||||
|
//Am not sure why an attribute is used here instead of just sending this in as data to the template?
|
||||||
|
|
||||||
|
// Set title and subtitle.
|
||||||
|
VClassGroup classGroup = vclass.getGroup();
|
||||||
|
String title;
|
||||||
|
if (classGroup == null) {
|
||||||
|
title = vclass.getName();
|
||||||
|
} else {
|
||||||
|
title = classGroup.getPublicName();
|
||||||
|
body.put("subtitle", vclass.getName());
|
||||||
|
}
|
||||||
|
body.put("title", title);
|
||||||
|
populateSolrQueryResults(vclass, body);
|
||||||
|
body.put("bodyTemplate", this.defaultTemplate);
|
||||||
|
} else {
|
||||||
|
log.error("No VClass URIs found. No query will be executed");
|
||||||
|
}
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populateSolrQueryResults(VClass vclass, Map<String, Object> body) {
|
||||||
|
try {
|
||||||
|
String alpha = SolrQueryUtils.getAlphaParameter(vreq);
|
||||||
|
int page = SolrQueryUtils.getPageParameter(vreq);
|
||||||
|
Map<String,Object> map = IndividualListController.getResultsForVClass(
|
||||||
|
vclass.getURI(),
|
||||||
|
page,
|
||||||
|
alpha,
|
||||||
|
vreq.getWebappDaoFactory().getIndividualDao(),
|
||||||
|
vreq.getSession().getServletContext());
|
||||||
|
body.putAll(map);
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
List<Individual> inds = (List<Individual>)map.get("entities");
|
||||||
|
List<ListedIndividual> indsTm = new ArrayList<ListedIndividual>();
|
||||||
|
if (inds != null) {
|
||||||
|
for ( Individual ind : inds ) {
|
||||||
|
indsTm.add(new ListedIndividual(ind,vreq));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
body.put("individuals", indsTm);
|
||||||
|
body.put("rdfUrl", UrlBuilder.getUrl("/listrdf", "vclass", vclass.getURI()));
|
||||||
|
} catch (SearchException ex) {
|
||||||
|
log.error("Error retrieving results for display.", ex);
|
||||||
|
}
|
||||||
|
catch(Exception ex) {
|
||||||
|
log.error("Error occurred in retrieving results ", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String saveToVarPropertyURI= "<" + DisplayVocabulary.SAVE_TO_VAR+ ">";
|
||||||
|
private static final String vclassIdPropertyURI= "<" + DisplayVocabulary.VCLASSID+ ">";
|
||||||
|
|
||||||
|
|
||||||
|
public static final String defaultVarNameForResults = "results";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query to get the definition of the Solr individuals data getter for a given URI.
|
||||||
|
*/
|
||||||
|
private static final String dataGetterQuery =
|
||||||
|
"PREFIX display: <" + DisplayVocabulary.DISPLAY_NS +"> \n" +
|
||||||
|
"SELECT ?vclassUri ?saveToVar WHERE { \n" +
|
||||||
|
" OPTIONAL{ ?dataGetterURI "+saveToVarPropertyURI+" ?saveToVar } \n " +
|
||||||
|
" OPTIONAL{ ?dataGetterURI "+vclassIdPropertyURI+" ?vclassUri } \n " +
|
||||||
|
"}";
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -4,17 +4,37 @@ package edu.cornell.mannlib.vitro.webapp.utils.solr;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
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.LogFactory;
|
||||||
|
import org.apache.solr.client.solrj.SolrQuery;
|
||||||
|
import org.apache.solr.client.solrj.SolrServer;
|
||||||
|
import org.apache.solr.client.solrj.SolrServerException;
|
||||||
import org.apache.solr.client.solrj.response.QueryResponse;
|
import org.apache.solr.client.solrj.response.QueryResponse;
|
||||||
|
|
||||||
|
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.IndividualListQueryResults;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController.SearchException;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some static method to help in constructing Solr queries and parsing the
|
* Some static method to help in constructing Solr queries and parsing the
|
||||||
* results.
|
* results.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class SolrQueryUtils {
|
public class SolrQueryUtils {
|
||||||
|
private static final Log log = LogFactory.getLog(SolrQueryUtils.class.getName());
|
||||||
|
|
||||||
public enum Conjunction {
|
public enum Conjunction {
|
||||||
AND, OR;
|
AND, OR;
|
||||||
|
|
||||||
|
@ -100,4 +120,101 @@ public class SolrQueryUtils {
|
||||||
return fieldName + ":\"" + word + "\"";
|
return fieldName + ":\"" + word + "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Methods that can be used in multiple places, such as IndividualListController and SolrIndividualsDataGetter
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static String getAlphaParameter(VitroRequest request){
|
||||||
|
return request.getParameter("alpha");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getPageParameter(VitroRequest request) {
|
||||||
|
String pageStr = request.getParameter("page");
|
||||||
|
if( pageStr != null ){
|
||||||
|
try{
|
||||||
|
return Integer.parseInt(pageStr);
|
||||||
|
}catch(NumberFormatException nfe){
|
||||||
|
log.debug("could not parse page parameter");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get count of individuals without actually getting the results
|
||||||
|
public static long getIndividualCount(List<String> vclassUris, IndividualDao indDao, ServletContext context) {
|
||||||
|
SolrQuery query = new SolrQuery(makeMultiClassQuery(vclassUris));
|
||||||
|
query.setRows(0);
|
||||||
|
try {
|
||||||
|
SolrServer solr = SolrSetup.getSolrServer(context);
|
||||||
|
QueryResponse response = null;
|
||||||
|
response = solr.query(query);
|
||||||
|
return response.getResults().getNumFound();
|
||||||
|
} catch(Exception ex) {
|
||||||
|
log.error("An error occured in retrieving individual count", ex);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* builds a query with a type clause for each type in vclassUris, NAME_LOWERCASE filetred by
|
||||||
|
* alpha, and just the hits for the page for pageSize.
|
||||||
|
*/
|
||||||
|
public static SolrQuery getQuery(List<String> vclassUris, String alpha, int page, int pageSize){
|
||||||
|
String queryText = "";
|
||||||
|
|
||||||
|
try {
|
||||||
|
queryText = makeMultiClassQuery(vclassUris);
|
||||||
|
|
||||||
|
// Add alpha filter if applicable
|
||||||
|
if ( alpha != null && !"".equals(alpha) && alpha.length() == 1) {
|
||||||
|
queryText += VitroSearchTermNames.NAME_LOWERCASE + ":" + alpha.toLowerCase() + "*";
|
||||||
|
}
|
||||||
|
|
||||||
|
SolrQuery query = new SolrQuery(queryText);
|
||||||
|
|
||||||
|
//page count starts at 1, row count starts at 0
|
||||||
|
int startRow = (page-1) * pageSize ;
|
||||||
|
query.setStart( startRow ).setRows( pageSize );
|
||||||
|
|
||||||
|
// Need a single-valued field for sorting
|
||||||
|
query.setSortField(VitroSearchTermNames.NAME_LOWERCASE_SINGLE_VALUED, SolrQuery.ORDER.asc);
|
||||||
|
|
||||||
|
log.debug("Query is " + query.toString());
|
||||||
|
return query;
|
||||||
|
|
||||||
|
} catch (Exception ex){
|
||||||
|
log.error("Could not make Solr query",ex);
|
||||||
|
return new SolrQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String makeMultiClassQuery( List<String> vclassUris){
|
||||||
|
List<String> queryTypes = new ArrayList<String>();
|
||||||
|
try {
|
||||||
|
// query term for rdf:type - multiple types possible
|
||||||
|
for(String vclassUri: vclassUris) {
|
||||||
|
queryTypes.add(VitroSearchTermNames.RDFTYPE + ":\"" + vclassUri + "\" ");
|
||||||
|
}
|
||||||
|
return StringUtils.join(queryTypes, " AND ");
|
||||||
|
} catch (Exception ex){
|
||||||
|
log.error("Could not make Solr query",ex);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IndividualListQueryResults buildAndExecuteVClassQuery(
|
||||||
|
List<String> vclassURIs, String alpha, int page, int pageSize,
|
||||||
|
ServletContext context, IndividualDao indDao)
|
||||||
|
throws SolrServerException {
|
||||||
|
SolrQuery query = SolrQueryUtils.getQuery(vclassURIs, alpha, page, pageSize);
|
||||||
|
IndividualListQueryResults results = IndividualListQueryResults.runQuery(query, indDao, context);
|
||||||
|
log.debug("Executed solr query for " + vclassURIs);
|
||||||
|
if (results.getIndividuals().isEmpty()) {
|
||||||
|
log.debug("entities list is null for vclass " + vclassURIs);
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,11 @@ owl:ObjectProperty
|
||||||
<java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.SparqlQueryDataGetter>
|
<java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.SparqlQueryDataGetter>
|
||||||
a owl:Class .
|
a owl:Class .
|
||||||
|
|
||||||
|
##Adding a data getter type that is Solr Class search, i.e. get individuals for VClass
|
||||||
|
<java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.SolrIndividualsDataGetter>
|
||||||
|
a owl:Class .
|
||||||
|
|
||||||
|
|
||||||
########Data Properties#########
|
########Data Properties#########
|
||||||
|
|
||||||
###Basic
|
###Basic
|
||||||
|
@ -131,6 +136,11 @@ rdfs:domain
|
||||||
owl:topObjectProperty
|
owl:topObjectProperty
|
||||||
a owl:ObjectProperty .
|
a owl:ObjectProperty .
|
||||||
|
|
||||||
|
##Adding object property defining class for solr data getter
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#hasVClassId>
|
||||||
|
a owl:ObjectProperty.
|
||||||
|
|
||||||
|
|
||||||
###Vitro properties without which individual templates throw errors as are required
|
###Vitro properties without which individual templates throw errors as are required
|
||||||
|
|
||||||
<http://vitro.mannlib.cornell.edu/ns/vitro/public#mainImage>
|
<http://vitro.mannlib.cornell.edu/ns/vitro/public#mainImage>
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
||||||
|
|
||||||
|
<#-- List individuals in the requested class. -->
|
||||||
|
|
||||||
|
<#import "lib-list.ftl" as l>
|
||||||
|
|
||||||
|
<#include "individualList-checkForData.ftl">
|
||||||
|
|
||||||
|
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/css/browseIndex.css" />')}
|
||||||
|
|
||||||
|
<section class="individualList">
|
||||||
|
<h2>${title}
|
||||||
|
</h2>
|
||||||
|
<#if subtitle?has_content>
|
||||||
|
<h4>${subtitle}</h4>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<#if (!noData)>
|
||||||
|
<#if errorMessage?has_content>
|
||||||
|
<p>${errorMessage}</p>
|
||||||
|
<#else>
|
||||||
|
<#assign pagination>
|
||||||
|
<#if (pages?has_content && pages?size > 1)>
|
||||||
|
pages:
|
||||||
|
<ul class="pagination">
|
||||||
|
<#list pages as page>
|
||||||
|
<#if page.selected>
|
||||||
|
<li class="selectedNavPage">${page.text}</li>
|
||||||
|
<#else>
|
||||||
|
<#-- RY Ideally the urls would be generated by the controller; see search-pagedResults.ftl -->
|
||||||
|
<li><a href="${urls.base}/individuallist?${page.param}&vclassId=${vclassId?url}" title="page text">${page.text}</a></li>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</ul>
|
||||||
|
</#if>
|
||||||
|
</#assign>
|
||||||
|
|
||||||
|
${pagination}
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<#list individuals as individual>
|
||||||
|
<li>
|
||||||
|
<@shortView uri=individual.uri viewContext="index" />
|
||||||
|
</li>
|
||||||
|
</#list>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
${pagination}
|
||||||
|
</#if>
|
||||||
|
<#else>
|
||||||
|
${noDataNotification}
|
||||||
|
</#if>
|
||||||
|
</section> <!-- .individualList -->
|
Loading…
Add table
Add a link
Reference in a new issue