NIHVIVO-2460 Solr-based RDF generation on individual list page

This commit is contained in:
ryounes 2011-05-24 15:09:50 +00:00
parent 5364161038
commit c3049eb9c5
7 changed files with 185 additions and 182 deletions

View file

@ -44,18 +44,18 @@ public void doGet (HttpServletRequest req, HttpServletResponse res) throws IOExc
String url = req.getRequestURI().substring(req.getContextPath().length());
ContentType contentType = checkForRequestType(req.getHeader("accept"));
if(Pattern.compile("^/entityurl/$").matcher(url).matches()){
if(Pattern.compile("^/listrdf/$").matcher(url).matches()){
String redirectURL = null;
if(contentType!=null){
if ( RDFXML_MIMETYPE.equals(contentType.getMediaType()))
redirectURL = "/entityurl/entityurl.rdf";
redirectURL = "/listrdf/listrdf.rdf";
else if( N3_MIMETYPE.equals(contentType.getMediaType()))
redirectURL = "/entityurl/entityurl.n3";
redirectURL = "/listrdf/listrdf.n3";
else if ( TTL_MIMETYPE.equals(contentType.getMediaType()))
redirectURL = "/entityurl/entityurl.ttl";
redirectURL = "/listrdf/listrdf.ttl";
}
else{
redirectURL = "/entityurl/entityrurl.rdf";
redirectURL = "/listrdf/listrdf.rdf";
}
String hn = req.getHeader("Host");

View file

@ -0,0 +1,159 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.document.Document;
import org.apache.lucene.search.ScoreDoc;
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;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.vocabulary.RDF;
import edu.cornell.mannlib.vitro.webapp.search.lucene.Entity2LuceneDoc.VitroLuceneTermNames;
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
import edu.cornell.mannlib.vitro.webapp.web.ContentType;
public class IndividualListRdfController extends VitroHttpServlet {
private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(IndividualListRdfController.class.getName());
private static final String PATH = "listrdf";
private static final String FILENAME = PATH;
public static final String URL = "/" + PATH + "/";
public static final int ENTITY_LIST_CONTROLLER_MAX_RESULTS = 30000;
public void doGet (HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
String url = req.getRequestURI().substring(req.getContextPath().length());
ContentType contentType = checkForRequestType(req.getHeader("accept"));
if (url.equals(URL)) {
String redirectURL = URL + FILENAME;
if (contentType!=null) {
if (RDFXML_MIMETYPE.equals(contentType.getMediaType()))
redirectURL += ".rdf";
else if (N3_MIMETYPE.equals(contentType.getMediaType()))
redirectURL += ".n3";
else if (TTL_MIMETYPE.equals(contentType.getMediaType()))
redirectURL += ".ttl";
} else {
redirectURL += ".rdf";
}
String hn = req.getHeader("Host");
if (req.isSecure()) {
res.setHeader("Location", res.encodeURL("https://" + hn
+ req.getContextPath() + redirectURL));
log.info("doRedirect by using HTTPS");
} else {
res.setHeader("Location", res.encodeURL("http://" + hn
+ req.getContextPath() + redirectURL));
log.info("doRedirect by using HTTP");
}
res.setStatus(HttpServletResponse.SC_SEE_OTHER);
return;
}
// Make the query
String classUri = (String) getServletContext().getAttribute("classuri");
String queryStr = VitroLuceneTermNames.RDFTYPE + ":\"" + classUri + "\"";
SolrQuery query = new SolrQuery(queryStr);
query.setStart(0)
.setRows(ENTITY_LIST_CONTROLLER_MAX_RESULTS)
.setFields(VitroLuceneTermNames.URI)
.setSortField(VitroLuceneTermNames.NAME_LOWERCASE_SINGLE_VALUED, SolrQuery.ORDER.asc);
// Execute the query
SolrServer solr = SolrSetup.getSolrServer(getServletContext());
QueryResponse response = null;
try {
response = solr.query(query);
} catch (Throwable t) {
log.error(t, t);
}
if ( response == null ) {
throw new ServletException("Could not run search in IndividualListRdfController");
}
SolrDocumentList 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(VitroLuceneTermNames.URI).toString();
Resource resource = ResourceFactory.createResource(uri);
RDFNode node = (RDFNode) ResourceFactory.createResource(classUri);
model.add(resource, RDF.type, node);
}
String format = "";
if(contentType != null){
if ( RDFXML_MIMETYPE.equals(contentType.getMediaType()))
format = "RDF/XML";
else if( N3_MIMETYPE.equals(contentType.getMediaType()))
format = "N3";
else if ( TTL_MIMETYPE.equals(contentType.getMediaType()))
format ="TTL";
res.setContentType(contentType.getMediaType());
}
else{
res.setContentType(RDFXML_MIMETYPE);
format = "RDF/XML";
}
model.write(res.getOutputStream(), format);
}
public void doPost (HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException{
doGet(req,res);
}
protected ContentType checkForRequestType(String acceptHeader) {
try {
//check the accept header
if (acceptHeader != null) {
List<ContentType> actualContentTypes = new ArrayList<ContentType>();
actualContentTypes.add(new ContentType( XHTML_MIMETYPE ));
actualContentTypes.add(new ContentType( HTML_MIMETYPE ));
actualContentTypes.add(new ContentType( RDFXML_MIMETYPE ));
actualContentTypes.add(new ContentType( N3_MIMETYPE ));
actualContentTypes.add(new ContentType( TTL_MIMETYPE ));
ContentType best = ContentType.getBestContentType(acceptHeader,actualContentTypes);
if (best!=null && (
RDFXML_MIMETYPE.equals(best.getMediaType()) ||
N3_MIMETYPE.equals(best.getMediaType()) ||
TTL_MIMETYPE.equals(best.getMediaType()) ))
return best;
}
}
catch (Throwable th) {
log.error("problem while checking accept header " , th);
}
return null;
}
}

View file

@ -1,162 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.vocabulary.RDF;
import edu.cornell.mannlib.vitro.webapp.search.lucene.Entity2LuceneDoc;
import edu.cornell.mannlib.vitro.webapp.search.lucene.Entity2LuceneDoc.VitroLuceneTermNames;
import edu.cornell.mannlib.vitro.webapp.search.lucene.LuceneIndexFactory;
import edu.cornell.mannlib.vitro.webapp.web.ContentType;
public class SolrEntityUrlController extends VitroHttpServlet {
private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(SolrEntityUrlController.class.getName());
public static final int ENTITY_LIST_CONTROLLER_MAX_RESULTS = 30000;
public void doGet (HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException{
String url = req.getRequestURI().substring(req.getContextPath().length());
ContentType contentType = checkForRequestType(req.getHeader("accept"));
if(Pattern.compile("^/entityurl/$").matcher(url).matches()){
String redirectURL = null;
if(contentType!=null){
if ( RDFXML_MIMETYPE.equals(contentType.getMediaType()))
redirectURL = "/entityurl/entityurl.rdf";
else if( N3_MIMETYPE.equals(contentType.getMediaType()))
redirectURL = "/entityurl/entityurl.n3";
else if ( TTL_MIMETYPE.equals(contentType.getMediaType()))
redirectURL = "/entityurl/entityurl.ttl";
}
else{
redirectURL = "/entityurl/entityrurl.rdf";
}
String hn = req.getHeader("Host");
if (req.isSecure()) {
res.setHeader("Location", res.encodeURL("https://" + hn
+ req.getContextPath() + redirectURL));
log.info("doRedirect by using HTTPS");
} else {
res.setHeader("Location", res.encodeURL("http://" + hn
+ req.getContextPath() + redirectURL));
log.info("doRedirect by using HTTP");
}
res.setStatus(res.SC_SEE_OTHER);
return;
}
String classUri = (String) getServletContext().getAttribute("classuri");
BooleanQuery query = new BooleanQuery();
query.add(
new TermQuery( new Term(VitroLuceneTermNames.RDFTYPE, classUri)),
BooleanClause.Occur.MUST );
IndexSearcher index = LuceneIndexFactory.getIndexSearcher(getServletContext());
TopDocs docs = index.search(query, null,
ENTITY_LIST_CONTROLLER_MAX_RESULTS,
new Sort(VitroLuceneTermNames.NAME_LOWERCASE));
if( docs == null ){
log.error("Search of lucene index returned null");
throw new ServletException("Search of lucene index returned null");
}
int ii = 0;
int size = docs.totalHits;
Resource resource = null;
RDFNode node = null;
Model model = ModelFactory.createDefaultModel();
while( ii < size ){
ScoreDoc hit = docs.scoreDocs[ii];
if (hit != null) {
Document doc = index.doc(hit.doc);
if (doc != null) {
String uri = doc.getField(VitroLuceneTermNames.URI).stringValue();
resource = ResourceFactory.createResource(uri);
node = (RDFNode) ResourceFactory.createResource(classUri);
model.add(resource, RDF.type, node);
} else {
log.warn("no document found for lucene doc id " + hit.doc);
}
} else {
log.debug("hit was null");
}
ii++;
}
String format = "";
if(contentType != null){
if ( RDFXML_MIMETYPE.equals(contentType.getMediaType()))
format = "RDF/XML";
else if( N3_MIMETYPE.equals(contentType.getMediaType()))
format = "N3";
else if ( TTL_MIMETYPE.equals(contentType.getMediaType()))
format ="TTL";
res.setContentType(contentType.getMediaType());
}
else{
res.setContentType(RDFXML_MIMETYPE);
format = "RDF/XML";
}
model.write(res.getOutputStream(), format);
}
public void doPost (HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException{
doGet(req,res);
}
protected ContentType checkForRequestType(String acceptHeader) {
try {
//check the accept header
if (acceptHeader != null) {
List<ContentType> actualContentTypes = new ArrayList<ContentType>();
actualContentTypes.add(new ContentType( XHTML_MIMETYPE ));
actualContentTypes.add(new ContentType( HTML_MIMETYPE ));
actualContentTypes.add(new ContentType( RDFXML_MIMETYPE ));
actualContentTypes.add(new ContentType( N3_MIMETYPE ));
actualContentTypes.add(new ContentType( TTL_MIMETYPE ));
ContentType best = ContentType.getBestContentType(acceptHeader,actualContentTypes);
if (best!=null && (
RDFXML_MIMETYPE.equals(best.getMediaType()) ||
N3_MIMETYPE.equals(best.getMediaType()) ||
TTL_MIMETYPE.equals(best.getMediaType()) ))
return best;
}
}
catch (Throwable th) {
log.error("problem while checking accept header " , th);
}
return null;
}
}

View file

@ -125,7 +125,7 @@ public class IndividualListController extends FreemarkerHttpServlet {
body.put("subtitle", vclass.getName());
}
body.put("title", title);
body.put("redirecturl", vreq.getContextPath()+"/entityurl/");
body.put("rdfUrl", vreq.getContextPath()+"/listrdf/");
getServletContext().setAttribute("classuri", vclass.getURI());
}

View file

@ -25,6 +25,7 @@ import org.apache.solr.common.SolrDocumentList;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
import edu.cornell.mannlib.vitro.webapp.controller.IndividualListRdfController;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ExceptionResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
@ -56,7 +57,6 @@ public class SolrIndividualListController extends FreemarkerHttpServlet {
String templateName = TEMPLATE_DEFAULT;
Map<String, Object> body = new HashMap<String, Object>();
String errorMessage = null;
String message = null;
try {
Object obj = vreq.getAttribute("vclass");
@ -72,7 +72,7 @@ public class SolrIndividualListController extends FreemarkerHttpServlet {
errorMessage = "Class " + vitroClassIdStr + " not found";
}
} catch (Exception ex) {
throw new HelpException("IndividualListController: request parameter 'vclassId' must be a URI string.");
throw new HelpException("IndividualListController: url parameter 'vclassId' must be a URI string.");
}
}
} else if (obj instanceof VClass) {
@ -95,14 +95,16 @@ public class SolrIndividualListController extends FreemarkerHttpServlet {
getServletContext());
body.putAll(map);
@SuppressWarnings("unchecked")
List<Individual> inds = (List<Individual>)map.get("entities");
List<ListedIndividualTemplateModel> indsTm = new ArrayList<ListedIndividualTemplateModel>();
for(Individual ind : inds ){
for ( Individual ind : inds ) {
indsTm.add(new ListedIndividualTemplateModel(ind,vreq));
}
body.put("individuals", indsTm);
List<TemplateModel> wpages = new ArrayList<TemplateModel>();
@SuppressWarnings("unchecked")
List<PageRecord> pages = (List<PageRecord>)body.get("pages");
BeansWrapper wrapper = new BeansWrapper();
for( PageRecord pr: pages ){
@ -119,10 +121,10 @@ public class SolrIndividualListController extends FreemarkerHttpServlet {
body.put("subtitle", vclass.getName());
}
body.put("title", title);
body.put("redirecturl", vreq.getContextPath()+"/entityurl/");
body.put("rdfUrl", vreq.getContextPath() + IndividualListRdfController.URL);
getServletContext().setAttribute("classuri", vclass.getURI());
}
} catch (HelpException help){
errorMessage = "Request attribute 'vclass' or request parameter 'vclassId' must be set before calling. Its value must be a class uri.";
} catch (Throwable e) {
@ -132,10 +134,8 @@ public class SolrIndividualListController extends FreemarkerHttpServlet {
if (errorMessage != null) {
templateName = Template.ERROR_MESSAGE.toString();
body.put("errorMessage", errorMessage);
} else if (message != null) {
body.put("message", message);
}
return new TemplateResponseValues(templateName, body);
}
@ -244,7 +244,7 @@ public class SolrIndividualListController extends FreemarkerHttpServlet {
int start = (page-1)*INDIVIDUALS_PER_PAGE;
query.setStart(start)
.setRows(INDIVIDUALS_PER_PAGE)
.setSortField("nameLowercaseSingleValued", SolrQuery.ORDER.asc);
.setSortField(VitroLuceneTermNames.NAME_LOWERCASE_SINGLE_VALUED, SolrQuery.ORDER.asc);
log.debug("Query: " + query);
return query;