merging 8813 8810 8803 8802 8741 8731

This commit is contained in:
briancaruso 2011-07-22 23:20:13 +00:00
parent ee42cad576
commit 199a5f6c2f
12 changed files with 585 additions and 344 deletions

View file

@ -5,13 +5,16 @@ List view configuration guidelines
REGISTERING THE LIST VIEW
-------------------------
A custom list view is associated with an object property in the file /vivo/productMods/WEB-INF/ontologies/app/listViewConfig.owl.
Example:
A custom list view is associated with an object property in the RDF files in the directory /vivo/productMods/WEB-INF/ontologies/app/loadedAtStartup
To register a list view, create a new .rdf or .n3 file in that directory. The file must be well formed RDF/XML or N3.
Example of registering a new association in a file named newListViews.n3:
<rdf:Description rdf:about="http://vivoweb.org/ontology/core#authorInAuthorship">
<display:listViewConfigFile rdf:datatype="http://www.w3.org/2001/XMLSchema#string">listViewConfig-authorInAuthorship.xml</display:listViewConfigFile>
</rdf:Description>
<http://vivoweb.org/ontology/core#authorInAuthorship>
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#listViewConfigFile>
"listViewConfig-authorInAuthorship.xml" .
Place this file in /vivo/productMods/WEB-INF/ontologies/app/loadedAtStartup, redeploy and restart tomcat to put the new custom list view in effect.
-----------------
REQUIRED ELEMENTS

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rdf:RDF [
<!ENTITY display "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#">
<!ENTITY owl "http://www.w3.org/2002/07/owl#">
<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#">
<!ENTITY xsd "http://www.w3.org/2001/XMLSchema#">
<!ENTITY vitro "http://vitro.mannlib.cornell.edu/ns/vitro/0.7#">
]>
<rdf:RDF xml:base="http://vitro.mannlib.cornell.edu/ontologies/display/1.1/"
xmlns:display="&display;"
xmlns:owl="&owl;"
xmlns:rdf="&rdf;"
xmlns:rdfs="&rdfs;"
xmlns:vitro="&vitro;">
<rdf:Description rdf:about="http://vitro.mannlib.cornell.edu/ontologies/display/1.1#hasElement">
<display:listViewConfigFile rdf:datatype="http://www.w3.org/2001/XMLSchema#string">listViewConfig-hasElement.xml</display:listViewConfigFile>
</rdf:Description>
</rdf:RDF>

View file

@ -1,23 +1,27 @@
# $This file is distributed under the terms of the license in /doc/license.txt$
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix vitroDisplay: <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix core: <http://vivoweb.org/ontology/core#> .
@prefix example: <http://example/ns/> .
# All instances of a class can be excluded from the search index
# by adding a vitroDisplay:excludeClass property between
# vitroDisplay:SearchIndex and the URI of the class
# that you would like to exclude.
# All .n3 files in this directory will be used to configure
# the search exclusions. Only .n3 files will be loaded.
#
# All .n3 or .rdf files in this directory will be used to configure
# the search exclusions. Each file must be a valid file in the format
# specified by its extension. Each file will be loaded individually and
# must be a complete stand alone example of its format. Each file must contain all
# the necessary prefixes, namespaces and preambles required by the format
# specified by its extension.
# If you would like to add classes to the
# exclusions, add a file to this directory ending in .n3 with
# N3 statements similar to this example.
#
# @prefix owl: <http://www.w3.org/2002/07/owl#> .
# @prefix vitroDisplay: <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#> .
# @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
# @prefix example: <http://example/ns/> .
#
# vitroDisplay:SearchIndex
# rdf:type owl:Thing ;
# vitroDisplay:excludeClass example:classToExclude ;

View file

@ -54,6 +54,7 @@ public class JsonServlet extends VitroHttpServlet {
private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(JsonServlet.class);
private static final int REPLY_SIZE = 256;
private static final int INDIVIDUALS_PER_PAGE = 30;
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
@ -267,7 +268,7 @@ public class JsonServlet extends VitroHttpServlet {
try {
map = IndividualListController.getResultsForVClassIntersections(
vclassURIs,
page,
page, INDIVIDUALS_PER_PAGE,
alpha,
vreq.getWebappDaoFactory().getIndividualDao(),
context);
@ -292,17 +293,11 @@ public class JsonServlet extends VitroHttpServlet {
}
public static String getDataPropertyValue(Individual ind, DataProperty dp, WebappDaoFactory wdf){
List<Literal> values = wdf.getDataPropertyStatementDao()
.getDataPropertyValuesForIndividualByProperty(ind, dp);
if( values == null || values.isEmpty() )
String value = ind.getDataValue(dp.getURI());
if( value == null || value.isEmpty() )
return "";
else{
if( values.get(0) != null )
return values.get(0).getLexicalForm();
else
return "";
}
else
return value;
}
/**

View file

@ -6,6 +6,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@ -40,8 +41,7 @@ public class IndividualListController extends FreemarkerHttpServlet {
private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(IndividualListController.class.getName());
private static final int INDIVIDUAL_LIST_CONTROLLER_MAX_RESULTS = 30000;
private static final int INDIVIDUALS_PER_PAGE = 30;
private static final int MAX_PAGES = 40; // must be even
@ -165,22 +165,23 @@ public class IndividualListController extends FreemarkerHttpServlet {
}
}
//Pulling out common code that is used for both single (regular) vclass query and multiple (intersection) query
public static Map<String,Object> getResultsForVClasses(List<String> vclassURIs, int page, String alpha, IndividualDao indDao, ServletContext context)
throws IOException, ServletException{
Map<String,Object> rvMap = new HashMap<String,Object>();
try{
SolrQuery query = getQuery(vclassURIs, alpha);
rvMap = getResultsForVClassQuery(query, page, alpha, indDao, context);
List<Individual> individuals = (List<Individual>) rvMap.get("entities");
if (individuals == null)
log.debug("entities list is null for vclasses " + vclassURIs.toString() );
} catch(Throwable th) {
log.error("An error occurred retrieving results for vclass query", th);
}
return rvMap;
}
// //Pulling out common code that is used for both single (regular) vclass query and multiple (intersection) query
// public static Map<String,Object> getResultsForVClasses(List<String> vclassURIs, int page, String alpha, IndividualDao indDao, ServletContext context)
// throws IOException, ServletException{
// Map<String,Object> rvMap = new HashMap<String,Object>();
// try{
// SolrQuery query = getQuery(vclassURIs, alpha, page, INDIVIDUALS_PER_PAGE);
// rvMap = getResultsForVClassQuery(query, page, alpha, indDao, context);
// List<Individual> individuals = (List<Individual>) rvMap.get("entities");
// if (individuals == null)
// log.debug("entities list is null for vclasses " + vclassURIs.toString() );
// } catch(Throwable th) {
// log.error("An error occurred retrieving results for vclass query", th);
// }
// return rvMap;
// }
@SuppressWarnings("unchecked")
public static Map<String,Object> getResultsForVClass(String vclassURI, int page, String alpha, IndividualDao indDao, ServletContext context)
throws IOException, SearchException{
Map<String,Object> rvMap = new HashMap<String,Object>();
@ -188,8 +189,8 @@ public class IndividualListController extends FreemarkerHttpServlet {
//make query for this rdf:type
List<String> classUris = new ArrayList<String>();
classUris.add(vclassURI);
SolrQuery query = getQuery(classUris, alpha);
rvMap = getResultsForVClassQuery(query, page, alpha, indDao, context);
SolrQuery query = getQuery(classUris, alpha, page, INDIVIDUALS_PER_PAGE);
rvMap = getResultsForVClassQuery(query, page, INDIVIDUALS_PER_PAGE, alpha, indDao, context);
List<Individual> individuals = (List<Individual>) rvMap.get("entities");
if (individuals == null)
log.debug("entities list is null for vclass " + vclassURI );
@ -204,14 +205,15 @@ public class IndividualListController extends FreemarkerHttpServlet {
return rvMap;
}
public static Map<String,Object> getResultsForVClassIntersections(List<String> vclassURIs, int page, String alpha, IndividualDao indDao, ServletContext context)
@SuppressWarnings("unchecked")
public static Map<String,Object> getResultsForVClassIntersections(List<String> vclassURIs, int page, int pageSize, String alpha, IndividualDao indDao, ServletContext context)
throws IOException, ServletException{
Map<String,Object> rvMap = new HashMap<String,Object>();
try{
// make query for multiple rdf types
SolrQuery query = getQuery(vclassURIs, alpha);
SolrQuery query = getQuery(vclassURIs, alpha, page, pageSize);
log.debug("Executed solr query for " + vclassURIs.toString());
rvMap = getResultsForVClassQuery(query, page, alpha, indDao, context);
rvMap = getResultsForVClassQuery(query, page, pageSize, alpha, indDao, context);
List<Individual> individuals = (List<Individual>) rvMap.get("entities");
if (individuals == null)
log.debug("entities list is null for vclass " + vclassURIs.toString() );
@ -225,7 +227,7 @@ public class IndividualListController extends FreemarkerHttpServlet {
* This method is now called in a couple of places. It should be refactored
* into a DAO or similar object.
*/
public static Map<String,Object> getResultsForVClassQuery(SolrQuery query, int page, String alpha, IndividualDao indDao, ServletContext context)
protected static Map<String,Object> getResultsForVClassQuery(SolrQuery query, int page, int pageSize, String alpha, IndividualDao indDao, ServletContext context)
throws IOException, ServletException {
Map<String,Object> rvMap = new HashMap<String,Object>();
SolrServer solr = SolrSetup.getSolrServer(context);
@ -252,31 +254,26 @@ public class IndividualListController extends FreemarkerHttpServlet {
long hitCount = docs.getNumFound();
log.debug("Number of search results: " + hitCount);
List<Individual> individuals = new ArrayList<Individual>(INDIVIDUALS_PER_PAGE);
int individualsAdded = 0;
int index = (page-1) * INDIVIDUALS_PER_PAGE;
if(docs.size() > 0) {
while (individualsAdded < INDIVIDUALS_PER_PAGE && index < hitCount) {
SolrDocument doc = docs.get(index);
Iterator<SolrDocument> docIter = docs.iterator();
List<Individual> individuals = new ArrayList<Individual>(docs.size());
while ( docIter.hasNext() ){
SolrDocument doc = docIter.next();
if (doc != null) {
String uri = doc.get(VitroSearchTermNames.URI).toString();
Individual individual = indDao.getIndividualByURI( uri );
if (individual != null) {
individualsAdded++;
individuals.add(individual);
if (individual != null) {
individuals.add( individual );
log.debug("Adding individual " + uri + " to individual list display");
} else {
log.debug("No existing individual for search document with uri = " + uri);
}
}
index++;
}
} else {
log.debug("Docs size is 0");
}
if ( hitCount > INDIVIDUALS_PER_PAGE ){
}
}
if ( hitCount > pageSize ){
rvMap.put("showPages", Boolean.TRUE);
List<PageRecord> pageRecords = makePagesList(hitCount, INDIVIDUALS_PER_PAGE, page);
List<PageRecord> pageRecords = makePagesList(hitCount, pageSize, page);
rvMap.put("pages", pageRecords);
}else{
rvMap.put("showPages", Boolean.FALSE);
@ -292,63 +289,71 @@ public class IndividualListController extends FreemarkerHttpServlet {
}
//Get count of individuals without actually getting the results
public static long getIndividualCount(List<String> vclassUris, IndividualDao indDao, ServletContext context) {
SolrQuery query = getQuery(vclassUris, null, 0);
try {
Map<String,Object> rvMap = getResultsForVClassQuery(query, 1, null, indDao, context);
Long count = (Long) rvMap.get("totalCount");
return count.longValue();
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;
}
private static SolrQuery getQuery(List<String> vclassUris, String alpha) {
return getQuery(vclassUris, alpha, INDIVIDUAL_LIST_CONTROLLER_MAX_RESULTS);
}
private static SolrQuery getQuery(List<String> vclassUris, String alpha, int numberRows){
/**
* 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 = "";
List<String> queryTypes = new ArrayList<String>();
try {
try {
queryText = makeMultiClassQuery(vclassUris);
// query term for rdf:type - multiple types possible
for(String vclassUri: vclassUris) {
queryTypes.add(VitroSearchTermNames.RDFTYPE + ":\"" + vclassUri + "\" ");
}
if (queryTypes.size() > 0) {
queryText = StringUtils.join(queryTypes, " AND ");
}
// Add alpha filter if applicable
if ( alpha != null && !"".equals(alpha) && alpha.length() == 1) {
queryText += VitroSearchTermNames.NAME_LOWERCASE + ":" + alpha.toLowerCase() + "*";
}
SolrQuery query = new SolrQuery(queryText);
log.debug("Query text is " + queryText);
// Get all available results from index rather than just those for the current page.
// Otherwise, if there are a large number of non-existent individuals in the search
// index, the current page of results might not retrieve any existing individuals,
// and nothing gets returned.
query.setStart(0)
.setRows(numberRows)
// Need a single-valued field for sorting
.setSortField(VitroSearchTermNames.NAME_LOWERCASE_SINGLE_VALUED, SolrQuery.ORDER.asc);
query.setStart( page > 0 ? pageSize * page + 1 : 0 )
.setRows( pageSize );
// Need a single-valued field for sorting
query.setSortField(VitroSearchTermNames.NAME_LOWERCASE_SINGLE_VALUED, SolrQuery.ORDER.asc);
log.debug("Query text is " + queryText);
return query;
} catch (Exception ex){
log.error(ex,ex);
log.error("Could not make Solr query",ex);
return new SolrQuery();
}
}
private static String makeMultiClassQuery( List<String> vclassUris){
String queryText = "";
List<String> queryTypes = new ArrayList<String>();
try {
// query term for rdf:type - multiple types possible
for(String vclassUri: vclassUris) {
queryTypes.add(VitroSearchTermNames.RDFTYPE + ":\"" + vclassUri + "\" ");
}
if (queryTypes.size() > 0) {
queryText = StringUtils.join(queryTypes, " AND ");
}
return queryText;
} catch (Exception ex){
log.error("Could not make Solr query",ex);
return "";
}
}
public static List<PageRecord> makePagesList( long size, int pageSize, int selectedPage ) {
List<PageRecord> records = new ArrayList<PageRecord>( MAX_PAGES + 1 );

View file

@ -8,6 +8,8 @@ import java.io.FileInputStream;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase;
public class FileBasedProhibitedFromSearch extends ProhibitedFromSearch {
/**
@ -17,42 +19,12 @@ public class FileBasedProhibitedFromSearch extends ProhibitedFromSearch {
* @param dir to find N3 files in.
*/
public FileBasedProhibitedFromSearch(String uri, File dir){
super( uri, getModelFromDir(dir));
super( uri, JenaDataSourceSetupBase.getModelFromDir(dir));
}
public FileBasedProhibitedFromSearch(String URI, OntModel model) {
super(URI, model);
}
protected static OntModel getModelFromDir( File dir){
if( dir == null )
throw new IllegalStateException("Must pass a File to FileBasedProhibitedFromSearch");
if( !dir.isDirectory() )
throw new IllegalStateException("Parameter dir to FileBasedProhibitedFromSearch " +
"must be a File object for a directory");
if( !dir.canRead() )
throw new IllegalStateException("Parameter dir to FileBasedProhibitedFromSearch must " +
"be a directory that is readable, check premissions on " + dir.getAbsolutePath());
OntModel modelOnlyForPFS = ModelFactory.createOntologyModel();
for( File file : dir.listFiles()){
if( file.isFile()
&& file.canRead()
&& file.getName() != null
&& file.getName().endsWith(".n3")){
try{
modelOnlyForPFS.read( new FileInputStream(file), null, "N3");
}catch( Throwable th){
log.warn("could not load file " +
file.getAbsolutePath() + file.separator + file.getName(), th);
}
}
}
if( modelOnlyForPFS.size() == 0 ){
log.warn("No class exclusion statements found.");
}
return modelOnlyForPFS;
}
}

View file

@ -11,7 +11,6 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@ -24,13 +23,14 @@ 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.response.FacetField;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.FacetField.Count;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
@ -51,7 +51,6 @@ import edu.cornell.mannlib.vitro.webapp.search.beans.VitroQuery;
import edu.cornell.mannlib.vitro.webapp.search.beans.VitroQueryFactory;
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.LinkTemplateModel;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individuallist.BaseListedIndividual;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.searchresult.IndividualSearchResult;
import freemarker.template.Configuration;
@ -67,8 +66,8 @@ public class PagedSearchController extends FreemarkerHttpServlet {
private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(PagedSearchController.class);
private static final int DEFAULT_HITS_PER_PAGE = 25;
private static final int DEFAULT_MAX_HIT_COUNT = 1000;
protected static final int DEFAULT_HITS_PER_PAGE = 25;
protected static final int DEFAULT_MAX_HIT_COUNT = 1000;
private static final String PARAM_XML_REQUEST = "xml";
private static final String PARAM_START_INDEX = "startIndex";
@ -146,26 +145,8 @@ public class PagedSearchController extends FreemarkerHttpServlet {
log.debug("IndividualDao is " + iDao.toString() + " Public classes in the classgroup are " + grpDao.getPublicGroupsWithVClasses().toString());
log.debug("VClassDao is "+ vclassDao.toString() );
int startIndex = 0;
try{
startIndex = Integer.parseInt(vreq.getParameter(PARAM_START_INDEX));
}catch (Throwable e) {
startIndex = 0;
}
log.debug("startIndex is " + startIndex);
int hitsPerPage = DEFAULT_HITS_PER_PAGE;
try{
hitsPerPage = Integer.parseInt(vreq.getParameter(PARAM_HITS_PER_PAGE));
} catch (Throwable e) {
hitsPerPage = DEFAULT_HITS_PER_PAGE;
}
log.debug("hitsPerPage is " + hitsPerPage);
int maxHitCount = DEFAULT_MAX_HIT_COUNT ;
if( startIndex >= DEFAULT_MAX_HIT_COUNT - hitsPerPage )
maxHitCount = startIndex + DEFAULT_MAX_HIT_COUNT ;
log.debug("maxHitCount is " + maxHitCount);
int startIndex = getStartIndex(vreq);
int hitsPerPage = getHitsPerPage( vreq );
String qtxt = vreq.getParameter(VitroQuery.QUERY_PARAMETER_NAME);
log.debug("Query text is \""+ qtxt + "\"");
@ -175,42 +156,27 @@ public class PagedSearchController extends FreemarkerHttpServlet {
return doFailedSearch(badQueryMsg, qtxt, format);
}
SolrQuery query = getQuery(qtxt, maxHitCount, vreq);
SolrQuery query = getQuery(qtxt, hitsPerPage, startIndex, vreq);
SolrServer solr = SolrSetup.getSolrServer(getServletContext());
QueryResponse response = null;
QueryResponse response = null;
try {
response = solr.query(query);
} catch (Throwable t) {
log.error("in first pass at search: " + t);
// this is a hack to deal with odd cases where search and index threads interact
try{
wait(150);
response = solr.query(query);
} catch (Exception ex) {
log.error(ex);
String msg = makeBadSearchMessage(qtxt, ex.getMessage());
if (msg == null) {
msg = "The search request contained errors.";
}
return doFailedSearch(msg, qtxt, format);
}
} catch (Exception ex) {
String msg = makeBadSearchMessage(qtxt, ex.getMessage());
log.error("could not run Solr query",ex);
return doFailedSearch(msg, qtxt, format);
}
if (response == null) {
log.error("Search response was null");
String msg = "The search request contained errors.";
return doFailedSearch(msg, qtxt, format);
log.error("Search response was null");
return doFailedSearch("The search request contained errors.", qtxt, format);
}
SolrDocumentList docs = response.getResults();
if (docs == null) {
log.error("Document list for a search was null");
String msg = "The search request contained errors.";
return doFailedSearch(msg, qtxt,format);
return doFailedSearch("The search request contained errors.", qtxt,format);
}
long hitCount = docs.getNumFound();
@ -218,30 +184,20 @@ public class PagedSearchController extends FreemarkerHttpServlet {
if ( hitCount < 1 ) {
return doNoHits(qtxt,format);
}
long lastHitToShow = 0;
if ((startIndex + hitsPerPage) > hitCount ) {
lastHitToShow = hitCount;
} else {
lastHitToShow = startIndex + hitsPerPage;
}
List<Individual> individuals = new LinkedList<Individual>();
for(int i = startIndex; i < lastHitToShow; i++){
try {
SolrDocument doc = docs.get(i);
String uri = doc.get(VitroSearchTermNames.URI).toString();
log.debug("Retrieving individual with uri "+ uri);
Individual ent = new IndividualImpl();
ent.setURI(uri);
ent = iDao.getIndividualByURI(uri);
if(ent!=null) {
ent.setSearchSnippet(getSnippet(doc, response));
individuals.add(ent);
List<Individual> individuals = new ArrayList<Individual>(docs.size());
Iterator<SolrDocument> docIter = docs.iterator();
while( docIter.hasNext() ){
try {
SolrDocument doc = docIter.next();
String uri = doc.get(VitroSearchTermNames.URI).toString();
Individual ind = iDao.getIndividualByURI(uri);
if(ind != null) {
ind.setSearchSnippet( getSnippet(doc, response) );
individuals.add(ind);
}
} catch(Exception e) {
log.error("Problem getting usable individuals from search hits. " +
e.getMessage());
log.error("Problem getting usable individuals from search hits. ",e);
}
}
@ -275,31 +231,19 @@ public class PagedSearchController extends FreemarkerHttpServlet {
body.put("typeName", type.getName());
}
/* Add classgroup and type refinement links to body */
/* Add ClassGroup and type refinement links to body */
if( wasHtmlRequested ){
// Search request includes no classgroup and no type, so add classgroup search refinement links.
if ( !classGroupFilterRequested && !typeFilterRequested ) {
List<VClassGroup> classgroups = getClassGroups(grpDao, docs, maxHitCount);
List<VClassGroupSearchLink> classGroupLinks = new ArrayList<VClassGroupSearchLink>(classgroups.size());
for (VClassGroup vcg : classgroups) {
if (vcg.getPublicName() != null) {
classGroupLinks.add(new VClassGroupSearchLink(qtxt, vcg));
}
}
body.put("classGroupLinks", classGroupLinks);
// Search request is for a classgroup, so add rdf:type search refinement links
// but try to filter out classes that are subclasses
} else if ( classGroupFilterRequested && !typeFilterRequested ) {
List<VClass> vClasses = getVClasses(vclassDao, docs);
List<VClassSearchLink> vClassLinks = new ArrayList<VClassSearchLink>(vClasses.size());
for (VClass vc : vClasses) {
vClassLinks.add(new VClassSearchLink(qtxt, vc));
}
body.put("classLinks", vClassLinks);
if ( !classGroupFilterRequested && !typeFilterRequested ) {
// Search request includes no ClassGroup and no type, so add ClassGroup search refinement links.
body.put("classGroupLinks", getClassGroupsLinks(grpDao, docs, response, qtxt));
} else if ( classGroupFilterRequested && !typeFilterRequested ) {
// Search request is for a ClassGroup, so add rdf:type search refinement links
// but try to filter out classes that are subclasses
body.put("classLinks", getVClassLinks(vclassDao, docs, response, qtxt));
pagingLinkParams.put(PARAM_CLASSGROUP, classGroupParam);
} else {
//search request is for a class so there are no more refinements
pagingLinkParams.put(PARAM_RDFTYPE, typeParam);
}
}
@ -314,9 +258,10 @@ public class PagedSearchController extends FreemarkerHttpServlet {
body.put("hitCount", hitCount);
body.put("startIndex", startIndex);
body.put("pagingLinks", getPagingLinks(startIndex, hitsPerPage,
hitCount, maxHitCount, vreq.getServletPath(),
pagingLinkParams));
body.put("pagingLinks",
getPagingLinks(startIndex, hitsPerPage, hitCount,
vreq.getServletPath(),
pagingLinkParams));
if (startIndex != 0) {
body.put("prevPage", getPreviousPageLink(startIndex,
@ -336,6 +281,28 @@ public class PagedSearchController extends FreemarkerHttpServlet {
}
private int getHitsPerPage(VitroRequest vreq) {
int hitsPerPage = DEFAULT_HITS_PER_PAGE;
try{
hitsPerPage = Integer.parseInt(vreq.getParameter(PARAM_HITS_PER_PAGE));
} catch (Throwable e) {
hitsPerPage = DEFAULT_HITS_PER_PAGE;
}
log.debug("hitsPerPage is " + hitsPerPage);
return hitsPerPage;
}
private int getStartIndex(VitroRequest vreq) {
int startIndex = 0;
try{
startIndex = Integer.parseInt(vreq.getParameter(PARAM_START_INDEX));
}catch (Throwable e) {
startIndex = 0;
}
log.debug("startIndex is " + startIndex);
return startIndex;
}
private String badQueryText(String qtxt) {
if( qtxt == null || "".equals( qtxt.trim() ) )
return "Please enter a search term.";
@ -348,80 +315,103 @@ public class PagedSearchController extends FreemarkerHttpServlet {
/**
* Get the class groups represented for the individuals in the documents.
* @param qtxt
*/
private List<VClassGroup> getClassGroups(VClassGroupDao grpDao, SolrDocumentList docs, int maxHitCount) {
LinkedHashMap<String,VClassGroup> grpMap = grpDao.getClassGroupMap();
int n = grpMap.size();
private List<VClassGroupSearchLink> getClassGroupsLinks(VClassGroupDao grpDao, SolrDocumentList docs, QueryResponse rsp, String qtxt) {
Map<String,Long> cgURItoCount = new HashMap<String,Long>();
HashSet<String> classGroupsInHits = new HashSet<String>(n);
int grpsFound = 0;
List<VClassGroup> classgroups = new ArrayList<VClassGroup>( );
List<FacetField> ffs = rsp.getFacetFields();
for(FacetField ff : ffs){
if(VitroSearchTermNames.CLASSGROUP_URI.equals(ff.getName())){
List<Count> counts = ff.getValues();
for( Count ct: counts){
VClassGroup vcg = grpDao.getGroupByURI( ct.getName() );
if( vcg == null ){
log.debug("could not get classgroup for URI " + ct.getName());
}else{
classgroups.add(vcg);
cgURItoCount.put(vcg.getURI(), ct.getCount());
}
}
}
}
long maxHits = Math.min(docs.getNumFound(), maxHitCount);
for(int i = 0; i < maxHits && n > grpsFound ;i++){
try{
SolrDocument doc = docs.get(i);
Collection<Object> grps = doc.getFieldValues(VitroSearchTermNames.CLASSGROUP_URI);
if (grps != null) {
for (Object o : grps) {
String groupUri = o.toString();
if( groupUri != null && !classGroupsInHits.contains(groupUri)){
classGroupsInHits.add(groupUri);
grpsFound++;
if( grpsFound >= n )
break;
}
}
}
} catch(Exception e) {
log.error("problem getting VClassGroups from search hits "
+ e.getMessage() );
e.printStackTrace();
}
}
List<String> classgroupURIs= Collections.list(Collections.enumeration(classGroupsInHits));
List<VClassGroup> classgroups = new ArrayList<VClassGroup>( classgroupURIs.size() );
for(String cgUri: classgroupURIs){
if( cgUri != null && ! "".equals(cgUri) ){
VClassGroup vcg = grpDao.getGroupByURI( cgUri );
if( vcg == null ){
log.debug("could not get classgroup for URI " + cgUri);
}else{
classgroups.add(vcg);
}
}
}
grpDao.sortGroupList(classgroups);
return classgroups;
List<VClassGroupSearchLink> classGroupLinks = new ArrayList<VClassGroupSearchLink>(classgroups.size());
for (VClassGroup vcg : classgroups) {
long count = cgURItoCount.get( vcg.getURI() );
if (vcg.getPublicName() != null && count > 0 ) {
classGroupLinks.add(new VClassGroupSearchLink(qtxt, vcg, count));
}
}
return classGroupLinks;
}
private List<VClass> getVClasses(VClassDao vclassDao, SolrDocumentList docs){
private List<VClassSearchLink> getVClassLinks(VClassDao vclassDao, SolrDocumentList docs, QueryResponse rsp, String qtxt){
HashSet<String> typesInHits = getVClassUrisForHits(docs);
List<VClass> classes = new ArrayList<VClass>(typesInHits.size());
Map<String,Long> typeURItoCount = new HashMap<String,Long>();
Iterator<String> it = typesInHits.iterator();
while(it.hasNext()){
String typeUri = it.next();
try{
if( VitroVocabulary.OWL_THING.equals(typeUri))
continue;
VClass type = vclassDao.getVClassByURI(typeUri);
if( type != null &&
! type.isAnonymous() &&
type.getName() != null && !"".equals(type.getName()) &&
type.getGroupURI() != null ) //don't display classes that aren't in classgroups
classes.add(type);
}catch(Exception ex){
if( log.isDebugEnabled() )
log.debug("could not add type " + typeUri, ex);
}
// Iterator<String> it = typesInHits.iterator();
// while(it.hasNext()){
// String typeUri = it.next();
// try{
// if( VitroVocabulary.OWL_THING.equals(typeUri))
// continue;
// VClass type = vclassDao.getVClassByURI(typeUri);
// if( type != null &&
// ! type.isAnonymous() &&
// type.getName() != null && !"".equals(type.getName()) &&
// type.getGroupURI() != null ) //don't display classes that aren't in classgroups
// classes.add(type);
// }catch(Exception ex){
// if( log.isDebugEnabled() )
// log.debug("could not add type " + typeUri, ex);
// }
// }
List<FacetField> ffs = rsp.getFacetFields();
for(FacetField ff : ffs){
if(VitroSearchTermNames.RDFTYPE.equals(ff.getName())){
List<Count> counts = ff.getValues();
for( Count ct: counts){
String typeUri = ct.getName();
long count = ct.getCount();
try{
if( VitroVocabulary.OWL_THING.equals(typeUri) ||
count == 0 )
continue;
VClass type = vclassDao.getVClassByURI(typeUri);
if( type != null &&
! type.isAnonymous() &&
type.getName() != null && !"".equals(type.getName()) &&
type.getGroupURI() != null ){ //don't display classes that aren't in classgroups
typeURItoCount.put(typeUri,count);
classes.add(type);
}
}catch(Exception ex){
if( log.isDebugEnabled() )
log.debug("could not add type " + typeUri, ex);
}
}
}
}
Collections.sort(classes, new Comparator<VClass>(){
public int compare(VClass o1, VClass o2) {
return o1.compareTo(o2);
}});
return classes;
List<VClassSearchLink> vClassLinks = new ArrayList<VClassSearchLink>(classes.size());
for (VClass vc : classes) {
long count = typeURItoCount.get(vc.getURI());
vClassLinks.add(new VClassSearchLink(qtxt, vc, count ));
}
return vClassLinks;
}
private HashSet<String> getVClassUrisForHits(SolrDocumentList docs){
@ -455,51 +445,68 @@ public class PagedSearchController extends FreemarkerHttpServlet {
return text.toString();
}
private SolrQuery getQuery(String queryText, int maxHitCount, VitroRequest vreq) {
private SolrQuery getQuery(String queryText, int hitsPerPage, int startIndex, VitroRequest vreq) {
SolrQuery query = new SolrQuery(queryText);
// Solr requires these values, but we don't want them to be the real values for this page
// of results, else the refinement links won't work correctly: each page of results needs to
// show refinement links generated for all results, not just for the results on the current page.
query.setStart(0)
.setRows(maxHitCount);
query.setStart( startIndex )
.setRows(hitsPerPage);
// Classgroup filtering
// ClassGroup filtering param
String classgroupParam = (String) vreq.getParameter(PARAM_CLASSGROUP);
if ( ! StringUtils.isBlank(classgroupParam) ) {
// rdf:type filtering param
String typeParam = (String) vreq.getParameter(PARAM_RDFTYPE);
if ( ! StringUtils.isBlank(classgroupParam) ) {
// ClassGroup filtering
log.debug("Firing classgroup query ");
log.debug("request.getParameter(classgroup) is "+ classgroupParam);
query.addFilterQuery(VitroSearchTermNames.CLASSGROUP_URI + ":\"" + classgroupParam + "\"");
}
// rdf:type filtering
String typeParam = (String) vreq.getParameter(PARAM_RDFTYPE);
if ( ! StringUtils.isBlank(typeParam) ) {
//with ClassGroup filtering we want type facets
query.add("facet","true");
query.add("facet.limit","-1");
query.add("facet.field",VitroSearchTermNames.RDFTYPE);
}else if ( ! StringUtils.isBlank(typeParam) ) {
// rdf:type filtering
log.debug("Firing type query ");
log.debug("request.getParameter(type) is "+ typeParam);
query.addFilterQuery(VitroSearchTermNames.RDFTYPE + ":\"" + typeParam + "\"");
}
//query.setQuery(queryText);
//with type filtering we don't have facets.
}else{
//When no filtering is set, we want ClassGroup facets
query.add("facet","true");
query.add("facet.limit","-1");
query.add("facet.field",VitroSearchTermNames.CLASSGROUP_URI);
}
log.debug("Query = " + query.toString());
return query;
}
private class VClassGroupSearchLink extends LinkTemplateModel {
VClassGroupSearchLink(String querytext, VClassGroup classgroup) {
}
protected class VClassGroupSearchLink extends LinkTemplateModel {
long count = 0;
VClassGroupSearchLink(String querytext, VClassGroup classgroup, long count) {
super(classgroup.getPublicName(), "/search", PARAM_QUERY_TEXT, querytext, PARAM_CLASSGROUP, classgroup.getURI());
this.count = count;
}
}
private class VClassSearchLink extends LinkTemplateModel {
VClassSearchLink(String querytext, VClass type) {
super(type.getName(), "/search", PARAM_QUERY_TEXT, querytext, PARAM_RDFTYPE, type.getURI());
}
public String getCount() { return Long.toString(count); }
}
private List<PagingLink> getPagingLinks(int startIndex, int hitsPerPage, long hitCount, int maxHitCount, String baseUrl, ParamMap params) {
protected class VClassSearchLink extends LinkTemplateModel {
long count = 0;
VClassSearchLink(String querytext, VClass type, long count) {
super(type.getName(), "/search", PARAM_QUERY_TEXT, querytext, PARAM_RDFTYPE, type.getURI());
this.count = count;
}
public String getCount() { return Long.toString(count); }
}
protected static List<PagingLink> getPagingLinks(int startIndex, int hitsPerPage, long hitCount, String baseUrl, ParamMap params) {
List<PagingLink> pagingLinks = new ArrayList<PagingLink>();
@ -508,17 +515,23 @@ public class PagedSearchController extends FreemarkerHttpServlet {
return pagingLinks;
}
int maxHitCount = DEFAULT_MAX_HIT_COUNT ;
if( startIndex >= DEFAULT_MAX_HIT_COUNT - hitsPerPage )
maxHitCount = startIndex + DEFAULT_MAX_HIT_COUNT ;
for (int i = 0; i < hitCount; i += hitsPerPage) {
params.put(PARAM_START_INDEX, String.valueOf(i));
if ( i < maxHitCount - hitsPerPage) {
int pageNumber = i/hitsPerPage + 1;
if (i >= startIndex && i < (startIndex + hitsPerPage)) {
boolean iIsCurrentPage = (i >= startIndex && i < (startIndex + hitsPerPage));
if ( iIsCurrentPage ) {
pagingLinks.add(new PagingLink(pageNumber));
} else {
pagingLinks.add(new PagingLink(pageNumber, baseUrl, params));
}
} else {
pagingLinks.add(new PagingLink("more...", baseUrl, params));
break;
}
}
@ -535,7 +548,7 @@ public class PagedSearchController extends FreemarkerHttpServlet {
return UrlBuilder.getUrl(baseUrl, params);
}
private class PagingLink extends LinkTemplateModel {
protected static class PagingLink extends LinkTemplateModel {
PagingLink(int pageNumber, String baseUrl, ParamMap params) {
super(String.valueOf(pageNumber), baseUrl, params);

View file

@ -195,8 +195,8 @@ public class IndexBuilder extends Thread {
if(! stopRequested && log != null )//may be null on shutdown
log.info("Stopping IndexBuilder thread");
}
public static void checkIndexOnRootLogin(HttpServletRequest req){
HttpSession session = req.getSession();
ServletContext context = session.getServletContext();

View file

@ -2,6 +2,7 @@
package edu.cornell.mannlib.vitro.webapp.servlet.setup;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.File;
import java.sql.SQLException;
@ -15,6 +16,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.graph.Graph;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
@ -57,6 +59,12 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon {
//these files are loaded everytime the system starts up
public static String APPPATH_LOAD = APPPATH + "menuload/";
protected static String SUBMODELS = "/WEB-INF/submodels/";
//All files in this directory will be reloaded every startup
//and attached as sub-models to the displayOntModel.
static final String DISPLAY_MODEL_LOAD_AT_STARTUP_DIR =
APPPATH + "loadedAtStartup";
protected static boolean firstStartup = false;
String DB_USER = "jenatest"; // database user id
@ -406,6 +414,39 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon {
}
/**
* Read all the files in the directory as RDF files
* and return a model build from all RDF data found in those files.
* This will attempt to load formats supported by getRdfFormat().
*/
public static OntModel getModelFromDir( File dir){
if( dir == null )
throw new IllegalStateException("Must pass a File to getModelFromDir()");
if( !dir.isDirectory() )
throw new IllegalStateException("Directory must be a File object for a directory");
if( !dir.canRead() )
throw new IllegalStateException("getModelFromDir(): Directory " +
" must be readable, check premissions on " + dir.getAbsolutePath());
OntModel model = ModelFactory.createOntologyModel();
for( File file : dir.listFiles()){
if( file.isFile()
&& file.canRead()
&& file.getName() != null ){
String format = getRdfFormat( file.getName() );
try{
model.read( new FileInputStream(file), null, format);
}catch( Throwable th){
log.warn("Could not load file " +
file.getAbsolutePath() + file.separator + file.getName() +
" check that it contains valid " + format + " data.",
th);
}
}
}
return model;
}
public static void setVitroJenaModelMaker(VitroJenaModelMaker vjmm,
ServletContext ctx){
ctx.setAttribute(rdbModelMaker, vjmm);

View file

@ -2,14 +2,23 @@
package edu.cornell.mannlib.vitro.webapp.servlet.setup;
import java.io.File;
import java.io.FileOutputStream;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime;
import org.joda.time.format.ISODateTimeFormat;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
@ -21,8 +30,8 @@ public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase
private static final Log log = LogFactory.getLog(
JenaPersistentDataSourceSetup.class.getName());
@Override
public void contextInitialized(ServletContextEvent sce) {
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext ctx = sce.getServletContext();
if (AbortStartup.isStartupAborted(ctx)) {
@ -35,7 +44,7 @@ public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase
JENA_USER_ACCOUNTS_MODEL, DB_ONT_MODEL_SPEC, ctx);
if (userAccountsDbModel.size() == 0) {
firstStartup = true;
readOntologyFilesInPathSet(AUTHPATH, sce.getServletContext(),
readOntologyFilesInPathSet(AUTHPATH, ctx,
userAccountsDbModel);
}
OntModel userAccountsModel = ModelFactory.createOntologyModel(
@ -43,8 +52,8 @@ public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase
userAccountsModel.add(userAccountsDbModel);
userAccountsModel.getBaseModel().register(
new ModelSynchronizer(userAccountsDbModel));
sce.getServletContext().setAttribute(
"userAccountsOntModel", userAccountsModel);
ctx.setAttribute("userAccountsOntModel", userAccountsModel);
if (userAccountsModel.isEmpty()) {
initializeUserAccounts(ctx, userAccountsModel);
}
@ -54,22 +63,20 @@ public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase
// display, editing and navigation Model
try {
Model appDbModel = makeDBModelFromConfigurationProperties(
Model displayDbModel = makeDBModelFromConfigurationProperties(
JENA_DISPLAY_METADATA_MODEL, DB_ONT_MODEL_SPEC, ctx);
log.debug("Display model size is " + appDbModel.size());
if (appDbModel.size() == 0) {
readOntologyFilesInPathSet(
APPPATH, sce.getServletContext(),appDbModel);
log.debug("Loaded ontology files from " + APPPATH + " into display model");
if (displayDbModel.size() == 0) {
readOntologyFilesInPathSet(APPPATH, ctx,displayDbModel);
}
OntModel appModel = ModelFactory.createOntologyModel(
MEM_ONT_MODEL_SPEC);
appModel.add(appDbModel);
appModel.getBaseModel().register(new ModelSynchronizer(appDbModel));
ctx.setAttribute("displayOntModel", appModel);
OntModel displayModel = ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC);
displayModel.add(displayDbModel);
displayModel.getBaseModel().register(new ModelSynchronizer(displayDbModel));
ctx.setAttribute("displayOntModel", displayModel);
//at each startup load all RDF files from directory to sub-models of display model
initializeDisplayLoadedAtStartup(ctx, displayModel);
} catch (Throwable t) {
log.error("Unable to load user application configuration model from DB", t);
log.error("Unable to load user application configuration model", t);
}
//display tbox - currently reading in every time
@ -78,7 +85,7 @@ public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase
JENA_DISPLAY_TBOX_MODEL, DB_ONT_MODEL_SPEC, ctx);
//Reading in single file every time
//TODO: Check if original needs to be cleared/removed every time?
readOntologyFileFromPath(APPPATH_LOAD + "displayTBOX.n3", displayTboxModel, sce.getServletContext());
readOntologyFileFromPath(APPPATH_LOAD + "displayTBOX.n3", displayTboxModel, ctx);
OntModel appTBOXModel = ModelFactory.createOntologyModel(
MEM_ONT_MODEL_SPEC);
appTBOXModel.add(displayTboxModel);
@ -86,15 +93,16 @@ public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase
ctx.setAttribute("displayOntModelTBOX", appTBOXModel);
log.debug("Loaded file " + APPPATH_LOAD + "displayTBOX.n3 into display tbox model");
} catch (Throwable t) {
log.error("Unable to load user application configuration model TBOX from DB", t);
log.error("Unable to load user application configuration model TBOX", t);
}
//Display Display model, currently empty, create if doesn't exist but no files to load
try {
Model displayDisplayModel = makeDBModelFromConfigurationProperties(
JENA_DISPLAY_DISPLAY_MODEL, DB_ONT_MODEL_SPEC, ctx);
//Reading in single file every time
//TODO: Check if original needs to be cleared/removed every time?
readOntologyFileFromPath(APPPATH_LOAD + "displayDisplay.n3", displayDisplayModel, sce.getServletContext());
readOntologyFileFromPath(APPPATH_LOAD + "displayDisplay.n3", displayDisplayModel, ctx);
OntModel appDisplayDisplayModel = ModelFactory.createOntologyModel(
MEM_ONT_MODEL_SPEC);
@ -103,7 +111,7 @@ public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase
ctx.setAttribute("displayOntModelDisplayModel", appDisplayDisplayModel);
log.debug("Loaded file " + APPPATH_LOAD + "displayDisplay.n3 into display display model");
} catch (Throwable t) {
log.error("Unable to load user application configuration model Display Model from DB", t);
log.error("Unable to load user application configuration model Display Model", t);
}
}
@ -117,4 +125,123 @@ public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase
readOntologyFilesInPathSet(AUTHPATH, ctx, userAccountsModel);
}
/**
* Load the RDF found in the directory DISPLAY_MODEL_LOAD_AT_STARTUP_DIR
* a sub-models of displayModel. The RDF from thes files will not be saved
* in the database and it will be reloaded each time the system starts up.
*/
private void initializeDisplayLoadedAtStartup(ServletContext ctx, OntModel displayModel){
Model displayLoadAtStartup = readInDisplayModelLoadAtStartup(ctx);
if( log.isDebugEnabled() ){
log.debug("loaded display model from files in " + ctx.getRealPath(DISPLAY_MODEL_LOAD_AT_STARTUP_DIR) );
displayLoadAtStartup.write(System.out, "N3-PP");
}
checkForOldListViews(ctx,displayModel,displayLoadAtStartup);
displayModel.addSubModel( displayLoadAtStartup );
}
/**
* All of the list views should now reside in files in DISPLAY_MODEL_LOAD_AT_STARTUP_DIR.
* This will check for custom list view annotation statements in the displayModel, check
* if they exist in the files in DISPLAY_MODEL_LOAD_AT_STARTUP_DIR, and write any that don't
* exist there to a file in DISPLAY_MODEL_LOAD_AT_STARTUP_DIR. After that the statements
* will be removed from the displayDBModel.
*
* returns true if there were old list view statements in the DB, returns false
* if there were none. displayLoadAlways should be reloaded from the file system
* if this returns true as this method may have changed the files.
*
* displayLoadAtStartup and displayModel may be modified.
*/
private void checkForOldListViews( ServletContext ctx, OntModel displayModel, Model displayLoadAtStartup){
// run construct for old custom list view statements from displayModel
Model oldListViewModel = getOldListViewStatements( displayModel );
if( log.isDebugEnabled() ){
log.debug("Printing the old list view statements from the display model to System.out.");
oldListViewModel.write(System.out,"N3-PP");
}
// find statements in old stmts that are not in loadedAtStartup and
// save them in a new file in DISPLAY_MODEL_LOAD_AT_STARTUP_DIR
// so that in the future they will be in loadedAtStartup
Model stmtsInOldAndFiles = displayLoadAtStartup.intersection( displayModel );
Model unhandledOldListViewStmts = oldListViewModel.difference( stmtsInOldAndFiles );
boolean saved = false;
boolean neededSave = false;
if( unhandledOldListViewStmts != null && !unhandledOldListViewStmts.isEmpty() ){
log.debug("need to deal with old list view statements from the display model");
neededSave = true;
try{
//create a file for the old statements in the loadAtStartup directory
String newFileName = ctx.getRealPath(
DISPLAY_MODEL_LOAD_AT_STARTUP_DIR + File.separator
+ new DateTime().toString(ISODateTimeFormat.basicDateTime()) + ".n3" );
File file = new File( newFileName );
file.createNewFile();
log.info("Relocating " + unhandledOldListViewStmts.size() + " custom list view statements from DB and saving to "
+ file.getAbsolutePath()+ File.separator + file.getName()
+ ". These will be loaded from this file when the system starts up.");
FileOutputStream fileOut = new FileOutputStream(file);
unhandledOldListViewStmts.write(fileOut, "N3-PP");
fileOut.close();
saved = true;
}catch(Throwable th){
log.warn("Could not save old list view statements. Leaving them in the DB",th);
}
//need to reload displayLoadAlways because DISPLAY_MODEL_LOAD_AT_STARTUP_DIR may have changed
displayLoadAtStartup.removeAll().add(readInDisplayModelLoadAtStartup(ctx));
}
if( oldListViewModel != null && ! oldListViewModel.isEmpty() ){
//At this point, there are old list view statements in the DB but they
//should are all redundant with ones in DISPLAY_MODEL_LOAD_AT_STARTUP_DIR
if( (neededSave && saved) || (!neededSave) ){
//if there was nothing to save, just remove the old stuff
//if there was stuff to save, only remove if it was saved.
log.debug("removing old statements from displayModel");
displayModel.remove(oldListViewModel);
}
}
}
private Model getOldListViewStatements(OntModel displayModel) {
//run a construct on displayModel to get all list view statements
Query query = QueryFactory.create ( listViewQuery );
QueryExecution qexec = QueryExecutionFactory.create(query, displayModel) ;
Model oldModel = null;
try {
oldModel = qexec.execConstruct();
} catch( Throwable th ){
log.error("could not check for old custom list views, query exception",th);
}finally {
qexec.close() ;
}
if( oldModel != null)
return oldModel;
else
return ModelFactory.createDefaultModel();
}
private static final String listViewQuery = "" +
"PREFIX d: <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#>\n" +
"CONSTRUCT { \n" +
" ?a d:listViewConfigFile ?b . \n" +
"} WHERE {\n" +
" ?a d:listViewConfigFile ?b . \n" +
"} ";
protected Model readInDisplayModelLoadAtStartup( ServletContext ctx ){
return getModelFromDir( new File( ctx.getRealPath( DISPLAY_MODEL_LOAD_AT_STARTUP_DIR )));
}
}

View file

@ -246,11 +246,8 @@ public class DataGetterUtils {
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));
jo.put("firstName", JsonServlet.getDataPropertyValue(ind, fNameDp, fullWdf));
jo.put("lastName", JsonServlet.getDataPropertyValue(ind, lNameDp, fullWdf));
jo.put("mostSpecificTypes", JsonServlet.getMostSpecificTypes(ind,fullWdf));
jo.put("preferredTitle", JsonServlet.getDataPropertyValue(ind, preferredTitleDp, fullWdf));
jInds.put(jo);
}

View file

@ -0,0 +1,61 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
/**
*
*/
package edu.cornell.mannlib.vitro.webapp.search.controller;
import java.util.List;
import junit.framework.Assert;
import org.junit.Before;
import org.junit.Test;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
import edu.cornell.mannlib.vitro.webapp.search.controller.PagedSearchController.PagingLink;
public class PagedSearchControllerTest {
@Test
public void testGetPagingLinks() {
ParamMap pm = new ParamMap();
int hitsPerPage = 25;
int totalHits = 500;
int currentStartIndex = 0;
List<PagingLink> pageLinks = PagedSearchController.getPagingLinks(currentStartIndex, hitsPerPage, totalHits, "baseURL", pm);
Assert.assertNotNull(pageLinks);
Assert.assertEquals(500 / 25, pageLinks.size());
//test for no page links on a very short result
hitsPerPage = 25;
totalHits = 10;
currentStartIndex = 0;
pageLinks = PagedSearchController.getPagingLinks(currentStartIndex, hitsPerPage, totalHits, "baseURL", pm);
Assert.assertNotNull(pageLinks);
Assert.assertEquals(0, pageLinks.size());
}
@Test
public void testGetPagingLinksForLargeResults() {
ParamMap pm = new ParamMap();
int hitsPerPage = 25;
int totalHits = 349909;
int currentStartIndex = 0;
List<PagingLink> pageLinks = PagedSearchController.getPagingLinks(currentStartIndex, hitsPerPage, totalHits, "baseURL", pm);
Assert.assertNotNull(pageLinks);
Assert.assertEquals( PagedSearchController.DEFAULT_MAX_HIT_COUNT / hitsPerPage, pageLinks.size());
//test for large sets of results with high start index
hitsPerPage = 25;
totalHits = PagedSearchController.DEFAULT_MAX_HIT_COUNT + 20329;
currentStartIndex = PagedSearchController.DEFAULT_MAX_HIT_COUNT + 5432;
pageLinks = PagedSearchController.getPagingLinks(currentStartIndex, hitsPerPage, totalHits, "baseURL", pm);
Assert.assertNotNull(pageLinks);
Assert.assertEquals(
(currentStartIndex / hitsPerPage) + //all the pages that are before the current page
(PagedSearchController.DEFAULT_MAX_HIT_COUNT / hitsPerPage) + //some pages after the current apge
1, //for the more... page
pageLinks.size());
}
}