NIHVIVO-2411 Refactor JsonServlet into a controller and a group of "plug-in classes".

This commit is contained in:
j2blake 2012-04-30 20:17:56 +00:00
parent 588fbcf0e7
commit 00dec66662
11 changed files with 665 additions and 437 deletions

View file

@ -0,0 +1,39 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.json;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONObject;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.PageDataGetterUtils;
/**
* Gets data based on data getter for page uri and returns in the form of Json objects
*/
public class GetDataForPage extends JsonObjectProducer {
private static final Log log = LogFactory.getLog(GetDataForPage.class);
protected GetDataForPage(VitroRequest vreq) {
super(vreq);
}
@Override
protected JSONObject process() throws Exception {
JSONObject rObj = null;
String pageUri = vreq.getParameter("pageUri");
if(pageUri != null && !pageUri.isEmpty()) {
Map<String,Object> data = PageDataGetterUtils.getDataForPage(pageUri, vreq, ctx);
//Convert to json version based on type of page
if(data != null) {
//Convert to json version based on type of page
rObj = PageDataGetterUtils.covertDataToJSONForPage(pageUri, data, vreq, ctx);
}
}
return rObj;
}
}

View file

@ -0,0 +1,125 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.json;
import static edu.cornell.mannlib.vitro.webapp.controller.json.JsonServlet.REPLY_SIZE;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import javax.servlet.ServletException;
import javax.servlet.http.HttpSession;
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.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.WebappDaoFactory;
/**
* Gets a list of entities that are members of the indicated vClass.
*
* If the list is large then we will pass some token indicating that there is more
* to come. The results are sent back in 250 entity blocks. To get all of the
* entities for a VClass just keep requesting lists until there are not more
* continue tokens.
*
* If there are more entities the last item on the returned array will be an object
* with no id property. It will look like this:
*
* {"resultGroup":0,
* "resultKey":"2WEK2306",
* "nextUrl":"http://caruso.mannlib.cornell.edu:8080/vitro/dataservice?getEntitiesByVClass=1&resultKey=2WEK2306&resultGroup=1&vclassId=null",
* "entsInVClass":1752,
* "nextResultGroup":1,
* "standardReplySize":256}
*
*/
public class GetEntitiesByVClass extends JsonArrayProducer {
private static final Log log = LogFactory.getLog(GetEntitiesByVClass.class);
protected GetEntitiesByVClass(VitroRequest vreq) {
super(vreq);
}
@Override
protected JSONArray process() throws ServletException {
log.debug("in getEntitiesByVClass()");
String vclassURI = vreq.getParameter("vclassURI");
WebappDaoFactory daos = vreq.getFullWebappDaoFactory();
if( vclassURI == null ){
throw new ServletException("getEntitiesByVClass(): no value for 'vclassURI' found in the HTTP request");
}
VClass vclass = daos.getVClassDao().getVClassByURI( vclassURI );
if( vclass == null ){
throw new ServletException("getEntitiesByVClass(): could not find vclass for uri '"+ vclassURI + "'");
}
List<Individual> entsInVClass = daos.getIndividualDao().getIndividualsByVClass( vclass );
if( entsInVClass == null ){
throw new ServletException("getEntitiesByVClass(): null List<Individual> retruned by getIndividualsByVClass() for "+vclassURI);
}
int numberOfEntsInVClass = entsInVClass.size();
List<Individual> entsToReturn = new ArrayList<Individual>( REPLY_SIZE );
String requestHash = null;
int count = 0;
boolean more = false;
/* we have a large number of items to send back so we need to stash the list in the session scope */
if( entsInVClass.size() > REPLY_SIZE){
more = true;
HttpSession session = vreq.getSession(true);
requestHash = Integer.toString((vclassURI + System.currentTimeMillis()).hashCode());
session.setAttribute(requestHash, entsInVClass );
ListIterator<Individual> entsFromVclass = entsInVClass.listIterator();
while ( entsFromVclass.hasNext() && count < REPLY_SIZE ){
entsToReturn.add( entsFromVclass.next());
entsFromVclass.remove();
count++;
}
if( log.isDebugEnabled() ){ log.debug("getEntitiesByVClass(): Creating reply with continue token, found " + numberOfEntsInVClass + " Individuals"); }
}else{
if( log.isDebugEnabled() ) log.debug("getEntitiesByVClass(): sending " + numberOfEntsInVClass +" Individuals without continue token");
entsToReturn = entsInVClass;
count = entsToReturn.size();
}
//put all the entities on the JSON array
JSONArray ja = individualsToJson( entsToReturn );
//put the responseGroup number on the end of the JSON array
if( more ){
try{
JSONObject obj = new JSONObject();
obj.put("resultGroup", "true");
obj.put("size", count);
obj.put("total", numberOfEntsInVClass);
StringBuffer nextUrlStr = vreq.getRequestURL();
nextUrlStr.append("?")
.append("getEntitiesByVClass").append( "=1&" )
.append("resultKey=").append( requestHash );
obj.put("nextUrl", nextUrlStr.toString());
ja.put(obj);
}catch(JSONException je ){
throw new ServletException("unable to create continuation as JSON: " + je.getMessage());
}
}
log.debug("done with getEntitiesByVClass()");
return ja;
}
}

View file

@ -0,0 +1,96 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.json;
import static edu.cornell.mannlib.vitro.webapp.controller.json.JsonServlet.REPLY_SIZE;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import javax.servlet.ServletException;
import javax.servlet.http.HttpSession;
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.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
/**
*
*/
public class GetEntitiesByVClassContinuation extends JsonArrayProducer {
private static final Log log = LogFactory
.getLog(GetEntitiesByVClassContinuation.class);
protected GetEntitiesByVClassContinuation(VitroRequest vreq) {
super(vreq);
}
@Override
protected JSONArray process() throws ServletException {
log.debug("in getEntitiesByVClassContinuation()");
String resKey = vreq.getParameter("resultKey");
if( resKey == null )
throw new ServletException("Could not get resultKey");
HttpSession session = vreq.getSession();
if( session == null )
throw new ServletException("there is no session to get the pervious results from");
@SuppressWarnings("unchecked")
List<Individual> entsInVClass = (List<Individual>) session.getAttribute(resKey);
if( entsInVClass == null )
throw new ServletException("Could not find List<Individual> for resultKey " + resKey);
List<Individual> entsToReturn = new ArrayList<Individual>(REPLY_SIZE);
boolean more = false;
int count = 0;
/* we have a large number of items to send back so we need to stash the list in the session scope */
if( entsInVClass.size() > REPLY_SIZE){
more = true;
ListIterator<Individual> entsFromVclass = entsInVClass.listIterator();
while ( entsFromVclass.hasNext() && count <= REPLY_SIZE ){
entsToReturn.add( entsFromVclass.next());
entsFromVclass.remove();
count++;
}
if( log.isDebugEnabled() ) log.debug("getEntitiesByVClassContinuation(): Creating reply with continue token," +
" sending in this reply: " + count +", remaing to send: " + entsInVClass.size() );
} else {
//send out reply with no continuation
entsToReturn = entsInVClass;
count = entsToReturn.size();
session.removeAttribute(resKey);
if( log.isDebugEnabled()) log.debug("getEntitiesByVClassContinuation(): sending " + count + " Ind without continue token");
}
//put all the entities on the JSON array
JSONArray ja = individualsToJson( entsToReturn );
//put the responseGroup number on the end of the JSON array
if( more ){
try{
JSONObject obj = new JSONObject();
obj.put("resultGroup", "true");
obj.put("size", count);
StringBuffer nextUrlStr = vreq.getRequestURL();
nextUrlStr.append("?")
.append("getEntitiesByVClass").append( "=1&" )
.append("resultKey=").append( resKey );
obj.put("nextUrl", nextUrlStr.toString());
ja.put(obj);
}catch(JSONException je ){
throw new ServletException(je.getMessage());
}
}
log.debug("done with getEntitiesByVClassContinuation()");
return ja;
}
}

View file

@ -0,0 +1,42 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.json;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONObject;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
/**
*
*/
public class GetSolrIndividualsByVClass extends JsonObjectProducer {
private static final Log log = LogFactory
.getLog(GetSolrIndividualsByVClass.class);
protected GetSolrIndividualsByVClass(VitroRequest vreq) {
super(vreq);
}
@Override
protected JSONObject process() throws Exception {
VClass vclass=null;
String vitroClassIdStr = vreq.getParameter("vclassId");
if ( vitroClassIdStr != null && !vitroClassIdStr.isEmpty()){
vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vitroClassIdStr);
if (vclass == null) {
log.debug("Couldn't retrieve vclass ");
throw new Exception ("Class " + vitroClassIdStr + " not found");
}
}else{
log.debug("parameter vclassId URI parameter expected ");
throw new Exception("parameter vclassId URI parameter expected ");
}
vreq.setAttribute("displayType", vitroClassIdStr);
return JsonServlet.getSolrIndividualsByVClass(vclass.getURI(), vreq, ctx);
}
}

View file

@ -0,0 +1,51 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.json;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONObject;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
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 {
private static final Log log = LogFactory
.getLog(GetSolrIndividualsByVClasses.class);
public GetSolrIndividualsByVClasses(VitroRequest vreq) {
super(vreq);
}
@Override
protected JSONObject process() throws Exception {
log.debug("Executing retrieval of individuals by vclasses");
VClass vclass=null;
log.debug("Retrieving solr individuals by vclasses");
// Could have multiple vclass ids sent in
String[] vitroClassIdStr = vreq.getParameterValues("vclassId");
if ( vitroClassIdStr != null && vitroClassIdStr.length > 0){
for(String vclassId: vitroClassIdStr) {
log.debug("Iterating throug vclasses, using VClass " + vclassId);
vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vclassId);
if (vclass == null) {
log.error("Couldn't retrieve vclass ");
throw new Exception ("Class " + vclassId + " not found");
}
}
}else{
log.error("parameter vclassId URI parameter expected but not found");
throw new Exception("parameter vclassId URI parameter expected ");
}
List<String> vclassIds = Arrays.asList(vitroClassIdStr);
return JsonServlet.getSolrIndividualsByVClasses(vclassIds, vreq, ctx);
}
}

View file

@ -0,0 +1,56 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.json;
import java.util.ArrayList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONObject;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache;
/**
*
*/
public class GetVClassesForVClassGroup extends JsonObjectProducer {
private static final Log log = LogFactory
.getLog(GetVClassesForVClassGroup.class);
public GetVClassesForVClassGroup(VitroRequest vreq) {
super(vreq);
}
@Override
protected JSONObject process() throws Exception {
JSONObject map = new JSONObject();
String vcgUri = vreq.getParameter("classgroupUri");
if( vcgUri == null ){
throw new Exception("no URI passed for classgroupUri");
}
VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(ctx);
VClassGroup vcg = vcgc.getGroup(vcgUri);
if( vcg == null ){
throw new Exception("Could not find vclassgroup: " + vcgUri);
}
ArrayList<JSONObject> classes = new ArrayList<JSONObject>(vcg.size());
for( VClass vc : vcg){
JSONObject vcObj = new JSONObject();
vcObj.put("name", vc.getName());
vcObj.put("URI", vc.getURI());
vcObj.put("entityCount", vc.getEntityCount());
classes.add(vcObj);
}
map.put("classes", classes);
map.put("classGroupName", vcg.getPublicName());
map.put("classGroupUri", vcg.getURI());
return map;
}
}

View file

@ -0,0 +1,60 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.json;
import java.io.IOException;
import java.io.Writer;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
/**
* A base for classes that produce a JSON array based on the parameters in the
* VitroRequest.
*
* Catches any exceptions. Logs the error and returns an empty JSON array.
*/
public abstract class JsonArrayProducer extends JsonProducer {
private static final Log log = LogFactory.getLog(JsonArrayProducer.class);
protected final VitroRequest vreq;
protected final ServletContext ctx;
protected JsonArrayProducer(VitroRequest vreq) {
this.vreq = vreq;
this.ctx = vreq.getSession().getServletContext();
}
/**
* Sub-classes implement this method. Given the request, produce a JSON
* object as the result.
*/
protected abstract JSONArray process() throws Exception;
public final void process(HttpServletResponse resp) throws IOException {
JSONArray jsonArray = null;
try {
jsonArray = process();
} catch (Exception e) {
log.error("Failed to create JSON response" + e);
resp.setStatus(500 /* HttpURLConnection.HTTP_SERVER_ERROR */);
}
if (jsonArray == null) {
jsonArray = new JSONArray();
}
log.debug("Response to JSON request: " + jsonArray.toString());
resp.setCharacterEncoding("UTF-8");
resp.setContentType("application/json;charset=UTF-8");
Writer writer = resp.getWriter();
writer.write(jsonArray.toString());
}
}

View file

@ -0,0 +1,76 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.json;
import java.io.IOException;
import java.io.Writer;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import org.json.JSONObject;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
/**
* A base for classes that produce a JSON object, based on the parameters in the
* request.
*
* The result is never empty. At worst, it is an object that contains only an
* "errorMessage" field.
*
* If an exception occurrs during processing, The "errorMessage" field will
* contain the exception message and the response status will be set to 500
* (server error). Normally, "errorMessage" will be empty, and the status will
* default to 200 (OK).
*/
public abstract class JsonObjectProducer extends JsonProducer {
private static final Log log = LogFactory.getLog(JsonObjectProducer.class);
protected final VitroRequest vreq;
protected final ServletContext ctx;
protected JsonObjectProducer(VitroRequest vreq) {
this.vreq = vreq;
this.ctx = vreq.getSession().getServletContext();
}
/**
* Sub-classes implement this method. Given the request, produce a JSON
* object as the result.
*/
protected abstract JSONObject process() throws Exception;
public final void process(HttpServletResponse resp) throws IOException {
JSONObject jsonObject = null;
String errorMessage = "";
try {
jsonObject = process();
} catch (Exception e) {
log.error("Failed to create JSON response" + e);
errorMessage = e.toString();
resp.setStatus(500 /* HttpURLConnection.HTTP_SERVER_ERROR */);
}
if (jsonObject == null) {
jsonObject = new JSONObject();
}
log.debug("Response to JSON request: " + jsonObject.toString());
try {
resp.setCharacterEncoding("UTF-8");
resp.setContentType("application/json;charset=UTF-8");
Writer writer = resp.getWriter();
jsonObject.put("errorMessage", errorMessage);
writer.write(jsonObject.toString());
} catch (JSONException e) {
log.error(e, e);
}
}
}

View file

@ -0,0 +1,89 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.json;
import java.util.Arrays;
import java.util.List;
import javax.servlet.ServletException;
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.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
/**
* A base for the classes that produce JSON results. Contains some useful constants and convenience methods.
*/
public abstract class JsonProducer {
private static final Log log = LogFactory.getLog(JsonProducer.class);
/**
* Process a list of Individuals into a JSON array that holds the Names and URIs.
*/
protected JSONArray individualsToJson(List<Individual> individuals) throws ServletException {
try{
JSONArray ja = new JSONArray();
for (Individual ent: individuals) {
JSONObject entJ = new JSONObject();
entJ.put("name", ent.getName());
entJ.put("URI", ent.getURI());
ja.put( entJ );
}
return ja;
}catch(JSONException ex){
throw new ServletException("could not convert list of Individuals into JSON: " + ex);
}
}
/**
* Get the "vclassId" parameter from the request and instantiate the VClass.
*
* There must be one, and it must be valid.
*/
protected VClass getVclassParameter(VitroRequest vreq) {
String vclassId = vreq.getParameter("vclassId");
if (StringUtils.isEmpty(vclassId)) {
log.error("parameter vclassId expected but not found");
throw new IllegalStateException("parameter vclassId expected ");
}
return instantiateVclass(vclassId, vreq);
}
/**
* Get one or more "vclassId" parameters from the request. Confirm that
* there is at least one, and that all are valid.
*
* Return value is never null and never empty.
*/
protected List<String> getVclassIds(VitroRequest vreq) {
String[] vclassIds = vreq.getParameterValues("vclassId");
if ((vclassIds == null) || (vclassIds.length == 0)) {
log.error("parameter vclassId expected but not found");
throw new IllegalStateException("parameter vclassId expected ");
}
for (String vclassId : vclassIds) {
instantiateVclass(vclassId, vreq);
}
return Arrays.asList(vclassIds);
}
private VClass instantiateVclass(String uri, VitroRequest vreq) {
VClass vclass = vreq.getWebappDaoFactory().getVClassDao()
.getVClassByURI(uri);
if (vclass == null) {
log.error("Couldn't retrieve vclass ");
throw new IllegalStateException("Class " + uri + " not found");
}
return vclass;
}
}

View file

@ -2,48 +2,29 @@
package edu.cornell.mannlib.vitro.webapp.controller.json;
import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.DISPLAY_ONT_MODEL;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
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 com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController;
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.SelectListGenerator;
import edu.cornell.mannlib.vitro.webapp.search.beans.ProhibitedFromSearch;
import edu.cornell.mannlib.vitro.webapp.utils.log.LogUtils;
import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.PageDataGetterUtils;
/**
@ -53,11 +34,10 @@ import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.PageDataGetterUtils
*
*/
public class JsonServlet extends VitroHttpServlet {
private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(JsonServlet.class);
private static final int REPLY_SIZE = 256;
private static final int INDIVIDUALS_PER_PAGE = 30;
public static final int REPLY_SIZE = 256;
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
@ -67,106 +47,34 @@ public class JsonServlet extends VitroHttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
VitroRequest vreq = new VitroRequest(req);
log.debug(LogUtils.formatRequestProperties(log, "debug", req));
try{
if(vreq.getParameter("getEntitiesByVClass") != null ){
VitroRequest vreq = new VitroRequest(req);
if (vreq.getParameter("getEntitiesByVClass") != null) {
if( vreq.getParameter("resultKey") == null) {
getEntitiesByVClass(req, resp);
return;
new GetEntitiesByVClass(vreq).process(resp);
} else {
getEntitiesByVClassContinuation( req, resp);
return;
new GetEntitiesByVClassContinuation(vreq).process(resp);
}
}else if( vreq.getParameter("getN3EditOptionList") != null ){
doN3EditOptionList(req,resp);
return;
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 ){
getSolrIndividualsByVClass(req,resp);
return;
new GetSolrIndividualsByVClass(vreq).process(resp);
}else if( vreq.getParameter("getVClassesForVClassGroup") != null ){
getVClassesForVClassGroup(req,resp);
return;
new GetVClassesForVClassGroup(vreq).process(resp);
} else if( vreq.getParameter("getSolrIndividualsByVClasses") != null ){
log.debug("AJAX request to retrieve individuals by vclasses");
getSolrIndividualsByVClasses(req,resp);
return;
new GetSolrIndividualsByVClasses(vreq).process(resp);
} else if( vreq.getParameter("getDataForPage") != null ){
getDataForPage(req,resp);
return;
}
}catch(Exception ex){
log.warn(ex,ex);
new GetDataForPage(vreq).process(resp);
// }else if( vreq.getParameter("getRenderedSolrIndividualsByVClass") != null ){
// new GetRenderedSolrIndividualsByVClass(vreq).process(resp);
}
}
private void getVClassesForVClassGroup(HttpServletRequest req, HttpServletResponse resp) throws IOException, JSONException {
JSONObject map = new JSONObject();
VitroRequest vreq = new VitroRequest(req);
String vcgUri = vreq.getParameter("classgroupUri");
if( vcgUri == null ){
log.debug("no URI passed for classgroupUri");
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(getServletContext());
VClassGroup vcg = vcgc.getGroup(vcgUri);
if( vcg == null ){
log.debug("Could not find vclassgroup: " + vcgUri);
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
ArrayList<JSONObject> classes = new ArrayList<JSONObject>(vcg.size());
for( VClass vc : vcg){
JSONObject vcObj = new JSONObject();
vcObj.put("name", vc.getName());
vcObj.put("URI", vc.getURI());
vcObj.put("entityCount", vc.getEntityCount());
classes.add(vcObj);
}
map.put("classes", classes);
map.put("classGroupName", vcg.getPublicName());
map.put("classGroupUri", vcg.getURI());
resp.setCharacterEncoding("UTF-8");
resp.setContentType("application/json;charset=UTF-8");
Writer writer = resp.getWriter();
writer.write(map.toString());
}
private void getSolrIndividualsByVClass( HttpServletRequest req, HttpServletResponse resp ){
String errorMessage = null;
JSONObject rObj = null;
try{
VitroRequest vreq = new VitroRequest(req);
VClass vclass=null;
String vitroClassIdStr = vreq.getParameter("vclassId");
if ( vitroClassIdStr != null && !vitroClassIdStr.isEmpty()){
vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vitroClassIdStr);
if (vclass == null) {
log.debug("Couldn't retrieve vclass ");
throw new Exception (errorMessage = "Class " + vitroClassIdStr + " not found");
}
}else{
log.debug("parameter vclassId URI parameter expected ");
throw new Exception("parameter vclassId URI parameter expected ");
}
vreq.setAttribute("displayType", vitroClassIdStr);
rObj = getSolrIndividualsByVClass(vclass.getURI(),req, getServletContext());
}catch(Exception ex){
errorMessage = ex.toString();
log.error(ex,ex);
}
writeJsonResponse(rObj, errorMessage, resp);
}
public static JSONObject getSolrIndividualsByVClass(String vclassURI, HttpServletRequest req, ServletContext context) throws Exception {
List<String> vclassURIs = Collections.singletonList(vclassURI);
VitroRequest vreq = new VitroRequest(req);
@ -176,41 +84,6 @@ public class JsonServlet extends VitroHttpServlet {
return processVClassResults(map, vreq, context, false);
}
// Accepts multiple vclasses and returns individuals which correspond to the intersection of those classes (i.e. have all those types)
private void getSolrIndividualsByVClasses( HttpServletRequest req, HttpServletResponse resp ){
log.debug("Executing retrieval of individuals by vclasses");
String errorMessage = null;
JSONObject rObj = null;
try{
VitroRequest vreq = new VitroRequest(req);
VClass vclass=null;
log.debug("Retrieving solr individuals by vclasses");
// Could have multiple vclass ids sent in
String[] vitroClassIdStr = vreq.getParameterValues("vclassId");
if ( vitroClassIdStr != null && vitroClassIdStr.length > 0){
for(String vclassId: vitroClassIdStr) {
log.debug("Iterating throug vclasses, using VClass " + vclassId);
vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vclassId);
if (vclass == null) {
log.error("Couldn't retrieve vclass ");
throw new Exception (errorMessage = "Class " + vclassId + " not found");
}
}
}else{
log.error("parameter vclassId URI parameter expected but not found");
throw new Exception("parameter vclassId URI parameter expected ");
}
List<String> vclassIds = Arrays.asList(vitroClassIdStr);
rObj = getSolrIndividualsByVClasses(vclassIds,req, getServletContext());
}catch(Exception ex){
errorMessage = ex.toString();
log.error(ex,ex);
}
writeJsonResponse(rObj, errorMessage, resp);
}
public static JSONObject getSolrIndividualsByVClasses(List<String> vclassURIs, HttpServletRequest req, ServletContext context) throws Exception {
VitroRequest vreq = new VitroRequest(req);
log.debug("Retrieve solr results for vclasses" + vclassURIs.toString());
@ -247,7 +120,6 @@ public class JsonServlet extends VitroHttpServlet {
return rObj;
}
public static Collection<String> getMostSpecificTypes(Individual individual, WebappDaoFactory wdf) {
ObjectPropertyStatementDao opsDao = wdf.getObjectPropertyStatementDao();
Map<String, String> mostSpecificTypes = opsDao.getMostSpecificTypesInClassgroupsForIndividual(individual.getURI());
@ -262,289 +134,7 @@ public class JsonServlet extends VitroHttpServlet {
return value;
}
/**
* Gets an option list for a given EditConfiguration and Field.
* Requires following HTTP query parameters:
* editKey
* field
*/
private void doN3EditOptionList(HttpServletRequest req, HttpServletResponse resp) throws IOException {
log.debug("in doN3EditOptionList()");
String field = req.getParameter("field");
if( field == null ){
log.debug("could not find query parameter 'field' for doN3EditOptionList");
throw new IllegalArgumentException(" getN3EditOptionList requires parameter 'field'");
}
HttpSession sess = req.getSession(false);
EditConfiguration editConfig = EditConfiguration.getConfigFromSession(sess, req);
if( editConfig == null ) {
log.debug("could not find query parameter 'editKey' for doN3EditOptionList");
throw new IllegalArgumentException(" getN3EditOptionList requires parameter 'editKey'");
}
if( log.isDebugEnabled() )
log.debug(" attempting to get option list for field '" + field + "'");
// set ProhibitedFromSearch object so picklist doesn't show
// individuals from classes that should be hidden from list views
OntModel displayOntModel =
(OntModel) getServletConfig().getServletContext().getAttribute(DISPLAY_ONT_MODEL);
if (displayOntModel != null) {
ProhibitedFromSearch pfs = new ProhibitedFromSearch(
DisplayVocabulary.SEARCH_INDEX_URI, displayOntModel);
editConfig.setProhibitedFromSearch(pfs);
}
Map<String,String> options = SelectListGenerator.getOptions(editConfig, field, (new VitroRequest(req)).getFullWebappDaoFactory());
resp.setCharacterEncoding("UTF-8");
resp.setContentType("application/json;charset=UTF-8");
ServletOutputStream out = resp.getOutputStream();
out.println("[");
for(String key : options.keySet()){
JSONArray jsonObj = new JSONArray();
jsonObj.put( options.get(key));
jsonObj.put( key);
out.println(" " + jsonObj.toString() + ",");
}
out.println("]");
}
private void getEntitiesByVClassContinuation(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
log.debug("in getEntitiesByVClassContinuation()");
VitroRequest vreq = new VitroRequest(req);
String resKey = vreq.getParameter("resultKey");
if( resKey == null )
throw new ServletException("Could not get resultKey");
HttpSession session = vreq.getSession();
if( session == null )
throw new ServletException("there is no session to get the pervious results from");
@SuppressWarnings("unchecked")
List<Individual> entsInVClass = (List<Individual>) session.getAttribute(resKey);
if( entsInVClass == null )
throw new ServletException("Could not find List<Individual> for resultKey " + resKey);
List<Individual> entsToReturn = new ArrayList<Individual>(REPLY_SIZE);
boolean more = false;
int count = 0;
/* we have a large number of items to send back so we need to stash the list in the session scope */
if( entsInVClass.size() > REPLY_SIZE){
more = true;
ListIterator<Individual> entsFromVclass = entsInVClass.listIterator();
while ( entsFromVclass.hasNext() && count <= REPLY_SIZE ){
entsToReturn.add( entsFromVclass.next());
entsFromVclass.remove();
count++;
}
if( log.isDebugEnabled() ) log.debug("getEntitiesByVClassContinuation(): Creating reply with continue token," +
" sending in this reply: " + count +", remaing to send: " + entsInVClass.size() );
} else {
//send out reply with no continuation
entsToReturn = entsInVClass;
count = entsToReturn.size();
session.removeAttribute(resKey);
if( log.isDebugEnabled()) log.debug("getEntitiesByVClassContinuation(): sending " + count + " Ind without continue token");
}
//put all the entities on the JSON array
JSONArray ja = individualsToJson( entsToReturn );
//put the responseGroup number on the end of the JSON array
if( more ){
try{
JSONObject obj = new JSONObject();
obj.put("resultGroup", "true");
obj.put("size", count);
StringBuffer nextUrlStr = req.getRequestURL();
nextUrlStr.append("?")
.append("getEntitiesByVClass").append( "=1&" )
.append("resultKey=").append( resKey );
obj.put("nextUrl", nextUrlStr.toString());
ja.put(obj);
}catch(JSONException je ){
throw new ServletException(je.getMessage());
}
}
resp.setCharacterEncoding("UTF-8");
resp.setContentType("application/json;charset=UTF-8");
ServletOutputStream out = resp.getOutputStream();
out.print( ja.toString() );
log.debug("done with getEntitiesByVClassContinuation()");
}
/**
* Gets a list of entities that are members of the indicated vClass.
*
* If the list is large then we will pass some token indicating that there is more
* to come. The results are sent back in 250 entity blocks. To get all of the
* entities for a VClass just keep requesting lists until there are not more
* continue tokens.
*
* If there are more entities the last item on the returned array will be an object
* with no id property. It will look like this:
*
* {"resultGroup":0,
* "resultKey":"2WEK2306",
* "nextUrl":"http://caruso.mannlib.cornell.edu:8080/vitro/dataservice?getEntitiesByVClass=1&resultKey=2WEK2306&resultGroup=1&vclassId=null",
* "entsInVClass":1752,
* "nextResultGroup":1,
* "standardReplySize":256}
*
*/
private void getEntitiesByVClass(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException{
log.debug("in getEntitiesByVClass()");
VitroRequest vreq = new VitroRequest(req);
String vclassURI = vreq.getParameter("vclassURI");
WebappDaoFactory daos = (new VitroRequest(req)).getFullWebappDaoFactory();
resp.setCharacterEncoding("UTF-8");
PrintWriter out = resp.getWriter();
resp.getWriter();
if( vclassURI == null ){
log.debug("getEntitiesByVClass(): no value for 'vclassURI' found in the HTTP request");
out.print( (new JSONArray()).toString() ); return;
}
VClass vclass = daos.getVClassDao().getVClassByURI( vclassURI );
if( vclass == null ){
log.debug("getEntitiesByVClass(): could not find vclass for uri '"+ vclassURI + "'");
out.print( (new JSONArray()).toString() ); return;
}
List<Individual> entsInVClass = daos.getIndividualDao().getIndividualsByVClass( vclass );
if( entsInVClass == null ){
log.debug("getEntitiesByVClass(): null List<Individual> retruned by getIndividualsByVClass() for "+vclassURI);
out.print( (new JSONArray().toString() )); return ;
}
int numberOfEntsInVClass = entsInVClass.size();
List<Individual> entsToReturn = new ArrayList<Individual>( REPLY_SIZE );
String requestHash = null;
int count = 0;
boolean more = false;
/* we have a large number of items to send back so we need to stash the list in the session scope */
if( entsInVClass.size() > REPLY_SIZE){
more = true;
HttpSession session = vreq.getSession(true);
requestHash = Integer.toString((vclassURI + System.currentTimeMillis()).hashCode());
session.setAttribute(requestHash, entsInVClass );
ListIterator<Individual> entsFromVclass = entsInVClass.listIterator();
while ( entsFromVclass.hasNext() && count < REPLY_SIZE ){
entsToReturn.add( entsFromVclass.next());
entsFromVclass.remove();
count++;
}
if( log.isDebugEnabled() ){ log.debug("getEntitiesByVClass(): Creating reply with continue token, found " + numberOfEntsInVClass + " Individuals"); }
}else{
if( log.isDebugEnabled() ) log.debug("getEntitiesByVClass(): sending " + numberOfEntsInVClass +" Individuals without continue token");
entsToReturn = entsInVClass;
count = entsToReturn.size();
}
//put all the entities on the JSON array
JSONArray ja = individualsToJson( entsToReturn );
//put the responseGroup number on the end of the JSON array
if( more ){
try{
JSONObject obj = new JSONObject();
obj.put("resultGroup", "true");
obj.put("size", count);
obj.put("total", numberOfEntsInVClass);
StringBuffer nextUrlStr = req.getRequestURL();
nextUrlStr.append("?")
.append("getEntitiesByVClass").append( "=1&" )
.append("resultKey=").append( requestHash );
obj.put("nextUrl", nextUrlStr.toString());
ja.put(obj);
}catch(JSONException je ){
throw new ServletException("unable to create continuation as JSON: " + je.getMessage());
}
}
resp.setContentType("application/json;charset=UTF-8");
out.print( ja.toString() );
log.debug("done with getEntitiesByVClass()");
}
/**
* Gets data based on data getter for page uri and returns in the form of Json objects
* @param req
* @param resp
*/
private void getDataForPage(HttpServletRequest req, HttpServletResponse resp)
throws Exception{
VitroRequest vreq = new VitroRequest(req);
String errorMessage = null;
JSONObject rObj = null;
String pageUri = vreq.getParameter("pageUri");
if(pageUri != null && !pageUri.isEmpty()) {
ServletContext context = getServletContext();
Map<String,Object> data = PageDataGetterUtils.getDataForPage(pageUri, vreq, context);
//Convert to json version based on type of page
if(data != null) {
//Convert to json version based on type of page
rObj = PageDataGetterUtils.covertDataToJSONForPage(pageUri, data, vreq, context);
}
}
writeJsonResponse(rObj, errorMessage, resp);
}
private JSONArray individualsToJson(List<Individual> individuals) throws ServletException {
try{
JSONArray ja = new JSONArray();
for (Individual ent: individuals) {
JSONObject entJ = new JSONObject();
entJ.put("name", ent.getName());
entJ.put("URI", ent.getURI());
ja.put( entJ );
}
return ja;
}catch(JSONException ex){
throw new ServletException("could not convert list of Individuals into JSON: " + ex);
}
}
private void writeJsonResponse(JSONObject rObj, String errorMessage,
HttpServletResponse resp) {
if( rObj == null ) {
rObj = new JSONObject();
}
try{
resp.setCharacterEncoding("UTF-8");
resp.setContentType("application/json;charset=UTF-8");
if( errorMessage != null ){
rObj.put("errorMessage", errorMessage);
resp.setStatus(500 /*HttpURLConnection.HTTP_SERVER_ERROR*/);
}else{
rObj.put("errorMessage", "");
}
Writer writer = resp.getWriter();
writer.write(rObj.toString());
}catch(JSONException jse){
log.error(jse,jse);
} catch (IOException e) {
log.error(e,e);
}
}
}

View file

@ -126,9 +126,11 @@ public class JsonServletTest extends AbstractTestClass {
@Test
public void vclassesNoClassgroup() throws ServletException, IOException {
setLoggerLevel(JsonServlet.class, Level.FATAL);
setLoggerLevel(JsonObjectProducer.class, Level.FATAL);
req.addParameter(GET_VCLASSES_FOR_VCLASS_GROUP, "true");
servlet.service(req, resp);
assertEquals("empty response", "", resp.getOutput());
assertFailureWithErrorMessage("java.lang.Exception: no URI passed for classgroupUri");
assertEquals("status=failure", SC_INTERNAL_SERVER_ERROR,
resp.getStatus());
}
@ -160,6 +162,7 @@ public class JsonServletTest extends AbstractTestClass {
public void individualsByClassNoVClass() throws ServletException,
IOException {
setLoggerLevel(JsonServlet.class, Level.FATAL);
setLoggerLevel(JsonObjectProducer.class, Level.FATAL);
req.addParameter(GET_SOLR_INDIVIDUALS_BY_VCLASS, "true");
servlet.service(req, resp);
assertFailureWithErrorMessage("java.lang.Exception: "
@ -170,6 +173,7 @@ public class JsonServletTest extends AbstractTestClass {
public void individualsByClassUnrecognizedVClass() throws ServletException,
IOException {
setLoggerLevel(JsonServlet.class, Level.FATAL);
setLoggerLevel(JsonObjectProducer.class, Level.FATAL);
String vclassId = "http://bogusVclass";
req.addParameter(GET_SOLR_INDIVIDUALS_BY_VCLASS, "true");
req.addParameter(VCLASS_ID, vclassId);