Merge branch 'feature/searchModule' into develop
This commit is contained in:
commit
bc7d827741
109 changed files with 3159 additions and 1481 deletions
|
@ -41,9 +41,9 @@ display:RequiredAction a owl:Class ;
|
|||
a owl:Class ;
|
||||
rdfs:comment "Data getter for running a SPARQL query." .
|
||||
|
||||
<java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.SolrIndividualsDataGetter>
|
||||
<java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.SearchIndividualsDataGetter>
|
||||
a owl:Class ;
|
||||
rdfs:comment "A data getter for a Solr Class search, i.e. get individuals for VClass" .
|
||||
rdfs:comment "A data getter for a Class search, i.e. get individuals for VClass" .
|
||||
|
||||
<java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.SparqlUpdate>
|
||||
a owl:Class ;
|
||||
|
@ -141,7 +141,7 @@ owl:topObjectProperty
|
|||
|
||||
display:hasVClassId
|
||||
a owl:ObjectProperty ;
|
||||
rdfs:comment "Object property defining class for solr data getter" .
|
||||
rdfs:comment "Object property defining class for search data getter" .
|
||||
|
||||
###Vitro properties without which individual templates throw errors as are required
|
||||
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.application;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.Application;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||
import edu.cornell.mannlib.vitro.webapp.searchengine.SearchEngineWrapper;
|
||||
import edu.cornell.mannlib.vitro.webapp.searchengine.solr.SolrSearchEngine;
|
||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||
|
||||
/**
|
||||
* The basic implementation of the Application interface.
|
||||
*/
|
||||
public class ApplicationImpl implements Application {
|
||||
// ----------------------------------------------------------------------
|
||||
// The instance
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private final ServletContext ctx;
|
||||
private SearchEngine searchEngine;
|
||||
|
||||
public ApplicationImpl(ServletContext ctx) {
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletContext getServletContext() {
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchEngine getSearchEngine() {
|
||||
return searchEngine;
|
||||
}
|
||||
|
||||
public void setSearchEngine(SearchEngine searchEngine) {
|
||||
this.searchEngine = searchEngine;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// The Setup class.
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public static class Setup implements ServletContextListener {
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
ServletContext ctx = sce.getServletContext();
|
||||
StartupStatus ss = StartupStatus.getBean(ctx);
|
||||
|
||||
try {
|
||||
SearchEngine searchEngine = new SearchEngineWrapper(
|
||||
new SolrSearchEngine());
|
||||
|
||||
ApplicationImpl application = new ApplicationImpl(ctx);
|
||||
application.setSearchEngine(searchEngine);
|
||||
ApplicationUtils.setInstance(application);
|
||||
ss.info(this, "Appliation is configured.");
|
||||
} catch (Exception e) {
|
||||
ss.fatal(this, "Failed to initialize the Application.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce) {
|
||||
// Nothing to tear down.
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.application;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.Application;
|
||||
|
||||
/**
|
||||
* Tools for working with the current Application instance.
|
||||
*/
|
||||
public class ApplicationUtils {
|
||||
private static final Log log = LogFactory.getLog(ApplicationUtils.class);
|
||||
|
||||
private static volatile Application instance;
|
||||
|
||||
public static Application instance() {
|
||||
try {
|
||||
instance.getClass();
|
||||
return instance;
|
||||
} catch (NullPointerException e) {
|
||||
log.error("Called for Application before it was available", e);
|
||||
throw new IllegalStateException(
|
||||
"Called for Application before it was available", e);
|
||||
}
|
||||
}
|
||||
|
||||
static void setInstance(Application application) {
|
||||
instance = application;
|
||||
}
|
||||
|
||||
}
|
|
@ -8,11 +8,6 @@ import javax.servlet.http.HttpServletResponse;
|
|||
|
||||
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.QueryResponse;
|
||||
import org.apache.solr.common.SolrDocument;
|
||||
import org.apache.solr.common.SolrDocumentList;
|
||||
|
||||
import com.hp.hpl.jena.rdf.model.Model;
|
||||
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||
|
@ -21,8 +16,13 @@ import com.hp.hpl.jena.rdf.model.Resource;
|
|||
import com.hp.hpl.jena.rdf.model.ResourceFactory;
|
||||
import com.hp.hpl.jena.vocabulary.RDF;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResponse;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResultDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResultDocumentList;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
|
||||
|
||||
public class IndividualListRdfController extends VitroHttpServlet {
|
||||
|
||||
|
@ -31,24 +31,25 @@ public class IndividualListRdfController extends VitroHttpServlet {
|
|||
|
||||
public static final int ENTITY_LIST_CONTROLLER_MAX_RESULTS = 30000;
|
||||
|
||||
public void doGet (HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
|
||||
@Override
|
||||
public void doGet (HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
|
||||
SearchEngine search = ApplicationUtils.instance().getSearchEngine();
|
||||
|
||||
// Make the query
|
||||
String vclassUri = req.getParameter("vclass");
|
||||
String queryStr = VitroSearchTermNames.RDFTYPE + ":\"" + vclassUri + "\"";
|
||||
SolrQuery query = new SolrQuery(queryStr);
|
||||
SearchQuery query = search.createQuery(queryStr);
|
||||
query.setStart(0)
|
||||
.setRows(ENTITY_LIST_CONTROLLER_MAX_RESULTS)
|
||||
.setFields(VitroSearchTermNames.URI);
|
||||
.addFields(VitroSearchTermNames.URI);
|
||||
// For now, we're only displaying the url, so no need to sort.
|
||||
//.setSortField(VitroSearchTermNames.NAME_LOWERCASE_SINGLE_VALUED);
|
||||
//.addSortField(VitroSearchTermNames.NAME_LOWERCASE_SINGLE_VALUED);
|
||||
|
||||
// Execute the query
|
||||
SolrServer solr = SolrSetup.getSolrServer(getServletContext());
|
||||
QueryResponse response = null;
|
||||
SearchResponse response = null;
|
||||
|
||||
try {
|
||||
response = solr.query(query);
|
||||
response = search.query(query);
|
||||
} catch (Throwable t) {
|
||||
log.error(t, t);
|
||||
}
|
||||
|
@ -57,17 +58,17 @@ public class IndividualListRdfController extends VitroHttpServlet {
|
|||
throw new ServletException("Could not run search in IndividualListRdfController");
|
||||
}
|
||||
|
||||
SolrDocumentList docs = response.getResults();
|
||||
SearchResultDocumentList docs = response.getResults();
|
||||
|
||||
if (docs == null) {
|
||||
throw new ServletException("Could not run search in IndividualListRdfController");
|
||||
}
|
||||
|
||||
Model model = ModelFactory.createDefaultModel();
|
||||
for (SolrDocument doc : docs) {
|
||||
String uri = doc.get(VitroSearchTermNames.URI).toString();
|
||||
for (SearchResultDocument doc : docs) {
|
||||
String uri = doc.getStringValue(VitroSearchTermNames.URI);
|
||||
Resource resource = ResourceFactory.createResource(uri);
|
||||
RDFNode node = (RDFNode) ResourceFactory.createResource(vclassUri);
|
||||
RDFNode node = ResourceFactory.createResource(vclassUri);
|
||||
model.add(resource, RDF.type, node);
|
||||
}
|
||||
|
||||
|
@ -75,7 +76,8 @@ public class IndividualListRdfController extends VitroHttpServlet {
|
|||
model.write(res.getOutputStream(), "RDF/XML");
|
||||
}
|
||||
|
||||
public void doPost (HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException{
|
||||
@Override
|
||||
public void doPost (HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException{
|
||||
doGet(req,res);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller.accounts.admin.ajax;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames.AC_NAME_STEMMED;
|
||||
import static edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames.NAME_LOWERCASE_SINGLE_VALUED;
|
||||
import static edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames.NAME_RAW;
|
||||
import static edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames.NAME_UNSTEMMED;
|
||||
import static edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames.RDFTYPE;
|
||||
import static edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames.URI;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.solr.SolrQueryUtils.Conjunction.OR;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.searchengine.SearchQueryUtils.Conjunction.OR;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
@ -16,17 +15,11 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
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.SolrQuery.ORDER;
|
||||
import org.apache.solr.client.solrj.SolrServer;
|
||||
import org.apache.solr.client.solrj.SolrServerException;
|
||||
import org.apache.solr.client.solrj.response.QueryResponse;
|
||||
import org.json.JSONException;
|
||||
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
|
@ -39,15 +32,20 @@ import com.hp.hpl.jena.query.ResultSet;
|
|||
import com.hp.hpl.jena.query.Syntax;
|
||||
import com.hp.hpl.jena.rdf.model.Literal;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.SelfEditingConfiguration;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.ajax.AbstractAjaxResponder;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.solr.AutoCompleteWords;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.solr.FieldMap;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.solr.SolrQueryUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.solr.SolrResponseFilter;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngineException;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery.Order;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResponse;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.searchengine.AutoCompleteWords;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.searchengine.FieldMap;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.searchengine.SearchQueryUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.searchengine.SearchResponseFilter;
|
||||
|
||||
/**
|
||||
* Get a list of Profiles with last names that begin with this search term, and
|
||||
|
@ -61,7 +59,7 @@ import edu.cornell.mannlib.vitro.webapp.utils.solr.SolrResponseFilter;
|
|||
* if an error occurs, return an empty result.
|
||||
*/
|
||||
class ProfileAutoCompleter extends AbstractAjaxResponder implements
|
||||
SolrResponseFilter {
|
||||
SearchResponseFilter {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(ProfileAutoCompleter.class);
|
||||
|
||||
|
@ -72,7 +70,7 @@ class ProfileAutoCompleter extends AbstractAjaxResponder implements
|
|||
.singleton("http://xmlns.com/foaf/0.1/Person");
|
||||
|
||||
private static final String WORD_DELIMITER = "[, ]+";
|
||||
private static final FieldMap RESPONSE_FIELDS = SolrQueryUtils.fieldMap()
|
||||
private static final FieldMap RESPONSE_FIELDS = SearchQueryUtils.fieldMap()
|
||||
.put(URI, "uri").put(NAME_RAW, "label");
|
||||
|
||||
private static final Syntax SYNTAX = Syntax.syntaxARQ;
|
||||
|
@ -97,7 +95,7 @@ class ProfileAutoCompleter extends AbstractAjaxResponder implements
|
|||
this.externalAuthId = getStringParameter(PARAMETER_ETERNAL_AUTH_ID, "");
|
||||
|
||||
this.term = getStringParameter(PARAMETER_SEARCH_TERM, "");
|
||||
this.searchWords = SolrQueryUtils.parseForAutoComplete(term,
|
||||
this.searchWords = SearchQueryUtils.parseForAutoComplete(term,
|
||||
WORD_DELIMITER);
|
||||
|
||||
// TODO This seems to expose the matching property and mechanism too
|
||||
|
@ -121,10 +119,10 @@ class ProfileAutoCompleter extends AbstractAjaxResponder implements
|
|||
}
|
||||
|
||||
try {
|
||||
SolrQuery query = buildSolrQuery();
|
||||
QueryResponse queryResponse = executeSolrQuery(query);
|
||||
SearchQuery query = buildSearchQuery();
|
||||
SearchResponse queryResponse = executeSearchQuery(query);
|
||||
|
||||
List<Map<String, String>> maps = SolrQueryUtils
|
||||
List<Map<String, String>> maps = SearchQueryUtils
|
||||
.parseAndFilterResponse(queryResponse, RESPONSE_FIELDS,
|
||||
this, 30);
|
||||
|
||||
|
@ -133,17 +131,17 @@ class ProfileAutoCompleter extends AbstractAjaxResponder implements
|
|||
String response = assembleJsonResponse(maps);
|
||||
log.debug(response);
|
||||
return response;
|
||||
} catch (SolrServerException e) {
|
||||
} catch (SearchEngineException e) {
|
||||
log.error("Failed to get basic profile info", e);
|
||||
return EMPTY_RESPONSE;
|
||||
}
|
||||
}
|
||||
|
||||
private SolrQuery buildSolrQuery() {
|
||||
SolrQuery q = new SolrQuery();
|
||||
q.setFields(NAME_RAW, URI);
|
||||
q.setSortField(NAME_LOWERCASE_SINGLE_VALUED, ORDER.asc);
|
||||
q.setFilterQueries(SolrQueryUtils.assembleConjunctiveQuery(RDFTYPE,
|
||||
private SearchQuery buildSearchQuery() {
|
||||
SearchQuery q = ApplicationUtils.instance().getSearchEngine().createQuery();
|
||||
q.addFields(NAME_RAW, URI);
|
||||
q.addSortField(NAME_LOWERCASE_SINGLE_VALUED, Order.ASC);
|
||||
q.addFilterQuery(SearchQueryUtils.assembleConjunctiveQuery(RDFTYPE,
|
||||
profileTypes, OR));
|
||||
q.setStart(0);
|
||||
q.setRows(10000);
|
||||
|
@ -151,11 +149,10 @@ class ProfileAutoCompleter extends AbstractAjaxResponder implements
|
|||
return q;
|
||||
}
|
||||
|
||||
private QueryResponse executeSolrQuery(SolrQuery query)
|
||||
throws SolrServerException {
|
||||
ServletContext ctx = servlet.getServletContext();
|
||||
SolrServer solr = SolrSetup.getSolrServer(ctx);
|
||||
return solr.query(query);
|
||||
private SearchResponse executeSearchQuery(SearchQuery query)
|
||||
throws SearchEngineException {
|
||||
SearchEngine search = ApplicationUtils.instance().getSearchEngine();
|
||||
return search.query(query);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,32 +8,31 @@ import static edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames.NAME_
|
|||
import static edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames.NAME_UNSTEMMED;
|
||||
import static edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames.RDFTYPE;
|
||||
import static edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames.URI;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.solr.SolrQueryUtils.Conjunction.OR;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.searchengine.SearchQueryUtils.Conjunction.OR;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
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.SolrQuery.ORDER;
|
||||
import org.apache.solr.client.solrj.SolrServer;
|
||||
import org.apache.solr.client.solrj.SolrServerException;
|
||||
import org.apache.solr.client.solrj.response.QueryResponse;
|
||||
import org.json.JSONException;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.ajax.AbstractAjaxResponder;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.solr.AutoCompleteWords;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.solr.FieldMap;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.solr.SolrQueryUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngineException;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery.Order;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResponse;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.searchengine.AutoCompleteWords;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.searchengine.FieldMap;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.searchengine.SearchQueryUtils;
|
||||
|
||||
/**
|
||||
* Get the basic auto-complete info for the profile selection.
|
||||
|
@ -43,7 +42,7 @@ public class BasicProfilesGetter extends AbstractAjaxResponder {
|
|||
private static final Log log = LogFactory.getLog(BasicProfilesGetter.class);
|
||||
|
||||
private static final String WORD_DELIMITER = "[, ]+";
|
||||
private static final FieldMap RESPONSE_FIELDS = SolrQueryUtils
|
||||
private static final FieldMap RESPONSE_FIELDS = SearchQueryUtils
|
||||
.fieldMap().put(URI, "uri").put(NAME_RAW, "label")
|
||||
.put("bogus", "classLabel").put("bogus", "imageUrl");
|
||||
|
||||
|
@ -60,7 +59,7 @@ public class BasicProfilesGetter extends AbstractAjaxResponder {
|
|||
super(servlet, vreq, resp);
|
||||
|
||||
this.term = getStringParameter(PARAMETER_SEARCH_TERM, "");
|
||||
this.searchWords = SolrQueryUtils.parseForAutoComplete(term,
|
||||
this.searchWords = SearchQueryUtils.parseForAutoComplete(term,
|
||||
WORD_DELIMITER);
|
||||
|
||||
this.profileTypes = figureProfileTypes();
|
||||
|
@ -71,7 +70,7 @@ public class BasicProfilesGetter extends AbstractAjaxResponder {
|
|||
private List<String> figureProfileTypes() {
|
||||
String typesString = ConfigurationProperties.getBean(vreq).getProperty(
|
||||
PROPERTY_PROFILE_TYPES, DEFAULT_PROFILE_TYPES);
|
||||
List<String> list = SolrQueryUtils.parseWords(typesString,
|
||||
List<String> list = SearchQueryUtils.parseWords(typesString,
|
||||
WORD_DELIMITER);
|
||||
if (list.isEmpty()) {
|
||||
log.error("No types configured for profile pages in "
|
||||
|
@ -88,29 +87,27 @@ public class BasicProfilesGetter extends AbstractAjaxResponder {
|
|||
}
|
||||
|
||||
try {
|
||||
ServletContext ctx = servlet.getServletContext();
|
||||
SolrServer solr = SolrSetup.getSolrServer(ctx);
|
||||
SolrQuery query = buildSolrQuery();
|
||||
QueryResponse queryResponse = solr.query(query);
|
||||
SearchEngine search = ApplicationUtils.instance().getSearchEngine();
|
||||
SearchQuery query = buildSearchQuery();
|
||||
SearchResponse queryResponse = search.query(query);
|
||||
|
||||
List<Map<String, String>> parsed = SolrQueryUtils
|
||||
List<Map<String, String>> parsed = SearchQueryUtils
|
||||
.parseResponse(queryResponse, RESPONSE_FIELDS);
|
||||
|
||||
String response = assembleJsonResponse(parsed);
|
||||
log.debug(response);
|
||||
return response;
|
||||
} catch (SolrServerException e) {
|
||||
} catch (SearchEngineException e) {
|
||||
log.error("Failed to get basic profile info", e);
|
||||
return EMPTY_RESPONSE;
|
||||
}
|
||||
}
|
||||
|
||||
private SolrQuery buildSolrQuery() {
|
||||
SolrQuery q = new SolrQuery();
|
||||
q.setFields(NAME_RAW, URI);
|
||||
q.setSortField(NAME_LOWERCASE_SINGLE_VALUED, ORDER.asc);
|
||||
q.setFilterQueries(SolrQueryUtils.assembleConjunctiveQuery(RDFTYPE,
|
||||
profileTypes, OR));
|
||||
private SearchQuery buildSearchQuery() {
|
||||
SearchQuery q = ApplicationUtils.instance().getSearchEngine().createQuery();
|
||||
q.addFields(NAME_RAW, URI);
|
||||
q.addSortField(NAME_LOWERCASE_SINGLE_VALUED, Order.ASC);
|
||||
q.addFilterQuery(SearchQueryUtils.assembleConjunctiveQuery(RDFTYPE, profileTypes, OR));
|
||||
q.setStart(0);
|
||||
q.setRows(30);
|
||||
q.setQuery(searchWords.assembleQuery(NAME_UNSTEMMED, AC_NAME_STEMMED));
|
||||
|
|
|
@ -8,12 +8,9 @@ import java.util.HashMap;
|
|||
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.apache.solr.client.solrj.SolrServerException;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||
|
@ -24,7 +21,8 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Res
|
|||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.individuallist.IndividualListResults;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.solr.SolrQueryUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngineException;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.searchengine.SearchQueryUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individuallist.ListedIndividual;
|
||||
|
||||
/**
|
||||
|
@ -94,8 +92,7 @@ public class IndividualListController extends FreemarkerHttpServlet {
|
|||
vclass.getURI(),
|
||||
page,
|
||||
alpha,
|
||||
vreq.getWebappDaoFactory().getIndividualDao(),
|
||||
getServletContext());
|
||||
vreq.getWebappDaoFactory().getIndividualDao());
|
||||
body.putAll(vcResults.asFreemarkerMap());
|
||||
|
||||
List<Individual> inds = vcResults.getEntities();
|
||||
|
@ -141,21 +138,21 @@ public class IndividualListController extends FreemarkerHttpServlet {
|
|||
|
||||
//TODO: Remove and update reference within JsonServlet
|
||||
public static String getAlphaParameter(VitroRequest request){
|
||||
return SolrQueryUtils.getAlphaParameter(request);
|
||||
return SearchQueryUtils.getAlphaParameter(request);
|
||||
}
|
||||
|
||||
//TODO: Remove and update reference within JsonServlet
|
||||
public static int getPageParameter(VitroRequest request) {
|
||||
return SolrQueryUtils.getPageParameter(request);
|
||||
return SearchQueryUtils.getPageParameter(request);
|
||||
}
|
||||
|
||||
public static IndividualListResults getResultsForVClass(String vclassURI, int page, String alpha, IndividualDao indDao, ServletContext context)
|
||||
public static IndividualListResults getResultsForVClass(String vclassURI, int page, String alpha, IndividualDao indDao)
|
||||
throws SearchException{
|
||||
try{
|
||||
List<String> classUris = Collections.singletonList(vclassURI);
|
||||
IndividualListQueryResults results = SolrQueryUtils.buildAndExecuteVClassQuery(classUris, alpha, page, INDIVIDUALS_PER_PAGE, context, indDao);
|
||||
IndividualListQueryResults results = SearchQueryUtils.buildAndExecuteVClassQuery(classUris, alpha, page, INDIVIDUALS_PER_PAGE, indDao);
|
||||
return getResultsForVClassQuery(results, page, INDIVIDUALS_PER_PAGE, alpha);
|
||||
} catch (SolrServerException e) {
|
||||
} catch (SearchEngineException e) {
|
||||
String msg = "An error occurred retrieving results for vclass query";
|
||||
log.error(msg, e);
|
||||
// Throw this up to processRequest, so the template gets the error message.
|
||||
|
@ -166,9 +163,9 @@ public class IndividualListController extends FreemarkerHttpServlet {
|
|||
}
|
||||
}
|
||||
|
||||
public static IndividualListResults getResultsForVClassIntersections(List<String> vclassURIs, int page, int pageSize, String alpha, IndividualDao indDao, ServletContext context) {
|
||||
public static IndividualListResults getResultsForVClassIntersections(List<String> vclassURIs, int page, int pageSize, String alpha, IndividualDao indDao) {
|
||||
try{
|
||||
IndividualListQueryResults results = SolrQueryUtils.buildAndExecuteVClassQuery(vclassURIs, alpha, page, pageSize, context, indDao);
|
||||
IndividualListQueryResults results = SearchQueryUtils.buildAndExecuteVClassQuery(vclassURIs, alpha, page, pageSize, indDao);
|
||||
return getResultsForVClassQuery(results, page, pageSize, alpha);
|
||||
} catch(Throwable th) {
|
||||
log.error("Error retrieving individuals corresponding to intersection multiple classes." + vclassURIs.toString(), th);
|
||||
|
@ -176,10 +173,10 @@ public class IndividualListController extends FreemarkerHttpServlet {
|
|||
}
|
||||
}
|
||||
|
||||
public static IndividualListResults getRandomResultsForVClass(String vclassURI, int page, int pageSize, IndividualDao indDao, ServletContext context) {
|
||||
public static IndividualListResults getRandomResultsForVClass(String vclassURI, int page, int pageSize, IndividualDao indDao) {
|
||||
try{
|
||||
List<String> classUris = Collections.singletonList(vclassURI);
|
||||
IndividualListQueryResults results = SolrQueryUtils.buildAndExecuteRandomVClassQuery(classUris, page, pageSize, context, indDao);
|
||||
IndividualListQueryResults results = SearchQueryUtils.buildAndExecuteRandomVClassQuery(classUris, page, pageSize, indDao);
|
||||
return getResultsForVClassQuery(results, page, pageSize, "");
|
||||
} catch(Throwable th) {
|
||||
log.error("An error occurred retrieving random results for vclass query", th);
|
||||
|
@ -187,10 +184,10 @@ public class IndividualListController extends FreemarkerHttpServlet {
|
|||
}
|
||||
}
|
||||
|
||||
//TODO: Get rid of this method and utilize SolrQueryUtils - currently appears to be referenced
|
||||
//TODO: Get rid of this method and utilize SearchQueryUtils - currently appears to be referenced
|
||||
//only within DataGetterUtils
|
||||
public static long getIndividualCount(List<String> vclassUris, IndividualDao indDao, ServletContext context) {
|
||||
return SolrQueryUtils.getIndividualCount(vclassUris, indDao, context);
|
||||
public static long getIndividualCount(List<String> vclassUris) {
|
||||
return SearchQueryUtils.getIndividualCount(vclassUris);
|
||||
}
|
||||
|
||||
private static IndividualListResults getResultsForVClassQuery(IndividualListQueryResults results, int page, int pageSize, String alpha) {
|
||||
|
|
|
@ -5,24 +5,22 @@ package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
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.common.SolrDocument;
|
||||
import org.apache.solr.common.SolrDocumentList;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngineException;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResponse;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResultDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResultDocumentList;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
|
||||
|
||||
/**
|
||||
* Holds the Individuals that were found in a Solr search query.
|
||||
* Holds the Individuals that were found in a search query.
|
||||
*
|
||||
* Provides a convenience method to run the query and to find the Individuals.
|
||||
*/
|
||||
|
@ -37,20 +35,19 @@ public class IndividualListQueryResults {
|
|||
// Convenience method
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public static IndividualListQueryResults runQuery(SolrQuery query,
|
||||
IndividualDao indDao, ServletContext context)
|
||||
throws SolrServerException {
|
||||
public static IndividualListQueryResults runQuery(SearchQuery query,
|
||||
IndividualDao indDao)
|
||||
throws SearchEngineException {
|
||||
|
||||
SolrServer solr = SolrSetup.getSolrServer(context);
|
||||
QueryResponse response = null;
|
||||
response = solr.query(query);
|
||||
SearchEngine search = ApplicationUtils.instance().getSearchEngine();
|
||||
SearchResponse response = search.query(query);
|
||||
|
||||
if (response == null) {
|
||||
log.debug("response from search query was null");
|
||||
return EMPTY_RESULT;
|
||||
}
|
||||
|
||||
SolrDocumentList docs = response.getResults();
|
||||
SearchResultDocumentList docs = response.getResults();
|
||||
if (docs == null) {
|
||||
log.debug("results from search query response was null");
|
||||
return EMPTY_RESULT;
|
||||
|
@ -61,8 +58,8 @@ public class IndividualListQueryResults {
|
|||
log.debug("Number of search results: " + hitCount);
|
||||
|
||||
List<Individual> individuals = new ArrayList<Individual>(docs.size());
|
||||
for (SolrDocument doc : docs) {
|
||||
String uri = doc.get(VitroSearchTermNames.URI).toString();
|
||||
for (SearchResultDocument doc : docs) {
|
||||
String uri = doc.getStringValue(VitroSearchTermNames.URI);
|
||||
Individual individual = indDao.getIndividualByURI(uri);
|
||||
if (individual == null) {
|
||||
log.debug("No individual for search document with uri = " + uri);
|
||||
|
|
|
@ -18,23 +18,21 @@ import javax.servlet.http.HttpServletResponse;
|
|||
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.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngineException;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResponse;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResultDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResultDocumentList;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
|
||||
|
||||
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.common.SolrDocument;
|
||||
import org.apache.solr.common.SolrDocumentList;
|
||||
|
||||
/**
|
||||
* This servlet is for servicing JSON requests from Google Refine's
|
||||
|
@ -125,7 +123,7 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
|||
|
||||
try {
|
||||
for (int i = 0; i < queries.size(); i++) {
|
||||
String queryStr = (String) queries.get(i);
|
||||
String queryStr = queries.get(i);
|
||||
JSONObject json = new JSONObject(queryStr);
|
||||
|
||||
if (json.has("query")) { // single query
|
||||
|
@ -138,7 +136,7 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
|||
} else { // multiple queries
|
||||
for (Iterator<String> iter = json.keys(); iter.hasNext();) {
|
||||
ArrayList<JSONObject> jsonList = new ArrayList<JSONObject>();
|
||||
String key = (String) iter.next();
|
||||
String key = iter.next();
|
||||
Object obj = json.get(key);
|
||||
JSONObject jsonLvl2 = (JSONObject) obj;
|
||||
if (jsonLvl2.has("query")) {
|
||||
|
@ -234,7 +232,7 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
|||
for (Map.Entry<String, JSONObject> entry : currMap.entrySet()) {
|
||||
JSONObject resultAllJson = new JSONObject();
|
||||
String key = entry.getKey();
|
||||
JSONObject json = (JSONObject) entry.getValue();
|
||||
JSONObject json = entry.getValue();
|
||||
String queryVal = json.getString("query");
|
||||
|
||||
// System.out.println("query: " + json.toString());
|
||||
|
@ -273,17 +271,16 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
|||
// begin search
|
||||
JSONArray resultJsonArr = new JSONArray();
|
||||
|
||||
// Solr
|
||||
SolrQuery query = getQuery(queryVal, searchType, limit, propertiesList);
|
||||
QueryResponse queryResponse = null;
|
||||
SearchQuery query = getQuery(queryVal, searchType, limit, propertiesList);
|
||||
SearchResponse queryResponse = null;
|
||||
if (query != null) {
|
||||
SolrServer solr = SolrSetup.getSolrServer(getServletContext());
|
||||
queryResponse = solr.query(query);
|
||||
SearchEngine search = ApplicationUtils.instance().getSearchEngine();
|
||||
queryResponse = search.query(query);
|
||||
} else {
|
||||
log.error("Query for a search was null");
|
||||
}
|
||||
|
||||
SolrDocumentList docs = null;
|
||||
SearchResultDocumentList docs = null;
|
||||
if (queryResponse != null) {
|
||||
docs = queryResponse.getResults();
|
||||
} else {
|
||||
|
@ -293,29 +290,16 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
|||
if (docs != null) {
|
||||
|
||||
List<SearchResult> results = new ArrayList<SearchResult>();
|
||||
for (SolrDocument doc : docs) {
|
||||
for (SearchResultDocument doc : docs) {
|
||||
try {
|
||||
String uri = doc.get(VitroSearchTermNames.URI).toString();
|
||||
// RY 7/1/2011
|
||||
// Comment was: VitroSearchTermNames.NAME_RAW is a multivalued field, so doc.get() returns a list.
|
||||
// Changed to: VitroSearchTermNames.NAME_RAW is a multivalued field, so doc.get() could return a list
|
||||
// But in fact: I'm no longer seeing any lists returned for individuals with multiple labels. Not sure
|
||||
// if this is new behavior or what. ???
|
||||
Object nameRaw = doc.get(VitroSearchTermNames.NAME_RAW);
|
||||
String name = null;
|
||||
if (nameRaw instanceof List<?>) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> nameRawList = (List<String>) nameRaw;
|
||||
name = nameRawList.get(0);
|
||||
} else {
|
||||
name = (String) nameRaw;
|
||||
}
|
||||
String uri = doc.getStringValue(VitroSearchTermNames.URI);
|
||||
String name = doc.getStringValue(VitroSearchTermNames.NAME_RAW);
|
||||
|
||||
SearchResult result = new SearchResult(name, uri);
|
||||
|
||||
// populate result for Google Refine
|
||||
JSONObject resultJson = new JSONObject();
|
||||
resultJson.put("score", doc.getFieldValue("score"));
|
||||
resultJson.put("score", doc.getFirstValue("score"));
|
||||
String modUri = result.getUri().replace("#", "%23");
|
||||
resultJson.put("id", modUri);
|
||||
resultJson.put("name", result.getLabel());
|
||||
|
@ -361,16 +345,16 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
|||
log.error("JSONException: " + ex);
|
||||
throw new ServletException("JSONReconcileServlet JSONException: "
|
||||
+ ex);
|
||||
} catch (SolrServerException ex) {
|
||||
} catch (SearchEngineException ex) {
|
||||
log.error("JSONException: " + ex);
|
||||
throw new ServletException("JSONReconcileServlet SolrServerException: "
|
||||
throw new ServletException("JSONReconcileServlet SearchEngineException: "
|
||||
+ ex);
|
||||
}
|
||||
|
||||
return qJson;
|
||||
}
|
||||
|
||||
protected SolrQuery getQuery(String queryStr, String searchType, int limit, ArrayList<String[]> propertiesList) {
|
||||
protected SearchQuery getQuery(String queryStr, String searchType, int limit, ArrayList<String[]> propertiesList) {
|
||||
|
||||
if ( queryStr == null) {
|
||||
log.error("There was no parameter '"+ PARAM_QUERY
|
||||
|
@ -383,10 +367,10 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
|||
}
|
||||
|
||||
/// original
|
||||
///SolrQuery query = new SolrQuery();
|
||||
///SearchQuery query = new SearchQuery();
|
||||
|
||||
/// test
|
||||
SolrQuery query = new SolrQuery(queryStr.toLowerCase());
|
||||
SearchQuery query = ApplicationUtils.instance().getSearchEngine().createQuery(queryStr.toLowerCase());
|
||||
|
||||
// original code:
|
||||
// query.setStart(0).setRows(DEFAULT_MAX_HIT_COUNT);
|
||||
|
@ -403,17 +387,17 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
|||
}
|
||||
|
||||
// Added score to original code:
|
||||
query.setFields(VitroSearchTermNames.NAME_RAW, VitroSearchTermNames.URI, "*", "score"); // fields to retrieve
|
||||
query.addFields(VitroSearchTermNames.NAME_RAW, VitroSearchTermNames.URI, "*", "score"); // fields to retrieve
|
||||
|
||||
// if propertiesList has elements, add extra queries to query
|
||||
Iterator<String[]> it = propertiesList.iterator();
|
||||
while (it.hasNext()) {
|
||||
String[] pvPair = it.next();
|
||||
query.addFilterQuery(tokenizeNameQuery(pvPair[1]), VitroSearchTermNames.RDFTYPE + ":\"" + pvPair[0] + "\"");
|
||||
query.addFilterQueries(tokenizeNameQuery(pvPair[1]), VitroSearchTermNames.RDFTYPE + ":\"" + pvPair[0] + "\"");
|
||||
}
|
||||
|
||||
// Can't sort on multivalued field, so we sort the results in Java when we get them.
|
||||
// query.setSortField(VitroSearchTermNames.NAME_LOWERCASE, SolrQuery.ORDER.asc);
|
||||
// query.addSortField(VitroSearchTermNames.NAME_LOWERCASE, Order.ASC);
|
||||
|
||||
return query;
|
||||
}
|
||||
|
@ -470,7 +454,7 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
|||
}
|
||||
|
||||
private String escapeWhitespaceInQueryString(String queryStr) {
|
||||
// Solr wants whitespace to be escaped with a backslash
|
||||
// The search engine wants whitespace to be escaped with a backslash
|
||||
return queryStr.replaceAll("\\s+", "\\\\ ");
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller.json;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -14,7 +13,6 @@ import org.json.JSONException;
|
|||
import org.json.JSONObject;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.services.shortview.ShortViewService;
|
||||
|
@ -26,11 +24,11 @@ import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.Individual
|
|||
* Does a Solr search for individuals, and uses the short view to render each of
|
||||
* the results.
|
||||
*/
|
||||
public class GetRandomSolrIndividualsByVClass extends GetSolrIndividualsByVClass {
|
||||
public class GetRandomSearchIndividualsByVClass extends GetSearchIndividualsByVClass {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(GetRandomSolrIndividualsByVClass.class);
|
||||
.getLog(GetRandomSearchIndividualsByVClass.class);
|
||||
|
||||
protected GetRandomSolrIndividualsByVClass(VitroRequest vreq) {
|
||||
protected GetRandomSearchIndividualsByVClass(VitroRequest vreq) {
|
||||
super(vreq);
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller.json;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -14,7 +13,6 @@ import org.json.JSONException;
|
|||
import org.json.JSONObject;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.services.shortview.ShortViewService;
|
||||
|
@ -23,14 +21,14 @@ import edu.cornell.mannlib.vitro.webapp.services.shortview.ShortViewServiceSetup
|
|||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.IndividualTemplateModel;
|
||||
|
||||
/**
|
||||
* Does a Solr search for individuals, and uses the short view to render each of
|
||||
* Does a search for individuals, and uses the short view to render each of
|
||||
* the results.
|
||||
*/
|
||||
public class GetRenderedSolrIndividualsByVClass extends GetSolrIndividualsByVClasses {
|
||||
public class GetRenderedSearchIndividualsByVClass extends GetSearchIndividualsByVClasses {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(GetRenderedSolrIndividualsByVClass.class);
|
||||
.getLog(GetRenderedSearchIndividualsByVClass.class);
|
||||
|
||||
protected GetRenderedSolrIndividualsByVClass(VitroRequest vreq) {
|
||||
protected GetRenderedSearchIndividualsByVClass(VitroRequest vreq) {
|
||||
super(vreq);
|
||||
}
|
||||
|
||||
|
@ -62,8 +60,6 @@ public class GetRenderedSolrIndividualsByVClass extends GetSolrIndividualsByVCla
|
|||
return rObj;
|
||||
}
|
||||
|
||||
//Get
|
||||
|
||||
/**
|
||||
* Look through the return object. For each individual, render the short
|
||||
* view and insert the resulting HTML into the object.
|
|
@ -12,11 +12,11 @@ import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
|||
/**
|
||||
*
|
||||
*/
|
||||
public class GetSolrIndividualsByVClass extends JsonObjectProducer {
|
||||
public class GetSearchIndividualsByVClass extends JsonObjectProducer {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(GetSolrIndividualsByVClass.class);
|
||||
.getLog(GetSearchIndividualsByVClass.class);
|
||||
|
||||
protected GetSolrIndividualsByVClass(VitroRequest vreq) {
|
||||
protected GetSearchIndividualsByVClass(VitroRequest vreq) {
|
||||
super(vreq);
|
||||
}
|
||||
|
||||
|
@ -39,9 +39,9 @@ public class GetSolrIndividualsByVClass extends JsonObjectProducer {
|
|||
|
||||
vreq.setAttribute("displayType", vitroClassIdStr);
|
||||
if ( queryType != null && queryType.equals("random")){
|
||||
return JsonServlet.getRandomSolrIndividualsByVClass(vclass.getURI(), vreq, ctx);
|
||||
return JsonServlet.getRandomSearchIndividualsByVClass(vclass.getURI(), vreq);
|
||||
} else {
|
||||
return JsonServlet.getSolrIndividualsByVClass(vclass.getURI(), vreq, ctx);
|
||||
return JsonServlet.getSearchIndividualsByVClass(vclass.getURI(), vreq);
|
||||
}
|
||||
}
|
||||
|
|
@ -16,11 +16,11 @@ import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
|||
* Accepts multiple vclasses and returns individuals which correspond to the
|
||||
* intersection of those classes (i.e. have all those types)
|
||||
*/
|
||||
public class GetSolrIndividualsByVClasses extends JsonObjectProducer {
|
||||
public class GetSearchIndividualsByVClasses extends JsonObjectProducer {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(GetSolrIndividualsByVClasses.class);
|
||||
.getLog(GetSearchIndividualsByVClasses.class);
|
||||
|
||||
public GetSolrIndividualsByVClasses(VitroRequest vreq) {
|
||||
public GetSearchIndividualsByVClasses(VitroRequest vreq) {
|
||||
super(vreq);
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ public class GetSolrIndividualsByVClasses extends JsonObjectProducer {
|
|||
protected JSONObject process() throws Exception {
|
||||
log.debug("Executing retrieval of individuals by vclasses");
|
||||
VClass vclass=null;
|
||||
log.debug("Retrieving solr individuals by vclasses");
|
||||
log.debug("Retrieving search individuals by vclasses");
|
||||
// Could have multiple vclass ids sent in
|
||||
String[] vitroClassIdStr = vreq.getParameterValues("vclassId");
|
||||
if ( vitroClassIdStr != null && vitroClassIdStr.length > 0){
|
||||
|
@ -45,7 +45,7 @@ public class GetSolrIndividualsByVClasses extends JsonObjectProducer {
|
|||
throw new Exception("parameter vclassId URI parameter expected ");
|
||||
}
|
||||
List<String> vclassIds = Arrays.asList(vitroClassIdStr);
|
||||
return JsonServlet.getSolrIndividualsByVClasses(vclassIds, vreq, ctx);
|
||||
return JsonServlet.getSearchIndividualsByVClasses(vclassIds, vreq);
|
||||
}
|
||||
|
||||
}
|
|
@ -3,12 +3,9 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.controller.json;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
@ -22,9 +19,8 @@ import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
|||
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.individuallist.IndividualListResultsUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.individuallist.IndividualListResults;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.individuallist.IndividualListResultsUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.log.LogUtils;
|
||||
|
||||
|
@ -62,21 +58,21 @@ public class JsonServlet extends VitroHttpServlet {
|
|||
throw new IllegalArgumentException("The call invoked deprecated classes " +
|
||||
"and the parameter for this call appeared nowhere in the code base, " +
|
||||
"so it was removed in May, 2012.");
|
||||
}else if( vreq.getParameter("getSolrIndividualsByVClass") != null ){
|
||||
new GetSolrIndividualsByVClass(vreq).process(resp);
|
||||
}else if( vreq.getParameter("getSearchIndividualsByVClass") != null ){
|
||||
new GetSearchIndividualsByVClass(vreq).process(resp);
|
||||
}else if( vreq.getParameter("getVClassesForVClassGroup") != null ){
|
||||
new GetVClassesForVClassGroup(vreq).process(resp);
|
||||
} else if( vreq.getParameter("getSolrIndividualsByVClasses") != null ){
|
||||
} else if( vreq.getParameter("getSearchIndividualsByVClasses") != null ){
|
||||
log.debug("AJAX request to retrieve individuals by vclasses");
|
||||
new GetSolrIndividualsByVClasses(vreq).process(resp);
|
||||
new GetSearchIndividualsByVClasses(vreq).process(resp);
|
||||
} else if( vreq.getParameter("getDataForPage") != null ){
|
||||
throw new IllegalArgumentException("The call invoked deprecated classes " +
|
||||
"and the parameter for this call appeared nowhere in the code base, " +
|
||||
"so it was removed in Aug 5th 2013.");
|
||||
}else if( vreq.getParameter("getRenderedSolrIndividualsByVClass") != null ){
|
||||
new GetRenderedSolrIndividualsByVClass(vreq).process(resp);
|
||||
}else if( vreq.getParameter("getRandomSolrIndividualsByVClass") != null ){
|
||||
new GetRandomSolrIndividualsByVClass(vreq).process(resp);
|
||||
}else if( vreq.getParameter("getRenderedSearchIndividualsByVClass") != null ){
|
||||
new GetRenderedSearchIndividualsByVClass(vreq).process(resp);
|
||||
}else if( vreq.getParameter("getRandomSearchIndividualsByVClass") != null ){
|
||||
new GetRandomSearchIndividualsByVClass(vreq).process(resp);
|
||||
} else if( vreq.getParameter("getAllVClasses") != null ){
|
||||
new GetAllVClasses(vreq).process(resp);
|
||||
}
|
||||
|
@ -84,27 +80,27 @@ public class JsonServlet extends VitroHttpServlet {
|
|||
}
|
||||
|
||||
|
||||
public static JSONObject getSolrIndividualsByVClass(String vclassURI, HttpServletRequest req, ServletContext context) throws Exception {
|
||||
public static JSONObject getSearchIndividualsByVClass(String vclassURI, HttpServletRequest req) throws Exception {
|
||||
List<String> vclassURIs = Collections.singletonList(vclassURI);
|
||||
VitroRequest vreq = new VitroRequest(req);
|
||||
|
||||
IndividualListResults vcResults = getSolrVClassIntersectionResults(vclassURIs, vreq, context);
|
||||
IndividualListResults vcResults = getSearchVClassIntersectionResults(vclassURIs, vreq);
|
||||
//last parameter indicates single vclass instead of multiple vclasses
|
||||
return IndividualListResultsUtils.wrapIndividualListResultsInJson(vcResults, vreq, false);
|
||||
}
|
||||
|
||||
public static JSONObject getSolrIndividualsByVClasses(List<String> vclassURIs, HttpServletRequest req, ServletContext context) throws Exception {
|
||||
public static JSONObject getSearchIndividualsByVClasses(List<String> vclassURIs, HttpServletRequest req) throws Exception {
|
||||
VitroRequest vreq = new VitroRequest(req);
|
||||
log.debug("Retrieve solr results for vclasses" + vclassURIs.toString());
|
||||
IndividualListResults vcResults = getSolrVClassIntersectionResults(vclassURIs, vreq, context);
|
||||
log.debug("Results returned from Solr for " + vclassURIs.toString() + " are of size " + vcResults.getTotalCount());
|
||||
log.debug("Retrieve search results for vclasses" + vclassURIs.toString());
|
||||
IndividualListResults vcResults = getSearchVClassIntersectionResults(vclassURIs, vreq);
|
||||
log.debug("Results returned from search engine for " + vclassURIs.toString() + " are of size " + vcResults.getTotalCount());
|
||||
|
||||
return IndividualListResultsUtils.wrapIndividualListResultsInJson(vcResults, vreq, true);
|
||||
}
|
||||
|
||||
//Including version for Solr query for Vclass Intersections
|
||||
private static IndividualListResults getSolrVClassIntersectionResults(List<String> vclassURIs, VitroRequest vreq, ServletContext context){
|
||||
log.debug("Retrieving Solr intersection results for " + vclassURIs.toString());
|
||||
//Including version for search query for Vclass Intersections
|
||||
private static IndividualListResults getSearchVClassIntersectionResults(List<String> vclassURIs, VitroRequest vreq){
|
||||
log.debug("Retrieving search intersection results for " + vclassURIs.toString());
|
||||
String alpha = IndividualListController.getAlphaParameter(vreq);
|
||||
int page = IndividualListController.getPageParameter(vreq);
|
||||
log.debug("Alpha and page parameters are " + alpha + " and " + page);
|
||||
|
@ -113,8 +109,7 @@ public class JsonServlet extends VitroHttpServlet {
|
|||
vclassURIs,
|
||||
page, INDIVIDUALS_PER_PAGE,
|
||||
alpha,
|
||||
vreq.getWebappDaoFactory().getIndividualDao(),
|
||||
context);
|
||||
vreq.getWebappDaoFactory().getIndividualDao());
|
||||
} catch(Exception ex) {
|
||||
log.error("Error in retrieval of search results for VClass " + vclassURIs.toString(), ex);
|
||||
return IndividualListResults.EMPTY;
|
||||
|
@ -129,17 +124,17 @@ public class JsonServlet extends VitroHttpServlet {
|
|||
return value;
|
||||
}
|
||||
|
||||
public static JSONObject getRandomSolrIndividualsByVClass(String vclassURI, HttpServletRequest req, ServletContext context) throws Exception {
|
||||
public static JSONObject getRandomSearchIndividualsByVClass(String vclassURI, HttpServletRequest req) throws Exception {
|
||||
VitroRequest vreq = new VitroRequest(req);
|
||||
|
||||
IndividualListResults vcResults = getRandomSolrVClassResults(vclassURI, vreq, context);
|
||||
IndividualListResults vcResults = getRandomSearchVClassResults(vclassURI, vreq);
|
||||
//last parameter indicates single vclass instead of multiple vclasses
|
||||
return IndividualListResultsUtils.wrapIndividualListResultsInJson(vcResults, vreq, false);
|
||||
}
|
||||
|
||||
//Including version for Random Solr query for Vclass Intersections
|
||||
private static IndividualListResults getRandomSolrVClassResults(String vclassURI, VitroRequest vreq, ServletContext context){
|
||||
log.debug("Retrieving random Solr intersection results for " + vclassURI);
|
||||
//Including version for Random search query for Vclass Intersections
|
||||
private static IndividualListResults getRandomSearchVClassResults(String vclassURI, VitroRequest vreq){
|
||||
log.debug("Retrieving random search intersection results for " + vclassURI);
|
||||
|
||||
int page = IndividualListController.getPageParameter(vreq);
|
||||
int pageSize = Integer.parseInt(vreq.getParameter("pageSize"));
|
||||
|
@ -149,8 +144,7 @@ public class JsonServlet extends VitroHttpServlet {
|
|||
vclassURI,
|
||||
page,
|
||||
pageSize,
|
||||
vreq.getWebappDaoFactory().getIndividualDao(),
|
||||
context);
|
||||
vreq.getWebappDaoFactory().getIndividualDao());
|
||||
} catch(Exception ex) {
|
||||
log.error("Error in retrieval of search results for VClass " + vclassURI, ex);
|
||||
return IndividualListResults.EMPTY;
|
||||
|
|
|
@ -133,7 +133,7 @@ public class DisplayVocabulary {
|
|||
public static final String FIXED_HTML_VALUE = DISPLAY_NS + "htmlValue";
|
||||
|
||||
|
||||
/* URI of property for Solr Query Generator */
|
||||
/* URI of property for Search Query Generator */
|
||||
public static final String VCLASSID = DISPLAY_NS + "hasVClassId";
|
||||
|
||||
|
||||
|
|
|
@ -14,12 +14,6 @@ import javax.servlet.http.HttpServletRequest;
|
|||
|
||||
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.FacetField;
|
||||
import org.apache.solr.client.solrj.response.FacetField.Count;
|
||||
import org.apache.solr.client.solrj.response.QueryResponse;
|
||||
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
import com.hp.hpl.jena.rdf.listeners.StatementListener;
|
||||
|
@ -30,6 +24,7 @@ import com.hp.hpl.jena.vocabulary.OWL;
|
|||
import com.hp.hpl.jena.vocabulary.RDF;
|
||||
import com.hp.hpl.jena.vocabulary.RDFS;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
|
||||
|
@ -40,11 +35,17 @@ import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
|||
import edu.cornell.mannlib.vitro.webapp.dao.filtering.WebappDaoFactoryFiltering;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilterUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilters;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngineException;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchFacetField;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchFacetField.Count;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResponse;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.beans.ProhibitedFromSearch;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.indexing.IndexBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.indexing.IndexingEventListener;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
|
||||
import edu.cornell.mannlib.vitro.webapp.searchindex.SearchIndexerSetup;
|
||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.threads.VitroBackgroundThread;
|
||||
|
||||
|
@ -55,15 +56,15 @@ import edu.cornell.mannlib.vitro.webapp.utils.threads.VitroBackgroundThread;
|
|||
* The cache is updated asynchronously by the thread RebuildGroupCacheThread.
|
||||
* A synchronous rebuild can be performed with VClassGroupCache.doSynchronousRebuild()
|
||||
*
|
||||
* This class should handle the condition where Solr is not available.
|
||||
* This class should handle the condition where the search engine is not available.
|
||||
* It will not throw an exception but it will return a empty list of classes
|
||||
* or class groups.
|
||||
*
|
||||
* VClassGroupCache.doSynchronousRebuild() and the RebuildGroupCacheThread will try
|
||||
* to connect to the Solr server a couple of times and then give up.
|
||||
* to connect to the search engine a couple of times and then give up.
|
||||
*
|
||||
* As of VIVO release 1.4, the counts come from the Solr index. If the
|
||||
* solr index is not built or if there were problems building the index,
|
||||
* As of VIVO release 1.4, the counts come from the search index. If the
|
||||
* search index is not built or if there were problems building the index,
|
||||
* the class counts from VClassGroupCache will be incorrect.
|
||||
*/
|
||||
public class VClassGroupCache implements IndexingEventListener {
|
||||
|
@ -184,18 +185,18 @@ public class VClassGroupCache implements IndexingEventListener {
|
|||
}
|
||||
|
||||
public void doSynchronousRebuild(){
|
||||
//try to rebuild a couple times since the Solr server may not yet be up.
|
||||
//try to rebuild a couple times since the search engine may not yet be up.
|
||||
|
||||
int attempts = 0;
|
||||
int maxTries = 3;
|
||||
SolrServerException exception = null;
|
||||
SearchEngineException exception = null;
|
||||
|
||||
while( attempts < maxTries ){
|
||||
try {
|
||||
attempts++;
|
||||
rebuildCacheUsingSolr(this);
|
||||
rebuildCacheUsingSearch(this);
|
||||
break;
|
||||
} catch (SolrServerException e) {
|
||||
} catch (SearchEngineException e) {
|
||||
exception = e;
|
||||
try { Thread.sleep(250); }
|
||||
catch (InterruptedException e1) {/*ignore interrupt*/}
|
||||
|
@ -203,7 +204,7 @@ public class VClassGroupCache implements IndexingEventListener {
|
|||
}
|
||||
|
||||
if( exception != null )
|
||||
log.error("Could not rebuild cache. " + exception.getRootCause().getMessage() );
|
||||
log.error("Could not rebuild cache. " + exception.getCause().getMessage() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -243,21 +244,15 @@ public class VClassGroupCache implements IndexingEventListener {
|
|||
|
||||
/**
|
||||
* Method that rebuilds the cache. This will use a WebappDaoFactory,
|
||||
* a SolrSever and maybe a ProhibitedFromSearch from the cache.context.
|
||||
* a SearchEngine and maybe a ProhibitedFromSearch from the cache.context.
|
||||
*
|
||||
* If ProhibitedFromSearch is not found in the context, that will be skipped.
|
||||
*
|
||||
* @throws SolrServerException if there are problems with the Solr server.
|
||||
*/
|
||||
protected static void rebuildCacheUsingSolr( VClassGroupCache cache ) throws SolrServerException{
|
||||
protected static void rebuildCacheUsingSearch( VClassGroupCache cache ) throws SearchEngineException{
|
||||
long start = System.currentTimeMillis();
|
||||
WebappDaoFactory wdFactory = ModelAccess.on(cache.context).getWebappDaoFactory();
|
||||
|
||||
SolrServer solrServer = (SolrServer)cache.context.getAttribute(SolrSetup.SOLR_SERVER);
|
||||
if( solrServer == null){
|
||||
log.error("Unable to rebuild cache: could not get solrServer from ServletContext");
|
||||
return;
|
||||
}
|
||||
SearchEngine searchEngine = ApplicationUtils.instance().getSearchEngine();
|
||||
|
||||
VitroFilters vFilters = VitroFilterUtils.getPublicFilter(cache.context);
|
||||
VClassGroupDao vcgDao = new WebappDaoFactoryFiltering(wdFactory, vFilters).getVClassGroupDao();
|
||||
|
@ -266,7 +261,7 @@ public class VClassGroupCache implements IndexingEventListener {
|
|||
INCLUDE_UNINSTANTIATED, DONT_INCLUDE_INDIVIDUAL_COUNT);
|
||||
|
||||
removeClassesHiddenFromSearch(groups, cache.context);
|
||||
addCountsUsingSolr(groups, solrServer);
|
||||
addCountsUsingSearch(groups, searchEngine);
|
||||
cache.setCache(groups, classMapForGroups(groups));
|
||||
|
||||
log.debug("msec to build cache: " + (System.currentTimeMillis() - start));
|
||||
|
@ -291,7 +286,7 @@ public class VClassGroupCache implements IndexingEventListener {
|
|||
* Removes classes from groups that are prohibited from search.
|
||||
*/
|
||||
protected static void removeClassesHiddenFromSearch(List<VClassGroup> groups, ServletContext context2) {
|
||||
ProhibitedFromSearch pfs = (ProhibitedFromSearch)context2.getAttribute(SolrSetup.PROHIBITED_FROM_SEARCH);
|
||||
ProhibitedFromSearch pfs = (ProhibitedFromSearch)context2.getAttribute(SearchIndexerSetup.PROHIBITED_FROM_SEARCH);
|
||||
if(pfs==null){
|
||||
log.debug("Could not get ProhibitedFromSearch from ServletContext");
|
||||
return;
|
||||
|
@ -311,34 +306,33 @@ public class VClassGroupCache implements IndexingEventListener {
|
|||
|
||||
/**
|
||||
* Add the Individual count to classes in groups.
|
||||
* @throws SolrServerException
|
||||
* @throws SearchEngineException
|
||||
*/
|
||||
protected static void addCountsUsingSolr(List<VClassGroup> groups, SolrServer solrServer)
|
||||
throws SolrServerException {
|
||||
if( groups == null || solrServer == null )
|
||||
protected static void addCountsUsingSearch(List<VClassGroup> groups, SearchEngine searchEngine)
|
||||
throws SearchEngineException {
|
||||
if( groups == null || searchEngine == null )
|
||||
return;
|
||||
for( VClassGroup group : groups){
|
||||
addClassCountsToGroup(group, solrServer);
|
||||
addClassCountsToGroup(group, searchEngine);
|
||||
}
|
||||
}
|
||||
|
||||
protected static void addClassCountsToGroup(VClassGroup group, SolrServer solrServer)
|
||||
throws SolrServerException {
|
||||
protected static void addClassCountsToGroup(VClassGroup group, SearchEngine searchEngine)
|
||||
throws SearchEngineException {
|
||||
if( group == null ) return;
|
||||
|
||||
String groupUri = group.getURI();
|
||||
String facetOnField = VitroSearchTermNames.RDFTYPE;
|
||||
|
||||
SolrQuery query = new SolrQuery( ).
|
||||
SearchQuery query = searchEngine.createQuery().
|
||||
setRows(0).
|
||||
setQuery(VitroSearchTermNames.CLASSGROUP_URI + ":" + groupUri ).
|
||||
setFacet(true). //facet on type to get counts for classes in classgroup
|
||||
addFacetField( facetOnField ).
|
||||
addFacetFields( facetOnField ). //facet on type to get counts for classes in classgroup
|
||||
setFacetMinCount(0);
|
||||
|
||||
log.debug("query: " + query);
|
||||
|
||||
QueryResponse rsp = solrServer.query(query);
|
||||
SearchResponse rsp = searchEngine.query(query);
|
||||
|
||||
//Get individual count
|
||||
long individualCount = rsp.getResults().getNumFound();
|
||||
|
@ -346,7 +340,7 @@ public class VClassGroupCache implements IndexingEventListener {
|
|||
group.setIndividualCount((int) individualCount);
|
||||
|
||||
//get counts for classes
|
||||
FacetField ff = rsp.getFacetField( facetOnField );
|
||||
SearchFacetField ff = rsp.getFacetField( facetOnField );
|
||||
if( ff != null ){
|
||||
List<Count> counts = ff.getValues();
|
||||
if( counts != null ){
|
||||
|
@ -407,7 +401,8 @@ public class VClassGroupCache implements IndexingEventListener {
|
|||
this.cache = cache;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
@Override
|
||||
public void run() {
|
||||
while (!die) {
|
||||
int delay;
|
||||
|
||||
|
@ -421,23 +416,23 @@ public class VClassGroupCache implements IndexingEventListener {
|
|||
setWorkLevel(WorkLevel.WORKING);
|
||||
rebuildRequested = false;
|
||||
try {
|
||||
rebuildCacheUsingSolr( cache );
|
||||
rebuildCacheUsingSearch( cache );
|
||||
log.debug("rebuildGroupCacheThread.run() -- rebuilt cache ");
|
||||
failedAttempts = 0;
|
||||
delay = 100;
|
||||
} catch (SolrServerException e) {
|
||||
} catch (SearchEngineException e) {
|
||||
failedAttempts++;
|
||||
if( failedAttempts >= maxFailedAttempts ){
|
||||
log.error("Could not build VClassGroupCache. " +
|
||||
"Could not connect with Solr after " +
|
||||
failedAttempts + " attempts.", e.getRootCause());
|
||||
"Could not connect with the search engine after " +
|
||||
failedAttempts + " attempts.", e.getCause());
|
||||
rebuildRequested = false;
|
||||
failedAttempts = 0;
|
||||
delay = 1000;
|
||||
}else{
|
||||
rebuildRequested = true;
|
||||
delay = (int) (( Math.pow(2, failedAttempts) ) * 1000);
|
||||
log.debug("Could not connect with Solr, will attempt " +
|
||||
log.debug("Could not connect with the search engine, will attempt " +
|
||||
"again in " + delay + " msec.");
|
||||
}
|
||||
}catch(Exception ex){
|
||||
|
@ -479,11 +474,13 @@ public class VClassGroupCache implements IndexingEventListener {
|
|||
* Listen for changes to what class group classes are in and their display rank.
|
||||
*/
|
||||
protected class VClassGroupCacheChangeListener extends StatementListener {
|
||||
public void addedStatement(Statement stmt) {
|
||||
@Override
|
||||
public void addedStatement(Statement stmt) {
|
||||
checkAndDoUpdate(stmt);
|
||||
}
|
||||
|
||||
public void removedStatement(Statement stmt) {
|
||||
@Override
|
||||
public void removedStatement(Statement stmt) {
|
||||
checkAndDoUpdate(stmt);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,39 +8,35 @@ import java.util.List;
|
|||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
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.QueryResponse;
|
||||
import org.apache.solr.common.SolrDocument;
|
||||
import org.apache.solr.common.SolrDocumentList;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResponse;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResultDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResultDocumentList;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.fields.FieldUtils;
|
||||
|
||||
/*
|
||||
* This runs a solr query to get individuals of a certain class instead of relying on the dao classes.
|
||||
* This runs a search query to get individuals of a certain class instead of relying on the dao classes.
|
||||
* Also it gets individuals that belong to the most specific type(s) specified.
|
||||
*/
|
||||
public class IndividualsViaSolrQueryOptions extends IndividualsViaVClassOptions implements FieldOptions {
|
||||
private Log log = LogFactory.getLog(IndividualsViaSolrQueryOptions.class);
|
||||
public class IndividualsViaSearchQueryOptions extends IndividualsViaVClassOptions implements FieldOptions {
|
||||
private Log log = LogFactory.getLog(IndividualsViaSearchQueryOptions.class);
|
||||
|
||||
private ServletContext servletContext;
|
||||
private String subjectUri;
|
||||
private String predicateUri;
|
||||
private String objectUri;
|
||||
public IndividualsViaSolrQueryOptions(ServletContext context, String inputSubjectUri, String inputPredicateUri, String inputObjectUri, String ... vclassURIs) throws Exception {
|
||||
public IndividualsViaSearchQueryOptions(String inputSubjectUri, String inputPredicateUri, String inputObjectUri, String ... vclassURIs) throws Exception {
|
||||
super(vclassURIs);
|
||||
this.servletContext = context;
|
||||
this.subjectUri = inputSubjectUri;
|
||||
this.predicateUri = inputPredicateUri;
|
||||
this.objectUri = inputObjectUri;
|
||||
|
@ -50,10 +46,10 @@ public class IndividualsViaSolrQueryOptions extends IndividualsViaVClassOptions
|
|||
protected Map<String,Individual> getIndividualsForClass(String vclassURI, WebappDaoFactory wDaoFact ){
|
||||
Map<String, Individual> individualMap = new HashMap<String, Individual>();
|
||||
try {
|
||||
SolrServer solrServer = SolrSetup.getSolrServer(servletContext);
|
||||
SearchEngine searchEngine = ApplicationUtils.instance().getSearchEngine();
|
||||
|
||||
//solr query for type count.
|
||||
SolrQuery query = new SolrQuery();
|
||||
//search query for type count.
|
||||
SearchQuery query = searchEngine.createQuery();
|
||||
if( VitroVocabulary.OWL_THING.equals( vclassURI )){
|
||||
query.setQuery( "*:*" );
|
||||
}else{
|
||||
|
@ -61,15 +57,15 @@ public class IndividualsViaSolrQueryOptions extends IndividualsViaVClassOptions
|
|||
}
|
||||
query.setStart(0)
|
||||
.setRows(1000);
|
||||
query.setFields(VitroSearchTermNames.URI); // fields to retrieve
|
||||
query.addFields(VitroSearchTermNames.URI); // fields to retrieve
|
||||
|
||||
QueryResponse rsp = solrServer.query(query);
|
||||
SolrDocumentList docs = rsp.getResults();
|
||||
SearchResponse rsp = searchEngine.query(query);
|
||||
SearchResultDocumentList docs = rsp.getResults();
|
||||
long found = docs.getNumFound();
|
||||
if(found > 0) {
|
||||
for (SolrDocument doc : docs) {
|
||||
for (SearchResultDocument doc : docs) {
|
||||
try {
|
||||
String uri = doc.get(VitroSearchTermNames.URI).toString();
|
||||
String uri = doc.getStringValue(VitroSearchTermNames.URI);
|
||||
Individual individual = wDaoFact.getIndividualDao().getIndividualByURI(uri);
|
||||
if (individual == null) {
|
||||
log.debug("No individual for search document with uri = " + uri);
|
||||
|
@ -79,13 +75,13 @@ public class IndividualsViaSolrQueryOptions extends IndividualsViaVClassOptions
|
|||
}
|
||||
}
|
||||
catch(Exception ex) {
|
||||
log.error("An error occurred retrieving the individual solr query resutls", ex);
|
||||
log.error("An error occurred retrieving the individual search resutls", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch(Exception ex) {
|
||||
log.error("Error occurred in executing solr query ", ex);
|
||||
log.error("Error occurred in executing search query ", ex);
|
||||
}
|
||||
return individualMap;
|
||||
}
|
|
@ -5,24 +5,18 @@ package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
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.common.SolrDocumentList;
|
||||
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
import com.hp.hpl.jena.rdf.model.Literal;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||
|
@ -37,9 +31,13 @@ import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo;
|
|||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.IndividualsViaObjectPropetyOptions;
|
||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators.AntiXssValidation;
|
||||
import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngineException;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResponse;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResultDocumentList;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.beans.ProhibitedFromSearch;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.FrontEndEditingUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.FrontEndEditingUtils.EditMode;
|
||||
|
||||
|
@ -175,9 +173,9 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
|
|||
return types;
|
||||
}
|
||||
|
||||
private boolean tooManyRangeOptions(VitroRequest vreq, HttpSession session ) throws SolrServerException {
|
||||
private boolean tooManyRangeOptions(VitroRequest vreq, HttpSession session ) throws SearchEngineException {
|
||||
List<VClass> rangeTypes = getRangeTypes(vreq);
|
||||
SolrServer solrServer = SolrSetup.getSolrServer(session.getServletContext());
|
||||
SearchEngine searchEngine = ApplicationUtils.instance().getSearchEngine();
|
||||
|
||||
List<String> types = new ArrayList<String>();
|
||||
for (VClass vclass : rangeTypes) {
|
||||
|
@ -193,16 +191,16 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
|
|||
|
||||
long count = 0;
|
||||
for( String type:types){
|
||||
//solr query for type count.
|
||||
SolrQuery query = new SolrQuery();
|
||||
//search query for type count.
|
||||
SearchQuery query = searchEngine.createQuery();
|
||||
if( VitroVocabulary.OWL_THING.equals( type )){
|
||||
query.setQuery( "*:*" );
|
||||
}else{
|
||||
query.setQuery( VitroSearchTermNames.RDFTYPE + ":" + type);
|
||||
}
|
||||
query.setRows(0);
|
||||
QueryResponse rsp = solrServer.query(query);
|
||||
SolrDocumentList docs = rsp.getResults();
|
||||
SearchResponse rsp = searchEngine.query(query);
|
||||
SearchResultDocumentList docs = rsp.getResults();
|
||||
long found = docs.getNumFound();
|
||||
count = count + found;
|
||||
if( count > maxNonACRangeIndividualCount )
|
||||
|
@ -524,7 +522,7 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
|
|||
editConfiguration.setFormSpecificData(formSpecificData);
|
||||
}
|
||||
|
||||
public void addFormSpecificDataForAC(EditConfigurationVTwo editConfiguration, VitroRequest vreq, HttpSession session) throws SolrServerException {
|
||||
public void addFormSpecificDataForAC(EditConfigurationVTwo editConfiguration, VitroRequest vreq, HttpSession session) throws SearchEngineException {
|
||||
HashMap<String, Object> formSpecificData = new HashMap<String, Object>();
|
||||
//Get the edit mode
|
||||
formSpecificData.put("editMode", getEditMode(vreq).toString().toLowerCase());
|
||||
|
@ -554,7 +552,7 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
|
|||
}
|
||||
|
||||
//TODO: find out if there are any individuals in the classes of objectTypes
|
||||
formSpecificData.put("rangeIndividualsExist", rangeIndividualsExist(session,types) );
|
||||
formSpecificData.put("rangeIndividualsExist", rangeIndividualsExist(types) );
|
||||
|
||||
formSpecificData.put("sparqlForAcFilter", getSparqlForAcFilter(vreq));
|
||||
if(customErrorMessages != null && !customErrorMessages.isEmpty()) {
|
||||
|
@ -564,19 +562,18 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
|
|||
editConfiguration.setFormSpecificData(formSpecificData);
|
||||
}
|
||||
|
||||
private Object rangeIndividualsExist(HttpSession session, List<VClass> types) throws SolrServerException {
|
||||
SolrServer solrServer = SolrSetup.getSolrServer(session.getServletContext());
|
||||
private Object rangeIndividualsExist(List<VClass> types) throws SearchEngineException {
|
||||
SearchEngine searchEngine = ApplicationUtils.instance().getSearchEngine();
|
||||
|
||||
boolean rangeIndividualsFound = false;
|
||||
for( VClass type:types){
|
||||
//solr for type count.
|
||||
SolrQuery query = new SolrQuery();
|
||||
|
||||
//search for type count.
|
||||
SearchQuery query = searchEngine.createQuery();
|
||||
query.setQuery( VitroSearchTermNames.RDFTYPE + ":" + type.getURI());
|
||||
query.setRows(0);
|
||||
|
||||
QueryResponse rsp = solrServer.query(query);
|
||||
SolrDocumentList docs = rsp.getResults();
|
||||
SearchResponse rsp = searchEngine.query(query);
|
||||
SearchResultDocumentList docs = rsp.getResults();
|
||||
if( docs.getNumFound() > 0 ){
|
||||
rangeIndividualsFound = true;
|
||||
break;
|
||||
|
|
|
@ -2,47 +2,18 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
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.common.SolrDocumentList;
|
||||
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
import com.hp.hpl.jena.rdf.model.Literal;
|
||||
import com.hp.hpl.jena.rdf.model.Model;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
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.edit.n3editing.VTwo.EditConfigurationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
|
||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo;
|
||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.IndividualsViaObjectPropertyByRankOptions;
|
||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.IndividualsViaObjectPropetyOptions;
|
||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators.AntiXssValidation;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.beans.ProhibitedFromSearch;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.FrontEndEditingUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.FrontEndEditingUtils.EditMode;
|
||||
|
||||
/**
|
||||
* Generates the edit configuration for a default property form.
|
||||
|
|
|
@ -526,7 +526,7 @@ private String getExistingIsSelfContainedTemplateQuery() {
|
|||
MenuManagementDataUtils.includeRequiredSystemData(vreq.getSession().getServletContext(), data);
|
||||
data.put("classGroup", new ArrayList<String>());
|
||||
data.put("classGroups", DataGetterUtils.getClassGroups(vreq));
|
||||
//for solr individuals data get getter
|
||||
//for search individuals data get getter
|
||||
data.put("classes", this.getAllVClasses(vreq));
|
||||
data.put("availablePermissions", this.getAvailablePermissions(vreq));
|
||||
data.put("availablePermissionOrderedList", this.getAvailablePermissonsOrderedURIs());
|
||||
|
@ -671,9 +671,9 @@ private String getExistingIsSelfContainedTemplateQuery() {
|
|||
return query;
|
||||
}
|
||||
|
||||
//Get all vclasses for the list of vclasses for solr
|
||||
//Get all vclasses for the list of vclasses for search
|
||||
//Originally considered using an ajax request to get the vclasses list which is fine for adding a new content type
|
||||
//but for an existing solr content type, would need to make yet another ajax request which seems too much
|
||||
//but for an existing search content type, would need to make yet another ajax request which seems too much
|
||||
private List<HashMap<String, String>> getAllVClasses(VitroRequest vreq) {
|
||||
List<VClass> vclasses = new ArrayList<VClass>();
|
||||
VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(vreq);
|
||||
|
|
|
@ -18,7 +18,7 @@ public class ProcessDataGetterN3Map {
|
|||
map.put("edu.cornell.mannlib.vitro.webapp.utils.dataGetter.ClassGroupPageData", "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils.ProcessClassGroupDataGetterN3");
|
||||
map.put("edu.cornell.mannlib.vitro.webapp.utils.dataGetter.IndividualsForClassesDataGetter", "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils.ProcessIndividualsForClassesDataGetterN3");
|
||||
map.put("edu.cornell.mannlib.vitro.webapp.utils.dataGetter.FixedHTMLDataGetter", "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils.ProcessFixedHTMLN3");
|
||||
map.put("edu.cornell.mannlib.vitro.webapp.utils.dataGetter.SolrIndividualsDataGetter", "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils.ProcessSolrIndividualsDataGetterN3");
|
||||
map.put("edu.cornell.mannlib.vitro.webapp.utils.dataGetter.SearchIndividualsDataGetter", "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils.ProcessSearchIndividualsDataGetterN3");
|
||||
|
||||
return map;
|
||||
}
|
||||
|
|
|
@ -24,11 +24,11 @@ import com.hp.hpl.jena.rdf.model.Resource;
|
|||
|
||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo;
|
||||
//Returns the appropriate n3 based on data getter
|
||||
public class ProcessSolrIndividualsDataGetterN3 extends ProcessDataGetterAbstract {
|
||||
private static String classType = "java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.SolrIndividualsDataGetter";
|
||||
public class ProcessSearchIndividualsDataGetterN3 extends ProcessDataGetterAbstract {
|
||||
private static String classType = "java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.SearchIndividualsDataGetter";
|
||||
private Log log = LogFactory.getLog(ProcessFixedHTMLN3.class);
|
||||
|
||||
public ProcessSolrIndividualsDataGetterN3(){
|
||||
public ProcessSearchIndividualsDataGetterN3(){
|
||||
|
||||
}
|
||||
//Pass in variable that represents the counter
|
|
@ -21,18 +21,18 @@ import javax.servlet.http.HttpServletResponse;
|
|||
import org.apache.commons.collections.EnumerationUtils;
|
||||
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 edu.cornell.mannlib.vedit.beans.LoginStatusBean;
|
||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
||||
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.solr.FieldMap;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.solr.SolrQueryUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.solr.SolrResultsParser;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngineException;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResponse;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.searchengine.FieldMap;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.searchengine.SearchQueryUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.searchengine.SearchResultsParser;
|
||||
|
||||
/**
|
||||
* Assist in cache management for individual profile pages.
|
||||
|
@ -41,7 +41,7 @@ import edu.cornell.mannlib.vitro.webapp.utils.solr.SolrResultsParser;
|
|||
*
|
||||
* Only works for users who are not logged in.
|
||||
*
|
||||
* The Solr index must be configured to keep an ETAG on each individual's
|
||||
* The search index must be configured to keep an ETAG on each individual's
|
||||
* record. The ETAG is a hash of the record's content and is updated each time
|
||||
* the individual is re-indexed.
|
||||
*
|
||||
|
@ -59,10 +59,10 @@ import edu.cornell.mannlib.vitro.webapp.utils.solr.SolrResultsParser;
|
|||
* generated, with a Cache-Control header that should prevent the cache from
|
||||
* storing that response.
|
||||
*
|
||||
* If the requesting user is not logged in, this filter will ask Solr for the
|
||||
* ETAG on the requested individual. If it is the same as the ETAG supplied by
|
||||
* the cache in the request, then the response is 304 Not Modified. Otherwise, a
|
||||
* fresh response is generated.
|
||||
* If the requesting user is not logged in, this filter will ask the search
|
||||
* engine for the ETAG on the requested individual. If it is the same as the
|
||||
* ETAG supplied by the cache in the request, then the response is 304 Not
|
||||
* Modified. Otherwise, a fresh response is generated.
|
||||
*
|
||||
* An unconditional request may mean that there is no external cache, or that
|
||||
* the cache doesn't have a copy of this particular page.
|
||||
|
@ -77,7 +77,7 @@ public class CachingResponseFilter implements Filter {
|
|||
private static final String PROPERTY_ENABLE_CACHING = "http.createCacheHeaders";
|
||||
private static final String ETAG_FIELD = "etag";
|
||||
|
||||
private static final FieldMap parserFieldMap = SolrQueryUtils.fieldMap()
|
||||
private static final FieldMap parserFieldMap = SearchQueryUtils.fieldMap()
|
||||
.put(ETAG_FIELD, ETAG_FIELD);
|
||||
|
||||
private ServletContext ctx;
|
||||
|
@ -241,19 +241,18 @@ public class CachingResponseFilter implements Filter {
|
|||
}
|
||||
|
||||
/**
|
||||
* Ask Solr whether it has an ETAG for this URI.
|
||||
* Ask the search engine whether it has an ETAG for this URI.
|
||||
*/
|
||||
private String findEtagForIndividual(String individualUri) {
|
||||
SolrQuery query = new SolrQuery("URI:" + individualUri)
|
||||
.setFields(ETAG_FIELD);
|
||||
|
||||
SolrServer solr = SolrSetup.getSolrServer(ctx);
|
||||
SearchEngine search = ApplicationUtils.instance().getSearchEngine();
|
||||
SearchQuery query = search.createQuery("URI:" + individualUri).addFields(
|
||||
ETAG_FIELD);
|
||||
|
||||
try {
|
||||
QueryResponse response = solr.query(query);
|
||||
List<Map<String, String>> maps = new SolrResultsParser(response,
|
||||
SearchResponse response = search.query(query);
|
||||
List<Map<String, String>> maps = new SearchResultsParser(response,
|
||||
parserFieldMap).parse();
|
||||
log.debug("Solr response for '" + query.getQuery() + "' was "
|
||||
log.debug("Search response for '" + query.getQuery() + "' was "
|
||||
+ maps);
|
||||
|
||||
if (maps.isEmpty()) {
|
||||
|
@ -261,16 +260,16 @@ public class CachingResponseFilter implements Filter {
|
|||
} else {
|
||||
return maps.get(0).get(ETAG_FIELD);
|
||||
}
|
||||
} catch (SolrServerException e) {
|
||||
} catch (SearchEngineException e) {
|
||||
log.warn(
|
||||
"Solr query '" + query.getQuery() + "' threw an exception",
|
||||
"Search query '" + query.getQuery() + "' threw an exception",
|
||||
e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The ETAG from the Solr index is not specific enough, since we may have
|
||||
* The ETAG from the search index is not specific enough, since we may have
|
||||
* different versions for different languages. Add the Locales from the
|
||||
* request to make it unique.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.modules;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||
|
||||
/**
|
||||
* The interface that holds the modules and extensions together.
|
||||
*/
|
||||
public interface Application {
|
||||
ServletContext getServletContext();
|
||||
|
||||
SearchEngine getSearchEngine();
|
||||
|
||||
public interface Component {
|
||||
enum LifecycleState {
|
||||
NEW, ACTIVE, STOPPED
|
||||
}
|
||||
|
||||
void startup(Application application, ComponentStartupStatus ss);
|
||||
|
||||
void shutdown(Application application);
|
||||
}
|
||||
|
||||
public static interface Module extends Component {
|
||||
// Nothing except lifecycle so far.
|
||||
}
|
||||
|
||||
public static interface Extension extends Component {
|
||||
// Nothing except lifecycle so far.
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.modules;
|
||||
|
||||
/**
|
||||
* A facade for the StartupStatus that already knows who the
|
||||
* ServletContextListener is.
|
||||
*/
|
||||
public interface ComponentStartupStatus {
|
||||
void info(String message);
|
||||
|
||||
void info(String message, Throwable cause);
|
||||
|
||||
void warning(String message);
|
||||
|
||||
void warning(String message, Throwable cause);
|
||||
|
||||
void fatal(String message);
|
||||
|
||||
void fatal(String message, Throwable cause);
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.modules.searchEngine;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.Application;
|
||||
|
||||
/**
|
||||
* The principle interface for the SearchEngine. All search-related objects are
|
||||
* created by these methods.
|
||||
*/
|
||||
public interface SearchEngine extends Application.Module {
|
||||
|
||||
/**
|
||||
* Check to see whether the SearchEngine is alive.
|
||||
*
|
||||
* @throws SearchEngineException
|
||||
* if the SearchEngine does not respond.
|
||||
*/
|
||||
void ping() throws SearchEngineException;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Indexing operations
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create a SearchInputDocument that can be populated and added to the
|
||||
* index.
|
||||
*/
|
||||
SearchInputDocument createInputDocument();
|
||||
|
||||
/**
|
||||
* Add documents to the search index.
|
||||
*/
|
||||
void add(SearchInputDocument... docs) throws SearchEngineException;
|
||||
|
||||
/**
|
||||
* Add documents to the search index.
|
||||
*/
|
||||
void add(Collection<SearchInputDocument> docs) throws SearchEngineException;
|
||||
|
||||
/**
|
||||
* Explicitly commit all pending changes, and wait until they are visible to
|
||||
* the search.
|
||||
*/
|
||||
void commit() throws SearchEngineException;
|
||||
|
||||
/**
|
||||
* Explicitly commit all pending changes, and optionally wait until they are
|
||||
* visible to the search.
|
||||
*/
|
||||
void commit(boolean wait) throws SearchEngineException;
|
||||
|
||||
/**
|
||||
* Delete documents from the search index, by unique ID.
|
||||
*/
|
||||
void deleteById(String... ids) throws SearchEngineException;
|
||||
|
||||
/**
|
||||
* Delete documents from the search index, by unique ID.
|
||||
*/
|
||||
void deleteById(Collection<String> ids) throws SearchEngineException;
|
||||
|
||||
/**
|
||||
* Delete documents from the search index if they satisfy the query.
|
||||
*/
|
||||
void deleteByQuery(String query) throws SearchEngineException;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Searching operations
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create a SearchQuery that can be populated and used for searching.
|
||||
*/
|
||||
SearchQuery createQuery();
|
||||
|
||||
/**
|
||||
* Convenience method to create a SearchQuery and set the query text in one
|
||||
* step.
|
||||
*/
|
||||
SearchQuery createQuery(String queryText);
|
||||
|
||||
/**
|
||||
* Query the search index and return the results. Response is never null.
|
||||
*/
|
||||
SearchResponse query(SearchQuery query) throws SearchEngineException;
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.modules.searchEngine;
|
||||
|
||||
/**
|
||||
* Indicates a problem with a request to the SearchEngine.
|
||||
*/
|
||||
public class SearchEngineException extends Exception {
|
||||
|
||||
public SearchEngineException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public SearchEngineException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public SearchEngineException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public SearchEngineException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.modules.searchEngine;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Holds the faceting information from a query result.
|
||||
*/
|
||||
public interface SearchFacetField {
|
||||
|
||||
/**
|
||||
* The name of the field that was faceted. Never null.
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* The different facet values. May return an empty list, but never null.
|
||||
*/
|
||||
List<Count> getValues();
|
||||
|
||||
/**
|
||||
* Holds one facet from this field.
|
||||
*/
|
||||
public interface Count {
|
||||
|
||||
/**
|
||||
* The value of this facet. Never null.
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* The number of times that the value occurs in the results.
|
||||
*/
|
||||
long getCount();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.modules.searchEngine;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A collection of fields and values that will be used to build a record in the
|
||||
* search index.
|
||||
*/
|
||||
public interface SearchInputDocument {
|
||||
/**
|
||||
* Create a field that can be populated and added to the document.
|
||||
*/
|
||||
SearchInputField createField(String name);
|
||||
|
||||
/**
|
||||
* Put the field into the document. If a field with this name already exists
|
||||
* in the document, it will be replaced.
|
||||
*/
|
||||
void addField(SearchInputField field);
|
||||
|
||||
/**
|
||||
* Create a field with this name and values, and put it into the document. If
|
||||
* a field with this name already exists in the document, it will be
|
||||
* replaced.
|
||||
*/
|
||||
void addField(String name, Object... values);
|
||||
|
||||
/**
|
||||
* Create a field with this name and values, and put it into the document. If
|
||||
* a field with this name already exists in the document, it will be
|
||||
* replaced.
|
||||
*/
|
||||
void addField(String name, Collection<Object> values);
|
||||
|
||||
/**
|
||||
* Create a field with this name, boost level and values, and put it into
|
||||
* the document. If a field with this name already exists in the document,
|
||||
* it will be replaced.
|
||||
*/
|
||||
void addField(String name, float boost, Object... values);
|
||||
|
||||
/**
|
||||
* Create a field with this name, boost level and values, and put it into
|
||||
* the document. If a field with this name already exists in the document,
|
||||
* it will be replaced.
|
||||
*/
|
||||
void addField(String name, float boost, Collection<Object> values);
|
||||
|
||||
/**
|
||||
* Set a boost level for the document as a whole.
|
||||
*/
|
||||
void setDocumentBoost(float searchBoost);
|
||||
|
||||
float getDocumentBoost();
|
||||
|
||||
/**
|
||||
* May return null.
|
||||
*/
|
||||
SearchInputField getField(String name);
|
||||
|
||||
/**
|
||||
* May return an empty map, but never null.
|
||||
*/
|
||||
Map<String, SearchInputField> getFieldMap();
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.modules.searchEngine;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* A named field with a name and one or more values. This can be added to a
|
||||
* SearchInputDocument and inserted into the search index.
|
||||
*/
|
||||
public interface SearchInputField {
|
||||
|
||||
/**
|
||||
* Add values to this field.
|
||||
*/
|
||||
void addValues(Object... values);
|
||||
|
||||
/**
|
||||
* Add values to this field.
|
||||
*/
|
||||
void addValues(Collection<? extends Object> values);
|
||||
|
||||
/**
|
||||
* Set the boost level for this field.
|
||||
*/
|
||||
void setBoost(float boost);
|
||||
|
||||
String getName();
|
||||
|
||||
float getBoost();
|
||||
|
||||
/**
|
||||
* May return an empty collection, but never null.
|
||||
*/
|
||||
Collection<Object> getValues();
|
||||
|
||||
/**
|
||||
* May return null.
|
||||
*/
|
||||
Object getFirstValue();
|
||||
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.modules.searchEngine;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A collection of search terms that will be used to query the search index.
|
||||
*
|
||||
* Each of the "set" and "add" methods will return the searchQuery itself, so
|
||||
* calls can easily be chained together.
|
||||
*/
|
||||
public interface SearchQuery {
|
||||
public enum Order {
|
||||
ASC, DESC
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text of the query. This will be parsed using Lucene query syntax.
|
||||
*
|
||||
* @return this query
|
||||
*/
|
||||
SearchQuery setQuery(String query);
|
||||
|
||||
/**
|
||||
* Where in the ordered list of result documents should the response begin?
|
||||
* That is, how many of the results should be skipped? (allows paging of
|
||||
* results). The default is 0.
|
||||
*
|
||||
* @return this query
|
||||
*/
|
||||
SearchQuery setStart(int start);
|
||||
|
||||
/**
|
||||
* What is the maximum number of documents that will be returned from the
|
||||
* query? A negative value means no limit. The default is -1.
|
||||
*
|
||||
* @return this query
|
||||
*/
|
||||
SearchQuery setRows(int rows);
|
||||
|
||||
/**
|
||||
* Which fields should be returned from the query?
|
||||
*
|
||||
* @return this query
|
||||
*/
|
||||
SearchQuery addFields(String... names);
|
||||
|
||||
/**
|
||||
* Which fields should be returned from the query?
|
||||
*
|
||||
* @return this query
|
||||
*/
|
||||
SearchQuery addFields(Collection<String> names);
|
||||
|
||||
/**
|
||||
* What field should be used to sort the results, and in what order?
|
||||
*
|
||||
* @return this query
|
||||
*/
|
||||
SearchQuery addSortField(String name, Order order);
|
||||
|
||||
/**
|
||||
* Restrict the results by this query.
|
||||
*
|
||||
* @return this query
|
||||
*/
|
||||
SearchQuery addFilterQuery(String filterQuery);
|
||||
|
||||
/**
|
||||
* Restrict the results by these queries.
|
||||
*
|
||||
* @return this query
|
||||
*/
|
||||
SearchQuery addFilterQueries(String... filterQueries);
|
||||
|
||||
/**
|
||||
* What fields should be used to facet the results?
|
||||
*
|
||||
* @return this query
|
||||
*/
|
||||
SearchQuery addFacetFields(String... fields);
|
||||
|
||||
/**
|
||||
* The maximum number of facet counts that will be returned from the query.
|
||||
* The default is 100. A negative value means no limit.
|
||||
*
|
||||
* @return this query
|
||||
*/
|
||||
SearchQuery setFacetLimit(int cnt);
|
||||
|
||||
/**
|
||||
* Facet having fewer hits will be excluded from the list. The default is 0.
|
||||
*
|
||||
* @return this query
|
||||
*/
|
||||
SearchQuery setFacetMinCount(int cnt);
|
||||
|
||||
/**
|
||||
* @return The text of the query. May be empty, but never null.
|
||||
*/
|
||||
String getQuery();
|
||||
|
||||
int getStart();
|
||||
|
||||
/**
|
||||
* @return A negative value means that no limit has been specified.
|
||||
*/
|
||||
int getRows();
|
||||
|
||||
/**
|
||||
* @return May return an empty set, but never null.
|
||||
*/
|
||||
Set<String> getFieldsToReturn();
|
||||
|
||||
/**
|
||||
* @return May return an empty map, but never null.
|
||||
*/
|
||||
Map<String, SearchQuery.Order> getSortFields();
|
||||
|
||||
/**
|
||||
* @return May return an empty set, but never null.
|
||||
*/
|
||||
Set<String> getFilters();
|
||||
|
||||
/**
|
||||
* @return May return an empty set, but never null.
|
||||
*/
|
||||
Set<String> getFacetFields();
|
||||
|
||||
/**
|
||||
* @return A negative value means that no limit has been specified.
|
||||
*/
|
||||
int getFacetLimit();
|
||||
|
||||
/**
|
||||
* @return A negative value means that no limit has been specified.
|
||||
*/
|
||||
int getFacetMinCount();
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.modules.searchEngine;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The response to a query against the search index. It includes a list of the
|
||||
* results, as well as an optional collection of facet fields.
|
||||
*/
|
||||
public interface SearchResponse {
|
||||
|
||||
/**
|
||||
* May return an empty list, but never null.
|
||||
*/
|
||||
SearchResultDocumentList getResults();
|
||||
|
||||
/**
|
||||
* May return an empty map, but never null.
|
||||
*/
|
||||
Map<String, Map<String, List<String>>> getHighlighting();
|
||||
|
||||
/**
|
||||
* May return null.
|
||||
*/
|
||||
SearchFacetField getFacetField(String name);
|
||||
|
||||
/**
|
||||
* May return an empty list, but never null.
|
||||
*/
|
||||
List<SearchFacetField> getFacetFields();
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.modules.searchEngine;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The concrete representation of a document in the search index. Obtained in
|
||||
* response to a query.
|
||||
*/
|
||||
public interface SearchResultDocument {
|
||||
|
||||
/**
|
||||
* A document identifier that can be used in SearchEngine.deleteById();
|
||||
* Never null.
|
||||
*/
|
||||
public String getUniqueId();
|
||||
|
||||
/**
|
||||
* May return an empty collection, but never null.
|
||||
*/
|
||||
public Collection<String> getFieldNames();
|
||||
|
||||
/**
|
||||
* May return null.
|
||||
*/
|
||||
public Object getFirstValue(String name);
|
||||
|
||||
/**
|
||||
* Gets the first value for the named field, and converts it to a String.
|
||||
* May return null.
|
||||
*/
|
||||
public String getStringValue(String name);
|
||||
|
||||
/**
|
||||
* Get the values for the named field. May return an empty collection, but
|
||||
* never null.
|
||||
*/
|
||||
public Collection<Object> getFieldValues(String name);
|
||||
|
||||
/**
|
||||
* May return an empty map, but never null. The values collection for any
|
||||
* key may be empty, but never null.
|
||||
*/
|
||||
public Map<String, Collection<Object>> getFieldValuesMap();
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.modules.searchEngine;
|
||||
|
||||
/**
|
||||
* A collection of results that are returned from a query.
|
||||
*/
|
||||
public interface SearchResultDocumentList extends
|
||||
Iterable<SearchResultDocument> {
|
||||
|
||||
/**
|
||||
* The number of documents that would satisfy the query
|
||||
*/
|
||||
long getNumFound();
|
||||
|
||||
/**
|
||||
* The number of documents that are included in this result.
|
||||
*/
|
||||
int size();
|
||||
|
||||
SearchResultDocument get(int i);
|
||||
|
||||
}
|
|
@ -1,33 +1,33 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.search.solr;
|
||||
package edu.cornell.mannlib.vitro.webapp.search;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
|
||||
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.UpdateResponse;
|
||||
import org.apache.solr.common.SolrDocumentList;
|
||||
import org.apache.solr.common.SolrInputDocument;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngineException;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery.Order;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResponse;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResultDocumentList;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.IndexingException;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.beans.IndexerIface;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding.IndividualToSolrDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.documentBuilding.IndividualToSearchDocument;
|
||||
|
||||
|
||||
public class SolrIndexer implements IndexerIface {
|
||||
private final static Log log = LogFactory.getLog(SolrIndexer.class);
|
||||
public class SearchIndexer implements IndexerIface {
|
||||
private final static Log log = LogFactory.getLog(SearchIndexer.class);
|
||||
|
||||
protected SolrServer server;
|
||||
protected SearchEngine server;
|
||||
protected boolean indexing;
|
||||
protected HashSet<String> urisIndexed;
|
||||
protected IndividualToSolrDocument individualToSolrDoc;
|
||||
protected IndividualToSearchDocument individualToSearchDoc;
|
||||
|
||||
/**
|
||||
* System is shutting down if true.
|
||||
|
@ -36,7 +36,7 @@ public class SolrIndexer implements IndexerIface {
|
|||
|
||||
/**
|
||||
* This records when a full re-index starts so that once it is done
|
||||
* all the documents on the Solr service that are earlier than the
|
||||
* all the documents in the search index that are earlier than the
|
||||
* reindexStart can be removed.
|
||||
*/
|
||||
protected long reindexStart = 0L;
|
||||
|
@ -48,48 +48,48 @@ public class SolrIndexer implements IndexerIface {
|
|||
*/
|
||||
protected boolean doingFullIndexRebuild = false;
|
||||
|
||||
public SolrIndexer( SolrServer server, IndividualToSolrDocument indToDoc){
|
||||
public SearchIndexer( SearchEngine server, IndividualToSearchDocument indToDoc){
|
||||
this.server = server;
|
||||
this.individualToSolrDoc = indToDoc;
|
||||
this.individualToSearchDoc = indToDoc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void index(Individual ind) throws IndexingException {
|
||||
if( ! indexing )
|
||||
throw new IndexingException("SolrIndexer: must call " +
|
||||
throw new IndexingException("SearchIndexer: must call " +
|
||||
"startIndexing() before index().");
|
||||
|
||||
if( ind == null )
|
||||
if( ind == null ) {
|
||||
log.debug("Individual to index was null, ignoring.");
|
||||
return;
|
||||
}
|
||||
|
||||
try{
|
||||
if( urisIndexed.contains(ind.getURI()) ){
|
||||
log.debug("already indexed " + ind.getURI() );
|
||||
return;
|
||||
}else{
|
||||
SolrInputDocument solrDoc = null;
|
||||
SearchInputDocument doc = null;
|
||||
synchronized(this){
|
||||
urisIndexed.add(ind.getURI());
|
||||
}
|
||||
log.debug("indexing " + ind.getURI());
|
||||
solrDoc = individualToSolrDoc.translate(ind);
|
||||
doc = individualToSearchDoc.translate(ind);
|
||||
|
||||
if( solrDoc != null){
|
||||
if( doc != null){
|
||||
if( log.isDebugEnabled()){
|
||||
log.info("boost for " + ind.getName() + " is " + solrDoc.getDocumentBoost());
|
||||
log.debug( solrDoc.toString() );
|
||||
log.info("boost for " + ind.getName() + " is " + doc.getDocumentBoost());
|
||||
log.debug( doc.toString() );
|
||||
}
|
||||
|
||||
UpdateResponse res = server.add( solrDoc );
|
||||
log.debug("response after adding docs to server: "+ res);
|
||||
server.add( doc );
|
||||
log.debug("Added docs to server.");
|
||||
}else{
|
||||
log.debug("removing from index " + ind.getURI());
|
||||
removeFromIndex(ind.getURI());
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
throw new IndexingException(ex.getMessage());
|
||||
} catch (SolrServerException ex) {
|
||||
} catch (SearchEngineException ex) {
|
||||
throw new IndexingException(ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
@ -109,11 +109,9 @@ public class SolrIndexer implements IndexerIface {
|
|||
public void removeFromIndex(String uri) throws IndexingException {
|
||||
if( uri != null ){
|
||||
try {
|
||||
server.deleteById(individualToSolrDoc.getIdForUri(uri));
|
||||
server.deleteById(individualToSearchDoc.getIdForUri(uri));
|
||||
log.debug("deleted " + " " + uri);
|
||||
} catch (SolrServerException e) {
|
||||
log.error( "could not delete individual " + uri, e);
|
||||
} catch (IOException e) {
|
||||
} catch (SearchEngineException e) {
|
||||
log.error( "could not delete individual " + uri, e);
|
||||
}
|
||||
}
|
||||
|
@ -122,7 +120,7 @@ public class SolrIndexer implements IndexerIface {
|
|||
@Override
|
||||
public synchronized void startIndexing() throws IndexingException {
|
||||
if( indexing)
|
||||
log.debug("SolrIndexer.startIndexing() Indexing in progress, waiting for completion...");
|
||||
log.debug("SearchIndexer.startIndexing() Indexing in progress, waiting for completion...");
|
||||
while( indexing && ! shutdownRequested ){ //wait for indexing to end.
|
||||
try{ wait( 250 ); }
|
||||
catch(InterruptedException ex){}
|
||||
|
@ -138,7 +136,7 @@ public class SolrIndexer implements IndexerIface {
|
|||
public void abortIndexingAndCleanUp() {
|
||||
shutdownRequested = true;
|
||||
try{
|
||||
individualToSolrDoc.shutdown();
|
||||
individualToSearchDoc.shutdown();
|
||||
}catch(Exception e){
|
||||
if( log != null)
|
||||
log.debug(e,e);
|
||||
|
@ -160,8 +158,8 @@ public class SolrIndexer implements IndexerIface {
|
|||
server.commit();
|
||||
} catch (Throwable e) {
|
||||
if( ! shutdownRequested ){
|
||||
log.debug("could not commit to solr server, " +
|
||||
"this should not be a problem since solr will do autocommit");
|
||||
log.debug("could not commit to the search engine, " +
|
||||
"this should not be a problem since the search engine will do autocommit");
|
||||
}
|
||||
}
|
||||
indexing = false;
|
||||
|
@ -172,12 +170,9 @@ public class SolrIndexer implements IndexerIface {
|
|||
try {
|
||||
server.deleteByQuery("indexedTime:[ * TO " + reindexStart + " ]");
|
||||
server.commit();
|
||||
} catch (SolrServerException e) {
|
||||
} catch (SearchEngineException e) {
|
||||
if( ! shutdownRequested )
|
||||
log.error("could not delete documents from before rebuild.",e);
|
||||
} catch (IOException e) {
|
||||
if( ! shutdownRequested )
|
||||
log.error("could not delete documents from before rebuild.",e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,17 +181,17 @@ public class SolrIndexer implements IndexerIface {
|
|||
public long getModified() {
|
||||
long modified = 0;
|
||||
|
||||
SolrQuery query = new SolrQuery();
|
||||
SearchQuery query = ApplicationUtils.instance().getSearchEngine().createQuery();
|
||||
query.setQuery("*:*");
|
||||
query.addSortField("indexedTime", SolrQuery.ORDER.desc);
|
||||
query.addSortField("indexedTime", Order.DESC);
|
||||
|
||||
try {
|
||||
QueryResponse rsp = server.query(query);
|
||||
SolrDocumentList docs = rsp.getResults();
|
||||
SearchResponse rsp = server.query(query);
|
||||
SearchResultDocumentList docs = rsp.getResults();
|
||||
if(docs!=null){
|
||||
modified = (Long)docs.get(0).getFieldValue("indexedTime");
|
||||
modified = (Long)docs.get(0).getFirstValue("indexedTime");
|
||||
}
|
||||
} catch (SolrServerException e) {
|
||||
} catch (SearchEngineException e) {
|
||||
log.error(e,e);
|
||||
}
|
||||
|
||||
|
@ -208,16 +203,16 @@ public class SolrIndexer implements IndexerIface {
|
|||
* and returns false on failure to connect to server.
|
||||
*/
|
||||
public boolean isIndexEmpty() {
|
||||
SolrQuery query = new SolrQuery();
|
||||
SearchQuery query = ApplicationUtils.instance().getSearchEngine().createQuery();
|
||||
query.setQuery("*:*");
|
||||
try {
|
||||
QueryResponse rsp = server.query(query);
|
||||
SolrDocumentList docs = rsp.getResults();
|
||||
SearchResponse rsp = server.query(query);
|
||||
SearchResultDocumentList docs = rsp.getResults();
|
||||
if(docs==null || docs.size()==0){
|
||||
return true;
|
||||
}
|
||||
} catch (SolrServerException e) {
|
||||
log.error("Could not connect to solr server" ,e.getRootCause());
|
||||
} catch (SearchEngineException e) {
|
||||
log.error("Could not connect to the search engine." ,e.getCause());
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -10,8 +10,8 @@ import edu.cornell.mannlib.vitro.webapp.search.IndexingException;
|
|||
* IndexBuilder will manage getting lists of object to index and then use
|
||||
* an object that implements IndexerIface to stuff the backend index.
|
||||
*
|
||||
* An example is SolrIndexer which is set up and associated with a
|
||||
* IndexBuilder in SolrSetup.
|
||||
* An example is SearchIndexer which is set up and associated with a
|
||||
* IndexBuilder in SearchIndexerSetup.
|
||||
*
|
||||
* @author bdc34
|
||||
*
|
||||
|
|
|
@ -16,20 +16,20 @@ import javax.servlet.http.HttpServletResponse;
|
|||
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.response.QueryResponse;
|
||||
import org.apache.solr.common.SolrDocument;
|
||||
import org.apache.solr.common.SolrDocumentList;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.ajax.VitroAjaxController;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResponse;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResultDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResultDocumentList;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
|
||||
|
||||
/**
|
||||
* AutocompleteController generates autocomplete content
|
||||
|
@ -66,7 +66,7 @@ public class AutocompleteController extends VitroAjaxController {
|
|||
|
||||
String qtxt = vreq.getParameter(PARAM_QUERY);
|
||||
|
||||
SolrQuery query = getQuery(qtxt, vreq);
|
||||
SearchQuery query = getQuery(qtxt, vreq);
|
||||
if (query == null ) {
|
||||
log.debug("query for '" + qtxt +"' is null.");
|
||||
doNoQuery(response);
|
||||
|
@ -74,8 +74,8 @@ public class AutocompleteController extends VitroAjaxController {
|
|||
}
|
||||
log.debug("query for '" + qtxt +"' is " + query.toString());
|
||||
|
||||
SolrServer solr = SolrSetup.getSolrServer(getServletContext());
|
||||
QueryResponse queryResponse = solr.query(query);
|
||||
SearchEngine search = ApplicationUtils.instance().getSearchEngine();
|
||||
SearchResponse queryResponse = search.query(query);
|
||||
|
||||
if ( queryResponse == null) {
|
||||
log.error("Query response for a search was null");
|
||||
|
@ -83,7 +83,7 @@ public class AutocompleteController extends VitroAjaxController {
|
|||
return;
|
||||
}
|
||||
|
||||
SolrDocumentList docs = queryResponse.getResults();
|
||||
SearchResultDocumentList docs = queryResponse.getResults();
|
||||
|
||||
if ( docs == null) {
|
||||
log.error("Docs for a search was null");
|
||||
|
@ -99,33 +99,11 @@ public class AutocompleteController extends VitroAjaxController {
|
|||
}
|
||||
|
||||
List<SearchResult> results = new ArrayList<SearchResult>();
|
||||
for (SolrDocument doc : docs) {
|
||||
for (SearchResultDocument doc : docs) {
|
||||
try {
|
||||
String uri = doc.get(VitroSearchTermNames.URI).toString();
|
||||
// RY 7/1/2011
|
||||
// Comment was: VitroSearchTermNames.NAME_RAW is a multivalued field, so doc.get() returns a list.
|
||||
// Changed to: VitroSearchTermNames.NAME_RAW is a multivalued field, so doc.get() could return a list
|
||||
// But in fact: I'm no longer seeing any lists returned for individuals with multiple labels. Not sure
|
||||
// if this is new behavior or what. ???
|
||||
Object nameRaw = doc.get(VitroSearchTermNames.NAME_RAW);
|
||||
String name = null;
|
||||
if (nameRaw instanceof List<?>) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> nameRawList = (List<String>) nameRaw;
|
||||
name = nameRawList.get(0);
|
||||
} else {
|
||||
name = (String) nameRaw;
|
||||
}
|
||||
|
||||
Object mostSpecificType = doc.get(VitroSearchTermNames.MOST_SPECIFIC_TYPE_URIS);
|
||||
String mst = null;
|
||||
if (mostSpecificType instanceof List<?>) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> mstList = (List<String>) mostSpecificType;
|
||||
mst = mstList.get(0);
|
||||
} else {
|
||||
mst = (String) mostSpecificType;
|
||||
}
|
||||
String uri = doc.getStringValue(VitroSearchTermNames.URI);
|
||||
String name = doc.getStringValue(VitroSearchTermNames.NAME_RAW);
|
||||
String mst = doc.getStringValue(VitroSearchTermNames.MOST_SPECIFIC_TYPE_URIS);
|
||||
|
||||
SearchResult result = new SearchResult(name, uri, mst);
|
||||
results.add(result);
|
||||
|
@ -150,7 +128,7 @@ public class AutocompleteController extends VitroAjaxController {
|
|||
}
|
||||
}
|
||||
|
||||
private SolrQuery getQuery(String queryStr, VitroRequest vreq) {
|
||||
private SearchQuery getQuery(String queryStr, VitroRequest vreq) {
|
||||
|
||||
if ( queryStr == null) {
|
||||
log.error("There was no parameter '"+ PARAM_QUERY
|
||||
|
@ -162,26 +140,26 @@ public class AutocompleteController extends VitroAjaxController {
|
|||
return null;
|
||||
}
|
||||
|
||||
SolrQuery query = new SolrQuery();
|
||||
SearchQuery query = ApplicationUtils.instance().getSearchEngine().createQuery();
|
||||
query.setStart(0)
|
||||
.setRows(DEFAULT_MAX_HIT_COUNT);
|
||||
setNameQuery(query, queryStr, vreq);
|
||||
// Filter by type
|
||||
String typeParam = (String) vreq.getParameter(PARAM_RDFTYPE);
|
||||
String multipleTypesParam = (String) vreq.getParameter(PARAM_MULTIPLE_RDFTYPE);
|
||||
String typeParam = vreq.getParameter(PARAM_RDFTYPE);
|
||||
String multipleTypesParam = vreq.getParameter(PARAM_MULTIPLE_RDFTYPE);
|
||||
if (typeParam != null) {
|
||||
addFilterQuery(query, typeParam, multipleTypesParam);
|
||||
}
|
||||
|
||||
query.setFields(VitroSearchTermNames.NAME_RAW, VitroSearchTermNames.URI, VitroSearchTermNames.MOST_SPECIFIC_TYPE_URIS); // fields to retrieve
|
||||
query.addFields(VitroSearchTermNames.NAME_RAW, VitroSearchTermNames.URI, VitroSearchTermNames.MOST_SPECIFIC_TYPE_URIS); // fields to retrieve
|
||||
|
||||
// Can't sort on multivalued field, so we sort the results in Java when we get them.
|
||||
// query.setSortField(VitroSearchTermNames.NAME_LOWERCASE, SolrQuery.ORDER.asc);
|
||||
// query.addSortField(VitroSearchTermNames.NAME_LOWERCASE, Order.ASC);
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
private void addFilterQuery(SolrQuery query, String typeParam, String multipleTypesParam) {
|
||||
private void addFilterQuery(SearchQuery query, String typeParam, String multipleTypesParam) {
|
||||
if(multipleTypesParam == null || multipleTypesParam.equals("null") || multipleTypesParam.isEmpty()) {
|
||||
//Single type parameter, process as usual
|
||||
query.addFilterQuery(VitroSearchTermNames.RDFTYPE + ":\"" + typeParam + "\"");
|
||||
|
@ -200,12 +178,12 @@ public class AutocompleteController extends VitroAjaxController {
|
|||
}
|
||||
}
|
||||
|
||||
private void setNameQuery(SolrQuery query, String queryStr, HttpServletRequest request) {
|
||||
private void setNameQuery(SearchQuery query, String queryStr, HttpServletRequest request) {
|
||||
|
||||
if (StringUtils.isBlank(queryStr)) {
|
||||
log.error("No query string");
|
||||
}
|
||||
String tokenizeParam = (String) request.getParameter("tokenize");
|
||||
String tokenizeParam = request.getParameter("tokenize");
|
||||
boolean tokenize = "true".equals(tokenizeParam);
|
||||
|
||||
// Note: Stemming is only relevant if we are tokenizing: an untokenized name
|
||||
|
@ -218,7 +196,7 @@ public class AutocompleteController extends VitroAjaxController {
|
|||
}
|
||||
}
|
||||
|
||||
private void setTokenizedNameQuery(SolrQuery query, String queryStr, HttpServletRequest request) {
|
||||
private void setTokenizedNameQuery(SearchQuery query, String queryStr, HttpServletRequest request) {
|
||||
|
||||
/* We currently have no use case for a tokenized, unstemmed autocomplete search field, so the option
|
||||
* has been disabled. If needed in the future, will need to add a new field and field type which
|
||||
|
@ -262,7 +240,7 @@ public class AutocompleteController extends VitroAjaxController {
|
|||
|
||||
}
|
||||
|
||||
private void setUntokenizedNameQuery(SolrQuery query, String queryStr) {
|
||||
private void setUntokenizedNameQuery(SearchQuery query, String queryStr) {
|
||||
queryStr = queryStr.trim();
|
||||
queryStr = makeTermQuery(VitroSearchTermNames.AC_NAME_UNTOKENIZED, queryStr, true);
|
||||
query.setQuery(queryStr);
|
||||
|
@ -276,7 +254,7 @@ public class AutocompleteController extends VitroAjaxController {
|
|||
}
|
||||
|
||||
private String escapeWhitespaceInQueryString(String queryStr) {
|
||||
// Solr wants whitespace to be escaped with a backslash
|
||||
// The search engine wants whitespace to be escaped with a backslash
|
||||
return queryStr.replaceAll("\\s+", "\\\\ ");
|
||||
}
|
||||
|
||||
|
|
|
@ -5,28 +5,15 @@ package edu.cornell.mannlib.vitro.webapp.search.controller;
|
|||
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
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.response.QueryResponse;
|
||||
import org.apache.solr.common.SolrDocument;
|
||||
import org.apache.solr.common.SolrDocumentList;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import com.hp.hpl.jena.query.Dataset;
|
||||
import com.hp.hpl.jena.query.DatasetFactory;
|
||||
|
@ -42,10 +29,8 @@ import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
|||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.ajax.SparqlUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.ajax.VitroAjaxController;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.ajax.SparqlUtils.AjaxControllerException;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.ajax.VitroAjaxController;
|
||||
|
||||
/**
|
||||
* DataAutocompleteController generates autocomplete content
|
||||
|
|
|
@ -15,9 +15,8 @@ import javax.servlet.http.HttpServletResponse;
|
|||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.solr.client.solrj.SolrServer;
|
||||
import org.apache.solr.client.solrj.SolrServerException;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
|
@ -28,7 +27,6 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Red
|
|||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.indexing.IndexBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.threads.VitroBackgroundThread.WorkLevel;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.threads.VitroBackgroundThread.WorkLevelStamp;
|
||||
|
||||
|
@ -40,8 +38,8 @@ import edu.cornell.mannlib.vitro.webapp.utils.threads.VitroBackgroundThread.Work
|
|||
* That IndexBuilder will be associated with a object that implements the
|
||||
* IndexerIface.
|
||||
*
|
||||
* An example of the IndexerIface is SolrIndexer. An example of the IndexBuilder
|
||||
* and SolrIndexer setup is in SolrSetup.
|
||||
* An example of the IndexerIface is SearchIndexer. An example of the IndexBuilder
|
||||
* and SearchIndexer setup is in SearchIndexerSetup.
|
||||
*
|
||||
* @author bdc34
|
||||
*/
|
||||
|
@ -160,10 +158,10 @@ public class IndexController extends FreemarkerHttpServlet {
|
|||
|
||||
private Boolean testIndexConnection() {
|
||||
try {
|
||||
SolrSetup.getSolrServer(getServletContext()).ping();
|
||||
ApplicationUtils.instance().getSearchEngine().ping();
|
||||
return Boolean.TRUE;
|
||||
} catch (Exception e) {
|
||||
log.error("Can't connect to the Solr server.", e);
|
||||
log.error("Can't connect to the search engine.", e);
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,14 +21,8 @@ import javax.servlet.http.HttpServletResponse;
|
|||
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.response.FacetField;
|
||||
import org.apache.solr.client.solrj.response.FacetField.Count;
|
||||
import org.apache.solr.client.solrj.response.QueryResponse;
|
||||
import org.apache.solr.common.SolrDocument;
|
||||
import org.apache.solr.common.SolrDocumentList;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||
|
@ -47,18 +41,21 @@ import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupsForRequest;
|
|||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache;
|
||||
import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchFacetField;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchFacetField.Count;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResponse;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResultDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResultDocumentList;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.IndexConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames;
|
||||
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.searchresult.IndividualSearchResult;
|
||||
import edu.ucsf.vitro.opensocial.OpenSocialManager;
|
||||
|
||||
/**
|
||||
* Paged search controller that uses Solr
|
||||
*
|
||||
* @author bdc34, rjy7
|
||||
*
|
||||
* Paged search controller that uses the search engine
|
||||
*/
|
||||
|
||||
public class PagedSearchController extends FreemarkerHttpServlet {
|
||||
|
@ -169,15 +166,15 @@ public class PagedSearchController extends FreemarkerHttpServlet {
|
|||
return doFailedSearch(badQueryMsg, queryText, format, vreq);
|
||||
}
|
||||
|
||||
SolrQuery query = getQuery(queryText, hitsPerPage, startIndex, vreq);
|
||||
SolrServer solr = SolrSetup.getSolrServer(getServletContext());
|
||||
QueryResponse response = null;
|
||||
SearchQuery query = getQuery(queryText, hitsPerPage, startIndex, vreq);
|
||||
SearchEngine search = ApplicationUtils.instance().getSearchEngine();
|
||||
SearchResponse response = null;
|
||||
|
||||
try {
|
||||
response = solr.query(query);
|
||||
response = search.query(query);
|
||||
} catch (Exception ex) {
|
||||
String msg = makeBadSearchMessage(queryText, ex.getMessage(), vreq);
|
||||
log.error("could not run Solr query",ex);
|
||||
log.error("could not run search query",ex);
|
||||
return doFailedSearch(msg, queryText, format, vreq);
|
||||
}
|
||||
|
||||
|
@ -186,7 +183,7 @@ public class PagedSearchController extends FreemarkerHttpServlet {
|
|||
return doFailedSearch(I18n.text(vreq, "error_in_search_request"), queryText, format, vreq);
|
||||
}
|
||||
|
||||
SolrDocumentList docs = response.getResults();
|
||||
SearchResultDocumentList docs = response.getResults();
|
||||
if (docs == null) {
|
||||
log.error("Document list for a search was null");
|
||||
return doFailedSearch(I18n.text(vreq, "error_in_search_request"), queryText,format, vreq);
|
||||
|
@ -199,11 +196,11 @@ public class PagedSearchController extends FreemarkerHttpServlet {
|
|||
}
|
||||
|
||||
List<Individual> individuals = new ArrayList<Individual>(docs.size());
|
||||
Iterator<SolrDocument> docIter = docs.iterator();
|
||||
Iterator<SearchResultDocument> docIter = docs.iterator();
|
||||
while( docIter.hasNext() ){
|
||||
try {
|
||||
SolrDocument doc = docIter.next();
|
||||
String uri = doc.get(VitroSearchTermNames.URI).toString();
|
||||
SearchResultDocument doc = docIter.next();
|
||||
String uri = doc.getStringValue(VitroSearchTermNames.URI);
|
||||
Individual ind = iDao.getIndividualByURI(uri);
|
||||
if(ind != null) {
|
||||
ind.setSearchSnippet( getSnippet(doc, response) );
|
||||
|
@ -353,12 +350,12 @@ public class PagedSearchController extends FreemarkerHttpServlet {
|
|||
* Get the class groups represented for the individuals in the documents.
|
||||
* @param qtxt
|
||||
*/
|
||||
private List<VClassGroupSearchLink> getClassGroupsLinks(VitroRequest vreq, VClassGroupDao grpDao, SolrDocumentList docs, QueryResponse rsp, String qtxt) {
|
||||
private List<VClassGroupSearchLink> getClassGroupsLinks(VitroRequest vreq, VClassGroupDao grpDao, SearchResultDocumentList docs, SearchResponse rsp, String qtxt) {
|
||||
Map<String,Long> cgURItoCount = new HashMap<String,Long>();
|
||||
|
||||
List<VClassGroup> classgroups = new ArrayList<VClassGroup>( );
|
||||
List<FacetField> ffs = rsp.getFacetFields();
|
||||
for(FacetField ff : ffs){
|
||||
List<SearchFacetField> ffs = rsp.getFacetFields();
|
||||
for(SearchFacetField ff : ffs){
|
||||
if(VitroSearchTermNames.CLASSGROUP_URI.equals(ff.getName())){
|
||||
List<Count> counts = ff.getValues();
|
||||
for( Count ct: counts){
|
||||
|
@ -388,13 +385,13 @@ public class PagedSearchController extends FreemarkerHttpServlet {
|
|||
return classGroupLinks;
|
||||
}
|
||||
|
||||
private List<VClassSearchLink> getVClassLinks(VClassDao vclassDao, SolrDocumentList docs, QueryResponse rsp, String qtxt){
|
||||
private List<VClassSearchLink> getVClassLinks(VClassDao vclassDao, SearchResultDocumentList docs, SearchResponse rsp, String qtxt){
|
||||
HashSet<String> typesInHits = getVClassUrisForHits(docs);
|
||||
List<VClass> classes = new ArrayList<VClass>(typesInHits.size());
|
||||
Map<String,Long> typeURItoCount = new HashMap<String,Long>();
|
||||
|
||||
List<FacetField> ffs = rsp.getFacetFields();
|
||||
for(FacetField ff : ffs){
|
||||
List<SearchFacetField> ffs = rsp.getFacetFields();
|
||||
for(SearchFacetField ff : ffs){
|
||||
if(VitroSearchTermNames.RDFTYPE.equals(ff.getName())){
|
||||
List<Count> counts = ff.getValues();
|
||||
for( Count ct: counts){
|
||||
|
@ -435,9 +432,9 @@ public class PagedSearchController extends FreemarkerHttpServlet {
|
|||
return vClassLinks;
|
||||
}
|
||||
|
||||
private HashSet<String> getVClassUrisForHits(SolrDocumentList docs){
|
||||
private HashSet<String> getVClassUrisForHits(SearchResultDocumentList docs){
|
||||
HashSet<String> typesInHits = new HashSet<String>();
|
||||
for (SolrDocument doc : docs) {
|
||||
for (SearchResultDocument doc : docs) {
|
||||
try {
|
||||
Collection<Object> types = doc.getFieldValues(VitroSearchTermNames.RDFTYPE);
|
||||
if (types != null) {
|
||||
|
@ -453,8 +450,8 @@ public class PagedSearchController extends FreemarkerHttpServlet {
|
|||
return typesInHits;
|
||||
}
|
||||
|
||||
private String getSnippet(SolrDocument doc, QueryResponse response) {
|
||||
String docId = doc.get(VitroSearchTermNames.DOCID).toString();
|
||||
private String getSnippet(SearchResultDocument doc, SearchResponse response) {
|
||||
String docId = doc.getStringValue(VitroSearchTermNames.DOCID);
|
||||
StringBuffer text = new StringBuffer();
|
||||
Map<String, Map<String, List<String>>> highlights = response.getHighlighting();
|
||||
if (highlights != null && highlights.get(docId) != null) {
|
||||
|
@ -466,19 +463,19 @@ public class PagedSearchController extends FreemarkerHttpServlet {
|
|||
return text.toString();
|
||||
}
|
||||
|
||||
private SolrQuery getQuery(String queryText, int hitsPerPage, int startIndex, VitroRequest vreq) {
|
||||
// Lowercase the search term to support wildcard searches: Solr applies no text
|
||||
private SearchQuery getQuery(String queryText, int hitsPerPage, int startIndex, VitroRequest vreq) {
|
||||
// Lowercase the search term to support wildcard searches: The search engine applies no text
|
||||
// processing to a wildcard search term.
|
||||
SolrQuery query = new SolrQuery( queryText );
|
||||
SearchQuery query = ApplicationUtils.instance().getSearchEngine().createQuery(queryText);
|
||||
|
||||
query.setStart( startIndex )
|
||||
.setRows(hitsPerPage);
|
||||
|
||||
// ClassGroup filtering param
|
||||
String classgroupParam = (String) vreq.getParameter(PARAM_CLASSGROUP);
|
||||
String classgroupParam = vreq.getParameter(PARAM_CLASSGROUP);
|
||||
|
||||
// rdf:type filtering param
|
||||
String typeParam = (String) vreq.getParameter(PARAM_RDFTYPE);
|
||||
String typeParam = vreq.getParameter(PARAM_RDFTYPE);
|
||||
|
||||
if ( ! StringUtils.isBlank(classgroupParam) ) {
|
||||
// ClassGroup filtering
|
||||
|
@ -487,22 +484,17 @@ public class PagedSearchController extends FreemarkerHttpServlet {
|
|||
query.addFilterQuery(VitroSearchTermNames.CLASSGROUP_URI + ":\"" + classgroupParam + "\"");
|
||||
|
||||
//with ClassGroup filtering we want type facets
|
||||
query.add("facet","true");
|
||||
query.add("facet.limit","-1");
|
||||
query.add("facet.field",VitroSearchTermNames.RDFTYPE);
|
||||
query.addFacetFields(VitroSearchTermNames.RDFTYPE).setFacetLimit(-1);
|
||||
|
||||
}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 + "\"");
|
||||
|
||||
//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);
|
||||
query.addFacetFields(VitroSearchTermNames.CLASSGROUP_URI).setFacetLimit(-1);
|
||||
}
|
||||
|
||||
log.debug("Query = " + query.toString());
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
package edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding;
|
||||
package edu.cornell.mannlib.vitro.webapp.search.documentBuilding;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
@ -9,16 +9,14 @@ import java.util.List;
|
|||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.solr.common.SolrInputDocument;
|
||||
import org.apache.solr.common.SolrInputField;
|
||||
|
||||
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.RDFNode;
|
||||
import com.hp.hpl.jena.rdf.model.ResourceFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputField;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
|
||||
|
@ -39,7 +37,7 @@ public class ContextNodeFields implements DocumentModifier{
|
|||
protected RDFServiceFactory rdfServiceFactory;
|
||||
|
||||
/**
|
||||
* Construct this with a model to query when building Solr Documents and
|
||||
* Construct this with a model to query when building search documents and
|
||||
* a list of the SPARQL queries to run.
|
||||
*/
|
||||
protected ContextNodeFields(List<String> queries, RDFServiceFactory rdfServiceFactory){
|
||||
|
@ -53,7 +51,7 @@ public class ContextNodeFields implements DocumentModifier{
|
|||
}
|
||||
|
||||
@Override
|
||||
public void modifyDocument(Individual individual, SolrInputDocument doc, StringBuffer addUri) {
|
||||
public void modifyDocument(Individual individual, SearchInputDocument doc, StringBuffer addUri) {
|
||||
if( individual == null )
|
||||
return;
|
||||
|
||||
|
@ -65,20 +63,20 @@ public class ContextNodeFields implements DocumentModifier{
|
|||
/* get text from the context nodes and add the to ALLTEXT */
|
||||
StringBuffer values = executeQueryForValues(individual, queries);
|
||||
|
||||
SolrInputField field = doc.getField(VitroSearchTermNames.ALLTEXT);
|
||||
SearchInputField field = doc.getField(VitroSearchTermNames.ALLTEXT);
|
||||
if( field == null ){
|
||||
doc.addField(VitroSearchTermNames.ALLTEXT, values);
|
||||
}else{
|
||||
field.addValue(values, field.getBoost());
|
||||
field.addValues(values, field.getBoost());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* this method gets values that will be added to ALLTEXT
|
||||
* field of solr Document for each individual.
|
||||
* field of the search index Document for each individual.
|
||||
*
|
||||
* @param individual
|
||||
* @return StringBuffer with text values to add to ALLTEXT field of solr Document.
|
||||
* @return StringBuffer with text values to add to ALLTEXT field of the search index Document.
|
||||
*/
|
||||
protected StringBuffer executeQueryForValues( Individual individual, Collection<String> queries){
|
||||
/* execute all the queries on the list and concat the values to add to all text */
|
|
@ -0,0 +1,16 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.search.documentBuilding;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputDocument;
|
||||
/**
|
||||
* This interface represents an object that can add to a SearchInputDocument.
|
||||
*/
|
||||
public interface DocumentModifier {
|
||||
public void modifyDocument(Individual individual, SearchInputDocument doc, StringBuffer addUri) throws SkipIndividualException;
|
||||
|
||||
//called to inform the DocumentModifier that the system is shutting down
|
||||
public void shutdown();
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
package edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding;
|
||||
package edu.cornell.mannlib.vitro.webapp.search.documentBuilding;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
|
@ -1,5 +1,5 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
package edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding;
|
||||
package edu.cornell.mannlib.vitro.webapp.search.documentBuilding;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
|
@ -1,5 +1,5 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
package edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding;
|
||||
package edu.cornell.mannlib.vitro.webapp.search.documentBuilding;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
@ -7,8 +7,6 @@ import java.util.List;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.solr.common.SolrInputDocument;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
package edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding;
|
||||
package edu.cornell.mannlib.vitro.webapp.search.documentBuilding;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding.IndividualToSolrDocument.DONT_EXCLUDE;
|
||||
import static edu.cornell.mannlib.vitro.webapp.search.documentBuilding.IndividualToSearchDocument.DONT_EXCLUDE;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding;
|
||||
package edu.cornell.mannlib.vitro.webapp.search.documentBuilding;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
@ -12,25 +12,26 @@ import java.util.Map.Entry;
|
|||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.solr.common.SolrDocument;
|
||||
import org.apache.solr.common.SolrInputDocument;
|
||||
import org.joda.time.DateTime;
|
||||
import org.jsoup.Jsoup;
|
||||
|
||||
import com.hp.hpl.jena.shared.JenaException;
|
||||
import com.hp.hpl.jena.vocabulary.OWL;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResultDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.IndexingException;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames;
|
||||
|
||||
public class IndividualToSolrDocument {
|
||||
public class IndividualToSearchDocument {
|
||||
|
||||
public static final Log log = LogFactory.getLog(IndividualToSolrDocument.class.getName());
|
||||
public static final Log log = LogFactory.getLog(IndividualToSearchDocument.class.getName());
|
||||
|
||||
public static VitroSearchTermNames term = new VitroSearchTermNames();
|
||||
|
||||
|
@ -40,13 +41,13 @@ public class IndividualToSolrDocument {
|
|||
|
||||
protected List<SearchIndexExcluder> excludes;
|
||||
|
||||
public IndividualToSolrDocument(List<SearchIndexExcluder> excludes, List<DocumentModifier> docModifiers){
|
||||
public IndividualToSearchDocument(List<SearchIndexExcluder> excludes, List<DocumentModifier> docModifiers){
|
||||
this.excludes = excludes;
|
||||
this.documentModifiers = docModifiers;
|
||||
}
|
||||
|
||||
@SuppressWarnings("static-access")
|
||||
public SolrInputDocument translate(Individual ind) throws IndexingException{
|
||||
public SearchInputDocument translate(Individual ind) throws IndexingException{
|
||||
try{
|
||||
String excludeMsg = checkExcludes( ind );
|
||||
if( excludeMsg != DONT_EXCLUDE){
|
||||
|
@ -54,7 +55,7 @@ public class IndividualToSolrDocument {
|
|||
return null;
|
||||
}
|
||||
|
||||
SolrInputDocument doc = new SolrInputDocument();
|
||||
SearchInputDocument doc = ApplicationUtils.instance().getSearchEngine().createInputDocument();
|
||||
|
||||
//DocID
|
||||
doc.addField(term.DOCID, getIdForUri( ind.getURI() ) );
|
||||
|
@ -79,7 +80,7 @@ public class IndividualToSolrDocument {
|
|||
addObjectPropertyText(ind, doc, objectNames, addUri);
|
||||
|
||||
//time of index in msec past epoch
|
||||
doc.addField(term.INDEXEDTIME, new Long( (new DateTime()).getMillis() ) );
|
||||
doc.addField(term.INDEXEDTIME, (Object) new DateTime().getMillis() );
|
||||
|
||||
addAllText( ind, doc, classPublicNames, objectNames );
|
||||
|
||||
|
@ -125,7 +126,7 @@ public class IndividualToSolrDocument {
|
|||
protected Map<String,Long> docModClassToTime = new HashMap<String,Long>();
|
||||
protected long docModCount =0;
|
||||
|
||||
protected void runAdditionalDocModifers( Individual ind, SolrInputDocument doc, StringBuffer addUri )
|
||||
protected void runAdditionalDocModifers( Individual ind, SearchInputDocument doc, StringBuffer addUri )
|
||||
throws SkipIndividualException{
|
||||
//run the document modifiers
|
||||
if( documentModifiers != null && !documentModifiers.isEmpty()){
|
||||
|
@ -158,7 +159,7 @@ public class IndividualToSolrDocument {
|
|||
}
|
||||
}
|
||||
|
||||
protected void addAllText(Individual ind, SolrInputDocument doc, StringBuffer classPublicNames, StringBuffer objectNames) {
|
||||
protected void addAllText(Individual ind, SearchInputDocument doc, StringBuffer classPublicNames, StringBuffer objectNames) {
|
||||
String t=null;
|
||||
//ALLTEXT, all of the 'full text'
|
||||
StringBuffer allTextValue = new StringBuffer();
|
||||
|
@ -209,7 +210,7 @@ public class IndividualToSolrDocument {
|
|||
* Get the rdfs:labes for objects of statements and put in objectNames.
|
||||
* Get the URIs for objects of statements and put in addUri.
|
||||
*/
|
||||
protected void addObjectPropertyText(Individual ind, SolrInputDocument doc,
|
||||
protected void addObjectPropertyText(Individual ind, SearchInputDocument doc,
|
||||
StringBuffer objectNames, StringBuffer addUri) {
|
||||
|
||||
try{
|
||||
|
@ -245,7 +246,7 @@ public class IndividualToSolrDocument {
|
|||
* @returns true if prohibited from search
|
||||
* @throws SkipIndividualException
|
||||
*/
|
||||
protected void addClasses(Individual ind, SolrInputDocument doc, StringBuffer classPublicNames) throws SkipIndividualException{
|
||||
protected void addClasses(Individual ind, SearchInputDocument doc, StringBuffer classPublicNames) throws SkipIndividualException{
|
||||
ArrayList<String> superClassNames = null;
|
||||
|
||||
List<VClass> vclasses = ind.getVClasses(false);
|
||||
|
@ -279,7 +280,7 @@ public class IndividualToSolrDocument {
|
|||
}
|
||||
}
|
||||
|
||||
protected void addMostSpecificTypeUris(Individual ind, SolrInputDocument doc){
|
||||
protected void addMostSpecificTypeUris(Individual ind, SearchInputDocument doc){
|
||||
List<String> mstURIs = ind.getMostSpecificTypeURIs();
|
||||
if( mstURIs != null ){
|
||||
for( String typeURI : mstURIs ){
|
||||
|
@ -289,7 +290,7 @@ public class IndividualToSolrDocument {
|
|||
}
|
||||
}
|
||||
|
||||
protected void addLabel(Individual ind, SolrInputDocument doc) {
|
||||
protected void addLabel(Individual ind, SearchInputDocument doc) {
|
||||
String value = "";
|
||||
String label = ind.getRdfsLabel();
|
||||
if (label != null) {
|
||||
|
@ -301,12 +302,12 @@ public class IndividualToSolrDocument {
|
|||
doc.addField(term.NAME_RAW, value);
|
||||
doc.addField(term.NAME_LOWERCASE_SINGLE_VALUED,value);
|
||||
|
||||
// NAME_RAW will be copied by solr into the following fields:
|
||||
// NAME_RAW will be copied by the search engine into the following fields:
|
||||
// NAME_LOWERCASE, NAME_UNSTEMMED, NAME_STEMMED, NAME_PHONETIC, AC_NAME_UNTOKENIZED, AC_NAME_STEMMED
|
||||
}
|
||||
|
||||
public Object getIndexId(Object obj) {
|
||||
throw new Error("IndiviudalToSolrDocument.getIndexId() is unimplemented");
|
||||
throw new Error("IndiviudalToSearchDocument.getIndexId() is unimplemented");
|
||||
}
|
||||
|
||||
public String getIdForUri(String uri){
|
||||
|
@ -324,8 +325,8 @@ public class IndividualToSolrDocument {
|
|||
public Individual unTranslate(Object result) {
|
||||
Individual ent = null;
|
||||
|
||||
if( result != null && result instanceof SolrDocument){
|
||||
SolrDocument hit = (SolrDocument) result;
|
||||
if( result instanceof SearchResultDocument){
|
||||
SearchResultDocument hit = (SearchResultDocument) result;
|
||||
String uri= (String) hit.getFirstValue(term.URI);
|
||||
|
||||
ent = new IndividualImpl();
|
|
@ -0,0 +1,47 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.search.documentBuilding;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames.NAME_LOWERCASE;
|
||||
import static edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames.NAME_RAW;
|
||||
import static edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames.NAME_STEMMED;
|
||||
import static edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames.NAME_UNSTEMMED;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputField;
|
||||
|
||||
public class NameBoost implements DocumentModifier {
|
||||
|
||||
/**
|
||||
* These are the fields in the search Document that
|
||||
* are related to the name. If you modify the schema,
|
||||
* please consider if you need to change this list
|
||||
* of name fields to boost.
|
||||
*/
|
||||
String[] fieldsToBoost = {NAME_RAW,NAME_LOWERCASE,NAME_UNSTEMMED,NAME_STEMMED};
|
||||
|
||||
|
||||
final float boost;
|
||||
|
||||
public NameBoost(float boost){
|
||||
this.boost = boost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modifyDocument(Individual individual, SearchInputDocument doc,
|
||||
StringBuffer addUri) {
|
||||
|
||||
for( String fieldName : fieldsToBoost){
|
||||
SearchInputField field = doc.getField(fieldName);
|
||||
if( field != null ){
|
||||
field.setBoost(field.getBoost() + boost);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
// do nothing.
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding;
|
||||
package edu.cornell.mannlib.vitro.webapp.search.documentBuilding;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
|
@ -8,9 +8,9 @@ import java.io.InputStreamReader;
|
|||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.solr.common.SolrInputDocument;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ResultFormat;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
|
||||
|
@ -31,7 +31,7 @@ public class NameFields implements DocumentModifier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void modifyDocument(Individual ind, SolrInputDocument doc,
|
||||
public void modifyDocument(Individual ind, SearchInputDocument doc,
|
||||
StringBuffer addUri) throws SkipIndividualException {
|
||||
if( ind == null || ind.getURI() == null ){
|
||||
return;
|
|
@ -1,5 +1,5 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
package edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding;
|
||||
package edu.cornell.mannlib.vitro.webapp.search.documentBuilding;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding;
|
||||
package edu.cornell.mannlib.vitro.webapp.search.documentBuilding;
|
||||
|
||||
public class SkipIndividualException extends Exception{
|
||||
|
|
@ -1,10 +1,9 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding;
|
||||
|
||||
import org.apache.solr.common.SolrInputDocument;
|
||||
package edu.cornell.mannlib.vitro.webapp.search.documentBuilding;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames;
|
||||
|
||||
public class SourceInstitution implements DocumentModifier {
|
||||
|
@ -22,7 +21,7 @@ public class SourceInstitution implements DocumentModifier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void modifyDocument(Individual individual, SolrInputDocument doc,
|
||||
public void modifyDocument(Individual individual, SearchInputDocument doc,
|
||||
StringBuffer addUri) throws SkipIndividualException {
|
||||
|
||||
doc.addField(VitroSearchTermNames.SITE_URL, siteURL);
|
|
@ -1,5 +1,5 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
package edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding;
|
||||
package edu.cornell.mannlib.vitro.webapp.search.documentBuilding;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
|
@ -1,6 +1,6 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding;
|
||||
package edu.cornell.mannlib.vitro.webapp.search.documentBuilding;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames.THUMBNAIL;
|
||||
import static edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames.THUMBNAIL_URL;
|
||||
|
@ -9,13 +9,13 @@ import java.util.Iterator;
|
|||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.solr.common.SolrInputDocument;
|
||||
|
||||
import com.hp.hpl.jena.query.QuerySolution;
|
||||
import com.hp.hpl.jena.query.ResultSet;
|
||||
import com.hp.hpl.jena.rdf.model.RDFNode;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
|
||||
|
@ -45,7 +45,7 @@ public class ThumbnailImageURL implements DocumentModifier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void modifyDocument(Individual individual, SolrInputDocument doc,
|
||||
public void modifyDocument(Individual individual, SearchInputDocument doc,
|
||||
StringBuffer addUri) throws SkipIndividualException {
|
||||
|
||||
//add a field for storing the location of thumbnail for the individual.
|
||||
|
@ -56,7 +56,7 @@ public class ThumbnailImageURL implements DocumentModifier {
|
|||
/**
|
||||
* Adds if the individual has a thumbnail image or not.
|
||||
*/
|
||||
protected void addThumbnailExistence(Individual ind, SolrInputDocument doc) {
|
||||
protected void addThumbnailExistence(Individual ind, SearchInputDocument doc) {
|
||||
try{
|
||||
if(ind.hasThumb())
|
||||
doc.addField(THUMBNAIL, "1");
|
|
@ -33,7 +33,7 @@ import edu.cornell.mannlib.vitro.webapp.utils.threads.VitroBackgroundThread;
|
|||
* The IndexBuilder is used to rebuild or update a search index.
|
||||
* There should only be one IndexBuilder in a vitro web application.
|
||||
* It uses an implementation of a back-end through an object that
|
||||
* implements IndexerIface. An example of a back-end is SolrIndexer.
|
||||
* implements IndexerIface. An example of a back-end is SearchIndexer.
|
||||
*
|
||||
* See the class SearchReindexingListener for an example of how a model change
|
||||
* listener can use an IndexBuilder to keep the full text index in sncy with
|
||||
|
|
|
@ -11,14 +11,12 @@ import org.apache.commons.logging.LogFactory;
|
|||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.IndexingException;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.beans.IndexerIface;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding.IndividualToSolrDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.threads.VitroBackgroundThread;
|
||||
|
||||
class IndexWorkerThread extends VitroBackgroundThread{
|
||||
private static final Log log = LogFactory.getLog(IndexWorkerThread.class);
|
||||
|
||||
protected final int threadNum;
|
||||
protected IndividualToSolrDocument individualToSolrDoc;
|
||||
protected final IndexerIface indexer;
|
||||
protected final Iterator<Individual> individualsToIndex;
|
||||
protected boolean stopRequested = false;
|
||||
|
@ -38,6 +36,7 @@ class IndexWorkerThread extends VitroBackgroundThread{
|
|||
stopRequested = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(){
|
||||
setWorkLevel(WorkLevel.WORKING, "indexing " + individualsToIndex + " individuals");
|
||||
|
||||
|
|
|
@ -1,209 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.search.solr;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
|
||||
import org.apache.solr.client.solrj.SolrServer;
|
||||
import org.apache.solr.client.solrj.impl.HttpSolrServer;
|
||||
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
import com.hp.hpl.jena.rdf.model.Model;
|
||||
import com.hp.hpl.jena.vocabulary.OWL;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.filtering.WebappDaoFactoryFiltering;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilterUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilters;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.beans.StatementToURIsToUpdate;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.indexing.AdditionalUriFinders;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.indexing.IndexBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.indexing.SearchReindexingListener;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding.DocumentModifier;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding.ExcludeBasedOnNamespace;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding.ExcludeBasedOnType;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding.ExcludeBasedOnTypeNamespace;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding.ExcludeNonFlagVitro;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding.IndividualToSolrDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding.NameBoost;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding.NameFields;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding.SearchIndexExcluder;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding.SyncingExcludeBasedOnType;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding.ThumbnailImageURL;
|
||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||
|
||||
public class SolrSetup implements javax.servlet.ServletContextListener{
|
||||
|
||||
public static final String SOLR_SERVER = "vitro.local.solr.server";
|
||||
public static final String PROHIBITED_FROM_SEARCH = "edu.cornell.mannlib.vitro.webapp.search.beans.ProhibitedFromSearch";
|
||||
|
||||
/** Exclude from the search index Individuals with types from these namespaces */
|
||||
private static final String[] TYPE_NS_EXCLUDES = {
|
||||
VitroVocabulary.PUBLIC
|
||||
//if you do OWL.NS here you will exclude all of owl:Thing.
|
||||
};
|
||||
|
||||
/** Exclude from the search index individuals who's URIs start with these namespaces. */
|
||||
private static final String[] INDIVIDUAL_NS_EXCLUDES={
|
||||
VitroVocabulary.vitroURI,
|
||||
VitroVocabulary.VITRO_PUBLIC,
|
||||
VitroVocabulary.PSEUDO_BNODE_NS,
|
||||
OWL.NS
|
||||
};
|
||||
|
||||
|
||||
/** Individuals of these types will be excluded from the search index */
|
||||
private static final String[] OWL_TYPES_EXCLUDES = {
|
||||
OWL.ObjectProperty.getURI(),
|
||||
OWL.DatatypeProperty.getURI(),
|
||||
OWL.AnnotationProperty.getURI()
|
||||
};
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
ServletContext context = sce.getServletContext();
|
||||
StartupStatus ss = StartupStatus.getBean(context);
|
||||
|
||||
/* setup the http connection with the solr server */
|
||||
String solrServerUrlString = ConfigurationProperties.getBean(sce).getProperty("vitro.local.solr.url");
|
||||
if( solrServerUrlString == null ){
|
||||
ss.fatal(this, "Could not find vitro.local.solr.url in runtime.properties. "+
|
||||
"Vitro application needs a URL of a solr server that it can use to index its data. " +
|
||||
"It should be something like http://localhost:${port}" + context.getContextPath() + "solr"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
HttpSolrServer server;
|
||||
boolean useMultiPartPost = true;
|
||||
server = new HttpSolrServer( solrServerUrlString );
|
||||
server.setSoTimeout(10000); // socket read timeout
|
||||
server.setConnectionTimeout(10000);
|
||||
server.setDefaultMaxConnectionsPerHost(100);
|
||||
server.setMaxTotalConnections(100);
|
||||
server.setMaxRetries(1);
|
||||
|
||||
context.setAttribute(SOLR_SERVER, server);
|
||||
|
||||
/* set up the individual to solr doc translation */
|
||||
OntModel jenaOntModel = ModelAccess.on(context).getJenaOntModel();
|
||||
OntModel displayModel = ModelAccess.on(context).getDisplayModel();
|
||||
|
||||
/* try to get context attribute DocumentModifiers
|
||||
* and use that as the start of the list of DocumentModifier
|
||||
* objects. This allows other ContextListeners to add to
|
||||
* the basic set of DocumentModifiers. */
|
||||
@SuppressWarnings("unchecked")
|
||||
List<DocumentModifier> modifiersFromContext =
|
||||
(List<DocumentModifier>)context.getAttribute("DocumentModifiers");
|
||||
|
||||
/* try to get context attribute SearchIndexExcludes
|
||||
* and use that as the start of the list of exclude
|
||||
* objects. This allows other ContextListeners to add to
|
||||
* the basic set of SearchIndexExcludes . */
|
||||
@SuppressWarnings("unchecked")
|
||||
List<SearchIndexExcluder> searchIndexExcludesFromContext =
|
||||
(List<SearchIndexExcluder>)context.getAttribute("SearchIndexExcludes");
|
||||
|
||||
IndividualToSolrDocument indToSolrDoc =
|
||||
setupTransltion(jenaOntModel, displayModel,
|
||||
RDFServiceUtils.getRDFServiceFactory(context),
|
||||
modifiersFromContext,
|
||||
searchIndexExcludesFromContext);
|
||||
|
||||
/* setup solr indexer */
|
||||
SolrIndexer solrIndexer = new SolrIndexer(server, indToSolrDoc);
|
||||
|
||||
// This is where the builder gets the list of places to try to
|
||||
// get objects to index. It is filtered so that non-public text
|
||||
// does not get into the search index.
|
||||
WebappDaoFactory wadf = ModelAccess.on(context).getWebappDaoFactory();
|
||||
VitroFilters vf = VitroFilterUtils.getPublicFilter(context);
|
||||
wadf = new WebappDaoFactoryFiltering(wadf, vf);
|
||||
|
||||
// make objects that will find additional URIs for context nodes etc
|
||||
RDFService rdfService = RDFServiceUtils.getRDFServiceFactory(context).getRDFService();
|
||||
List<StatementToURIsToUpdate> uriFinders = AdditionalUriFinders.getList(rdfService,wadf.getIndividualDao());
|
||||
|
||||
// Make the IndexBuilder
|
||||
IndexBuilder builder = new IndexBuilder( solrIndexer, wadf, uriFinders );
|
||||
// Save it to the servlet context so we can access it later in the webapp.
|
||||
context.setAttribute(IndexBuilder.class.getName(), builder);
|
||||
|
||||
// set up listeners so search index builder is notified of changes to model
|
||||
ServletContext ctx = sce.getServletContext();
|
||||
SearchReindexingListener srl = new SearchReindexingListener( builder );
|
||||
ModelContext.registerListenerForChanges(ctx, srl);
|
||||
|
||||
ss.info(this, "Setup of Solr index completed.");
|
||||
} catch (Throwable e) {
|
||||
ss.fatal(this, "could not setup local solr server",e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce) {
|
||||
IndexBuilder builder = (IndexBuilder)sce.getServletContext().getAttribute(IndexBuilder.class.getName());
|
||||
if( builder != null )
|
||||
builder.stopIndexingThread();
|
||||
|
||||
}
|
||||
|
||||
public static SolrServer getSolrServer(ServletContext ctx){
|
||||
return (SolrServer) ctx.getAttribute(SOLR_SERVER);
|
||||
}
|
||||
|
||||
|
||||
public static IndividualToSolrDocument setupTransltion(
|
||||
OntModel jenaOntModel,
|
||||
Model displayModel,
|
||||
RDFServiceFactory rdfServiceFactory,
|
||||
List<DocumentModifier> modifiersFromContext,
|
||||
List<SearchIndexExcluder> searchIndexExcludesFromContext
|
||||
) {
|
||||
|
||||
/* try to get context attribute DocumentModifiers
|
||||
* and use that as the start of the list of DocumentModifier
|
||||
* objects. This allows other ContextListeners to add to
|
||||
* the basic set of DocumentModifiers. */
|
||||
List<DocumentModifier> modifiers = new ArrayList<DocumentModifier>();
|
||||
if( modifiersFromContext != null ){
|
||||
modifiers.addAll( modifiersFromContext);
|
||||
}
|
||||
|
||||
modifiers.add( new NameFields( rdfServiceFactory ));
|
||||
modifiers.add( new NameBoost( 1.2f ));
|
||||
modifiers.add( new ThumbnailImageURL( rdfServiceFactory ));
|
||||
|
||||
/* try to get context attribute SearchIndexExcludes
|
||||
* and use that as the start of the list of exclude
|
||||
* objects. This allows other ContextListeners to add to
|
||||
* the basic set of SearchIndexExcludes . */
|
||||
List<SearchIndexExcluder> excludes =
|
||||
new ArrayList<SearchIndexExcluder>();
|
||||
if( searchIndexExcludesFromContext != null ){
|
||||
excludes.addAll(searchIndexExcludesFromContext);
|
||||
}
|
||||
|
||||
excludes.add(new ExcludeBasedOnNamespace( INDIVIDUAL_NS_EXCLUDES ));
|
||||
excludes.add(new ExcludeBasedOnTypeNamespace( TYPE_NS_EXCLUDES ) );
|
||||
excludes.add(new ExcludeBasedOnType( OWL_TYPES_EXCLUDES) );
|
||||
excludes.add(new ExcludeNonFlagVitro() );
|
||||
excludes.add( new SyncingExcludeBasedOnType( displayModel ) );
|
||||
|
||||
return new IndividualToSolrDocument(excludes, modifiers);
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding;
|
||||
|
||||
import org.apache.solr.common.SolrInputDocument;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
/**
|
||||
* This interface represents an object that can add to a SolrInputDocument.
|
||||
*/
|
||||
public interface DocumentModifier {
|
||||
public void modifyDocument(Individual individual, SolrInputDocument doc, StringBuffer addUri) throws SkipIndividualException;
|
||||
|
||||
//called to inform the DocumentModifier that the system is shutting down
|
||||
public void shutdown();
|
||||
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding;
|
||||
|
||||
import org.apache.solr.common.SolrInputDocument;
|
||||
import org.apache.solr.common.SolrInputField;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames;
|
||||
|
||||
public class NameBoost implements DocumentModifier {
|
||||
|
||||
/**
|
||||
* These are the fields in the solr Document that
|
||||
* are related to the name. If you modify the schema,
|
||||
* please consider if you need to change this list
|
||||
* of name fields to boost.
|
||||
*/
|
||||
static final VitroSearchTermNames term = new VitroSearchTermNames();
|
||||
String[] fieldsToBoost = {term.NAME_RAW,term.NAME_LOWERCASE,term.NAME_UNSTEMMED,term.NAME_STEMMED};
|
||||
|
||||
|
||||
final float boost;
|
||||
|
||||
public NameBoost(float boost){
|
||||
this.boost = boost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modifyDocument(Individual individual, SolrInputDocument doc,
|
||||
StringBuffer addUri) {
|
||||
|
||||
for( String fieldName : fieldsToBoost){
|
||||
SolrInputField field = doc.getField(fieldName);
|
||||
if( field != null ){
|
||||
field.setBoost(field.getBoost() + boost);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
// do nothing.
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.searchengine;
|
||||
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.Application;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.ComponentStartupStatus;
|
||||
import edu.cornell.mannlib.vitro.webapp.startup.ComponentStartupStatusImpl;
|
||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||
|
||||
/**
|
||||
* Whatever search engine we have, start it up and shut it down.
|
||||
*/
|
||||
public class SearchEngineSetup implements ServletContextListener {
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
Application application = ApplicationUtils.instance();
|
||||
StartupStatus ss = StartupStatus.getBean(sce.getServletContext());
|
||||
ComponentStartupStatus css = new ComponentStartupStatusImpl(this, ss);
|
||||
application.getSearchEngine().startup(application, css);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce) {
|
||||
Application application = ApplicationUtils.instance();
|
||||
application.getSearchEngine().shutdown(application);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.searchengine;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.webapp.modules.Application.Component.LifecycleState.ACTIVE;
|
||||
import static edu.cornell.mannlib.vitro.webapp.modules.Application.Component.LifecycleState.NEW;
|
||||
import static edu.cornell.mannlib.vitro.webapp.modules.Application.Component.LifecycleState.STOPPED;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.Application;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.ComponentStartupStatus;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngineException;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResponse;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
public class SearchEngineWrapper implements SearchEngine {
|
||||
private static final Log log = LogFactory.getLog(SearchEngineWrapper.class);
|
||||
|
||||
private final SearchEngine innerEngine;
|
||||
|
||||
private volatile LifecycleState lifecycleState = NEW;
|
||||
|
||||
public SearchEngineWrapper(SearchEngine innerEngine) {
|
||||
if (innerEngine == null) {
|
||||
throw new NullPointerException("innerEngine may not be null.");
|
||||
}
|
||||
this.innerEngine = innerEngine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Complain unless ACTIVE.
|
||||
*/
|
||||
private void confirmActive() {
|
||||
if (lifecycleState == NEW) {
|
||||
throw new IllegalStateException(
|
||||
"Search engine has not been started.");
|
||||
} else if (lifecycleState == STOPPED) {
|
||||
throw new IllegalStateException("Search engine has stopped.");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Overridden methods.
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* If NEW, do startup. If STOPPED, throw an exception. If ACTIVE, just
|
||||
* complain.
|
||||
*/
|
||||
@Override
|
||||
public void startup(Application application, ComponentStartupStatus css) {
|
||||
if (application == null) {
|
||||
throw new NullPointerException("application may not be null.");
|
||||
}
|
||||
switch (lifecycleState) {
|
||||
case NEW:
|
||||
innerEngine.startup(application, css);
|
||||
lifecycleState = ACTIVE;
|
||||
break;
|
||||
case STOPPED:
|
||||
throw new IllegalStateException(
|
||||
"startup called when already STOPPED");
|
||||
default: // ACTIVE:
|
||||
try {
|
||||
throw new IllegalStateException();
|
||||
} catch (Exception e) {
|
||||
log.warn("startup called when already ACTIVE", e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If ACTIVE, do shutdown. Otherwise, complain and do nothing.
|
||||
*/
|
||||
@Override
|
||||
public void shutdown(Application application) {
|
||||
if (application == null) {
|
||||
throw new NullPointerException("application may not be null.");
|
||||
}
|
||||
switch (lifecycleState) {
|
||||
case ACTIVE:
|
||||
innerEngine.shutdown(application);
|
||||
lifecycleState = STOPPED;
|
||||
break;
|
||||
default: // NEW, STOPPED:
|
||||
try {
|
||||
throw new IllegalStateException();
|
||||
} catch (Exception e) {
|
||||
log.warn("startup called when state was " + lifecycleState, e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ping() throws SearchEngineException {
|
||||
confirmActive();
|
||||
innerEngine.ping();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchInputDocument createInputDocument() {
|
||||
confirmActive();
|
||||
return innerEngine.createInputDocument();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(SearchInputDocument... docs) throws SearchEngineException {
|
||||
confirmActive();
|
||||
innerEngine.add(docs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Collection<SearchInputDocument> docs)
|
||||
throws SearchEngineException {
|
||||
confirmActive();
|
||||
innerEngine.add(docs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit() throws SearchEngineException {
|
||||
confirmActive();
|
||||
innerEngine.commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit(boolean wait) throws SearchEngineException {
|
||||
confirmActive();
|
||||
innerEngine.commit(wait);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteById(String... ids) throws SearchEngineException {
|
||||
confirmActive();
|
||||
innerEngine.deleteById(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteById(Collection<String> ids) throws SearchEngineException {
|
||||
confirmActive();
|
||||
innerEngine.deleteById(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByQuery(String query) throws SearchEngineException {
|
||||
confirmActive();
|
||||
innerEngine.deleteByQuery(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchQuery createQuery() {
|
||||
confirmActive();
|
||||
return innerEngine.createQuery();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchQuery createQuery(String queryText) {
|
||||
confirmActive();
|
||||
return innerEngine.createQuery(queryText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchResponse query(SearchQuery query) throws SearchEngineException {
|
||||
confirmActive();
|
||||
return innerEngine.query(query);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.searchengine.base;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchFacetField;
|
||||
|
||||
/**
|
||||
* A foundation class for implementing SearchFacetField.
|
||||
*/
|
||||
public class BaseSearchFacetField implements SearchFacetField {
|
||||
private final String name;
|
||||
private final List<Count> values;
|
||||
|
||||
public BaseSearchFacetField(String name, List<? extends Count> values) {
|
||||
this.name = name;
|
||||
this.values = new ArrayList<>(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Count> getValues() {
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* A foundation class for implementing SearchFacetField.Count.
|
||||
*/
|
||||
public static class BaseCount implements SearchFacetField.Count {
|
||||
private final String name;
|
||||
private final long count;
|
||||
|
||||
public BaseCount(String name, long count) {
|
||||
this.name = name;
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.searchengine.base;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputField;
|
||||
|
||||
/**
|
||||
* A foundation class for implementing SearchInputDocument.
|
||||
*/
|
||||
public class BaseSearchInputDocument implements SearchInputDocument {
|
||||
private final Map<String, SearchInputField> fieldMap = new HashMap<>();
|
||||
private float documentBoost = 1.0F;
|
||||
|
||||
@Override
|
||||
public void addField(SearchInputField field) {
|
||||
fieldMap.put(field.getName(), field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addField(String name, Object... values) {
|
||||
addField(name, 1.0F, Arrays.asList(values));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addField(String name, Collection<Object> values) {
|
||||
addField(name, 1.0F, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addField(String name, float boost, Object... values) {
|
||||
addField(name, boost, Arrays.asList(values));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addField(String name, float boost, Collection<Object> values) {
|
||||
BaseSearchInputField field = new BaseSearchInputField(name);
|
||||
field.setBoost(boost);
|
||||
field.addValues(values);
|
||||
fieldMap.put(name, field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDocumentBoost(float searchBoost) {
|
||||
this.documentBoost = searchBoost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getDocumentBoost() {
|
||||
return this.documentBoost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchInputField getField(String name) {
|
||||
return fieldMap.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, SearchInputField> getFieldMap() {
|
||||
return new HashMap<>(fieldMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sub-classes should override this if the field requires special
|
||||
* functionality.
|
||||
*/
|
||||
@Override
|
||||
public SearchInputField createField(String name) {
|
||||
return new BaseSearchInputField(name);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.searchengine.base;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputField;
|
||||
|
||||
/**
|
||||
* A foundation class for implementing SearchInputField.
|
||||
*/
|
||||
public class BaseSearchInputField implements SearchInputField {
|
||||
private final String name;
|
||||
private final List<Object> valueList = new ArrayList<>();
|
||||
|
||||
private float boost = 1.0F;
|
||||
|
||||
public BaseSearchInputField(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addValues(Object... values) {
|
||||
addValues(Arrays.asList(values));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addValues(Collection<? extends Object> values) {
|
||||
valueList.addAll(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBoost(float boost) {
|
||||
this.boost = boost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getBoost() {
|
||||
return boost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Object> getValues() {
|
||||
return new ArrayList<Object>(valueList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getFirstValue() {
|
||||
if (valueList.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
return valueList.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.searchengine.base;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery;
|
||||
|
||||
/**
|
||||
* A foundation class for implementing SearchQuery.
|
||||
*/
|
||||
public class BaseSearchQuery implements SearchQuery {
|
||||
private String queryText;
|
||||
private int start = 0;
|
||||
private int rows = -1;
|
||||
|
||||
private final Set<String> fieldsToReturn = new HashSet<>();
|
||||
private final Map<String, SearchQuery.Order> sortFields = new HashMap<>();
|
||||
private final Set<String> filters = new HashSet<>();
|
||||
|
||||
private final Set<String> facetFields = new HashSet<>();
|
||||
private int facetLimit = 100;
|
||||
private int facetMinCount = -1;
|
||||
|
||||
@Override
|
||||
public SearchQuery setQuery(String query) {
|
||||
this.queryText = query;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchQuery setStart(int start) {
|
||||
this.start = start;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchQuery setRows(int rows) {
|
||||
this.rows = rows;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchQuery addFields(String... names) {
|
||||
return addFields(Arrays.asList(names));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchQuery addFields(Collection<String> names) {
|
||||
this.fieldsToReturn.addAll(names);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchQuery addSortField(String name, Order order) {
|
||||
sortFields.put(name, order);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchQuery addFilterQuery(String filterQuery) {
|
||||
filters.add(filterQuery);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchQuery addFilterQueries(String... filterQueries) {
|
||||
this.filters.addAll(Arrays.asList(filterQueries));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchQuery addFacetFields(String... fields) {
|
||||
facetFields.addAll(Arrays.asList(fields));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchQuery setFacetLimit(int cnt) {
|
||||
facetLimit = cnt;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchQuery setFacetMinCount(int cnt) {
|
||||
facetMinCount = cnt;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQuery() {
|
||||
return queryText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRows() {
|
||||
return rows;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getFieldsToReturn() {
|
||||
return Collections.unmodifiableSet(fieldsToReturn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, SearchQuery.Order> getSortFields() {
|
||||
return Collections.unmodifiableMap(sortFields);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getFilters() {
|
||||
return Collections.unmodifiableSet(filters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getFacetFields() {
|
||||
return Collections.unmodifiableSet(facetFields);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFacetLimit() {
|
||||
return facetLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFacetMinCount() {
|
||||
return facetMinCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BaseSearchQuery[queryText=" + queryText + ", start=" + start
|
||||
+ ", rows=" + rows + ", fieldsToReturn=" + fieldsToReturn
|
||||
+ ", sortFields=" + sortFields + ", filters=" + filters
|
||||
+ ", facetFields=" + facetFields + ", facetLimit=" + facetLimit
|
||||
+ ", facetMinCount=" + facetMinCount + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.searchengine.base;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchFacetField;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResponse;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResultDocumentList;
|
||||
|
||||
/**
|
||||
* A foundation class for implementing SearchResponse;
|
||||
*/
|
||||
public class BaseSearchResponse implements SearchResponse {
|
||||
private final Map<String, Map<String, List<String>>> highlighting;
|
||||
private final Map<String, SearchFacetField> facetFields;
|
||||
private final SearchResultDocumentList results;
|
||||
|
||||
public BaseSearchResponse(
|
||||
Map<String, Map<String, List<String>>> highlighting,
|
||||
Map<String, SearchFacetField> facetFields,
|
||||
SearchResultDocumentList results) {
|
||||
this.highlighting = highlighting;
|
||||
this.facetFields = facetFields;
|
||||
this.results = results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchResultDocumentList getResults() {
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Map<String, List<String>>> getHighlighting() {
|
||||
return Collections.unmodifiableMap(highlighting);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchFacetField getFacetField(String name) {
|
||||
return facetFields.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SearchFacetField> getFacetFields() {
|
||||
return new ArrayList<>(facetFields.values());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.searchengine.base;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResultDocument;
|
||||
|
||||
/**
|
||||
* A foundation class for implementing SearchResultDocument.
|
||||
*/
|
||||
public class BaseSearchResultDocument implements SearchResultDocument {
|
||||
private final String uniqueId;
|
||||
private final Map<String, Collection<Object>> fieldValuesMap;
|
||||
|
||||
public BaseSearchResultDocument(String uniqueId, Map<String, Collection<Object>> fieldValuesMap) {
|
||||
this.uniqueId = uniqueId;
|
||||
|
||||
Map<String, Collection<Object>> map = new HashMap<>();
|
||||
for (String name : fieldValuesMap.keySet()) {
|
||||
map.put(name, Collections.unmodifiableList(new ArrayList<>(
|
||||
fieldValuesMap.get(name))));
|
||||
}
|
||||
this.fieldValuesMap = Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUniqueId() {
|
||||
return uniqueId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getFieldNames() {
|
||||
return fieldValuesMap.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getFirstValue(String name) {
|
||||
Collection<Object> values = fieldValuesMap.get(name);
|
||||
if (values == null || values.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return values.iterator().next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStringValue(String name) {
|
||||
Object o = getFirstValue(name);
|
||||
if (o == null) {
|
||||
return null;
|
||||
} else {
|
||||
return String.valueOf(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Object> getFieldValues(String name) {
|
||||
Collection<Object> values = fieldValuesMap.get(name);
|
||||
if (values == null) {
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
return values;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Collection<Object>> getFieldValuesMap() {
|
||||
return fieldValuesMap;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,174 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.searchengine.solr;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.solr.client.solrj.SolrQuery;
|
||||
import org.apache.solr.client.solrj.SolrQuery.ORDER;
|
||||
import org.apache.solr.client.solrj.response.FacetField;
|
||||
import org.apache.solr.client.solrj.response.QueryResponse;
|
||||
import org.apache.solr.common.SolrInputDocument;
|
||||
import org.apache.solr.common.SolrInputField;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchFacetField;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputField;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery.Order;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResponse;
|
||||
import edu.cornell.mannlib.vitro.webapp.searchengine.base.BaseSearchFacetField;
|
||||
import edu.cornell.mannlib.vitro.webapp.searchengine.base.BaseSearchFacetField.BaseCount;
|
||||
import edu.cornell.mannlib.vitro.webapp.searchengine.base.BaseSearchResponse;
|
||||
|
||||
/**
|
||||
* Utility method for converting from Solr-specific instances to Search-generic
|
||||
* instances, and back.
|
||||
*/
|
||||
public class SolrConversionUtils {
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Convert input documents to Solr-specific.
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
static List<SolrInputDocument> convertToSolrInputDocuments(
|
||||
Collection<SearchInputDocument> docs) {
|
||||
List<SolrInputDocument> solrDocs = new ArrayList<>();
|
||||
for (SearchInputDocument doc : docs) {
|
||||
solrDocs.add(convertToSolrInputDocument(doc));
|
||||
}
|
||||
return solrDocs;
|
||||
}
|
||||
|
||||
private static SolrInputDocument convertToSolrInputDocument(
|
||||
SearchInputDocument doc) {
|
||||
SolrInputDocument solrDoc = new SolrInputDocument(
|
||||
convertToSolrInputFieldMap(doc.getFieldMap()));
|
||||
solrDoc.setDocumentBoost(doc.getDocumentBoost());
|
||||
return solrDoc;
|
||||
}
|
||||
|
||||
private static Map<String, SolrInputField> convertToSolrInputFieldMap(
|
||||
Map<String, SearchInputField> fieldMap) {
|
||||
Map<String, SolrInputField> solrFieldMap = new HashMap<>();
|
||||
for (String fieldName : fieldMap.keySet()) {
|
||||
solrFieldMap.put(fieldName,
|
||||
convertToSolrInputField(fieldMap.get(fieldName)));
|
||||
}
|
||||
return solrFieldMap;
|
||||
}
|
||||
|
||||
private static SolrInputField convertToSolrInputField(
|
||||
SearchInputField searchInputField) {
|
||||
SolrInputField solrField = new SolrInputField(
|
||||
searchInputField.getName());
|
||||
solrField.addValue(searchInputField.getValues(),
|
||||
searchInputField.getBoost());
|
||||
return solrField;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Convert queries to Solr-specific.
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Convert from a SearchQuery to a SolrQuery, so the Solr server may execute
|
||||
* it.
|
||||
*/
|
||||
static SolrQuery convertToSolrQuery(SearchQuery query) {
|
||||
SolrQuery solrQuery = new SolrQuery(query.getQuery());
|
||||
solrQuery.setStart(query.getStart());
|
||||
|
||||
int rows = query.getRows();
|
||||
if (rows >= 0) {
|
||||
solrQuery.setRows(rows);
|
||||
}
|
||||
|
||||
for (String fieldToReturn : query.getFieldsToReturn()) {
|
||||
solrQuery.addField(fieldToReturn);
|
||||
}
|
||||
|
||||
Map<String, Order> sortFields = query.getSortFields();
|
||||
for (String sortField : sortFields.keySet()) {
|
||||
solrQuery.addSortField(sortField,
|
||||
convertToSolrOrder(sortFields.get(sortField)));
|
||||
}
|
||||
|
||||
for (String filter : query.getFilters()) {
|
||||
solrQuery.addFilterQuery(filter);
|
||||
}
|
||||
|
||||
if (!query.getFacetFields().isEmpty()) {
|
||||
solrQuery.setFacet(true);
|
||||
}
|
||||
|
||||
for (String facetField : query.getFacetFields()) {
|
||||
solrQuery.addFacetField(facetField);
|
||||
}
|
||||
|
||||
int facetLimit = query.getFacetLimit();
|
||||
if (facetLimit >= 0) {
|
||||
solrQuery.setFacetLimit(facetLimit);
|
||||
}
|
||||
|
||||
int minCount = query.getFacetMinCount();
|
||||
if (minCount >= 0) {
|
||||
solrQuery.setFacetMinCount(minCount);
|
||||
}
|
||||
|
||||
return solrQuery;
|
||||
}
|
||||
|
||||
private static ORDER convertToSolrOrder(Order order) {
|
||||
if (order == Order.DESC) {
|
||||
return ORDER.desc;
|
||||
} else {
|
||||
return ORDER.asc;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Convert responses to Search-generic
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
static SearchResponse convertToSearchResponse(QueryResponse response) {
|
||||
return new BaseSearchResponse(response.getHighlighting(),
|
||||
convertToSearchFacetFieldMap(response.getFacetFields()),
|
||||
new SolrSearchResultDocumentList(response.getResults()));
|
||||
}
|
||||
|
||||
private static Map<String, SearchFacetField> convertToSearchFacetFieldMap(
|
||||
List<FacetField> facetFields) {
|
||||
Map<String, SearchFacetField> map = new HashMap<>();
|
||||
if (facetFields != null) {
|
||||
for (FacetField facetField : facetFields) {
|
||||
map.put(facetField.getName(),
|
||||
convertToSearchFacetField(facetField));
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private static SearchFacetField convertToSearchFacetField(
|
||||
FacetField facetField) {
|
||||
return new BaseSearchFacetField(facetField.getName(),
|
||||
convertToSearchFacetFieldCounts(facetField.getValues()));
|
||||
}
|
||||
|
||||
private static List<BaseCount> convertToSearchFacetFieldCounts(
|
||||
List<FacetField.Count> solrCounts) {
|
||||
List<BaseCount> searchCounts = new ArrayList<>();
|
||||
if (solrCounts != null) {
|
||||
for (FacetField.Count solrCount : solrCounts) {
|
||||
searchCounts.add(new BaseCount(solrCount.getName(), solrCount
|
||||
.getCount()));
|
||||
}
|
||||
}
|
||||
return searchCounts;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,170 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.searchengine.solr;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.apache.solr.client.solrj.SolrQuery;
|
||||
import org.apache.solr.client.solrj.SolrServerException;
|
||||
import org.apache.solr.client.solrj.impl.HttpSolrServer;
|
||||
import org.apache.solr.client.solrj.response.QueryResponse;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.Application;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.ComponentStartupStatus;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngineException;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResponse;
|
||||
import edu.cornell.mannlib.vitro.webapp.searchengine.base.BaseSearchInputDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.searchengine.base.BaseSearchQuery;
|
||||
|
||||
/**
|
||||
* The Solr-based implementation of SearchEngine.
|
||||
*/
|
||||
public class SolrSearchEngine implements SearchEngine {
|
||||
private HttpSolrServer server;
|
||||
|
||||
/**
|
||||
* Set up the http connection with the solr server
|
||||
*/
|
||||
@Override
|
||||
public void startup(Application application, ComponentStartupStatus css) {
|
||||
ServletContext ctx = application.getServletContext();
|
||||
String solrServerUrlString = ConfigurationProperties.getBean(ctx)
|
||||
.getProperty("vitro.local.solr.url");
|
||||
if (solrServerUrlString == null) {
|
||||
css.fatal("Could not find vitro.local.solr.url in "
|
||||
+ "runtime.properties. Vitro application needs the URL of "
|
||||
+ "a solr server that it can use to index its data. It "
|
||||
+ "should be something like http://localhost:${port}"
|
||||
+ ctx.getContextPath() + "solr");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
server = new HttpSolrServer(solrServerUrlString);
|
||||
server.setSoTimeout(10000); // socket read timeout
|
||||
server.setConnectionTimeout(10000);
|
||||
server.setDefaultMaxConnectionsPerHost(100);
|
||||
server.setMaxTotalConnections(100);
|
||||
server.setMaxRetries(1);
|
||||
css.info("Set up the Solr search engine; URL = '"
|
||||
+ solrServerUrlString + "'.");
|
||||
} catch (Exception e) {
|
||||
css.fatal("Could not set up the Solr search engine", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown(Application application) {
|
||||
server.shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ping() throws SearchEngineException {
|
||||
try {
|
||||
server.ping();
|
||||
} catch (SolrServerException | IOException e) {
|
||||
throw new SearchEngineException(
|
||||
"Solr server did not respont to ping.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchInputDocument createInputDocument() {
|
||||
return new BaseSearchInputDocument();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(SearchInputDocument... docs) throws SearchEngineException {
|
||||
add(Arrays.asList(docs));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Collection<SearchInputDocument> docs)
|
||||
throws SearchEngineException {
|
||||
try {
|
||||
server.add(SolrConversionUtils.convertToSolrInputDocuments(docs));
|
||||
} catch (SolrServerException | IOException e) {
|
||||
throw new SearchEngineException(
|
||||
"Solr server failed to add documents " + docs, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit() throws SearchEngineException {
|
||||
try {
|
||||
server.commit();
|
||||
} catch (SolrServerException | IOException e) {
|
||||
throw new SearchEngineException("Failed to commit to Solr server.",
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit(boolean wait) throws SearchEngineException {
|
||||
try {
|
||||
server.commit(wait, wait);
|
||||
} catch (SolrServerException | IOException e) {
|
||||
throw new SearchEngineException("Failed to commit to Solr server.",
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteById(String... ids) throws SearchEngineException {
|
||||
deleteById(Arrays.asList(ids));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteById(Collection<String> ids) throws SearchEngineException {
|
||||
try {
|
||||
server.deleteById(new ArrayList<>(ids));
|
||||
} catch (SolrServerException | IOException e) {
|
||||
throw new SearchEngineException(
|
||||
"Solr server failed to delete documents: " + ids, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByQuery(String query) throws SearchEngineException {
|
||||
try {
|
||||
server.deleteByQuery(query);
|
||||
} catch (SolrServerException | IOException e) {
|
||||
throw new SearchEngineException(
|
||||
"Solr server failed to delete documents: " + query, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchQuery createQuery() {
|
||||
return new BaseSearchQuery();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchQuery createQuery(String queryText) {
|
||||
BaseSearchQuery query = new BaseSearchQuery();
|
||||
query.setQuery(queryText);
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchResponse query(SearchQuery query) throws SearchEngineException {
|
||||
try {
|
||||
SolrQuery solrQuery = SolrConversionUtils.convertToSolrQuery(query);
|
||||
QueryResponse response = server.query(solrQuery);
|
||||
return SolrConversionUtils.convertToSearchResponse(response);
|
||||
} catch (SolrServerException e) {
|
||||
throw new SearchEngineException(
|
||||
"Solr server failed to execute the query" + query, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.searchengine.solr;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.solr.common.SolrDocument;
|
||||
import org.apache.solr.common.SolrDocumentList;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResultDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResultDocumentList;
|
||||
import edu.cornell.mannlib.vitro.webapp.searchengine.base.BaseSearchResultDocument;
|
||||
|
||||
/**
|
||||
* A Solr-based implementation of SearchResultDocumentList.
|
||||
*
|
||||
* It's necessary to use this instead of the base version, so the iterator can
|
||||
* convert each document as it is requested.
|
||||
*/
|
||||
public class SolrSearchResultDocumentList implements SearchResultDocumentList {
|
||||
private SolrDocumentList solrDocs;
|
||||
|
||||
public SolrSearchResultDocumentList(SolrDocumentList solrDocs) {
|
||||
if (solrDocs == null) {
|
||||
SolrDocumentList list = new SolrDocumentList();
|
||||
list.setStart(0L);
|
||||
list.setNumFound(0L);
|
||||
list.setMaxScore(0.0F);
|
||||
this.solrDocs = list;
|
||||
} else {
|
||||
this.solrDocs = solrDocs;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<SearchResultDocument> iterator() {
|
||||
return new SearchResultDocumentIterator(solrDocs.iterator());
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNumFound() {
|
||||
return solrDocs.getNumFound();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return solrDocs.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchResultDocument get(int i) {
|
||||
return convertToSearchResultDocument(solrDocs.get(i));
|
||||
}
|
||||
|
||||
private static class SearchResultDocumentIterator implements
|
||||
Iterator<SearchResultDocument> {
|
||||
private final Iterator<SolrDocument> solrIterator;
|
||||
|
||||
public SearchResultDocumentIterator(Iterator<SolrDocument> solrIterator) {
|
||||
this.solrIterator = solrIterator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return solrIterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchResultDocument next() {
|
||||
return convertToSearchResultDocument(solrIterator.next());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static SearchResultDocument convertToSearchResultDocument(
|
||||
SolrDocument solrDoc) {
|
||||
return new BaseSearchResultDocument(
|
||||
(String) solrDoc.getFieldValue("DocId"),
|
||||
solrDoc.getFieldValuesMap());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,192 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.searchindex;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
import com.hp.hpl.jena.rdf.model.Model;
|
||||
import com.hp.hpl.jena.vocabulary.OWL;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.filtering.WebappDaoFactoryFiltering;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilterUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilters;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.SearchIndexer;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.beans.StatementToURIsToUpdate;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.documentBuilding.DocumentModifier;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.documentBuilding.ExcludeBasedOnNamespace;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.documentBuilding.ExcludeBasedOnType;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.documentBuilding.ExcludeBasedOnTypeNamespace;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.documentBuilding.ExcludeNonFlagVitro;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.documentBuilding.IndividualToSearchDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.documentBuilding.NameBoost;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.documentBuilding.NameFields;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.documentBuilding.SearchIndexExcluder;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.documentBuilding.SyncingExcludeBasedOnType;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.documentBuilding.ThumbnailImageURL;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.indexing.AdditionalUriFinders;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.indexing.IndexBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.indexing.SearchReindexingListener;
|
||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
public class SearchIndexerSetup implements ServletContextListener {
|
||||
public static final String PROHIBITED_FROM_SEARCH = "edu.cornell.mannlib.vitro.webapp.search.beans.ProhibitedFromSearch";
|
||||
|
||||
/**
|
||||
* Exclude from the search index Individuals with types from these
|
||||
* namespaces
|
||||
*/
|
||||
private static final String[] TYPE_NS_EXCLUDES = { VitroVocabulary.PUBLIC
|
||||
// if you do OWL.NS here you will exclude all of owl:Thing.
|
||||
};
|
||||
|
||||
/**
|
||||
* Exclude from the search index individuals who's URIs start with these
|
||||
* namespaces.
|
||||
*/
|
||||
private static final String[] INDIVIDUAL_NS_EXCLUDES = {
|
||||
VitroVocabulary.vitroURI, VitroVocabulary.VITRO_PUBLIC,
|
||||
VitroVocabulary.PSEUDO_BNODE_NS, OWL.NS };
|
||||
|
||||
/** Individuals of these types will be excluded from the search index */
|
||||
private static final String[] OWL_TYPES_EXCLUDES = {
|
||||
OWL.ObjectProperty.getURI(), OWL.DatatypeProperty.getURI(),
|
||||
OWL.AnnotationProperty.getURI() };
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
ServletContext context = sce.getServletContext();
|
||||
StartupStatus ss = StartupStatus.getBean(context);
|
||||
SearchEngine searchEngine = ApplicationUtils.instance().getSearchEngine();
|
||||
|
||||
try {
|
||||
/* set up the individual to search doc translation */
|
||||
OntModel jenaOntModel = ModelAccess.on(context).getJenaOntModel();
|
||||
OntModel displayModel = ModelAccess.on(context).getDisplayModel();
|
||||
|
||||
/*
|
||||
* try to get context attribute DocumentModifiers and use that as
|
||||
* the start of the list of DocumentModifier objects. This allows
|
||||
* other ContextListeners to add to the basic set of
|
||||
* DocumentModifiers.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
List<DocumentModifier> modifiersFromContext = (List<DocumentModifier>) context
|
||||
.getAttribute("DocumentModifiers");
|
||||
|
||||
/*
|
||||
* try to get context attribute SearchIndexExcludes and use that as
|
||||
* the start of the list of exclude objects. This allows other
|
||||
* ContextListeners to add to the basic set of SearchIndexExcludes .
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
List<SearchIndexExcluder> searchIndexExcludesFromContext = (List<SearchIndexExcluder>) context
|
||||
.getAttribute("SearchIndexExcludes");
|
||||
|
||||
IndividualToSearchDocument indToSearchDoc = setupTranslation(
|
||||
jenaOntModel, displayModel,
|
||||
RDFServiceUtils.getRDFServiceFactory(context),
|
||||
modifiersFromContext, searchIndexExcludesFromContext);
|
||||
|
||||
/* setup search indexer */
|
||||
SearchIndexer searchIndexer = new SearchIndexer(searchEngine, indToSearchDoc);
|
||||
|
||||
// This is where the builder gets the list of places to try to
|
||||
// get objects to index. It is filtered so that non-public text
|
||||
// does not get into the search index.
|
||||
WebappDaoFactory wadf = ModelAccess.on(context)
|
||||
.getWebappDaoFactory();
|
||||
VitroFilters vf = VitroFilterUtils.getPublicFilter(context);
|
||||
wadf = new WebappDaoFactoryFiltering(wadf, vf);
|
||||
|
||||
// make objects that will find additional URIs for context nodes etc
|
||||
RDFService rdfService = RDFServiceUtils.getRDFServiceFactory(
|
||||
context).getRDFService();
|
||||
List<StatementToURIsToUpdate> uriFinders = AdditionalUriFinders
|
||||
.getList(rdfService, wadf.getIndividualDao());
|
||||
|
||||
// Make the IndexBuilder
|
||||
IndexBuilder builder = new IndexBuilder(searchIndexer, wadf,
|
||||
uriFinders);
|
||||
// Save it to the servlet context so we can access it later in the
|
||||
// webapp.
|
||||
context.setAttribute(IndexBuilder.class.getName(), builder);
|
||||
|
||||
// set up listeners so search index builder is notified of changes
|
||||
// to model
|
||||
ServletContext ctx = sce.getServletContext();
|
||||
SearchReindexingListener srl = new SearchReindexingListener(builder);
|
||||
ModelContext.registerListenerForChanges(ctx, srl);
|
||||
|
||||
ss.info(this, "Setup of search indexer completed.");
|
||||
} catch (Throwable e) {
|
||||
ss.fatal(this, "could not setup search engine", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce) {
|
||||
IndexBuilder builder = (IndexBuilder) sce.getServletContext()
|
||||
.getAttribute(IndexBuilder.class.getName());
|
||||
if (builder != null)
|
||||
builder.stopIndexingThread();
|
||||
|
||||
}
|
||||
|
||||
public static IndividualToSearchDocument setupTranslation(
|
||||
OntModel jenaOntModel, Model displayModel,
|
||||
RDFServiceFactory rdfServiceFactory,
|
||||
List<DocumentModifier> modifiersFromContext,
|
||||
List<SearchIndexExcluder> searchIndexExcludesFromContext) {
|
||||
|
||||
/*
|
||||
* try to get context attribute DocumentModifiers and use that as the
|
||||
* start of the list of DocumentModifier objects. This allows other
|
||||
* ContextListeners to add to the basic set of DocumentModifiers.
|
||||
*/
|
||||
List<DocumentModifier> modifiers = new ArrayList<DocumentModifier>();
|
||||
if (modifiersFromContext != null) {
|
||||
modifiers.addAll(modifiersFromContext);
|
||||
}
|
||||
|
||||
modifiers.add(new NameFields(rdfServiceFactory));
|
||||
modifiers.add(new NameBoost(1.2f));
|
||||
modifiers.add(new ThumbnailImageURL(rdfServiceFactory));
|
||||
|
||||
/*
|
||||
* try to get context attribute SearchIndexExcludes and use that as the
|
||||
* start of the list of exclude objects. This allows other
|
||||
* ContextListeners to add to the basic set of SearchIndexExcludes .
|
||||
*/
|
||||
List<SearchIndexExcluder> excludes = new ArrayList<SearchIndexExcluder>();
|
||||
if (searchIndexExcludesFromContext != null) {
|
||||
excludes.addAll(searchIndexExcludesFromContext);
|
||||
}
|
||||
|
||||
excludes.add(new ExcludeBasedOnNamespace(INDIVIDUAL_NS_EXCLUDES));
|
||||
excludes.add(new ExcludeBasedOnTypeNamespace(TYPE_NS_EXCLUDES));
|
||||
excludes.add(new ExcludeBasedOnType(OWL_TYPES_EXCLUDES));
|
||||
excludes.add(new ExcludeNonFlagVitro());
|
||||
excludes.add(new SyncingExcludeBasedOnType(displayModel));
|
||||
|
||||
return new IndividualToSearchDocument(excludes, modifiers);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.startup;
|
||||
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.ComponentStartupStatus;
|
||||
|
||||
/**
|
||||
* A temporary wrapper around the StartupStatus, with the ServletContextListener
|
||||
* built in.
|
||||
*/
|
||||
public class ComponentStartupStatusImpl implements ComponentStartupStatus {
|
||||
private final ServletContextListener listener;
|
||||
private final StartupStatus ss;
|
||||
|
||||
public ComponentStartupStatusImpl(ServletContextListener listener,
|
||||
StartupStatus ss) {
|
||||
this.listener = listener;
|
||||
this.ss = ss;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String message) {
|
||||
ss.info(listener, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String message, Throwable cause) {
|
||||
ss.info(listener, message, cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warning(String message) {
|
||||
ss.warning(listener, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warning(String message, Throwable cause) {
|
||||
ss.warning(listener, message, cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fatal(String message) {
|
||||
ss.fatal(listener, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fatal(String message, Throwable cause) {
|
||||
ss.fatal(listener, message, cause);
|
||||
}
|
||||
|
||||
}
|
|
@ -91,7 +91,7 @@ public class BrowseDataGetter extends DataGetterBase implements DataGetter {
|
|||
|
||||
//Get data servuice
|
||||
public String getDataServiceUrl() {
|
||||
return UrlBuilder.getUrl("/dataservice?getSolrIndividualsByVClass=1&vclassId=");
|
||||
return UrlBuilder.getUrl("/dataservice?getSearchIndividualsByVClass=1&vclassId=");
|
||||
}
|
||||
private Map<String, Object> doClassAlphaDisplay( Map params, VitroRequest request, ServletContext context) throws Exception {
|
||||
Map<String,Object> body = new HashMap<String,Object>();
|
||||
|
@ -108,7 +108,7 @@ public class BrowseDataGetter extends DataGetterBase implements DataGetter {
|
|||
VClass vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(classUri);
|
||||
map.put("class", new VClassTemplateModel(vclass));
|
||||
|
||||
JSONObject vclassRes = JsonServlet.getSolrIndividualsByVClass(vclass.getURI(), request, context);
|
||||
JSONObject vclassRes = JsonServlet.getSearchIndividualsByVClass(vclass.getURI(), request);
|
||||
map.put("totalCount", JsonToFmModel.convertJSONObjectToMap( (String) vclassRes.get("totalCount") ));
|
||||
map.put("alpha", JsonToFmModel.convertJSONObjectToMap( (String) vclassRes.get("alpha") ));
|
||||
map.put("individuals", JsonToFmModel.convertJSONArrayToList( (JSONArray) vclassRes.get("individuals") ));
|
||||
|
|
|
@ -160,7 +160,7 @@ public class ClassGroupPageData extends DataGetterBase implements DataGetter{
|
|||
|
||||
//Get data servuice
|
||||
public String getDataServiceUrl() {
|
||||
return UrlBuilder.getUrl("/dataservice?getRenderedSolrIndividualsByVClass=1&vclassId=");
|
||||
return UrlBuilder.getUrl("/dataservice?getRenderedSearchIndividualsByVClass=1&vclassId=");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,7 +8,6 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
@ -56,7 +55,7 @@ public class DataGetterUtils {
|
|||
* exception if a page has PageDataGetters.
|
||||
*/
|
||||
public static List<DataGetter> getDataGettersForPage(VitroRequest vreq, Model displayModel, String pageURI)
|
||||
throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, SecurityException, InvocationTargetException, NoSuchMethodException {
|
||||
throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, SecurityException, InvocationTargetException {
|
||||
|
||||
if( vreq.getAttribute(DATA_GETTERS_FOR_PAGE) != null){
|
||||
return (List<DataGetter>) vreq.getAttribute(DATA_GETTERS_FOR_PAGE);
|
||||
|
@ -74,7 +73,7 @@ public class DataGetterUtils {
|
|||
* 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{
|
||||
throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, SecurityException, InvocationTargetException {
|
||||
List<String> dgUris = getDataGetterURIsForAssociatedURI( displayModel, classURI);
|
||||
List<DataGetter> dgList = dataGettersForURIs(vreq, displayModel, dgUris);
|
||||
log.debug("getDataGettersForClass: " + dgList);
|
||||
|
@ -86,7 +85,7 @@ public class DataGetterUtils {
|
|||
* @param templateName a filename like "index.ftl", which will be used as a URI like "freemarker:index.ftl".
|
||||
*/
|
||||
public static List<DataGetter> getDataGettersForTemplate( VitroRequest vreq, Model displayModel, String templateName)
|
||||
throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, SecurityException, InvocationTargetException, NoSuchMethodException{
|
||||
throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, SecurityException, InvocationTargetException {
|
||||
String templateUri = "freemarker:" + templateName;
|
||||
List<String> dgUris = getDataGetterURIsForAssociatedURI( displayModel, templateUri);
|
||||
List<DataGetter> dgList = dataGettersForURIs(vreq, displayModel, dgUris);
|
||||
|
@ -197,7 +196,7 @@ public class DataGetterUtils {
|
|||
}finally{ displayModel.leaveCriticalSection(); }
|
||||
|
||||
|
||||
return chooseType( types, displayModel, dataGetterURI);
|
||||
return chooseType( types, dataGetterURI);
|
||||
}
|
||||
|
||||
|
||||
|
@ -229,7 +228,7 @@ public class DataGetterUtils {
|
|||
return dgURIs;
|
||||
}
|
||||
|
||||
private static String chooseType(List<String> types, Model displayModel, String dataGetterURI) throws IllegalAccessException {
|
||||
private static String chooseType(List<String> types, String dataGetterURI) throws IllegalAccessException {
|
||||
//currently just get the first one that is not owl:Thing
|
||||
for(String type : types){
|
||||
if( ! StringUtils.isEmpty( type ) && !type.equals( OWL.Thing.getURI() ))
|
||||
|
@ -268,10 +267,10 @@ public class DataGetterUtils {
|
|||
* For page data getter conversions
|
||||
*/
|
||||
/**
|
||||
* Get Individual count for Solr query for intersection of multiple classes
|
||||
* Get Individual count for search query for intersection of multiple classes
|
||||
*/
|
||||
public static long getIndividualCountForIntersection(VitroRequest vreq, ServletContext context, List<String> classUris) {
|
||||
return IndividualListController.getIndividualCount(classUris, vreq.getWebappDaoFactory().getIndividualDao(), context);
|
||||
public static long getIndividualCountForIntersection(VitroRequest vreq, List<String> classUris) {
|
||||
return IndividualListController.getIndividualCount(classUris);
|
||||
}
|
||||
|
||||
//Return data getter type to be employed in display model
|
||||
|
@ -410,7 +409,7 @@ public class DataGetterUtils {
|
|||
/*
|
||||
* Copied from JSONServlet as expect this to be related to VitroClassGroup
|
||||
*/
|
||||
public static JSONObject processVClassGroupJSON(VitroRequest vreq, ServletContext context, VClassGroup vcg) {
|
||||
public static JSONObject processVClassGroupJSON(VClassGroup vcg) {
|
||||
JSONObject map = new JSONObject();
|
||||
try {
|
||||
ArrayList<JSONObject> classes = new ArrayList<JSONObject>(vcg.size());
|
||||
|
|
|
@ -163,7 +163,7 @@ public class IndividualsForClassesDataGetter extends DataGetterBase implements D
|
|||
protected void processClassesAndRestrictions(VitroRequest vreq, ServletContext context,
|
||||
HashMap<String, Object> data, List<String> classes, List<String> restrictClasses ) {
|
||||
processClassesForDisplay(vreq, context, data, classes);
|
||||
processRestrictionClasses(vreq, context, data, restrictClasses);
|
||||
processRestrictionClasses(vreq, data, restrictClasses);
|
||||
processIntersections(vreq, context, data);
|
||||
|
||||
}
|
||||
|
@ -210,14 +210,14 @@ public class IndividualsForClassesDataGetter extends DataGetterBase implements D
|
|||
|
||||
//update class count based on restrict classes
|
||||
private int retrieveCount(VitroRequest vreq, ServletContext context, VClass v, List<VClass> restrictClasses) {
|
||||
//Execute solr query that returns only count of individuals
|
||||
//Execute search query that returns only count of individuals
|
||||
log.debug("Entity count is " + v.getEntityCount());
|
||||
List<String> classUris = new ArrayList<String>();
|
||||
classUris.add(v.getURI());
|
||||
for(VClass r: restrictClasses) {
|
||||
classUris.add(r.getURI());
|
||||
}
|
||||
long count = DataGetterUtils.getIndividualCountForIntersection(vreq, context, classUris);
|
||||
long count = DataGetterUtils.getIndividualCountForIntersection(vreq, classUris);
|
||||
return new Long(count).intValue();
|
||||
|
||||
}
|
||||
|
@ -254,7 +254,7 @@ public class IndividualsForClassesDataGetter extends DataGetterBase implements D
|
|||
data.put("vClassGroup", classesGroup);
|
||||
}
|
||||
|
||||
private void processRestrictionClasses(VitroRequest vreq, ServletContext context,
|
||||
private void processRestrictionClasses(VitroRequest vreq,
|
||||
HashMap<String, Object> data, List<String> restrictClasses) {
|
||||
try {
|
||||
VClassGroup restrictClassesGroup = new VClassGroup();
|
||||
|
@ -305,7 +305,7 @@ public class IndividualsForClassesDataGetter extends DataGetterBase implements D
|
|||
}
|
||||
}
|
||||
|
||||
public static VClassGroupTemplateModel getClassGroup(String classGroupUri, ServletContext context, VitroRequest vreq){
|
||||
public static VClassGroupTemplateModel getClassGroup(String classGroupUri, VitroRequest vreq){
|
||||
|
||||
VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(vreq);
|
||||
List<VClassGroup> vcgList = vcgc.getGroups();
|
||||
|
@ -351,7 +351,7 @@ public class IndividualsForClassesDataGetter extends DataGetterBase implements D
|
|||
|
||||
//Get data servuice
|
||||
public String getDataServiceUrl() {
|
||||
return UrlBuilder.getUrl("/dataservice?getRenderedSolrIndividualsByVClass=1&vclassId=");
|
||||
return UrlBuilder.getUrl("/dataservice?getRenderedSearchIndividualsByVClass=1&vclassId=");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -34,10 +34,10 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListCont
|
|||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.individuallist.IndividualListResults;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.solr.SolrQueryUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.searchengine.SearchQueryUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individuallist.ListedIndividual;
|
||||
|
||||
public class SolrIndividualsDataGetter extends DataGetterBase implements DataGetter{
|
||||
public class SearchIndividualsDataGetter extends DataGetterBase implements DataGetter{
|
||||
String dataGetterURI;
|
||||
List<String> vclassUris = null;
|
||||
String saveToVar;
|
||||
|
@ -45,14 +45,14 @@ public class SolrIndividualsDataGetter extends DataGetterBase implements DataGet
|
|||
ServletContext context;
|
||||
|
||||
|
||||
final static Log log = LogFactory.getLog(SolrIndividualsDataGetter.class);
|
||||
final static Log log = LogFactory.getLog(SearchIndividualsDataGetter.class);
|
||||
//default template
|
||||
private final static String defaultTemplate = "menupage--defaultSolrIndividuals.ftl";
|
||||
private final static String defaultTemplate = "menupage--defaultSearchIndividuals.ftl";
|
||||
|
||||
/**
|
||||
* Constructor with display model and data getter URI that will be called by reflection.
|
||||
*/
|
||||
public SolrIndividualsDataGetter(VitroRequest vreq, Model displayModel, String dataGetterURI){
|
||||
public SearchIndividualsDataGetter(VitroRequest vreq, Model displayModel, String dataGetterURI){
|
||||
this.configure(vreq, displayModel,dataGetterURI);
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ public class SolrIndividualsDataGetter extends DataGetterBase implements DataGet
|
|||
merged.put(key, new String[] {String.valueOf(pageData.get(key))});
|
||||
}
|
||||
|
||||
return doSolrQuery( merged);
|
||||
return doSearchQuery( merged);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -125,12 +125,12 @@ public class SolrIndividualsDataGetter extends DataGetterBase implements DataGet
|
|||
|
||||
|
||||
//Partially copied from IndividualListController
|
||||
private Map<String, Object> doSolrQuery( Map<String, String[]> merged) {
|
||||
private Map<String, Object> doSearchQuery( 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");
|
||||
log.error("No vclass uri found. Search query will not work");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,7 +160,7 @@ public class SolrIndividualsDataGetter extends DataGetterBase implements DataGet
|
|||
body.put("subtitle", vclass.getName());
|
||||
}
|
||||
body.put("title", title);
|
||||
populateSolrQueryResults(vclass, body);
|
||||
populateSearchQueryResults(vclass, body);
|
||||
body.put("bodyTemplate", this.defaultTemplate);
|
||||
} else {
|
||||
log.error("No VClass URIs found. No query will be executed");
|
||||
|
@ -168,16 +168,15 @@ public class SolrIndividualsDataGetter extends DataGetterBase implements DataGet
|
|||
return body;
|
||||
}
|
||||
|
||||
private void populateSolrQueryResults(VClass vclass, Map<String, Object> body) {
|
||||
private void populateSearchQueryResults(VClass vclass, Map<String, Object> body) {
|
||||
try {
|
||||
String alpha = SolrQueryUtils.getAlphaParameter(vreq);
|
||||
int page = SolrQueryUtils.getPageParameter(vreq);
|
||||
String alpha = SearchQueryUtils.getAlphaParameter(vreq);
|
||||
int page = SearchQueryUtils.getPageParameter(vreq);
|
||||
IndividualListResults vcResults = IndividualListController.getResultsForVClass(
|
||||
vclass.getURI(),
|
||||
page,
|
||||
alpha,
|
||||
vreq.getWebappDaoFactory().getIndividualDao(),
|
||||
vreq.getSession().getServletContext());
|
||||
vreq.getWebappDaoFactory().getIndividualDao());
|
||||
body.putAll(vcResults.asFreemarkerMap());
|
||||
|
||||
List<Individual> inds = vcResults.getEntities();
|
||||
|
@ -204,7 +203,7 @@ public class SolrIndividualsDataGetter extends DataGetterBase implements DataGet
|
|||
public static final String defaultVarNameForResults = "results";
|
||||
|
||||
/**
|
||||
* Query to get the definition of the Solr individuals data getter for a given URI.
|
||||
* Query to get the definition of the search individuals data getter for a given URI.
|
||||
*/
|
||||
private static final String dataGetterQuery =
|
||||
"PREFIX display: <" + DisplayVocabulary.DISPLAY_NS +"> \n" +
|
|
@ -1,6 +1,6 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.solr;
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.searchengine;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
@ -27,15 +27,16 @@ public class AutoCompleteWords {
|
|||
private final String partialWord;
|
||||
|
||||
/**
|
||||
* Package-access. Use SolrQueryUtils.parseForAutoComplete() to create an
|
||||
* Package-access. Use SearchQueryUtils.parseForAutoComplete() to create an
|
||||
* instance.
|
||||
*/
|
||||
AutoCompleteWords(String searchTerm, String delimiterPattern) {
|
||||
this.searchTerm = searchTerm;
|
||||
this.searchTerm = (searchTerm == null) ? "" : searchTerm;
|
||||
this.delimiterPattern = delimiterPattern;
|
||||
|
||||
List<String> termWords = figureTermWords();
|
||||
if (termWords.isEmpty() || this.searchTerm.endsWith(" ")) {
|
||||
if (termWords.isEmpty()
|
||||
|| this.searchTerm.matches(".*" + delimiterPattern)) {
|
||||
this.completeWords = termWords;
|
||||
this.partialWord = null;
|
||||
} else {
|
|
@ -1,17 +1,17 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.solr;
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.searchengine;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A builder object that can assemble a map of Solr field names to JSON field
|
||||
* names.
|
||||
* A builder object that can assemble a map of search result field names to JSON
|
||||
* field names.
|
||||
*
|
||||
* Use like this:
|
||||
*
|
||||
* m = SolrQueryUtils.fieldMap().row("this", "that").row("2nd", "row").map();
|
||||
* m = SearchQueryUtils.fieldMap().put("this", "that").put("2nd", "row").map();
|
||||
*
|
||||
*/
|
||||
public class FieldMap {
|
||||
|
@ -20,14 +20,15 @@ public class FieldMap {
|
|||
/**
|
||||
* Add a row to the map
|
||||
*/
|
||||
public FieldMap put(String solrFieldName, String jsonFieldName) {
|
||||
if (solrFieldName == null) {
|
||||
throw new NullPointerException("solrFieldName may not be null.");
|
||||
public FieldMap put(String searchResultFieldName, String jsonFieldName) {
|
||||
if (searchResultFieldName == null) {
|
||||
throw new NullPointerException(
|
||||
"searchResultFieldName may not be null.");
|
||||
}
|
||||
if (jsonFieldName == null) {
|
||||
throw new NullPointerException("jsonFieldName may not be null.");
|
||||
}
|
||||
m.put(solrFieldName, jsonFieldName);
|
||||
m.put(searchResultFieldName, jsonFieldName);
|
||||
|
||||
return this;
|
||||
}
|
|
@ -1,35 +1,34 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.solr;
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.searchengine;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
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.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 edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListQueryResults;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngineException;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery.Order;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResponse;
|
||||
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 methods to help in constructing search queries and parsing the
|
||||
* results.
|
||||
*/
|
||||
|
||||
public class SolrQueryUtils {
|
||||
private static final Log log = LogFactory.getLog(SolrQueryUtils.class.getName());
|
||||
public class SearchQueryUtils {
|
||||
private static final Log log = LogFactory.getLog(SearchQueryUtils.class.getName());
|
||||
|
||||
public enum Conjunction {
|
||||
AND, OR;
|
||||
|
@ -49,8 +48,8 @@ public class SolrQueryUtils {
|
|||
}
|
||||
|
||||
/**
|
||||
* Create a builder object that can assemble a map of Solr field names to
|
||||
* JSON field names.
|
||||
* Create a builder object that can assemble a map of search result field
|
||||
* names to JSON field names.
|
||||
*/
|
||||
public static FieldMap fieldMap() {
|
||||
return new FieldMap();
|
||||
|
@ -59,25 +58,25 @@ public class SolrQueryUtils {
|
|||
/**
|
||||
* Parse a response into a list of maps, one map for each document.
|
||||
*
|
||||
* The Solr field names in the document are replaced by json field names in
|
||||
* the result, according to the fieldMap.
|
||||
* The search result field names in the document are replaced by json field
|
||||
* names in the result, according to the fieldMap.
|
||||
*/
|
||||
public static List<Map<String, String>> parseResponse(
|
||||
QueryResponse queryResponse, FieldMap fieldMap) {
|
||||
return new SolrResultsParser(queryResponse, fieldMap).parse();
|
||||
SearchResponse queryResponse, FieldMap fieldMap) {
|
||||
return new SearchResultsParser(queryResponse, fieldMap).parse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a response into a list of maps, accepting only those maps that pass
|
||||
* a filter, and only up to a maximum number of records.
|
||||
*
|
||||
* The Solr field names in the document are replaced by json field names in
|
||||
* the result, according to the fieldMap.
|
||||
* The search result field names in the document are replaced by json field
|
||||
* names in the result, according to the fieldMap.
|
||||
*/
|
||||
public static List<Map<String, String>> parseAndFilterResponse(
|
||||
QueryResponse queryResponse, FieldMap fieldMap,
|
||||
SolrResponseFilter filter, int maxNumberOfResults) {
|
||||
return new SolrResultsParser(queryResponse, fieldMap)
|
||||
SearchResponse queryResponse, FieldMap fieldMap,
|
||||
SearchResponseFilter filter, int maxNumberOfResults) {
|
||||
return new SearchResultsParser(queryResponse, fieldMap)
|
||||
.parseAndFilterResponse(filter, maxNumberOfResults);
|
||||
}
|
||||
|
||||
|
@ -108,8 +107,7 @@ public class SolrQueryUtils {
|
|||
for (String word : words) {
|
||||
terms.add(buildTerm(fieldName, word));
|
||||
}
|
||||
String q = StringUtils.join(terms, c.joiner());
|
||||
return q;
|
||||
return StringUtils.join(terms, c.joiner());
|
||||
}
|
||||
|
||||
private static String buildTerm(String fieldName, String word) {
|
||||
|
@ -117,7 +115,8 @@ public class SolrQueryUtils {
|
|||
}
|
||||
|
||||
/**
|
||||
* Methods that can be used in multiple places, such as IndividualListController and SolrIndividualsDataGetter
|
||||
* Methods that can be used in multiple places, such as
|
||||
* IndividualListController and SearchIndividualsDataGetter
|
||||
*/
|
||||
|
||||
public static String getAlphaParameter(VitroRequest request){
|
||||
|
@ -139,13 +138,13 @@ public class SolrQueryUtils {
|
|||
}
|
||||
|
||||
//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));
|
||||
public static long getIndividualCount(List<String> vclassUris) {
|
||||
SearchEngine search = ApplicationUtils.instance().getSearchEngine();
|
||||
SearchQuery query = search.createQuery(makeMultiClassQuery(vclassUris));
|
||||
query.setRows(0);
|
||||
try {
|
||||
SolrServer solr = SolrSetup.getSolrServer(context);
|
||||
QueryResponse response = null;
|
||||
response = solr.query(query);
|
||||
SearchResponse response = null;
|
||||
response = search.query(query);
|
||||
return response.getResults().getNumFound();
|
||||
} catch(Exception ex) {
|
||||
log.error("An error occured in retrieving individual count", ex);
|
||||
|
@ -157,8 +156,9 @@ public class SolrQueryUtils {
|
|||
* 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){
|
||||
public static SearchQuery getQuery(List<String> vclassUris, String alpha, int page, int pageSize){
|
||||
String queryText = "";
|
||||
SearchEngine searchEngine = ApplicationUtils.instance().getSearchEngine();
|
||||
|
||||
try {
|
||||
queryText = makeMultiClassQuery(vclassUris);
|
||||
|
@ -168,31 +168,32 @@ public class SolrQueryUtils {
|
|||
queryText += VitroSearchTermNames.NAME_LOWERCASE + ":" + alpha.toLowerCase() + "*";
|
||||
}
|
||||
|
||||
SolrQuery query = new SolrQuery(queryText);
|
||||
SearchQuery query = searchEngine.createQuery(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);
|
||||
query.addSortField(VitroSearchTermNames.NAME_LOWERCASE_SINGLE_VALUED, Order.ASC);
|
||||
|
||||
log.debug("Query is " + query.toString());
|
||||
return query;
|
||||
|
||||
} catch (Exception ex){
|
||||
log.error("Could not make Solr query",ex);
|
||||
return new SolrQuery();
|
||||
log.error("Could not make the search query",ex);
|
||||
return searchEngine.createQuery();
|
||||
}
|
||||
}
|
||||
|
||||
public static SolrQuery getRandomQuery(List<String> vclassUris, int page, int pageSize){
|
||||
public static SearchQuery getRandomQuery(List<String> vclassUris, int page, int pageSize){
|
||||
String queryText = "";
|
||||
SearchEngine searchEngine = ApplicationUtils.instance().getSearchEngine();
|
||||
|
||||
try {
|
||||
try {
|
||||
queryText = makeMultiClassQuery(vclassUris);
|
||||
log.debug("queryText is " + queryText);
|
||||
SolrQuery query = new SolrQuery(queryText);
|
||||
SearchQuery query = searchEngine.createQuery(queryText);
|
||||
|
||||
//page count starts at 1, row count starts at 0
|
||||
query.setStart( page ).setRows( pageSize );
|
||||
|
@ -201,8 +202,8 @@ public class SolrQueryUtils {
|
|||
return query;
|
||||
|
||||
} catch (Exception ex){
|
||||
log.error("Could not make the Solr query",ex);
|
||||
return new SolrQuery();
|
||||
log.error("Could not make the search query",ex);
|
||||
return searchEngine.createQuery();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,18 +216,17 @@ public class SolrQueryUtils {
|
|||
}
|
||||
return StringUtils.join(queryTypes, " AND ");
|
||||
} catch (Exception ex){
|
||||
log.error("Could not make Solr query",ex);
|
||||
log.error("Could not make the search 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);
|
||||
List<String> vclassURIs, String alpha, int page, int pageSize, IndividualDao indDao)
|
||||
throws SearchEngineException {
|
||||
SearchQuery query = SearchQueryUtils.getQuery(vclassURIs, alpha, page, pageSize);
|
||||
IndividualListQueryResults results = IndividualListQueryResults.runQuery(query, indDao);
|
||||
log.debug("Executed search query for " + vclassURIs);
|
||||
if (results.getIndividuals().isEmpty()) {
|
||||
log.debug("entities list is null for vclass " + vclassURIs);
|
||||
}
|
||||
|
@ -234,12 +234,11 @@ public class SolrQueryUtils {
|
|||
}
|
||||
|
||||
public static IndividualListQueryResults buildAndExecuteRandomVClassQuery(
|
||||
List<String> vclassURIs, int page, int pageSize,
|
||||
ServletContext context, IndividualDao indDao)
|
||||
throws SolrServerException {
|
||||
SolrQuery query = SolrQueryUtils.getRandomQuery(vclassURIs, page, pageSize);
|
||||
IndividualListQueryResults results = IndividualListQueryResults.runQuery(query, indDao, context);
|
||||
log.debug("Executed solr query for " + vclassURIs);
|
||||
List<String> vclassURIs, int page, int pageSize, IndividualDao indDao)
|
||||
throws SearchEngineException {
|
||||
SearchQuery query = SearchQueryUtils.getRandomQuery(vclassURIs, page, pageSize);
|
||||
IndividualListQueryResults results = IndividualListQueryResults.runQuery(query, indDao);
|
||||
log.debug("Executed search query for " + vclassURIs);
|
||||
if (results.getIndividuals().isEmpty()) {
|
||||
log.debug("entities list is null for vclass " + vclassURIs);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.searchengine;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This can be used to filter the results of the search query.
|
||||
*/
|
||||
public interface SearchResponseFilter {
|
||||
boolean accept(Map<String, String> map);
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.solr;
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.searchengine;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
@ -9,23 +9,24 @@ import java.util.Map;
|
|||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.solr.client.solrj.response.QueryResponse;
|
||||
import org.apache.solr.common.SolrDocument;
|
||||
import org.apache.solr.common.SolrDocumentList;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResponse;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResultDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResultDocumentList;
|
||||
|
||||
/**
|
||||
* Parse this Solr response, creating a map of values for each document.
|
||||
* Parse this search response, creating a map of values for each document.
|
||||
*
|
||||
* The Solr field names in the document are replaced by json field names in the
|
||||
* parsed results, according to the fieldMap.
|
||||
* The search response field names in the document are replaced by json field
|
||||
* names in the parsed results, according to the fieldMap.
|
||||
*/
|
||||
public class SolrResultsParser {
|
||||
private static final Log log = LogFactory.getLog(SolrResultsParser.class);
|
||||
public class SearchResultsParser {
|
||||
private static final Log log = LogFactory.getLog(SearchResultsParser.class);
|
||||
|
||||
private final QueryResponse queryResponse;
|
||||
private final SearchResponse queryResponse;
|
||||
private final Map<String, String> fieldNameMapping;
|
||||
|
||||
public SolrResultsParser(QueryResponse queryResponse, FieldMap fieldMap) {
|
||||
public SearchResultsParser(SearchResponse queryResponse, FieldMap fieldMap) {
|
||||
this.queryResponse = queryResponse;
|
||||
this.fieldNameMapping = fieldMap.map();
|
||||
}
|
||||
|
@ -41,14 +42,14 @@ public class SolrResultsParser {
|
|||
return maps;
|
||||
}
|
||||
|
||||
SolrDocumentList docs = queryResponse.getResults();
|
||||
SearchResultDocumentList docs = queryResponse.getResults();
|
||||
if (docs == null) {
|
||||
log.debug("Docs for a search was null");
|
||||
return maps;
|
||||
}
|
||||
log.debug("Total number of hits = " + docs.getNumFound());
|
||||
|
||||
for (SolrDocument doc : docs) {
|
||||
for (SearchResultDocument doc : docs) {
|
||||
maps.add(parseSingleDocument(doc));
|
||||
}
|
||||
|
||||
|
@ -61,7 +62,7 @@ public class SolrResultsParser {
|
|||
* have parsed the entire response).
|
||||
*/
|
||||
public List<Map<String, String>> parseAndFilterResponse(
|
||||
SolrResponseFilter filter, int maxNumberOfResults) {
|
||||
SearchResponseFilter filter, int maxNumberOfResults) {
|
||||
List<Map<String, String>> maps = new ArrayList<Map<String, String>>();
|
||||
|
||||
if (queryResponse == null) {
|
||||
|
@ -69,14 +70,14 @@ public class SolrResultsParser {
|
|||
return maps;
|
||||
}
|
||||
|
||||
SolrDocumentList docs = queryResponse.getResults();
|
||||
SearchResultDocumentList docs = queryResponse.getResults();
|
||||
if (docs == null) {
|
||||
log.debug("Docs for a search was null");
|
||||
return maps;
|
||||
}
|
||||
log.debug("Total number of hits = " + docs.getNumFound());
|
||||
|
||||
for (SolrDocument doc : docs) {
|
||||
for (SearchResultDocument doc : docs) {
|
||||
Map<String, String> map = parseSingleDocument(doc);
|
||||
if (filter.accept(map)) {
|
||||
maps.add(map);
|
||||
|
@ -92,12 +93,12 @@ public class SolrResultsParser {
|
|||
/**
|
||||
* Create a map from this document, applying translation on the field names.
|
||||
*/
|
||||
private Map<String, String> parseSingleDocument(SolrDocument doc) {
|
||||
private Map<String, String> parseSingleDocument(SearchResultDocument doc) {
|
||||
Map<String, String> result = new HashMap<String, String>();
|
||||
for (String solrFieldName : fieldNameMapping.keySet()) {
|
||||
String jsonFieldName = fieldNameMapping.get(solrFieldName);
|
||||
|
||||
result.put(jsonFieldName, parseSingleValue(doc, solrFieldName));
|
||||
for (String searchResultFieldName : fieldNameMapping.keySet()) {
|
||||
String jsonFieldName = fieldNameMapping.get(searchResultFieldName);
|
||||
result.put(jsonFieldName,
|
||||
parseSingleValue(doc, searchResultFieldName));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -106,8 +107,8 @@ public class SolrResultsParser {
|
|||
/**
|
||||
* Find a single value in the document
|
||||
*/
|
||||
private String parseSingleValue(SolrDocument doc, String key) {
|
||||
Object rawValue = getFirstValue(doc.get(key));
|
||||
private String parseSingleValue(SearchResultDocument doc, String key) {
|
||||
Object rawValue = doc.getFirstValue(key);
|
||||
|
||||
if (rawValue == null) {
|
||||
return "";
|
||||
|
@ -118,20 +119,4 @@ public class SolrResultsParser {
|
|||
return String.valueOf(rawValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* The result might be a list. If so, get the first element.
|
||||
*/
|
||||
private Object getFirstValue(Object rawValue) {
|
||||
if (rawValue instanceof List<?>) {
|
||||
List<?> list = (List<?>) rawValue;
|
||||
if (list.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
return list.get(0);
|
||||
}
|
||||
} else {
|
||||
return rawValue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.solr;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This can be used to filter the results of the Solr query.
|
||||
*/
|
||||
public interface SolrResponseFilter {
|
||||
boolean accept(Map<String, String> map);
|
||||
}
|
|
@ -83,7 +83,7 @@ public class BrowseWidget extends Widget {
|
|||
VClass vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(classUri);
|
||||
map.put("class", new VClassTemplateModel(vclass));
|
||||
|
||||
JSONObject vclassRes = JsonServlet.getSolrIndividualsByVClass(vclass.getURI(), request, context);
|
||||
JSONObject vclassRes = JsonServlet.getSearchIndividualsByVClass(vclass.getURI(), request);
|
||||
map.put("totalCount", JsonToFmModel.convertJSONObjectToMap( (String) vclassRes.get("totalCount") ));
|
||||
map.put("alpha", JsonToFmModel.convertJSONObjectToMap( (String) vclassRes.get("alpha") ));
|
||||
map.put("individuals", JsonToFmModel.convertJSONArrayToList( (JSONArray) vclassRes.get("individuals") ));
|
||||
|
|
|
@ -10,18 +10,19 @@ import java.util.regex.PatternSyntaxException;
|
|||
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
import org.apache.solr.client.solrj.SolrQuery;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import stubs.edu.cornell.mannlib.vitro.webapp.modules.ApplicationStub;
|
||||
import stubs.edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngineStub;
|
||||
import stubs.javax.servlet.ServletContextStub;
|
||||
import stubs.javax.servlet.http.HttpServletRequestStub;
|
||||
import stubs.javax.servlet.http.HttpServletResponseStub;
|
||||
|
||||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery;
|
||||
|
||||
/**
|
||||
* Tests on various methods in the class.
|
||||
|
@ -36,6 +37,8 @@ public class JSONReconcileServletTest extends AbstractTestClass {
|
|||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
ApplicationStub.setup(new ServletContextStub(), new SearchEngineStub());
|
||||
|
||||
request = new HttpServletRequestStub();
|
||||
request.setRequestUrl(new URL("http://vivo.this.that/reconcile"));
|
||||
request.setMethod("POST");
|
||||
|
@ -78,23 +81,17 @@ public class JSONReconcileServletTest extends AbstractTestClass {
|
|||
propertiesList.add(properties);
|
||||
|
||||
// test getQuery
|
||||
SolrQuery solrQuery = reconcile.getQuery(nameStr, nameType, rowNum, propertiesList);
|
||||
SearchQuery searchQuery = reconcile.getQuery(nameStr, nameType, rowNum, propertiesList);
|
||||
String messagePrefix = "Query should contain the text: ";
|
||||
testAssertTrue(messagePrefix + orgStr, orgStr, solrQuery.toString());
|
||||
testAssertTrue(messagePrefix + nameStr, nameStr, solrQuery.toString());
|
||||
testAssertTrue(messagePrefix + orgType, orgType, solrQuery.toString());
|
||||
testAssertTrue(messagePrefix + nameType, orgType, solrQuery.toString());
|
||||
testAssertTrue(messagePrefix + orgStr, orgStr, searchQuery.toString());
|
||||
testAssertTrue(messagePrefix + nameStr, nameStr, searchQuery.toString());
|
||||
testAssertTrue(messagePrefix + orgType, orgType, searchQuery.toString());
|
||||
testAssertTrue(messagePrefix + nameType, orgType, searchQuery.toString());
|
||||
}
|
||||
|
||||
private void testAssertTrue(String message, String inputStr, String resultStr) {
|
||||
try {
|
||||
String modStr = null;
|
||||
if (inputStr.contains(":") && inputStr.contains("/")) {
|
||||
modStr = inputStr.replaceAll(":", "%3A").replaceAll("/", "%2F");
|
||||
} else {
|
||||
modStr = inputStr;
|
||||
}
|
||||
Pattern regex = Pattern.compile(modStr, Pattern.CASE_INSENSITIVE);
|
||||
Pattern regex = Pattern.compile(inputStr, Pattern.CASE_INSENSITIVE);
|
||||
Matcher regexMatcher = regex.matcher(resultStr);
|
||||
Assert.assertTrue(message, regexMatcher.find());
|
||||
} catch (PatternSyntaxException e) {
|
||||
|
|
|
@ -20,22 +20,22 @@ import org.junit.Test;
|
|||
|
||||
import stubs.edu.cornell.mannlib.vitro.webapp.dao.VClassDaoStub;
|
||||
import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub;
|
||||
import stubs.edu.cornell.mannlib.vitro.webapp.modules.ApplicationStub;
|
||||
import stubs.edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngineStub;
|
||||
import stubs.javax.servlet.ServletConfigStub;
|
||||
import stubs.javax.servlet.ServletContextStub;
|
||||
import stubs.javax.servlet.http.HttpServletRequestStub;
|
||||
import stubs.javax.servlet.http.HttpServletResponseStub;
|
||||
import stubs.javax.servlet.http.HttpSessionStub;
|
||||
import stubs.org.apache.solr.client.solrj.SolrServerStub;
|
||||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
public class JsonServletTest extends AbstractTestClass {
|
||||
private static final String GET_SOLR_INDIVIDUALS_BY_VCLASS = "getSolrIndividualsByVClass";
|
||||
private static final String GET_SEARCH_INDIVIDUALS_BY_VCLASS = "getSearchIndividualsByVClass";
|
||||
|
||||
private static final String GET_VCLASSES_FOR_VCLASS_GROUP = "getVClassesForVClassGroup";
|
||||
|
||||
|
@ -51,16 +51,16 @@ public class JsonServletTest extends AbstractTestClass {
|
|||
* ents_edit_head.jsp
|
||||
* (there is an ents_edit.jsp, invoked from EntityEditController, which does not seem to invoke ents_edit.js)
|
||||
*
|
||||
* GetSolrIndividualsByVClass
|
||||
* Mock out SolrServer (from SolrSetup) and IndividualDao
|
||||
* GetSearchIndividualsByVClass
|
||||
* Mock out search engine and IndividualDao
|
||||
* invoked by BrowseDataGetter.java
|
||||
* home page
|
||||
* invoked by ClassGroupPageData.java
|
||||
* >>>> Bring up "People" tab.
|
||||
* invoked by BrowseWidget.java
|
||||
*
|
||||
* GetSolrIndividualsByVClasses
|
||||
* Mock out SolrServer (from SolrSetup) and IndividualDao
|
||||
* GetSearchIndividualsByVClasses
|
||||
* Mock out search engine and IndividualDao
|
||||
* invoked by IndividualsForClassesDataGetter.java
|
||||
* ProcessIndividualsForClasses
|
||||
* extended in vivo by ProcessInternalClasses
|
||||
|
@ -85,7 +85,7 @@ public class JsonServletTest extends AbstractTestClass {
|
|||
private WebappDaoFactoryStub wadf;
|
||||
private VClassDaoStub vcDao;
|
||||
|
||||
private SolrServerStub solr;
|
||||
private SearchEngineStub search;
|
||||
|
||||
@Before
|
||||
public void setup() throws ServletException {
|
||||
|
@ -112,8 +112,8 @@ public class JsonServletTest extends AbstractTestClass {
|
|||
vcDao = new VClassDaoStub();
|
||||
wadf.setVClassDao(vcDao);
|
||||
|
||||
solr = new SolrServerStub();
|
||||
ctx.setAttribute(SolrSetup.SOLR_SERVER, solr);
|
||||
search = new SearchEngineStub();
|
||||
ApplicationStub.setup(new ServletContextStub(), search);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -163,7 +163,7 @@ public class JsonServletTest extends AbstractTestClass {
|
|||
IOException {
|
||||
setLoggerLevel(JsonServlet.class, Level.FATAL);
|
||||
setLoggerLevel(JsonObjectProducer.class, Level.FATAL);
|
||||
req.addParameter(GET_SOLR_INDIVIDUALS_BY_VCLASS, "true");
|
||||
req.addParameter(GET_SEARCH_INDIVIDUALS_BY_VCLASS, "true");
|
||||
servlet.service(req, resp);
|
||||
assertFailureWithErrorMessage("java.lang.Exception: "
|
||||
+ "parameter vclassId URI parameter expected ");
|
||||
|
@ -175,7 +175,7 @@ public class JsonServletTest extends AbstractTestClass {
|
|||
setLoggerLevel(JsonServlet.class, Level.FATAL);
|
||||
setLoggerLevel(JsonObjectProducer.class, Level.FATAL);
|
||||
String vclassId = "http://bogusVclass";
|
||||
req.addParameter(GET_SOLR_INDIVIDUALS_BY_VCLASS, "true");
|
||||
req.addParameter(GET_SEARCH_INDIVIDUALS_BY_VCLASS, "true");
|
||||
req.addParameter(VCLASS_ID, vclassId);
|
||||
|
||||
servlet.service(req, resp);
|
||||
|
@ -185,7 +185,8 @@ public class JsonServletTest extends AbstractTestClass {
|
|||
|
||||
/**
|
||||
* TODO test successful responses. This will require figuring out how to
|
||||
* stub SolrServer. It's an abstract class, so we just need to figure out
|
||||
* stub SearchEngine. Since we are no longer dealing with an abstract class
|
||||
* (like SolrServer), so we just need to figure out
|
||||
* what sort of NamedList is required as a response to a request.
|
||||
*/
|
||||
@Test
|
||||
|
@ -195,7 +196,7 @@ public class JsonServletTest extends AbstractTestClass {
|
|||
setLoggerLevel(ModelAccess.class, Level.ERROR);
|
||||
String vclassId = "http://myVclass";
|
||||
vcDao.setVClass(vclassId, new VClass(vclassId));
|
||||
req.addParameter(GET_SOLR_INDIVIDUALS_BY_VCLASS, "true");
|
||||
req.addParameter(GET_SEARCH_INDIVIDUALS_BY_VCLASS, "true");
|
||||
req.addParameter(VCLASS_ID, vclassId);
|
||||
|
||||
servlet.service(req, resp);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding;
|
||||
package edu.cornell.mannlib.vitro.webapp.search.documentBuilding;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
|
@ -2,30 +2,35 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package edu.cornell.mannlib.vitro.webapp.search.solr;
|
||||
package edu.cornell.mannlib.vitro.webapp.search.documentBuilding;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.log4j.Level;
|
||||
import org.apache.solr.common.SolrInputDocument;
|
||||
import org.apache.solr.common.SolrInputField;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import stubs.edu.cornell.mannlib.vitro.webapp.modules.ApplicationStub;
|
||||
import stubs.edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngineStub;
|
||||
import stubs.javax.servlet.ServletContextStub;
|
||||
|
||||
import com.hp.hpl.jena.rdf.model.Model;
|
||||
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||
import com.hp.hpl.jena.rdf.model.impl.RDFDefaultErrorHandler;
|
||||
|
||||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputField;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceFactorySingle;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.model.RDFServiceModel;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding.SkipIndividualException;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding.ThumbnailImageURL;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.documentBuilding.SkipIndividualException;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.documentBuilding.ThumbnailImageURL;
|
||||
|
||||
public class ThumbnailImageURLTest extends AbstractTestClass{
|
||||
RDFServiceFactory testRDF;
|
||||
|
@ -37,6 +42,7 @@ public class ThumbnailImageURLTest extends AbstractTestClass{
|
|||
@Before
|
||||
public void setUp() throws Exception {
|
||||
setLoggerLevel(RDFDefaultErrorHandler.class, Level.OFF);
|
||||
ApplicationStub.setup(new ServletContextStub(), new SearchEngineStub());
|
||||
|
||||
Model model = ModelFactory.createDefaultModel();
|
||||
InputStream in = ThumbnailImageURLTest.class.getResourceAsStream("testPerson.n3");
|
||||
|
@ -47,12 +53,10 @@ public class ThumbnailImageURLTest extends AbstractTestClass{
|
|||
/**
|
||||
* Test to see if ThumbnailImageURL gets the date it is suppose to gete
|
||||
* from a set of RDF.
|
||||
*
|
||||
* Test method for {@link edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding.ThumbnailImageURL#modifyDocument(edu.cornell.mannlib.vitro.webapp.beans.Individual, org.apache.solr.common.SolrInputDocument, java.lang.StringBuffer)}.
|
||||
*/
|
||||
@Test
|
||||
public void testThumbnailFieldCreatedInSolrDoc() {
|
||||
SolrInputDocument doc = new SolrInputDocument();
|
||||
public void testThumbnailFieldCreatedInSearchDoc() {
|
||||
SearchInputDocument doc = ApplicationUtils.instance().getSearchEngine().createInputDocument();
|
||||
ThumbnailImageURL testMe = new ThumbnailImageURL( testRDF );
|
||||
Individual ind = new IndividualImpl();
|
||||
ind.setURI(personsURI);
|
||||
|
@ -64,13 +68,13 @@ public class ThumbnailImageURLTest extends AbstractTestClass{
|
|||
Assert.fail("Test individual was skipped by classes that build the search document: " + e.getMessage());
|
||||
}
|
||||
|
||||
//make sure that a Solr document field got created for the thumbnail image
|
||||
//make sure that a search document field got created for the thumbnail image
|
||||
|
||||
SolrInputField thumbnailField = doc.getField( VitroSearchTermNames.THUMBNAIL_URL );
|
||||
SearchInputField thumbnailField = doc.getField( VitroSearchTermNames.THUMBNAIL_URL );
|
||||
Assert.assertNotNull(thumbnailField);
|
||||
|
||||
Assert.assertNotNull( thumbnailField.getValues() );
|
||||
Assert.assertEquals(1, thumbnailField.getValueCount());
|
||||
Assert.assertEquals(1, thumbnailField.getValues().size());
|
||||
|
||||
Assert.assertEquals("http://vivo.cornell.edu/individual/n54945", thumbnailField.getFirstValue());
|
||||
}
|
|
@ -1,327 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
package edu.cornell.mannlib.vitro.webapp.search.solr;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
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.embedded.EmbeddedSolrServer;
|
||||
import org.apache.solr.client.solrj.response.QueryResponse;
|
||||
import org.apache.solr.common.SolrDocument;
|
||||
import org.apache.solr.common.SolrInputDocument;
|
||||
import org.apache.solr.core.CoreContainer;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
import com.hp.hpl.jena.rdf.model.Model;
|
||||
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||
import com.hp.hpl.jena.rdf.model.ResIterator;
|
||||
import com.hp.hpl.jena.rdf.model.Resource;
|
||||
import com.hp.hpl.jena.util.FileManager;
|
||||
|
||||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceFactorySingle;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.model.RDFServiceModel;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.solr.documentBuilding.IndividualToSolrDocument;
|
||||
|
||||
/**
|
||||
* This tests what results will be returned for queries to the
|
||||
* Solr service.
|
||||
*
|
||||
* The test will setup a temporary Solr service, setup a temporary RDF store, load the
|
||||
* store with some individuals, and then index the individuals in the store.
|
||||
*
|
||||
* Once this is done a set of test queries will be run against that service.
|
||||
*
|
||||
* This code is based on a similar test from the CUL Discovery and Access
|
||||
* integration layer.
|
||||
*
|
||||
* All RDF/XML files in webapp/test/testontologies/SolrQueryTestRDF will be
|
||||
* loaded into the model.
|
||||
*/
|
||||
|
||||
//ignored for now since the solr directory isn't yet found when running from vivo.
|
||||
@Ignore
|
||||
public class SolrQueryTest extends AbstractTestClass {
|
||||
/** Key of system property for build directory. */
|
||||
final static String buildDirSystemPropertyKey = "vitro.build.dir";
|
||||
|
||||
/** Solr index to run test queries on. */
|
||||
static SolrServer solr = null;
|
||||
|
||||
/** Container for solr */
|
||||
static CoreContainer coreContainer = null;
|
||||
|
||||
/** Folder to store the temporary Solr index. */
|
||||
public static TemporaryFolder solrIndexFolder = null;
|
||||
|
||||
/**
|
||||
* This test needs to load RDF data to use as a
|
||||
* source of individuals to to build documents.
|
||||
* This is relative to the build directory.
|
||||
*/
|
||||
final static String testRDFDir =
|
||||
"/webapp/test/testontologies/SolrQueryTestRDF";
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception{
|
||||
//solr makes a lot of output
|
||||
suppressSysout();
|
||||
suppressSyserr();
|
||||
|
||||
File buildDir = findBuildDir();
|
||||
|
||||
solrIndexFolder = new TemporaryFolder();
|
||||
solrIndexFolder.create();
|
||||
|
||||
File tempSolrBase = solrIndexFolder.newFolder("tempSolrBase");
|
||||
FileUtils.copyDirectory(getSolrTemplateDir(buildDir), tempSolrBase );
|
||||
solr = setupSolr( tempSolrBase );
|
||||
|
||||
indexRdf( loadTestRDF( buildDir ) );
|
||||
}
|
||||
|
||||
@After
|
||||
public void takedown() throws Exception{
|
||||
if( coreContainer != null )
|
||||
coreContainer.shutdown();
|
||||
|
||||
restoreOutputStreams();
|
||||
|
||||
if( solrIndexFolder != null )
|
||||
solrIndexFolder.delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* This will return the directory to use as the Solr
|
||||
* home template directory.
|
||||
*
|
||||
* Throws an exception if the directory is not found.
|
||||
* @param buildDir - must not be null, must be the base of the build.
|
||||
*/
|
||||
private File getSolrTemplateDir(File buildDir) throws Exception {
|
||||
if(buildDir == null || !buildDir.exists() )
|
||||
throw new Exception("buildDir must not be null");
|
||||
|
||||
String solrTemplateDirName = buildDir.getAbsolutePath() + "/solr/homeDirectoryTemplate";
|
||||
File solrTemplateDir = new File(solrTemplateDirName);
|
||||
|
||||
if( solrTemplateDir == null || ! solrTemplateDir.exists())
|
||||
throw new Exception("Solr home directory template " +
|
||||
"was not found at " + solrTemplateDirName);
|
||||
else
|
||||
return solrTemplateDir;
|
||||
}
|
||||
|
||||
protected SolrServer setupSolr(File solrBase)
|
||||
throws ParserConfigurationException, IOException, SAXException{
|
||||
System.setProperty("solr.solr.home", solrBase.getAbsolutePath());
|
||||
CoreContainer.Initializer initializer = new CoreContainer.Initializer();
|
||||
coreContainer = initializer.initialize();
|
||||
return new EmbeddedSolrServer(coreContainer, "");
|
||||
}
|
||||
|
||||
private OntModel loadTestRDF(File buildDir) throws Exception {
|
||||
String dirname = buildDir.getAbsolutePath() + testRDFDir;
|
||||
File rdfDir = new File( dirname );
|
||||
assertNotNull("could not find dir " + dirname , rdfDir);
|
||||
assertTrue(dirname + " must be a directory." ,rdfDir.isDirectory());
|
||||
|
||||
//load all files in test dir.
|
||||
File[] files = rdfDir.listFiles();
|
||||
assertNotNull("no test RDF files found",files);
|
||||
assertTrue("no test RDF files found", files.length > 0 );
|
||||
|
||||
OntModel model = ModelFactory.createOntologyModel();
|
||||
for (File file : files ){
|
||||
InputStream in = FileManager.get().open( file.getAbsolutePath() );
|
||||
assertNotNull("Could not load file " + file.getAbsolutePath(), in );
|
||||
try{
|
||||
if( file.getName().endsWith(".rdf") ){
|
||||
model.read(in,null);
|
||||
}else if( file.getName().endsWith(".n3")){
|
||||
model.read(in,null,"N3");
|
||||
}else if( file.getName().endsWith(".nt")){
|
||||
model.read(in,null,"N-TRIPLE");
|
||||
}else if( file.getName().endsWith(".ttl")){
|
||||
model.read(in,null,"TURTLE");
|
||||
}else{
|
||||
throw new Exception("Format unknown for file name " + file.getName());
|
||||
}
|
||||
}catch(Throwable th){
|
||||
throw new Exception( "Could not load RDF file "
|
||||
+ file.getAbsolutePath() , th);
|
||||
}
|
||||
}
|
||||
return model ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the base of the build directories.
|
||||
* @return This method will return a non-null file to use
|
||||
* or it will throw an exception if none can be found.
|
||||
* @throws Exception
|
||||
*/
|
||||
private File findBuildDir() throws Exception {
|
||||
|
||||
//First try to find the base directory
|
||||
//of the build in the system properties.
|
||||
|
||||
String buildDirName = System.getProperty(buildDirSystemPropertyKey);
|
||||
if( buildDirName != null ){
|
||||
File buildDir = new File(buildDirName);
|
||||
if( buildDir.exists() && buildDir.isDirectory() ){
|
||||
return buildDir;
|
||||
}
|
||||
}
|
||||
|
||||
//If there is no system property try to
|
||||
//guess the location based on the working directory
|
||||
File f = null;
|
||||
String[] fallBackBases = {"","../","../../"};
|
||||
List<String> attempted = new ArrayList<String>();
|
||||
for( String base: fallBackBases){
|
||||
String attemptedDir =base + "solr/homeDirectoryTemplate";
|
||||
f = new File( attemptedDir );
|
||||
attempted.add( System.getProperty("user.dir") + '/' + attemptedDir );
|
||||
if( f != null && f.exists() && f.isDirectory() ){
|
||||
f = new File( base );
|
||||
break;
|
||||
}else{
|
||||
f = null;
|
||||
}
|
||||
}
|
||||
|
||||
if( f == null ){
|
||||
throw new Exception(
|
||||
"Could not find the base of the " +
|
||||
"build directory for the project, " +
|
||||
"checked the system property " + buildDirSystemPropertyKey
|
||||
+ " and checked in these locations: \n" +
|
||||
StringUtils.join(attempted,"\n "));
|
||||
}else{
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Query the RDF, build Solr Documents from results, load them to Solr. */
|
||||
private void indexRdf(OntModel model) throws Exception {
|
||||
RDFServiceModel rdfService = new RDFServiceModel(model);
|
||||
|
||||
IndividualToSolrDocument r2d =
|
||||
SolrSetup.setupTransltion(
|
||||
model,
|
||||
model,
|
||||
new RDFServiceFactorySingle(rdfService),
|
||||
null, null);
|
||||
|
||||
WebappDaoFactory wdf = new WebappDaoFactoryJena(model);
|
||||
|
||||
for( String uri: getURISToIndex( model ) ){
|
||||
SolrInputDocument doc;
|
||||
try {
|
||||
doc = r2d.translate( wdf.getIndividualDao().getIndividualByURI(uri));
|
||||
} catch (Exception e) {
|
||||
throw new Exception("Failed on building document for uri:" + uri, e);
|
||||
}
|
||||
try {
|
||||
solr.add( doc );
|
||||
} catch (Exception e) {
|
||||
throw new Exception("Failed adding doc to solr for uri:" + uri, e);
|
||||
}
|
||||
}
|
||||
solr.commit();
|
||||
}
|
||||
|
||||
private List<String> getURISToIndex(Model model) {
|
||||
//just return all the URIs in the subject position
|
||||
List<String> uris = new LinkedList<String>();
|
||||
ResIterator it = model.listSubjects();
|
||||
while(it.hasNext() ){
|
||||
Resource res = it.nextResource();
|
||||
if( res != null && res.isURIResource() ){
|
||||
uris.add( res.getURI() );
|
||||
}
|
||||
}
|
||||
return uris;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a document with the given URIs are in the results for the query.
|
||||
* @throws SolrServerException */
|
||||
void testQueryGetsDocs(String errmsg, SolrQuery query, String[] expectedUris) throws SolrServerException{
|
||||
assertNotNull(errmsg + " but query was null", query);
|
||||
assertNotNull(errmsg + " but expected URIs was null", expectedUris );
|
||||
|
||||
QueryResponse resp = solr.query(query);
|
||||
if( resp == null )
|
||||
fail( errmsg + " but Could not get a solr response");
|
||||
|
||||
Set<String> uris = new HashSet<String>(Arrays.asList( expectedUris ));
|
||||
for( SolrDocument doc : resp.getResults()){
|
||||
assertNotNull(errmsg + ": solr doc was null", doc);
|
||||
String uri = (String) doc.getFirstValue( VitroSearchTermNames.URI );
|
||||
assertNotNull(errmsg+": no URI field in solr doc" , uri);
|
||||
uris.remove( uri );
|
||||
}
|
||||
if( uris.size() > 0){
|
||||
String errorMsg =
|
||||
"\nThe query '"+ query + "' was expected " +
|
||||
"to return the following URIs but did not:";
|
||||
for( String uri : uris){
|
||||
errorMsg= errorMsg+"\n" + uri;
|
||||
}
|
||||
|
||||
fail( errmsg + errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSolrWasStarted() throws SolrServerException, IOException {
|
||||
assertNotNull( solr );
|
||||
solr.ping();//this will throw an exception of the server is not reachable
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCorsonSearch() throws SolrServerException{
|
||||
|
||||
/* make sure that we have the document in the index before we do anything */
|
||||
SolrQuery query = new SolrQuery().setQuery("corson");
|
||||
|
||||
testQueryGetsDocs("Expect to find a doc when searching for 'corson'",
|
||||
query,new String[]{ "http://vivo.cornell.edu/individual/individual22972" } ) ;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormFeed() throws SolrServerException{
|
||||
/* make sure that we have the document in the index before we do anything */
|
||||
SolrQuery query = new SolrQuery().setQuery("vivo15");
|
||||
|
||||
testQueryGetsDocs("Expect to find a doc when searching for 'vivo15'",
|
||||
query,new String[]{ "http://vivo.cornell.edu/individual/individualIssueVivo15" } ) ;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils.searchengine;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||
|
||||
public class AutoCompleteWordsTest extends AbstractTestClass {
|
||||
private static final String WORD_DELIMITER = "[, ]+";
|
||||
private static final String FIELD_NAME_COMPLETE = "complete";
|
||||
private static final String FIELD_NAME_PARTIAL = "partial";
|
||||
|
||||
@Test
|
||||
public void nullSearchTerm() {
|
||||
assertQueryString(null, "");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptySearchTerm() {
|
||||
assertQueryString("", "");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void blankSearchTerm() {
|
||||
assertQueryString(" ", "");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void searchTermContainsOnlyCommas() {
|
||||
assertQueryString(",,", "");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void oneWord() {
|
||||
assertQueryString("first", "partial:\"first\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void twoWords() {
|
||||
assertQueryString("first, second",
|
||||
"complete:\"first\" AND partial:\"second\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void threeWords() {
|
||||
assertQueryString("first, second, third",
|
||||
"complete:\"first\" AND complete:\"second\" AND partial:\"third\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void oneWordAndComma() {
|
||||
assertQueryString("first,", "complete:\"first\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void oneWordAndCommaAndSpace() {
|
||||
assertQueryString("first, ", "complete:\"first\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyCompleteWord() {
|
||||
assertQueryString(", second", "partial:\"second\"");
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Helper methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private void assertQueryString(String searchTerm, String expected) {
|
||||
AutoCompleteWords acw = new AutoCompleteWords(searchTerm,
|
||||
WORD_DELIMITER);
|
||||
String actual = acw.assembleQuery(FIELD_NAME_COMPLETE,
|
||||
FIELD_NAME_PARTIAL);
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package stubs.edu.cornell.mannlib.vitro.webapp.modules;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.Application;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
public class ApplicationStub implements Application {
|
||||
/**
|
||||
* Create an ApplicationStub and set it as the instance in ApplicationUtils.
|
||||
*/
|
||||
public static void setup(ServletContext ctx, SearchEngine searchEngine) {
|
||||
ApplicationStub instance = new ApplicationStub(ctx, searchEngine);
|
||||
try {
|
||||
Field instanceField = ApplicationUtils.class
|
||||
.getDeclaredField("instance");
|
||||
instanceField.setAccessible(true);
|
||||
instanceField.set(null, instance);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Stub infrastructure
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private final ServletContext ctx;
|
||||
private final SearchEngine searchEngine;
|
||||
|
||||
public ApplicationStub(ServletContext ctx, SearchEngine searchEngine) {
|
||||
this.ctx = ctx;
|
||||
this.searchEngine = searchEngine;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Stub methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public ServletContext getServletContext() {
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchEngine getSearchEngine() {
|
||||
return searchEngine;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Un-implemented methods
|
||||
// ----------------------------------------------------------------------
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package stubs.edu.cornell.mannlib.vitro.webapp.modules.searchEngine;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.Application;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.ComponentStartupStatus;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngineException;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResponse;
|
||||
import edu.cornell.mannlib.vitro.webapp.searchengine.base.BaseSearchInputDocument;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
public class SearchEngineStub implements SearchEngine {
|
||||
// ----------------------------------------------------------------------
|
||||
// Stub infrastructure
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
Map<String, SearchResponseStub> queryResponses = new HashMap<>();
|
||||
|
||||
public void setQueryResponse(String queryText, SearchResponseStub response) {
|
||||
queryResponses.put(queryText, response);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Stub methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public SearchQuery createQuery() {
|
||||
return new SearchQueryStub();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchQuery createQuery(String queryText) {
|
||||
return new SearchQueryStub(queryText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchResponse query(SearchQuery query) throws SearchEngineException {
|
||||
SearchResponseStub response = queryResponses.get(query.getQuery());
|
||||
if (response == null) {
|
||||
return SearchResponseStub.EMPTY_RESPONSE;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchInputDocument createInputDocument() {
|
||||
return new BaseSearchInputDocument();
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Un-implemented methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void startup(Application application, ComponentStartupStatus ss) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException(
|
||||
"SearchEngineStub.startup() not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown(Application application) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException(
|
||||
"SearchEngineStub.shutdown() not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ping() throws SearchEngineException {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException("SearchEngineStub.ping() not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(SearchInputDocument... docs) throws SearchEngineException {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException("SearchEngineStub.add() not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Collection<SearchInputDocument> docs)
|
||||
throws SearchEngineException {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException("SearchEngineStub.add() not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit() throws SearchEngineException {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException("SearchEngineStub.commit() not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit(boolean wait) throws SearchEngineException {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException("SearchEngineStub.commit() not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteById(String... ids) throws SearchEngineException {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException(
|
||||
"SearchEngineStub.deleteById() not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteById(Collection<String> ids) throws SearchEngineException {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException(
|
||||
"SearchEngineStub.deleteById() not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByQuery(String query) throws SearchEngineException {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException(
|
||||
"SearchEngineStub.deleteByQuery() not implemented.");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package stubs.edu.cornell.mannlib.vitro.webapp.modules.searchEngine;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.searchengine.base.BaseSearchQuery;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
public class SearchQueryStub extends BaseSearchQuery {
|
||||
// ----------------------------------------------------------------------
|
||||
// Stub infrastructure
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @param queryText
|
||||
*/
|
||||
public SearchQueryStub() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param queryText
|
||||
*/
|
||||
public SearchQueryStub(String queryText) {
|
||||
super();
|
||||
setQuery(queryText);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Stub methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Un-implemented methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package stubs.edu.cornell.mannlib.vitro.webapp.modules.searchEngine;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchFacetField;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResponse;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResultDocumentList;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
public class SearchResponseStub implements SearchResponse {
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Stub infrastructure
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public static final SearchResponseStub EMPTY_RESPONSE = null;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Stub methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Un-implemented methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public SearchResultDocumentList getResults() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException(
|
||||
"SearchResponseStub.getResults() not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Map<String, List<String>>> getHighlighting() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException(
|
||||
"SearchResponseStub.getHighlighting() not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchFacetField getFacetField(String name) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException(
|
||||
"SearchResponseStub.getFacetField() not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SearchFacetField> getFacetFields() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException(
|
||||
"SearchResponseStub.getFacetFields() not implemented.");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package stubs.org.apache.solr.client.solrj;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.solr.client.solrj.SolrRequest;
|
||||
import org.apache.solr.client.solrj.SolrServer;
|
||||
import org.apache.solr.client.solrj.SolrServerException;
|
||||
import org.apache.solr.common.util.NamedList;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
public class SolrServerStub extends SolrServer {
|
||||
private static final Log log = LogFactory.getLog(SolrServerStub.class);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Stub infrastructure
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Stub methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.apache.solr.client.solrj.SolrServer#request(org.apache.solr.client
|
||||
* .solrj.SolrRequest)
|
||||
*/
|
||||
@Override
|
||||
public NamedList<Object> request(SolrRequest request)
|
||||
throws SolrServerException, IOException {
|
||||
// TODO not really an implementation.
|
||||
return new NamedList<Object>();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Un-implemented methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
}
|
|
@ -13,6 +13,8 @@ edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesSmokeTests
|
|||
|
||||
edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings$Setup
|
||||
|
||||
edu.cornell.mannlib.vitro.webapp.application.ApplicationImpl$Setup
|
||||
|
||||
edu.cornell.mannlib.vitro.webapp.config.RevisionInfoSetup
|
||||
|
||||
edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory$Setup
|
||||
|
@ -62,9 +64,10 @@ edu.ucsf.vitro.opensocial.OpenSocialSmokeTests
|
|||
# For multiple language support
|
||||
edu.cornell.mannlib.vitro.webapp.i18n.selection.LocaleSelectionSetup
|
||||
|
||||
# The Solr index uses a "public" permission, so the PropertyRestrictionPolicyHelper
|
||||
# The search indexer uses a "public" permission, so the PropertyRestrictionPolicyHelper
|
||||
# and the PermissionRegistry must already be set up.
|
||||
edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup
|
||||
edu.cornell.mannlib.vitro.webapp.searchengine.SearchEngineSetup
|
||||
edu.cornell.mannlib.vitro.webapp.searchindex.SearchIndexerSetup
|
||||
|
||||
edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerSetup
|
||||
edu.cornell.mannlib.vitro.webapp.freemarker.config.FreemarkerConfiguration$Setup
|
||||
|
|
|
@ -592,7 +592,7 @@ page_text = page text
|
|||
|
||||
sparql_query_results = Sparql Query Results
|
||||
no_results_returned = No results were returned.
|
||||
solr_individual_results = Solr Class Individuals
|
||||
solr_individual_results = Search Class Individuals
|
||||
select_vclass_uri = Select VClass
|
||||
#
|
||||
# manage proxies templates ( /templates/freemarker/body/manageproxies )
|
||||
|
|
|
@ -104,7 +104,7 @@ var pageManagementUtils = {
|
|||
this.classGroupSection = $("section#browseClassGroup");
|
||||
this.sparqlQuerySection = $("section#sparqlQuery");
|
||||
this.fixedHTMLSection = $("section#fixedHtml");
|
||||
this.solrIndividualsSection = $("section#solrIndividuals");
|
||||
this.searchIndividualsSection = $("section#searchIndividuals");
|
||||
//From original menu management edit
|
||||
this.defaultTemplateRadio = $('input.default-template');
|
||||
this.customTemplateRadio = $('input.custom-template');
|
||||
|
@ -133,8 +133,8 @@ var pageManagementUtils = {
|
|||
this.rightSideDiv = $("div#rightSide");
|
||||
//contentDivs container where content added/existing placed
|
||||
this.savedContentDivs = $("section#contentDivs");
|
||||
//for solr individuals data getter
|
||||
this.solrAllClassesDropdown = $("select#vclassUri");
|
||||
//for search individuals data getter
|
||||
this.searchAllClassesDropdown = $("select#vclassUri");
|
||||
},
|
||||
initDisplay: function(){
|
||||
//right side components
|
||||
|
@ -147,7 +147,7 @@ var pageManagementUtils = {
|
|||
this.classGroupSection.hide();
|
||||
this.sparqlQuerySection.hide();
|
||||
this.fixedHTMLSection.hide();
|
||||
this.solrIndividualsSection.hide();
|
||||
this.searchIndividualsSection.hide();
|
||||
this.classesForClassGroup.addClass('hidden');
|
||||
//left side components
|
||||
//These depend on whether or not this is an existing item or not
|
||||
|
@ -160,14 +160,14 @@ var pageManagementUtils = {
|
|||
this.menuSection.hide();
|
||||
}
|
||||
}
|
||||
//populates the dropdown of classes for the solr individuals template
|
||||
//populates the dropdown of classes for the search individuals template
|
||||
//dropdown now populated in template/from form specific data instead of ajax request
|
||||
//this.populateClassForSolrDropdown();
|
||||
//this.populateClassForSearchDropdown();
|
||||
},
|
||||
//this method can be utilized if using an ajax request to get the vclasses
|
||||
/*
|
||||
//for solr individuals - remember this populates the template class dropdown
|
||||
populateClassForSolrDropdown:function() {
|
||||
//for search individuals - remember this populates the template class dropdown
|
||||
populateClassForSearchDropdown:function() {
|
||||
|
||||
//Run ajax query
|
||||
var url = "dataservice?getAllVClasses=1";
|
||||
|
@ -176,10 +176,10 @@ var pageManagementUtils = {
|
|||
$.getJSON(url, function(results) {
|
||||
//Moved the function to processClassGroupDataGetterContent
|
||||
//Should probably remove this entire method and copy there
|
||||
pageManagementUtils.displayAllClassesForSolrDropdown(results);
|
||||
pageManagementUtils.displayAllClassesForSearchDropdown(results);
|
||||
});
|
||||
},
|
||||
displayAllClassesForSolrDropdown:function(results) {
|
||||
displayAllClassesForSearchDropdown:function(results) {
|
||||
if ( results.classes.length == 0 ) {
|
||||
|
||||
} else {
|
||||
|
@ -193,7 +193,7 @@ var pageManagementUtils = {
|
|||
|
||||
//if there are options to add
|
||||
if(appendHtml != "") {
|
||||
pageManagementUtils.solrAllClassesDropdown.html(appendHtml);
|
||||
pageManagementUtils.searchAllClassesDropdown.html(appendHtml);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -285,7 +285,7 @@ var pageManagementUtils = {
|
|||
pageManagementUtils.classGroupSection.hide();
|
||||
pageManagementUtils.fixedHTMLSection.hide();
|
||||
pageManagementUtils.sparqlQuerySection.hide();
|
||||
pageManagementUtils.solrIndividualsSection.hide();
|
||||
pageManagementUtils.searchIndividualsSection.hide();
|
||||
//Reset main content type drop-down
|
||||
pageManagementUtils.contentTypeSelectOptions.eq(0).attr('selected', 'selected');
|
||||
if ( pageManagementUtils.leftSideDiv.css("height") != undefined ) {
|
||||
|
@ -357,31 +357,31 @@ var pageManagementUtils = {
|
|||
pageManagementUtils.classGroupSection.show();
|
||||
pageManagementUtils.fixedHTMLSection.hide();
|
||||
pageManagementUtils.sparqlQuerySection.hide();
|
||||
pageManagementUtils.solrIndividualsSection.hide();
|
||||
pageManagementUtils.searchIndividualsSection.hide();
|
||||
pageManagementUtils.headerBar.text(pageManagementUtils.browseClassGroup + " - ");
|
||||
pageManagementUtils.headerBar.show();
|
||||
$('div#selfContainedDiv').hide();
|
||||
}
|
||||
if ( _this.contentTypeSelect.val() == "fixedHtml" || _this.contentTypeSelect.val() == "sparqlQuery" || _this.contentTypeSelect.val() == "solrIndividuals") {
|
||||
if ( _this.contentTypeSelect.val() == "fixedHtml" || _this.contentTypeSelect.val() == "sparqlQuery" || _this.contentTypeSelect.val() == "searchIndividuals") {
|
||||
pageManagementUtils.classGroupSection.hide();
|
||||
//if fixed html show that, otherwise show sparql results
|
||||
if ( _this.contentTypeSelect.val() == "fixedHtml" ) {
|
||||
pageManagementUtils.headerBar.text(pageManagementUtils.fixedHtml + " - ");
|
||||
pageManagementUtils.fixedHTMLSection.show();
|
||||
pageManagementUtils.sparqlQuerySection.hide();
|
||||
pageManagementUtils.solrIndividualsSection.hide();
|
||||
pageManagementUtils.searchIndividualsSection.hide();
|
||||
}
|
||||
else if (_this.contentTypeSelect.val() == "sparqlQuery"){
|
||||
pageManagementUtils.headerBar.text(pageManagementUtils.sparqlResults + " - ");
|
||||
pageManagementUtils.sparqlQuerySection.show();
|
||||
pageManagementUtils.fixedHTMLSection.hide();
|
||||
pageManagementUtils.solrIndividualsSection.hide();
|
||||
pageManagementUtils.searchIndividualsSection.hide();
|
||||
} else {
|
||||
//solr individuals
|
||||
pageManagementUtils.headerBar.text(pageManagementUtils.solrIndividuals + " - ");
|
||||
//search individuals
|
||||
pageManagementUtils.headerBar.text(pageManagementUtils.searchIndividuals + " - ");
|
||||
pageManagementUtils.sparqlQuerySection.hide();
|
||||
pageManagementUtils.fixedHTMLSection.hide();
|
||||
pageManagementUtils.solrIndividualsSection.show();
|
||||
pageManagementUtils.searchIndividualsSection.show();
|
||||
}
|
||||
|
||||
pageManagementUtils.headerBar.show();
|
||||
|
@ -392,7 +392,7 @@ var pageManagementUtils = {
|
|||
pageManagementUtils.classGroupSection.hide();
|
||||
pageManagementUtils.fixedHTMLSection.hide();
|
||||
pageManagementUtils.sparqlQuerySection.hide();
|
||||
pageManagementUtils.solrIndividualsSection.hide();
|
||||
pageManagementUtils.searchIndividualsSection.hide();
|
||||
pageManagementUtils.classesForClassGroup.addClass('hidden');
|
||||
pageManagementUtils.headerBar.hide();
|
||||
pageManagementUtils.headerBar.text("");
|
||||
|
@ -430,7 +430,7 @@ var pageManagementUtils = {
|
|||
pageManagementUtils.clearInputs(pageManagementUtils.fixedHTMLSection);
|
||||
pageManagementUtils.clearInputs(pageManagementUtils.sparqlQuerySection);
|
||||
pageManagementUtils.clearInputs(pageManagementUtils.classGroupSection);
|
||||
pageManagementUtils.clearInputs(pageManagementUtils.solrIndividualsSection);
|
||||
pageManagementUtils.clearInputs(pageManagementUtils.searchIndividualsSection);
|
||||
|
||||
},
|
||||
clearInputs:function($el) {
|
||||
|
@ -474,7 +474,7 @@ var pageManagementUtils = {
|
|||
// Get rid of the cancel link; it'll be replaced by a delete link
|
||||
$newContentObj.find('span#cancelContent' + counter).html('');
|
||||
|
||||
if ( contentType == "sparqlQuery" || contentType == "fixedHtml" || contentType == "solrIndividuals") {
|
||||
if ( contentType == "sparqlQuery" || contentType == "fixedHtml" || contentType == "searchIndividuals") {
|
||||
varOrClass = $newContentObj.find('input[name="saveToVar"]').val();
|
||||
}
|
||||
else if ( contentType == "browseClassGroup" ) {
|
||||
|
|
|
@ -10,7 +10,7 @@ var processDataGetterUtils = {
|
|||
"sparqlQuery": processSparqlDataGetterContent,
|
||||
"fixedHtml":processFixedHTMLDataGetterContent,
|
||||
"individualsForClasses":processIndividualsForClassesDataGetterContent,
|
||||
"solrIndividuals":processSolrDataGetterContent},
|
||||
"searchIndividuals":processSearchDataGetterContent},
|
||||
selectDataGetterType:function(pageContentSection) {
|
||||
var contentType = pageContentSection.attr("contentType");
|
||||
//The form can provide "browse class group" as content type but need to check
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue