diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/JSONServlet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/JSONServlet.java index 5494938c2..809b112e0 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/JSONServlet.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/JSONServlet.java @@ -6,6 +6,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.io.Writer; import java.net.URLEncoder; +import java.util.Arrays; import java.util.ArrayList; import java.util.Enumeration; import java.util.Iterator; @@ -43,6 +44,8 @@ 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.pageDataGetter.IndividualsForClassesDataGetter; +import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.DataGetterUtils; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.IndividualTemplateModel; /** @@ -81,6 +84,12 @@ public class JSONServlet extends VitroHttpServlet { }else if( vreq.getParameter("getVClassesForVClassGroup") != null ){ getVClassesForVClassGroup(req,resp); return; + } else if( vreq.getParameter("getSolrIndividualsByVClasses") != null ){ + getSolrIndividualsByVClasses(req,resp); + return; + } else if( vreq.getParameter("getDataForPage") != null ){ + getDataForPage(req,resp); + return; } }catch(Exception ex){ log.warn(ex,ex); @@ -171,118 +180,121 @@ public class JSONServlet extends VitroHttpServlet { } + //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 ){ + String errorMessage = null; + JSONObject rObj = null; + try{ + VitroRequest vreq = new VitroRequest(req); + VClass vclass=null; + + //Could have multiple vclass Ids sent in + List vclassIds = new ArrayList(); + String[] vitroClassIdStr = vreq.getParameterValues("vclassId"); + if ( vitroClassIdStr != null && vitroClassIdStr.length > 0){ + for(String vclassId: vitroClassIdStr) { + vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vclassId); + if (vclass == null) { + log.debug("Couldn't retrieve vclass "); + throw new Exception (errorMessage = "Class " + vclassId + " not found"); + } + } + }else{ + log.debug("parameter vclassId URI parameter expected "); + throw new Exception("parameter vclassId URI parameter expected "); + } + vclassIds = Arrays.asList(vitroClassIdStr); + //rObj = getLuceneIndividualsByVClass(vclass.getURI(),req, getServletContext()); + rObj = getSolrIndividualsByVClasses(vclassIds,req, getServletContext()); + }catch(Exception ex){ + errorMessage = ex.toString(); + log.error(ex,ex); + } + + 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); + } + } + public static JSONObject getLuceneIndividualsByVClass(String vclassURI, HttpServletRequest req, ServletContext context) throws Exception { VitroRequest vreq = new VitroRequest(req); - VClass vclass=null; - JSONObject rObj = new JSONObject(); - - DataProperty fNameDp = (new DataProperty()); - fNameDp.setURI("http://xmlns.com/foaf/0.1/firstName"); - DataProperty lNameDp = (new DataProperty()); - lNameDp.setURI("http://xmlns.com/foaf/0.1/lastName"); - DataProperty monikerDp = (new DataProperty()); - monikerDp.setURI( VitroVocabulary.MONIKER); - //this property is vivo specific - DataProperty preferredTitleDp = (new DataProperty()); - preferredTitleDp.setURI("http://vivoweb.org/ontology/core#preferredTitle"); - - - if( log.isDebugEnabled() ){ - Enumeration e = vreq.getParameterNames(); - while(e.hasMoreElements()){ - String name = (String)e.nextElement(); - log.debug("parameter: " + name); - for( String value : vreq.getParameterValues(name) ){ - log.debug("value for " + name + ": '" + value + "'"); - } - } - } - - //need an unfiltered dao to get firstnames and lastnames - WebappDaoFactory fullWdf = vreq.getFullWebappDaoFactory(); - - - 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 "); - } - - rObj.put("vclass", - new JSONObject().put("URI",vclass.getURI()) - .put("name",vclass.getName())); - - if (vclass != null) { - String alpha = IndividualListController.getAlphaParameter(vreq); - int page = IndividualListController.getPageParameter(vreq); - Map map = IndividualListController.getResultsForVClass( - vclass.getURI(), - page, - alpha, - vreq.getWebappDaoFactory().getIndividualDao(), - context); - - rObj.put("totalCount", map.get("totalCount")); - rObj.put("alpha", map.get("alpha")); - - List inds = (List)map.get("entities"); - - JSONArray jInds = new JSONArray(); - for(Individual ind : inds ){ - JSONObject jo = new JSONObject(); - jo.put("URI", ind.getURI()); - jo.put("label",ind.getRdfsLabel()); - jo.put("name",ind.getName()); - jo.put("thumbUrl", ind.getThumbUrl()); - jo.put("imageUrl", ind.getImageUrl()); - jo.put("profileUrl", UrlBuilder.getIndividualProfileUrl(ind, vreq.getWebappDaoFactory())); - - String moniker = getDataPropertyValue(ind, monikerDp, fullWdf); - jo.put("moniker", moniker); - jo.put("vclassName", getVClassName(ind,moniker,fullWdf)); - - jo.put("preferredTitle", getDataPropertyValue(ind, preferredTitleDp, fullWdf)); - jo.put("firstName", getDataPropertyValue(ind, fNameDp, fullWdf)); - jo.put("lastName", getDataPropertyValue(ind, lNameDp, fullWdf)); - - jInds.put(jo); - } - rObj.put("individuals", jInds); - - JSONArray wpages = new JSONArray(); - List pages = (List)map.get("pages"); - for( PageRecord pr: pages ){ - JSONObject p = new JSONObject(); - p.put("text", pr.text); - p.put("param", pr.param); - p.put("index", pr.index); - wpages.put( p ); - } - rObj.put("pages",wpages); - - JSONArray jletters = new JSONArray(); - List letters = Controllers.getLetters(); - for( String s : letters){ - JSONObject jo = new JSONObject(); - jo.put("text", s); - jo.put("param", "alpha=" + URLEncoder.encode(s, "UTF-8")); - jletters.put( jo ); - } - rObj.put("letters", jletters); - } - + Map map = getLuceneVclassResults(vclassURI, vreq, context); + //Last parameter defines whether single or multiple vclasses expected + JSONObject rObj = processVclassResults(map, vreq, context, false); return rObj; } - - private static String getVClassName(Individual ind, String moniker, + public static JSONObject getSolrIndividualsByVClasses(List vclassURIs, HttpServletRequest req, ServletContext context) throws Exception { + VitroRequest vreq = new VitroRequest(req); + Map map = getSolrVclassIntersectionResults(vclassURIs, vreq, context); + JSONObject rObj = processVclassResults(map, vreq, context, true); + return rObj; + } + + //Factoring out to allow for results to be processed from query for both lucene and solr + //Map given to process method includes the actual individuals returned from the search + public static JSONObject processVclassResults(Map map, VitroRequest vreq, ServletContext context, boolean multipleVclasses) throws Exception{ + JSONObject rObj = DataGetterUtils.processVclassResultsJSON(map, vreq, multipleVclasses); + return rObj; + } + private static Map getLuceneVclassResults(String vclassURI, VitroRequest vreq, ServletContext context){ + String alpha = IndividualListController.getAlphaParameter(vreq); + int page = IndividualListController.getPageParameter(vreq); + Map map = null; + try { + map = IndividualListController.getResultsForVClass( + vclassURI, + page, + alpha, + vreq.getWebappDaoFactory().getIndividualDao(), + context); + } catch(Exception ex) { + log.error("Error in retrieval of Lucene results for VClass " + vclassURI, ex); + } + + return map; + } + + //Including version for Solr query for Vclass Intersections + private static Map getSolrVclassIntersectionResults(List vclassURIs, VitroRequest vreq, ServletContext context){ + String alpha = IndividualListController.getAlphaParameter(vreq); + int page = IndividualListController.getPageParameter(vreq); + Map map = null; + try { + map = IndividualListController.getResultsForVClassIntersections( + vclassURIs, + page, + alpha, + vreq.getWebappDaoFactory().getIndividualDao(), + context); + } catch(Exception ex) { + log.error("Error in retrieval of Lucene results for VClass " + vclassURIs.toString(), ex); + } + + return map; + } + + + + public static String getVClassName(Individual ind, String moniker, WebappDaoFactory fullWdf) { /* so the moniker frequently has a vclass name in it. Try to return * the vclass name that is the same as the moniker so that the templates @@ -308,7 +320,7 @@ public class JSONServlet extends VitroHttpServlet { return ""; } - static String getDataPropertyValue(Individual ind, DataProperty dp, WebappDaoFactory wdf){ + public static String getDataPropertyValue(Individual ind, DataProperty dp, WebappDaoFactory wdf){ List values = wdf.getDataPropertyStatementDao() .getDataPropertyValuesForIndividualByProperty(ind, dp); if( values == null || values.isEmpty() ) @@ -539,6 +551,49 @@ public class JSONServlet extends VitroHttpServlet { 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) { + 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 data = DataGetterUtils.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 = DataGetterUtils.covertDataToJSONForPage(pageUri, data, vreq, context); + } + } + + if( rObj == null ) + rObj = new JSONObject(); + //Send object + 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); + } + + } private JSONArray individualsToJson(List individuals) throws ServletException { JSONArray ja = new JSONArray(); @@ -557,6 +612,8 @@ public class JSONServlet extends VitroHttpServlet { return ja; } + + private static final int REPLY_SIZE = 256; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/SolrJsonServlet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/SolrJsonServlet.java index 405e7ae4f..9d6d424d9 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/SolrJsonServlet.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/SolrJsonServlet.java @@ -7,6 +7,7 @@ import java.io.PrintWriter; import java.io.Writer; import java.net.URLEncoder; import java.util.ArrayList; +import java.util.Arrays; import java.util.Enumeration; import java.util.Iterator; import java.util.List; @@ -43,6 +44,7 @@ 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.pageDataGetter.DataGetterUtils; /** * This servlet is for servicing requests for JSON objects/data. @@ -84,6 +86,12 @@ public class SolrJsonServlet extends VitroHttpServlet { }else if( vreq.getParameter("getVClassesForVClassGroup") != null ){ getVClassesForVClassGroup(req,resp); return; + } else if( vreq.getParameter("getSolrIndividualsByVClasses") != null ){ + getSolrIndividualsByVClasses(req,resp); + return; + } else if( vreq.getParameter("getDataForPage") != null ){ + getDataForPage(req,resp); + return; } }catch(Exception ex){ log.warn(ex,ex); @@ -175,119 +183,108 @@ public class SolrJsonServlet extends VitroHttpServlet { } public static JSONObject getSolrIndividualsByVClass(String vclassURI, HttpServletRequest req, ServletContext context) throws Exception { - + List vclassURIs = new ArrayList(); + vclassURIs.add(vclassURI); VitroRequest vreq = new VitroRequest(req); VClass vclass=null; JSONObject rObj = new JSONObject(); - DataProperty fNameDp = (new DataProperty()); - fNameDp.setURI("http://xmlns.com/foaf/0.1/firstName"); - DataProperty lNameDp = (new DataProperty()); - lNameDp.setURI("http://xmlns.com/foaf/0.1/lastName"); - DataProperty monikerDp = (new DataProperty()); - monikerDp.setURI( VitroVocabulary.MONIKER); - //this property is vivo specific - DataProperty preferredTitleDp = (new DataProperty()); - preferredTitleDp.setURI("http://vivoweb.org/ontology/core#preferredTitle"); - - - if( log.isDebugEnabled() ){ - @SuppressWarnings("unchecked") - Enumeration e = vreq.getParameterNames(); - while(e.hasMoreElements()){ - String name = (String)e.nextElement(); - log.debug("parameter: " + name); - for( String value : vreq.getParameterValues(name) ){ - log.debug("value for " + name + ": '" + value + "'"); - } - } - } - - //need an unfiltered dao to get firstnames and lastnames - WebappDaoFactory fullWdf = vreq.getFullWebappDaoFactory(); - - - 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 "); - } - - rObj.put("vclass", - new JSONObject().put("URI",vclass.getURI()) - .put("name",vclass.getName())); - - if (vclass != null) { - String alpha = SolrIndividualListController.getAlphaParameter(vreq); - int page = SolrIndividualListController.getPageParameter(vreq); - Map map = SolrIndividualListController.getResultsForVClass( - vclass.getURI(), - page, - alpha, - vreq.getWebappDaoFactory().getIndividualDao(), - context); - - rObj.put("totalCount", map.get("totalCount")); - rObj.put("alpha", map.get("alpha")); - - @SuppressWarnings("unchecked") - List inds = (List)map.get("entities"); - - JSONArray jInds = new JSONArray(); - for(Individual ind : inds ){ - JSONObject jo = new JSONObject(); - jo.put("URI", ind.getURI()); - jo.put("label",ind.getRdfsLabel()); - jo.put("name",ind.getName()); - jo.put("thumbUrl", ind.getThumbUrl()); - jo.put("imageUrl", ind.getImageUrl()); - jo.put("profileUrl", UrlBuilder.getIndividualProfileUrl(ind, vreq.getWebappDaoFactory())); - - String moniker = getDataPropertyValue(ind, monikerDp, fullWdf); - jo.put("moniker", moniker); - jo.put("vclassName", getVClassName(ind,moniker,fullWdf)); - - jo.put("preferredTitle", getDataPropertyValue(ind, preferredTitleDp, fullWdf)); - jo.put("firstName", getDataPropertyValue(ind, fNameDp, fullWdf)); - jo.put("lastName", getDataPropertyValue(ind, lNameDp, fullWdf)); - - jInds.put(jo); - } - rObj.put("individuals", jInds); - - JSONArray wpages = new JSONArray(); - @SuppressWarnings("unchecked") - List pages = (List)map.get("pages"); - for( PageRecord pr: pages ){ - JSONObject p = new JSONObject(); - p.put("text", pr.text); - p.put("param", pr.param); - p.put("index", pr.index); - wpages.put( p ); - } - rObj.put("pages",wpages); - - JSONArray jletters = new JSONArray(); - List letters = Controllers.getLetters(); - for( String s : letters){ - JSONObject jo = new JSONObject(); - jo.put("text", s); - jo.put("param", "alpha=" + URLEncoder.encode(s, "UTF-8")); - jletters.put( jo ); - } - rObj.put("letters", jletters); - } - - return rObj; + Map map = getSolrVclassIntersectionResults(vclassURIs, vreq, context); + //last parameter indicates single vclass instead of multiple vclasses + rObj = processVclassResults(map, vreq, context, false); + return rObj; } + //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 ){ + String errorMessage = null; + JSONObject rObj = null; + try{ + VitroRequest vreq = new VitroRequest(req); + VClass vclass=null; + + //Could have multiple vclass Ids sent in + List vclassIds = new ArrayList(); + String[] vitroClassIdStr = vreq.getParameterValues("vclassId"); + if ( vitroClassIdStr != null && vitroClassIdStr.length > 0){ + for(String vclassId: vitroClassIdStr) { + vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vclassId); + if (vclass == null) { + log.debug("Couldn't retrieve vclass "); + throw new Exception (errorMessage = "Class " + vclassId + " not found"); + } + } + }else{ + log.debug("parameter vclassId URI parameter expected "); + throw new Exception("parameter vclassId URI parameter expected "); + } + vclassIds = Arrays.asList(vitroClassIdStr); + //rObj = getLuceneIndividualsByVClass(vclass.getURI(),req, getServletContext()); + rObj = getSolrIndividualsByVClasses(vclassIds,req, getServletContext()); + }catch(Exception ex){ + errorMessage = ex.toString(); + log.error(ex,ex); + } + + 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); + } + } + + public static JSONObject getSolrIndividualsByVClasses(List vclassURIs, HttpServletRequest req, ServletContext context) throws Exception { + VitroRequest vreq = new VitroRequest(req); + Map map = getSolrVclassIntersectionResults(vclassURIs, vreq, context); + JSONObject rObj = processVclassResults(map, vreq, context, true); + return rObj; + } + + //Including version for Solr query for Vclass Intersections + private static Map getSolrVclassIntersectionResults(List vclassURIs, VitroRequest vreq, ServletContext context){ + String alpha = SolrIndividualListController.getAlphaParameter(vreq); + int page = SolrIndividualListController.getPageParameter(vreq); + Map map = null; + try { + //TODO: This needs to be moved or copied to Solr Individual List Controller + //Note the method below does use Solr search + map = SolrIndividualListController.getResultsForVClassIntersections( + vclassURIs, + page, + alpha, + vreq.getWebappDaoFactory().getIndividualDao(), + context); + } catch(Exception ex) { + log.error("Error in retrieval of Lucene results for VClass " + vclassURIs.toString(), ex); + } + + return map; + } + + //Factoring out to allow for results to be processed from query for both lucene and solr + //Map given to process method includes the actual individuals returned from the search + public static JSONObject processVclassResults(Map map, VitroRequest vreq, ServletContext context, boolean multipleVclasses) throws Exception{ + JSONObject rObj = DataGetterUtils.processVclassResultsJSON(map, vreq, multipleVclasses); + return rObj; + } + + private static String getVClassName(Individual ind, String moniker, WebappDaoFactory fullWdf) { /* so the moniker frequently has a vclass name in it. Try to return @@ -545,6 +542,49 @@ public class SolrJsonServlet extends VitroHttpServlet { 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) { + 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 data = DataGetterUtils.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 = DataGetterUtils.covertDataToJSONForPage(pageUri, data, vreq, context); + } + } + + if( rObj == null ) + rObj = new JSONObject(); + //Send object + 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); + } + + } private JSONArray individualsToJson(List individuals) throws ServletException { JSONArray ja = new JSONArray(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/HomePageController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/HomePageController.java index 6979697f9..c1ff65ee3 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/HomePageController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/HomePageController.java @@ -36,8 +36,7 @@ public class HomePageController extends FreemarkerHttpServlet { String uriOfPageInDisplayModel = "not defined"; Map pageData = dataGetter.getData(getServletContext(), vreq, - uriOfPageInDisplayModel, body, - DisplayVocabulary.HOME_PAGE_TYPE); + uriOfPageInDisplayModel, body); if(pageData != null) body.putAll(pageData); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualListController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualListController.java index 5822143be..6e229ef7f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualListController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualListController.java @@ -29,6 +29,7 @@ import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TopDocs; import edu.cornell.mannlib.vitro.webapp.beans.Individual; +import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; @@ -38,9 +39,16 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Tem import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; import edu.cornell.mannlib.vitro.webapp.search.lucene.Entity2LuceneDoc; import edu.cornell.mannlib.vitro.webapp.search.lucene.LuceneIndexFactory; +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.templatemodels.individual.ListedIndividualTemplateModel; import freemarker.ext.beans.BeansWrapper; import freemarker.template.TemplateModel; +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; /** * Generates a list of individuals for display in a template @@ -194,6 +202,7 @@ public class IndividualListController extends FreemarkerHttpServlet { * This method includes what was formerly a part of the method above, allowing for refactoring of code * to use for a different number fo classes */ + public static Map getResultsForVClassQuery(Query query, int page, String alpha, IndividualDao indDao, ServletContext context) throws CorruptIndexException, IOException, ServletException{ Map rvMap = new HashMap(); @@ -260,6 +269,82 @@ public class IndividualListController extends FreemarkerHttpServlet { return rvMap; } + + + //Solr based version + public static Map getResultsForVClassQuery(SolrQuery query, int page, String alpha, IndividualDao indDao, ServletContext context) + throws CorruptIndexException, IOException, ServletException{ + Map rvMap = new HashMap(); + //Execute solr query + SolrServer solr = SolrSetup.getSolrServer(context); + QueryResponse response = null; + + try { + response = solr.query(query); + + } catch (Throwable t) { + log.error("in first pass at search: " + t); + // this is a hack to deal with odd cases where search and index threads interact + try{ + //Can't use the method below in a static class? + //wait(150); + response = solr.query(query); + } catch (Exception ex) { + log.error(ex); + //doFailedSearch() + //return doFailedSearch(msg, qtxt, format); + } + } + + + SolrDocumentList docs = response.getResults(); + if( docs == null ) + throw new ServletException("Could not run search in IndividualListController"); + + //get list of individuals for the search results + + int size = new Long(docs.getNumFound()).intValue(); + log.debug("Number of search results: " + size); + + // don't get all the results, only get results for the requestedSize + List individuals = new ArrayList(INDIVIDUALS_PER_PAGE); + int individualsAdded = 0; + int ii = (page-1)*INDIVIDUALS_PER_PAGE; + while( individualsAdded < INDIVIDUALS_PER_PAGE && ii < size ){ + SolrDocument doc = docs.get(ii); + if (doc != null) { + String uri = doc.get(VitroLuceneTermNames.URI).toString(); + log.debug("Retrieving individual with uri "+ uri); + Individual ind = indDao.getIndividualByURI(uri); + if( ind != null ){ + individuals.add( ind ); + individualsAdded++; + } + } else { + log.warn("no document found for lucene doc id " + doc); + } + ii++; + } + + rvMap.put("count", size); + + if( size > INDIVIDUALS_PER_PAGE ){ + rvMap.put("showPages", Boolean.TRUE); + List pageRecords = makePagesList(size, INDIVIDUALS_PER_PAGE, page); + rvMap.put("pages", pageRecords); + }else{ + rvMap.put("showPages", Boolean.FALSE); + rvMap.put("pages", Collections.emptyList()); + } + + rvMap.put("alpha",alpha); + + rvMap.put("totalCount", size); + rvMap.put("entities",individuals); + + return rvMap; + } + public static Map getResultsForVClassIntersections(List vclassURIs, int page, String alpha, IndividualDao indDao, ServletContext context) @@ -267,17 +352,20 @@ public class IndividualListController extends FreemarkerHttpServlet { Map rvMap = new HashMap(); try{ //make lucene query for multiple rdf types - Query query = getQuery(vclassURIs, alpha); + //change to solr + SolrQuery query = getSolrQuery(vclassURIs, alpha); //get results corresponding to this query rvMap = getResultsForVClassQuery(query, page, alpha, indDao, context); List individuals = (List) rvMap.get("entities"); if (individuals == null) log.debug("entities list is null for vclass " + vclassURIs.toString() ); } catch(Throwable th) { - log.error("Error retrieving individuals corresponding to intersection multiple classes." + vclassURIs.toString()); + log.error("Error retrieving individuals corresponding to intersection multiple classes." + vclassURIs.toString(), th); } return rvMap; } + + /* * This method creates a query to search for terms with rdf type corresponding to vclass Uri. * The original version allowed only for one class URI but needed to be extended to enable multiple @@ -309,6 +397,53 @@ public class IndividualListController extends FreemarkerHttpServlet { } } + //how to extend for solr query + //Alpha handling taken from SolrIndividualListController + private static SolrQuery getSolrQuery(ListvclassUris, String alpha){ + //SolrQuery query = getQuery(qtxt, maxHitCount, vreq); + //SolrServer solr = SolrSetup.getSolrServer(getServletContext()); + SolrQuery query = new SolrQuery(); + + // Solr requires these values, but we don't want them to be the real values for this page + // of results, else the refinement links won't work correctly: each page of results needs to + // show refinement links generated for all results, not just for the results on the current page. + query.setStart(0) + .setRows(1000); + String queryText = ""; + //Query text should be of form: + List queryTypes = new ArrayList(); + try{ + //query term for rdf:type - multiple types possible + for(String vclassUri: vclassUris) { + queryTypes.add(VitroLuceneTermNames.RDFTYPE + ":\"" + vclassUri + "\" "); + + } + + if(queryTypes.size() > 1) { + queryText = StringUtils.join(queryTypes, " AND "); + } else { + if(queryTypes.size() > 0) { + queryText = queryTypes.get(0); + } + } + + // Add alpha filter if it is needed + if ( alpha != null && !"".equals(alpha) && alpha.length() == 1) { + queryText += VitroLuceneTermNames.NAME_LOWERCASE + ":" + alpha.toLowerCase() + "*"; + } + + log.debug("Query text is " + queryText); + query.setQuery(queryText); + log.debug("Query: " + query); + return query; + } catch (Exception ex){ + log.error(ex,ex); + + return new SolrQuery(); + } + + } + public static List makePagesList( int count, int pageSize, int selectedPage){ List records = new ArrayList( MAX_PAGES + 1 ); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/PageController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/PageController.java index 625844155..c63bf3930 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/PageController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/PageController.java @@ -23,7 +23,8 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Tem import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.BrowseDataGetter; import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.PageDataGetter; import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.ClassGroupPageData; -import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.ClassIntersectionDataGetter; +import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.IndividualsForClassesDataGetter; +import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.DataGetterUtils; /** * Controller for getting data for pages defined in the display model. * @@ -51,23 +52,29 @@ public class PageController extends FreemarkerHttpServlet{ Mappage; try { pageUri = getPageUri( vreq , url ); - page = getMapForPage( vreq, pageUri ); + page = DataGetterUtils.getMapForPage( vreq, pageUri ); mapForTemplate.put( "page", page); if( page.containsKey("title") ){ mapForTemplate.put("title", page.get("title")); } - mapForTemplate.put("dataServiceUrlIndividualsByVClass", UrlBuilder.getUrl("/dataservice?getSolrIndividualsByVClass=1&vclassId=")); + + //For multiple classes, + //mapForTemplate.put("dataServiceUrlIndividualsByVClasses", UrlBuilder.getUrl("/dataservice?getSolrIndividualsByVClasses=1&vclassId=")); + } catch (Throwable th) { return doNotFound(vreq); } try{ - mapForTemplate.putAll( getAdditionalDataForPage( vreq, pageUri, page) ); + mapForTemplate.putAll( DataGetterUtils.getDataForPage(pageUri, vreq, getServletContext()) ); } catch( Throwable th){ log.error(th,th); return doError(vreq); } - + //set default in case doesn't exist for data getter + if(!mapForTemplate.containsKey("dataServiceUrlIndividualsByVClass")) { + mapForTemplate.put("dataServiceUrlIndividualsByVClass", UrlBuilder.getUrl("/dataservice?getSolrIndividualsByVClass=1&vclassId=")); + } ResponseValues rv = new TemplateResponseValues(getTemplate( mapForTemplate ), mapForTemplate); return rv; } catch (Throwable e) { @@ -87,46 +94,6 @@ public class PageController extends FreemarkerHttpServlet{ return DEFAULT_BODY_TEMPLATE; } - protected Map getAdditionalDataForPage(VitroRequest vreq, String pageUri, Mappage ) { - /* figure out if the page needs additional data added */ - Map data = new HashMap(); - List types = (List)page.get("types"); - if( types != null ){ - for( String type : types){ - Map moreData = null; - try{ - moreData = getAdditionalData(vreq,pageUri,page,type); - if( moreData != null) - data.putAll(moreData); - }catch(Throwable th){ - log.error(th,th); - } - } - } - return data; - } - - protected Map getAdditionalData( - VitroRequest vreq, String pageUri, Map page, String type) { - if(type == null || type.isEmpty()) - return Collections.emptyMap(); - - PageDataGetter getter = getPageDataGetterMap(getServletContext()).get(type); - //For now hardcoding, check to see if data getter included within - if((String)page.get("datagetter") != null) { - getter = new ClassIntersectionDataGetter(); - } - if( getter != null ){ - try{ - return getter.getData(getServletContext(), vreq, pageUri, page, type); - }catch(Throwable th){ - log.error(th,th); - return Collections.emptyMap(); - } - } else { - return Collections.emptyMap(); - } - } private ResponseValues doError(VitroRequest vreq) { Map body = new HashMap(); @@ -142,10 +109,6 @@ public class PageController extends FreemarkerHttpServlet{ return new TemplateResponseValues(Template.TITLED_ERROR_MESSAGE.toString(), body, HttpServletResponse.SC_NOT_FOUND); } - private Map getMapForPage(VitroRequest vreq, String pageUri) { - //do a query to the display model for attributes of this page. - return vreq.getWebappDaoFactory().getPageDao().getPage(pageUri); - } /** * Gets the page URI from the request. The page must be defined in the display model. @@ -181,7 +144,7 @@ public class PageController extends FreemarkerHttpServlet{ BrowseDataGetter bdg = new BrowseDataGetter(); getPageDataGetterMap(context).put(bdg.getType(), bdg); //TODO: Check if can include by type here - ClassIntersectionDataGetter cidg = new ClassIntersectionDataGetter(); + IndividualsForClassesDataGetter cidg = new IndividualsForClassesDataGetter(); getPageDataGetterMap(context).put(cidg.getType(), cidg); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/SolrIndividualListController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/SolrIndividualListController.java index 5abb763ef..cb4b8d3fd 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/SolrIndividualListController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/SolrIndividualListController.java @@ -16,6 +16,7 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.lucene.index.CorruptIndexException; +import org.apache.lucene.search.Query; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.response.QueryResponse; @@ -163,16 +164,65 @@ public class SolrIndividualListController extends FreemarkerHttpServlet { } } + //Pulling out common code that is used for both single (regular) vclass query and multiple (intersection) query + public static Map getResultsForVClasses(List vclassURIs, int page, String alpha, IndividualDao indDao, ServletContext context) + throws CorruptIndexException, IOException, ServletException{ + Map rvMap = new HashMap(); + try{ + SolrQuery query = getQuery(vclassURIs, alpha, page); + rvMap = getResultsForVClassQuery(query, page, alpha, indDao, context); + List individuals = (List) rvMap.get("entities"); + if (individuals == null) + log.debug("entities list is null for vclasses " + vclassURIs.toString() ); + } catch(Throwable th) { + log.error("An error occurred retrieving results for vclass query", th); + } + return rvMap; + } + + public static Map getResultsForVClass(String vclassURI, int page, String alpha, IndividualDao indDao, ServletContext context) + throws CorruptIndexException, IOException, ServletException{ + Map rvMap = new HashMap(); + try{ + //make lucene query for this rdf:type + List classUris = new ArrayList(); + classUris.add(vclassURI); + SolrQuery query = getQuery(classUris, alpha, page); + rvMap = getResultsForVClassQuery(query, page, alpha, indDao, context); + List individuals = (List) rvMap.get("entities"); + if (individuals == null) + log.debug("entities list is null for vclass " + vclassURI ); + } catch(Throwable th) { + log.error("An error occurred retrieving results for vclass query", th); + } + return rvMap; + } + + public static Map getResultsForVClassIntersections(List vclassURIs, int page, String alpha, IndividualDao indDao, ServletContext context) + throws CorruptIndexException, IOException, ServletException{ + Map rvMap = new HashMap(); + try{ + //make lucene query for multiple rdf types + //change to solr + SolrQuery query = getQuery(vclassURIs, alpha, page); + //get results corresponding to this query + rvMap = getResultsForVClassQuery(query, page, alpha, indDao, context); + List individuals = (List) rvMap.get("entities"); + if (individuals == null) + log.debug("entities list is null for vclass " + vclassURIs.toString() ); + } catch(Throwable th) { + log.error("Error retrieving individuals corresponding to intersection multiple classes." + vclassURIs.toString(), th); + } + return rvMap; + } + /** * This method is now called in a couple of places. It should be refactored * into a DAO or similar object. */ - public static Map getResultsForVClass(String vclassURI, int page, String alpha, IndividualDao indDao, ServletContext context) + public static Map getResultsForVClassQuery(SolrQuery query, int page, String alpha, IndividualDao indDao, ServletContext context) throws CorruptIndexException, IOException, ServletException { - Map rvMap = new HashMap(); - - // Make solr query for this rdf:type - SolrQuery query = getQuery(vclassURI, alpha, page); + Map rvMap = new HashMap(); SolrServer solr = SolrSetup.getSolrServer(context); QueryResponse response = null; @@ -220,32 +270,48 @@ public class SolrIndividualListController extends FreemarkerHttpServlet { rvMap.put("alpha",alpha); rvMap.put("totalCount", size); - rvMap.put("entities",individuals); - - if (individuals.isEmpty()) - log.debug("entities list is empty for vclass " + vclassURI ); + rvMap.put("entities",individuals); return rvMap; } - private static SolrQuery getQuery(String vclassUri, String alpha, int page){ - - String queryStr = VitroLuceneTermNames.RDFTYPE + ":\"" + vclassUri + "\""; - - // Add alpha filter if it is needed - if ( alpha != null && !"".equals(alpha) && alpha.length() == 1) { - queryStr += VitroLuceneTermNames.NAME_LOWERCASE + ":" + alpha.toLowerCase() + "*"; - } - - SolrQuery query = new SolrQuery(queryStr); - - int start = (page-1)*INDIVIDUALS_PER_PAGE; - query.setStart(start) - .setRows(INDIVIDUALS_PER_PAGE) - .setSortField(VitroLuceneTermNames.NAME_LOWERCASE_SINGLE_VALUED, SolrQuery.ORDER.asc); - - log.debug("Query: " + query); - return query; + private static SolrQuery getQuery(List vclassUris, String alpha, int page){ + // Solr requires these values, but we don't want them to be the real values for this page + // of results, else the refinement links won't work correctly: each page of results needs to + // show refinement links generated for all results, not just for the results on the current page. + + String queryText = ""; + //Query text should be of form: + List queryTypes = new ArrayList(); + try{ + //query term for rdf:type - multiple types possible + for(String vclassUri: vclassUris) { + queryTypes.add(VitroLuceneTermNames.RDFTYPE + ":\"" + vclassUri + "\" "); + } + + if(queryTypes.size() > 1) { + queryText = StringUtils.join(queryTypes, " AND "); + } else { + if(queryTypes.size() > 0) { + queryText = queryTypes.get(0); + } + } + + // Add alpha filter if it is needed + if ( alpha != null && !"".equals(alpha) && alpha.length() == 1) { + queryText += VitroLuceneTermNames.NAME_LOWERCASE + ":" + alpha.toLowerCase() + "*"; + } + SolrQuery query = new SolrQuery(queryText); + log.debug("Query text is " + queryText); + int start = (page-1)*INDIVIDUALS_PER_PAGE; + query.setStart(start) + .setRows(INDIVIDUALS_PER_PAGE) + .setSortField(VitroLuceneTermNames.NAME_LOWERCASE_SINGLE_VALUED, SolrQuery.ORDER.asc); + return query; + } catch (Exception ex){ + log.error(ex,ex); + return new SolrQuery(); + } } public static List makePagesList( long size, int pageSize, int selectedPage ) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/DisplayVocabulary.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/DisplayVocabulary.java index 136e0fecc..d1cc47bde 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/DisplayVocabulary.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/DisplayVocabulary.java @@ -17,6 +17,10 @@ public class DisplayVocabulary { /**

The ontology model that holds the vocabulary terms

*/ private static OntModel m_model = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM, null ); + /*Uris for Models for Display*/ + + public static final String DISPLAY_TBOX_MODEL_URI = "http://vitro.mannlib.cornell.edu/default/vitro-kb-displayMetadataTBOX"; + public static final String DISPLAY_DISPLAY_MODEL_URI = "http://vitro.mannlib.cornell.edu/default/vitro-kb-displayMetadata-displayModel"; /* Namespace for display vocabulary */ public static final String DISPLAY_NS = "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#"; private static final String NS = DISPLAY_NS; @@ -28,15 +32,22 @@ public class DisplayVocabulary { public static final String CONTEXT_NODES_URI = NS + "QueryForContextNodes"; /* Page types */ + //Corresponding to statements in menu management that define class of data getter to be used public static final String PAGE_TYPE = NS + "Page"; public static final String HOME_PAGE_TYPE = NS + "HomePage"; public static final String CLASSGROUP_PAGE_TYPE = NS + "ClassGroupPage"; - //Including for now, can take out later - public static final String CLASSINTERSECTION_PAGE_TYPE = NS + "ClassIntersectionPage"; + public static final String CLASSINDIVIDUALS_PAGE_TYPE = NS + "IndividualsForClassesPage"; /* Object Properties */ public static final String FOR_CLASSGROUP = NS + "forClassGroup"; public static final String CLASS_INTERSECTION = NS + "intersectsWithClass"; + public static final String HAS_CLASS_INTERSECTION = NS + "hasClassIntersection"; + + /**Data Getter object properties **/ + public static final String GETINDIVIDUALS_FOR_CLASS = NS + "getIndividualsForClass"; + public static final String RESTRICT_RESULTS_BY = NS + "restrictResultsByClass"; + + /* Data Properties */ public static final DatatypeProperty URL_MAPPING = m_model.createDatatypeProperty(NS + "urlMapping"); public static final String TITLE = NS + "title"; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/PageDao.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/PageDao.java index 4708f140a..860780301 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/PageDao.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/PageDao.java @@ -23,5 +23,8 @@ public interface PageDao { String getClassGroupPage(String pageUri); - List getClassIntersections(String pageUri); + Map> getClassIntersections(String pageUri); + + Map> getClassesAndRestrictionsForPage(String pageUri); + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PageDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PageDaoJena.java index b63d2bca4..c12587bd9 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PageDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PageDaoJena.java @@ -8,6 +8,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.HashMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -35,10 +36,14 @@ public class PageDaoJena extends JenaBaseDao implements PageDao { static protected Query pageQuery; static protected Query pageTypeQuery; + static protected Query pageDataGettersQuery; static protected Query pageMappingsQuery; static protected Query homePageUriQuery; static protected Query classGroupPageQuery; static protected Query classIntersectionPageQuery; + static protected Query individualsForClassesQuery; + static protected Query individualsForClassesRestrictedQuery; + static final String prefixes = "PREFIX rdf: <" + VitroVocabulary.RDF +"> \n" + @@ -62,6 +67,13 @@ public class PageDaoJena extends JenaBaseDao implements PageDao { " ?pageUri rdf:type ?type .\n"+ "} \n" ; + //Get data getters + static final protected String pageDataGettersQueryString = + prefixes + "\n" + + "SELECT ?dataGetter WHERE {\n" + + " ?pageUri display:hasDataGetter ?dg .\n"+ + " ?dg rdf:type ?dataGetter . \n" + + "} \n" ; static final protected String pageMappingsQueryString = prefixes + "\n" + "SELECT ?pageUri ?urlMapping WHERE {\n" + @@ -81,8 +93,33 @@ public class PageDaoJena extends JenaBaseDao implements PageDao { static final protected String classIntersectionPageQueryString = prefixes + "\n" + - "SELECT ?classIntersection WHERE { ?pageUri <" + DisplayVocabulary.CLASS_INTERSECTION + "> ?classIntersection . }"; + "SELECT ?classIntersection ?label ?class ?WHERE { ?pageUri <" + DisplayVocabulary.HAS_CLASS_INTERSECTION + "> ?classIntersection . \n " + + " ?classIntersection <" + DisplayVocabulary.CLASS_INTERSECTION + "> ?class . \n "+ + " ?classIntersection rdfs:label ?label . \n" + + "}"; + //prefixes + "\n" + + //"SELECT ?classIntersection WHERE { ?pageUri <" + DisplayVocabulary.CLASS_INTERSECTION + "> ?classIntersection . }"; + //Query to get what classes are to be employed on the page + static final protected String individualsForClassesDataGetterQueryString = + prefixes + "\n" + + "SELECT ?dg ?class ?restrictClass WHERE {\n" + + " ?pageUri display:hasDataGetter ?dg .\n"+ + " ?dg rdf:type <" + DisplayVocabulary.CLASSINDIVIDUALS_PAGE_TYPE + ">. \n" + + " ?dg <" + DisplayVocabulary.GETINDIVIDUALS_FOR_CLASS + "> ?class . \n" + + " ?dg <"+ DisplayVocabulary.RESTRICT_RESULTS_BY + "> ?restrictClass .\n" + + "} \n" ; + + //Given a data getter, check if results are to be restricted by class + //Also possible to merge these two into the same query + + static final protected String individualsForClassesRestrictedQueryString = + prefixes + "\n" + + "SELECT ?restrictClass WHERE {\n" + + " ?dg <"+ DisplayVocabulary.RESTRICT_RESULTS_BY + "> ?restrictClass .\n" + + "} \n" ; + // " ?pageUri display:hasDataGetter ?dg .\n"+ + static{ try{ pageQuery=QueryFactory.create(pageQueryString); @@ -96,6 +133,12 @@ public class PageDaoJena extends JenaBaseDao implements PageDao { log.error("could not create SPARQL query for pageTypeQuery " + th.getMessage()); log.error(pageTypeQueryString); } + try{ + pageDataGettersQuery = QueryFactory.create(pageDataGettersQueryString); + }catch(Throwable th){ + log.error("could not create SPARQL query for pageTypeQuery " + th.getMessage()); + log.error(pageDataGettersQueryString); + } try{ pageMappingsQuery=QueryFactory.create(pageMappingsQueryString); }catch(Throwable th){ @@ -120,6 +163,20 @@ public class PageDaoJena extends JenaBaseDao implements PageDao { log.error("could not create SPARQL query for classIntersectionPageQuery " + th.getMessage()); log.error(classIntersectionPageQueryString); } + + try{ + individualsForClassesQuery=QueryFactory.create(individualsForClassesDataGetterQueryString); + }catch(Throwable th){ + log.error("could not create SPARQL query for individualsForClassesQuery " + th.getMessage()); + log.error(individualsForClassesDataGetterQueryString); + } + + try{ + individualsForClassesRestrictedQuery=QueryFactory.create(individualsForClassesRestrictedQueryString); + }catch(Throwable th){ + log.error("could not create SPARQL query for individualsForClassesRestrictedQuery " + th.getMessage()); + log.error(individualsForClassesDataGetterQueryString); + } } public PageDaoJena(WebappDaoFactoryJena wadf) { @@ -174,14 +231,15 @@ public class PageDaoJena extends JenaBaseDao implements PageDao { Map pageData = list.get(0); //now get the rdf:types for the page - List types = new ArrayList(); + //Changing to get the data getters for the page (already know that it's a page type) + List dataGetters = new ArrayList(); displayModel.enterCriticalSection(false); try{ - QueryExecution qexec = QueryExecutionFactory.create(pageTypeQuery, displayModel, initialBindings); + QueryExecution qexec = QueryExecutionFactory.create(pageDataGettersQuery, displayModel, initialBindings); ResultSet rs = qexec.execSelect(); while(rs.hasNext()){ QuerySolution soln = rs.next(); - types.add( nodeToString( soln.get("type" ) )); + dataGetters.add( nodeToString( soln.get("dataGetter" ) )); } qexec.close(); }finally{ @@ -189,9 +247,9 @@ public class PageDaoJena extends JenaBaseDao implements PageDao { } if( list == null ) - log.error("could not get types for page " + pageUri); + log.error("could not get data getters for page " + pageUri); else - pageData.put("types", types); + pageData.put("dataGetters", dataGetters); return pageData; } @@ -252,29 +310,86 @@ public class PageDaoJena extends JenaBaseDao implements PageDao { } /** - * Get the names of the classes for class intersection. Multiple classes possible. + * Get the set of intersections for page - each intersection has a label and includes names of the classes for class intersection. Multiple classes possible. */ - public List getClassIntersections(String pageUri) { - List classIntersections = new ArrayList(); + public Map> getClassIntersections(String pageUri) { + Map> classIntersectionsMap = new HashMap>(); QuerySolutionMap initialBindings = new QuerySolutionMap(); initialBindings.add("pageUri", ResourceFactory.createResource(pageUri)); Model displayModel = getOntModelSelector().getDisplayModel(); QueryExecution qexec = QueryExecutionFactory.create( classIntersectionPageQuery, displayModel , initialBindings); + //Assuming unique labels or could use URI itself? + //TODO: Review whether to use labels or URIs ResultSet resultSet = qexec.execSelect(); while(resultSet.hasNext()){ QuerySolution soln = resultSet.next(); - classIntersections.add( nodeToString(soln.get("classIntersection")) ); + //Results format should be ?page hasClassIntersection . intersectsWithClass ?c; intersects With Class ?e. + String intersectionLabel = nodeToString(soln.get("label")); + + //first time encountering label, set up + if(!classIntersectionsMap.containsKey(intersectionLabel)) { + classIntersectionsMap.put(intersectionLabel, new ArrayList()); + } + + List classes = classIntersectionsMap.get(intersectionLabel); + classes.add(nodeToString(soln.get("class"))); + //classIntersections.add( nodeToString(soln.get("classIntersection")) ); } - if( classIntersections.size() == 0 ){ + if( classIntersectionsMap.size() == 0 ){ log.debug("No class intersections info defined in display model for "+ pageUri); return null; } - return classIntersections; + return classIntersectionsMap; } + + + /* + * Get the classes for which to get individuals returned. This should return a list of class uris. + * Return a list of classes to be returned along with any restrictions to be applied. + * Assumption: The page has a single data getter for classes and restrictions - all classes and restrictions + * for any data getters for the page will be lumped together. For multiple data getters, will need to return + * data for each one separately in the same map structure as below. + * * Get restriction class to be applied as filter to individuals for page. + * Although to be used specifically for internal class filtering and will usually be one class returned, + * allowing for multiple classes to be returned. + */ + public Map> getClassesAndRestrictionsForPage(String pageUri) { + Map> classesAndRestrictions = new HashMap>(); + QuerySolutionMap initialBindings = new QuerySolutionMap(); + initialBindings.add("pageUri", ResourceFactory.createResource(pageUri)); + List classes = new ArrayList(); + Model displayModel = getOntModelSelector().getDisplayModel(); + QueryExecution qexec = QueryExecutionFactory.create( individualsForClassesQuery, displayModel , initialBindings); + HashMap restrictClassesPresentMap = new HashMap(); + List restrictClasses = new ArrayList(); + + ResultSet resultSet = qexec.execSelect(); + while(resultSet.hasNext()){ + QuerySolution soln = resultSet.next(); + String dg = nodeToString(soln.get("dg")); + classes.add(nodeToString(soln.get("class"))); + String restrictClass = nodeToString(soln.get("restrictClass")); + if(!restrictClassesPresentMap.containsKey(restrictClass)) { + restrictClasses.add(restrictClass); + restrictClassesPresentMap.put(restrictClass, "true"); + } + } + + if( classes.size() == 0 ){ + log.debug("No classes defined in display model for "+ pageUri); + return null; + } + classesAndRestrictions.put("classes", classes); + classesAndRestrictions.put("restrictClasses", restrictClasses); + return classesAndRestrictions; + } + + + /* ****************************************************************************** */ diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyInstanceDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyInstanceDaoJena.java index a24a0b570..bf750c6cf 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyInstanceDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyInstanceDaoJena.java @@ -40,7 +40,6 @@ import edu.cornell.mannlib.vitro.webapp.dao.PropertyInstanceDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; import edu.cornell.mannlib.vitro.webapp.dao.jena.event.IndividualDeletionEvent; import edu.cornell.mannlib.vitro.webapp.dao.jena.event.IndividualUpdateEvent; - public class PropertyInstanceDaoJena extends JenaBaseDao implements PropertyInstanceDao { @@ -469,4 +468,4 @@ public class PropertyInstanceDaoJena extends JenaBaseDao implements this.deleteObjectPropertyStatement(prop.getSubjectEntURI(), prop.getPropertyURI(), prop.getObjectEntURI()); } -} +} \ No newline at end of file diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java index 9a64893a2..c79ee277d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java @@ -29,6 +29,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; 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.FilterFactory; @@ -221,8 +222,8 @@ public class VitroRequestPrep implements Filter { //if using special models for menu management, get main menu model from context and set tbox and display uris to be used useMainOntModel = (OntModel) _context.getAttribute("displayOntModel"); //Hardcoding tbox model uri for now - useTboxModelUri = "http://vitro.mannlib.cornell.edu/default/vitro-kb-displayMetadataTBOX"; - useDisplayModelUri = "http://vitro.mannlib.cornell.edu/default/vitro-kb-displayMetadata-displayModel"; + useTboxModelUri = DisplayVocabulary.DISPLAY_TBOX_MODEL_URI; + useDisplayModelUri = DisplayVocabulary.DISPLAY_DISPLAY_MODEL_URI; } else { //If main model uri passed as parameter then retrieve model from parameter Model mainModel = JenaDataSourceSetupBase.makeDBModel(bds, useMainModelUri, OntModelSpec.OWL_MEM, JenaDataSourceSetupBase.TripleStoreType.RDB, dbType, _context); @@ -232,13 +233,18 @@ public class VitroRequestPrep implements Filter { } } - tboxModel = JenaDataSourceSetupBase.makeDBModel(bds, useTboxModelUri, OntModelSpec.OWL_MEM, JenaDataSourceSetupBase.TripleStoreType.RDB, dbType, _context); - System.out.println("Checking what the display tbox model is returning"); - tboxModel.write(System.out, "N3"); - useTboxOntModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, tboxModel); - //Set "display model" for display model - displayModel = JenaDataSourceSetupBase.makeDBModel(bds, useDisplayModelUri, OntModelSpec.OWL_MEM, JenaDataSourceSetupBase.TripleStoreType.RDB, dbType, _context); - useDisplayOntModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, displayModel); + //Get tbox and display display model from servlet context otherwise load in directly from database + useTboxOntModel = (OntModel) _context.getAttribute("displayOntModelTBOX"); + useDisplayOntModel = (OntModel) _context.getAttribute("displayOntModelDisplayModel"); + if(useTboxOntModel == null){ + tboxModel = JenaDataSourceSetupBase.makeDBModel(bds, useTboxModelUri, OntModelSpec.OWL_MEM, JenaDataSourceSetupBase.TripleStoreType.RDB, dbType, _context); + useTboxOntModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, tboxModel); + } + if(useDisplayOntModel == null) { + //Set "display model" for display model + displayModel = JenaDataSourceSetupBase.makeDBModel(bds, useDisplayModelUri, OntModelSpec.OWL_MEM, JenaDataSourceSetupBase.TripleStoreType.RDB, dbType, _context); + useDisplayOntModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, displayModel); + } //Set special model for wadfj if(useMainOntModel != null) { wadfj.setSpecialDataModel(useMainOntModel, useTboxOntModel, useDisplayOntModel); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java index 5dd026b8f..9d5a82c11 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java @@ -22,6 +22,7 @@ import com.hp.hpl.jena.sdb.store.DatabaseType; import com.hp.hpl.jena.sdb.store.LayoutType; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; +import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaBaseDaoCon; import edu.cornell.mannlib.vitro.webapp.dao.jena.RDBGraphGenerator; import edu.cornell.mannlib.vitro.webapp.dao.jena.RegeneratingGraph; @@ -52,6 +53,8 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon { protected static String SYSTEMPATH = BASE+"system/"; protected static String AUTHPATH = BASE+"auth/"; public static String APPPATH = BASE+"app/"; + //these files are loaded everytime the system starts up + public static String APPPATH_LOAD = APPPATH + "menuload"; protected static String SUBMODELS = "/WEB-INF/submodels/"; protected static boolean firstStartup = false; @@ -107,6 +110,12 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon { // with this for release 1.2. static final String JENA_DISPLAY_METADATA_MODEL = "http://vitro.mannlib.cornell.edu/default/vitro-kb-displayMetadata"; + + //TBox and display model related + static final String JENA_DISPLAY_TBOX_MODEL = + DisplayVocabulary.DISPLAY_TBOX_MODEL_URI; + static final String JENA_DISPLAY_DISPLAY_MODEL = + DisplayVocabulary.DISPLAY_DISPLAY_MODEL_URI; static final String DEFAULT_DEFAULT_NAMESPACE = "http://vitro.mannlib.cornell.edu/ns/default#"; @@ -320,21 +329,25 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon { Set paths = ctx.getResourcePaths(path); if (paths != null) { for (String p : paths) { - String format = getRdfFormat(p); - log.info("Loading ontology file at " + p + - " as format " + format); - InputStream ontologyInputStream = ctx.getResourceAsStream(p); - try { - model.read(ontologyInputStream, null, format); - log.debug("...successful"); - } catch (Throwable t) { - log.error("Failed to load ontology file at '" + p + - "' as format " + format, t); - } + readOntologyFileFromPath(p, model, ctx); } } } + public static void readOntologyFileFromPath(String p, Model model, ServletContext ctx) { + String format = getRdfFormat(p); + log.info("Loading ontology file at " + p + + " as format " + format); + InputStream ontologyInputStream = ctx.getResourceAsStream(p); + try { + model.read(ontologyInputStream, null, format); + log.debug("...successful"); + } catch (Throwable t) { + log.error("Failed to load ontology file at '" + p + + "' as format " + format, t); + } + } + private static String getRdfFormat(String filename){ String defaultformat = "RDF/XML"; if( filename == null ) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaPersistentDataSourceSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaPersistentDataSourceSetup.java index b99a81e86..a6c99b25a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaPersistentDataSourceSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaPersistentDataSourceSetup.java @@ -67,7 +67,65 @@ public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase } catch (Throwable t) { log.error("Unable to load user application configuration model from DB", t); } - + + //display tbox - currently reading in every time + try { + Model displayTboxModel = makeDBModelFromConfigurationProperties( + JENA_DISPLAY_TBOX_MODEL, DB_ONT_MODEL_SPEC, ctx); + //Reading in single file every time + //TODO: Check if original needs to be cleared/removed every time? + readOntologyFileFromPath(APPPATH_LOAD + "displayTBOX.n3", displayTboxModel, sce.getServletContext()); + OntModel appTBOXModel = ModelFactory.createOntologyModel( + MEM_ONT_MODEL_SPEC); + appTBOXModel.add(displayTboxModel); + appTBOXModel.getBaseModel().register(new ModelSynchronizer(displayTboxModel)); + ctx.setAttribute("displayOntModelTBOX", appTBOXModel); + } catch (Throwable t) { + log.error("Unable to load user application configuration model TBOX from DB", t); + } + //Display Display model, currently empty, create if doesn't exist but no files to load + try { + Model displayDisplayModel = makeDBModelFromConfigurationProperties( + JENA_DISPLAY_DISPLAY_MODEL, DB_ONT_MODEL_SPEC, ctx); + //Reading in single file every time + //TODO: Check if original needs to be cleared/removed every time? + readOntologyFileFromPath(APPPATH_LOAD + "displayDisplay.n3", displayDisplayModel, sce.getServletContext()); + + OntModel appDisplayDisplayModel = ModelFactory.createOntologyModel( + MEM_ONT_MODEL_SPEC); + appDisplayDisplayModel.add(displayDisplayModel); + appDisplayDisplayModel.getBaseModel().register(new ModelSynchronizer(displayDisplayModel)); + ctx.setAttribute("displayOntModelDisplayModel", appDisplayDisplayModel); + } catch (Throwable t) { + log.error("Unable to load user application configuration model Display Model from DB", t); + } + /* + //For comparison purposes + //Read in application.owl and menu.n3 and compare with what is currently in the display model + //What are the differences + try { + //This is the model as retrieved on system load + Model loadedModel = ModelFactory.createDefaultModel(); + + + //Now read in from the menu model + Model appDbModel = makeDBModelFromConfigurationProperties( + JENA_DISPLAY_METADATA_MODEL, DB_ONT_MODEL_SPEC, ctx); + //Now compare - do differences in both directions + //What's in the upto date display that's not in the one that's loaded from files + Model notInLoadedModel = appDbModel.difference(loadedModel); + System.out.println("**These are the statements not in the loaded model that ARE in the current model"); + notInLoadedModel.write(System.out, "N3"); + //Could also do RDF.. if need to + //Do the opposite too to check + Model notInCurrentModel = loadedModel.difference(appDbModel); + System.out.println("**These are statements in loaded model NOT in the current model"); + notInCurrentModel.write(System.out, "N3"); + } catch (Exception ex) { + System.out.println("An error occurred in reading this file"); + ex.printStackTrace(); + } + */ } @Override diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/BrowseDataGetter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/BrowseDataGetter.java index 49118eccf..05483aa1a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/BrowseDataGetter.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/BrowseDataGetter.java @@ -21,6 +21,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; import edu.cornell.mannlib.vitro.webapp.controller.JSONServlet; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache; import edu.cornell.mannlib.vitro.webapp.utils.JSONtoFmModel; @@ -33,10 +34,10 @@ public class BrowseDataGetter implements PageDataGetter { @Override public Map getData(ServletContext context, - VitroRequest vreq, String pageUri, Map page, - String type) { + VitroRequest vreq, String pageUri, Map page) { try{ Map params = vreq.getParameterMap(); + Mode mode = getMode( vreq, params ); switch( mode ){ case VCLASS_ALPHA: @@ -61,7 +62,10 @@ public class BrowseDataGetter implements PageDataGetter { return DisplayVocabulary.HOME_PAGE_TYPE; } - + //Get data servuice + public String getDataServiceUrl() { + return UrlBuilder.getUrl("/dataservice?getSolrIndividualsByVClass=1&vclassId="); + } private Map doClassAlphaDisplay( Map params, VitroRequest request, ServletContext context) throws Exception { Map body = new HashMap(); body.putAll(getCommonValues(context, request)); @@ -215,5 +219,14 @@ public class BrowseDataGetter implements PageDataGetter { else return null; } + + /** + * For processig of JSONObject + */ + public JSONObject convertToJSON(Map dataMap, VitroRequest vreq) { + JSONObject rObj = null; + return rObj; + } + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/ClassGroupPageData.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/ClassGroupPageData.java index b57f38c59..35e0eea1c 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/ClassGroupPageData.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/ClassGroupPageData.java @@ -10,10 +10,12 @@ import javax.servlet.ServletContext; 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.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.VClassGroupTemplateModel; @@ -26,7 +28,7 @@ import edu.cornell.mannlib.vitro.webapp.web.templatemodels.VClassGroupTemplateMo public class ClassGroupPageData implements PageDataGetter{ private static final Log log = LogFactory.getLog(ClassGroupPageData.class); - public Map getData(ServletContext context, VitroRequest vreq, String pageUri, Map page, String type ){ + public Map getData(ServletContext context, VitroRequest vreq, String pageUri, Map page ){ HashMap data = new HashMap(); String classGroupUri = vreq.getWebappDaoFactory().getPageDao().getClassGroupPage(pageUri); data.put("classGroupUri", classGroupUri); @@ -64,7 +66,10 @@ public class ClassGroupPageData implements PageDataGetter{ } - data.put("vClassGroup", group); //may put null + data.put("vClassGroup", group); //may put null + //Also add data service url + //Hardcoding for now, need a more dynamic way of doing this + data.put("dataServiceUrlIndividualsByVClass", this.getDataServiceUrl()); return data; } @@ -112,6 +117,19 @@ public class ClassGroupPageData implements PageDataGetter{ return DisplayVocabulary.CLASSGROUP_PAGE_TYPE; } + //Get data servuice + public String getDataServiceUrl() { + return UrlBuilder.getUrl("/dataservice?getSolrIndividualsByVClass=1&vclassId="); + } + + + /** + * For processig of JSONObject + */ + public JSONObject convertToJSON(Map dataMap, VitroRequest vreq) { + JSONObject rObj = null; + return rObj; + } protected static void setAllClassCountsToZero(VClassGroup vcg){ for(VClass vc : vcg){ vc.setEntityCount(0); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/DataGetterUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/DataGetterUtils.java new file mode 100644 index 000000000..0b0256b5d --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/DataGetterUtils.java @@ -0,0 +1,307 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter; + +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +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 org.json.JSONObject; + +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.Controllers; +import edu.cornell.mannlib.vitro.webapp.controller.JSONServlet; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController; +import edu.cornell.mannlib.vitro.webapp.controller.freemarker.PageController; +import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; +import edu.cornell.mannlib.vitro.webapp.controller.freemarker.SolrIndividualListController.PageRecord; +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.dao.jena.VClassGroupCache; +import edu.cornell.mannlib.vitro.webapp.web.templatemodels.VClassGroupTemplateModel; +import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.ListedIndividualTemplateModel; +import freemarker.ext.beans.BeansWrapper; +import freemarker.template.TemplateModel; + +public class DataGetterUtils { + protected static final String DATA_GETTER_MAP = "pageTypeToDataGetterMap"; + private static final Log log = LogFactory.getLog(DataGetterUtils.class); + + public static Map getDataForPage(String pageUri, VitroRequest vreq, ServletContext context) { + //Based on page type get the appropriate data getter + Map page = getMapForPage(vreq, pageUri); + //Get data getters map + Map dataGetterMap = getPageDataGetterMap(context); + //Get types associated with page + Map data = new HashMap(); + List dataGetters = (List)page.get("dataGetters"); + if( dataGetters != null ){ + for( String dataGetter : dataGetters){ + Map moreData = null; + PageDataGetter getter = dataGetterMap.get(dataGetter); + try{ + moreData = getAdditionalData(pageUri, dataGetter, page, vreq, getter, context); + if( moreData != null) + data.putAll(moreData); + }catch(Throwable th){ + log.error(th,th); + } + } + } + return data; + } + + /** + * + * Convert data to JSON for page uri based on type and related datagetters + * TODO: How to handle different data getters? Will this replace json fields or add to them? + */ + public static JSONObject covertDataToJSONForPage(String pageUri, Map data, VitroRequest vreq, ServletContext context) { + //Based on page type get the appropriate data getter + Map page = getMapForPage(vreq, pageUri); + //Get data getters map + Map dataGetterMap = getPageDataGetterMap(context); + //Get types associated with page + JSONObject rObj = null; + List types = (List)page.get("types"); + if( types != null ){ + for( String type : types){ + JSONObject typeObj = null; + PageDataGetter getter = dataGetterMap.get(type); + try{ + typeObj = getter.convertToJSON(data, vreq); + if( typeObj != null) { + //Copy over everything from this type Obj to + //TODO: Review how to handle duplicate keys, etc. + if(rObj != null) { + //For now, just nests as separate entry + rObj.put(type, typeObj); + } else { + rObj = typeObj; + } + } + + }catch(Throwable th){ + log.error(th,th); + } + } + } + return rObj; + } + /* + * Returns map with all page attributes from display model + */ + public static Map getMapForPage(VitroRequest vreq, String pageUri) { + //do a query to the display model for attributes of this page. + return vreq.getWebappDaoFactory().getPageDao().getPage(pageUri); + } + + public static void setupDataGetters(ServletContext context){ + if( context != null && context.getAttribute(DATA_GETTER_MAP) == null ){ + context.setAttribute(DATA_GETTER_MAP, new HashMap()); + + /* register all page data getters with the PageController servlet. + * There should be a better way of doing this. */ + ClassGroupPageData cgpd = new ClassGroupPageData(); + getPageDataGetterMap(context).put(cgpd.getType(), cgpd); + BrowseDataGetter bdg = new BrowseDataGetter(); + getPageDataGetterMap(context).put(bdg.getType(), bdg); + //TODO: Check if can include by type here + IndividualsForClassesDataGetter cidg = new IndividualsForClassesDataGetter(); + getPageDataGetterMap(context).put(cidg.getType(), cidg); + + } + } + public static Map getPageDataGetterMap(ServletContext sc){ + setupDataGetters(sc); + return (Map)sc.getAttribute(DATA_GETTER_MAP); + } + /* + //Based on page Uri, do conversions + public static PageDataGetter getDataGetterForType(String type, ServletContext sc) { + Map map = getPageDataGetterMap(sc); + PageDataGetter pdg = (PageDataGetter) map.get(type); + return pdg; + }*/ + + protected static Map getAdditionalData( + String pageUri, String dataGetterName, Map page, VitroRequest vreq, PageDataGetter getter, ServletContext context) { + if(dataGetterName == null || dataGetterName.isEmpty()) + return Collections.emptyMap(); + + + if( getter != null ){ + try{ + return getter.getData(context, vreq, pageUri, page); + }catch(Throwable th){ + log.error(th,th); + return Collections.emptyMap(); + } + } else { + return Collections.emptyMap(); + } + } + + /** + * Process results related to VClass or vclasses. Handles both single and multiple vclasses being sent. + */ + public static JSONObject processVclassResultsJSON(Map map, VitroRequest vreq, boolean multipleVclasses) { + JSONObject rObj = new JSONObject(); + VClass vclass=null; + String errorMessage = null; + try{ + DataProperty fNameDp = (new DataProperty()); + fNameDp.setURI("http://xmlns.com/foaf/0.1/firstName"); + DataProperty lNameDp = (new DataProperty()); + lNameDp.setURI("http://xmlns.com/foaf/0.1/lastName"); + DataProperty monikerDp = (new DataProperty()); + monikerDp.setURI( VitroVocabulary.MONIKER); + //this property is vivo specific + DataProperty preferredTitleDp = (new DataProperty()); + preferredTitleDp.setURI("http://vivoweb.org/ontology/core#preferredTitle"); + + + if( log.isDebugEnabled() ){ + @SuppressWarnings("unchecked") + Enumeration e = vreq.getParameterNames(); + while(e.hasMoreElements()){ + String name = (String)e.nextElement(); + log.debug("parameter: " + name); + for( String value : vreq.getParameterValues(name) ){ + log.debug("value for " + name + ": '" + value + "'"); + } + } + } + + //need an unfiltered dao to get firstnames and lastnames + WebappDaoFactory fullWdf = vreq.getFullWebappDaoFactory(); + + String[] vitroClassIdStr = vreq.getParameterValues("vclassId"); + if ( vitroClassIdStr != null && vitroClassIdStr.length > 0){ + for(String vclassId: vitroClassIdStr) { + vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vclassId); + if (vclass == null) { + log.debug("Couldn't retrieve vclass "); + throw new Exception (errorMessage = "Class " + vclassId + " not found"); + } + } + }else{ + log.debug("parameter vclassId URI parameter expected "); + throw new Exception("parameter vclassId URI parameter expected "); + } + List vclassIds = Arrays.asList(vitroClassIdStr); + //if single vclass expected, then include vclass. This relates to what the expected behavior is, not size of list + if(!multipleVclasses) { + //currently used for ClassGroupPage + rObj.put("vclass", + new JSONObject().put("URI",vclass.getURI()) + .put("name",vclass.getName())); + } else { + //For now, utilize very first first VClass (assume that that is the one to be employed) + //TODO: Find more general way of dealing with this + //put multiple ones in? + if(vclassIds.size() > 0) { + vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vclassIds.get(0)); + rObj.put("vclass", new JSONObject().put("URI",vclass.getURI()) + .put("name",vclass.getName())); + } + // rObj.put("vclasses", new JSONObject().put("URIs",vitroClassIdStr) + // .put("name",vclass.getName())); + } + if (vclass != null) { + + rObj.put("totalCount", map.get("totalCount")); + rObj.put("alpha", map.get("alpha")); + + List inds = (List)map.get("entities"); + + JSONArray jInds = new JSONArray(); + for(Individual ind : inds ){ + JSONObject jo = new JSONObject(); + jo.put("URI", ind.getURI()); + jo.put("label",ind.getRdfsLabel()); + jo.put("name",ind.getName()); + jo.put("thumbUrl", ind.getThumbUrl()); + jo.put("imageUrl", ind.getImageUrl()); + jo.put("profileUrl", UrlBuilder.getIndividualProfileUrl(ind, vreq.getWebappDaoFactory())); + + String moniker = JSONServlet.getDataPropertyValue(ind, monikerDp, fullWdf); + jo.put("moniker", moniker); + jo.put("vclassName", JSONServlet.getVClassName(ind,moniker,fullWdf)); + + jo.put("preferredTitle", JSONServlet.getDataPropertyValue(ind, preferredTitleDp, fullWdf)); + jo.put("firstName", JSONServlet.getDataPropertyValue(ind, fNameDp, fullWdf)); + jo.put("lastName", JSONServlet.getDataPropertyValue(ind, lNameDp, fullWdf)); + + jInds.put(jo); + } + rObj.put("individuals", jInds); + + JSONArray wpages = new JSONArray(); + //Made sure that PageRecord here is SolrIndividualListController not IndividualListController + List pages = (List)map.get("pages"); + for( PageRecord pr: pages ){ + JSONObject p = new JSONObject(); + p.put("text", pr.text); + p.put("param", pr.param); + p.put("index", pr.index); + wpages.put( p ); + } + rObj.put("pages",wpages); + + JSONArray jletters = new JSONArray(); + List letters = Controllers.getLetters(); + for( String s : letters){ + JSONObject jo = new JSONObject(); + jo.put("text", s); + jo.put("param", "alpha=" + URLEncoder.encode(s, "UTF-8")); + jletters.put( jo ); + } + rObj.put("letters", jletters); + } + } catch(Exception ex) { + log.error("Error occurred in processing JSON object", ex); + } + return rObj; + } + + /* + * Copied from JSONServlet as expect this to be related to VitroClassGroup + */ + public static JSONObject processVClassGroupJSON(VitroRequest vreq, ServletContext context, VClassGroup vcg) { + JSONObject map = new JSONObject(); + try { + ArrayList classes = new ArrayList(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()); + } catch(Exception ex) { + log.error("Error occurred in processing VClass group ", ex); + } + return map; + } + +} \ No newline at end of file diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/IndividualsForClassesDataGetter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/IndividualsForClassesDataGetter.java new file mode 100644 index 000000000..d2e09689a --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/IndividualsForClassesDataGetter.java @@ -0,0 +1,223 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter; + +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.apache.commons.lang.StringUtils; + +import javax.servlet.ServletContext; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.json.JSONArray; +import org.json.JSONObject; + +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.Controllers; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController; +import edu.cornell.mannlib.vitro.webapp.controller.freemarker.SolrIndividualListController; +import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; +import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController.PageRecord; +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.dao.jena.VClassGroupCache; +import edu.cornell.mannlib.vitro.webapp.web.templatemodels.VClassGroupTemplateModel; +import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.ListedIndividualTemplateModel; +import edu.cornell.mannlib.vitro.webapp.controller.JSONServlet; +import freemarker.ext.beans.BeansWrapper; +import freemarker.template.TemplateModel; + +/** + * This will pass these variables to the template: + * classGroupUri: uri of the classgroup associated with this page. + * vClassGroup: a data structure that is the classgroup associated with this page. + */ +public class IndividualsForClassesDataGetter implements PageDataGetter{ + private static final Log log = LogFactory.getLog(IndividualsForClassesDataGetter.class); + + public Map getData(ServletContext context, VitroRequest vreq, String pageUri, Map page ){ + HashMap data = new HashMap(); + //This is the old technique of getting class intersections + Map> classIntersectionsMap = vreq.getWebappDaoFactory().getPageDao().getClassesAndRestrictionsForPage(pageUri); + + + //Use Individual List Controller to get all the individuals and related data + String alpha = IndividualListController.getAlphaParameter(vreq); + int pageParam = IndividualListController.getPageParameter(vreq); + List inds = new ArrayList(); + try{ + List classes = classIntersectionsMap.get("classes"); + List restrictClasses = classIntersectionsMap.get("restrictClasses"); + //Get vclass group + //Anonymous vclass group + VClassGroup classesGroup = new VClassGroup(); + classesGroup.setURI("displayClasses"); + VClassGroup restrictClassesGroup = new VClassGroup(); + restrictClassesGroup.setURI("restrictClasses"); + List vClasses = new ArrayList(); + List restrictVClasses = new ArrayList(); + VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + for(String classUri: classes) { + //VClass vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(classUri); + //Retrieve vclass from cache to get the count + VClass vclass = vcgc.getCachedVClass(classUri); + if(vclass != null) { + + System.out.println("VClass does exist for " + classUri + " and entity count is " + vclass.getEntityCount()); + vClasses.add(vclass); + } else { + System.out.println("Vclass " + classUri + " does not exist in the cache"); + log.error("Error occurred, vclass does not exist for this uri " + classUri); + //Throw exception here + } + } + classesGroup.setVitroClassList(vClasses); + //What is individual count? Total? + classesGroup.setIndividualCount(vClasses.size()); + data.put("vClassGroup", classesGroup); + List urlEncodedRestrictClasses = new ArrayList(); + if(restrictClasses.size() > 0) { + //classes for restriction are not displayed so don't need to include their class individual counts + for(String restrictClassUri: restrictClasses) { + VClass vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(restrictClassUri); + if(vclass != null) { + restrictVClasses.add(vclass); + } else { + log.error("Error occurred, vclass does not exist for this uri " + restrictClassUri); + } + //Assuming utf-8? + urlEncodedRestrictClasses.add(URLEncoder.encode(restrictClassUri, "UTF-8")); + } + + /* + //If we were actually getting the intersections + for(String classUri: classes) { + List intersectionUris = new ArrayList(); + intersectionUris.add(classUri); + intersectionUris.addAll(restrictClasses); + Map results = SolrIndividualListController.getResultsForVClassIntersections(intersectionUris, pageParam, alpha, vreq.getWebappDaoFactory().getIndividualDao(), context); + data.putAll(results); + List entities = (List)results.get("entities"); + inds.addAll(entities); + }*/ + restrictClassesGroup.setVitroClassList(restrictVClasses); + restrictClassesGroup.setIndividualCount(restrictVClasses.size()); + } else { + + } + String[] restrictClassesArray = new String[urlEncodedRestrictClasses.size()]; + restrictClassesArray = urlEncodedRestrictClasses.toArray(restrictClassesArray); + + //In case just want uris + data.put("restrictClasses", StringUtils.join(restrictClassesArray, ",")); + data.put("restrictVClasses", restrictVClasses); + //not sure if this is useful + data.put("restrictVClassGroup", restrictClassesGroup); + //if we were returning actual results + /* + + //Map results = IndividualListController.getResultsForVClassIntersections(classIntersections, pageParam, alpha, vreq.getWebappDaoFactory().getIndividualDao(), context); + //data.putAll(results); + //NOTE: Below is copied from Individual List Controller's processing as some of these are used in the template + //below may not be necessary if using a different template + + List indsTm = new ArrayList(); + for(Individual ind : inds ){ + indsTm.add(new ListedIndividualTemplateModel(ind,vreq)); + } + data.put("individuals", indsTm); + + List wpages = new ArrayList(); + List pages = (List)data.get("pages"); + BeansWrapper wrapper = new BeansWrapper(); + for( PageRecord pr: pages ){ + wpages.add( wrapper.wrap(pr) ); + } + + + data.put("rdfUrl", vreq.getContextPath()+"/listrdf/"); + + */ + //Also add data service url + //Hardcoding for now, need a more dynamic way of doing this + data.put("dataServiceUrlIndividualsByVClass", this.getDataServiceUrl()); + } catch(Exception ex) { + log.error("An error occurred retrieving Vclass Intersection individuals", ex); + } + + return data; + } + + public static VClassGroupTemplateModel getClassGroup(String classGroupUri, ServletContext context, VitroRequest vreq){ + + VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + List vcgList = vcgc.getGroups(); + VClassGroup group = null; + for( VClassGroup vcg : vcgList){ + if( vcg.getURI() != null && vcg.getURI().equals(classGroupUri)){ + group = vcg; + break; + } + } + + if( classGroupUri != null && !classGroupUri.isEmpty() && group == null ){ + /*This could be for two reasons: one is that the classgroup doesn't exist + * The other is that there are no individuals in any of the classgroup's classes */ + group = vreq.getWebappDaoFactory().getVClassGroupDao().getGroupByURI(classGroupUri); + if( group != null ){ + List vcgFullList = vreq.getWebappDaoFactory().getVClassGroupDao() + .getPublicGroupsWithVClasses(false, true, false); + for( VClassGroup vcg : vcgFullList ){ + if( classGroupUri.equals(vcg.getURI()) ){ + group = vcg; + break; + } + } + if( group == null ){ + log.error("Cannot get classgroup '" + classGroupUri + "'"); + return null; + }else{ + setAllClassCountsToZero(group); + } + }else{ + log.error("classgroup " + classGroupUri + " does not exist in the system"); + return null; + } + } + + return new VClassGroupTemplateModel(group); + } + + public String getType(){ + return DisplayVocabulary.CLASSINDIVIDUALS_PAGE_TYPE; + } + + //Get data servuice + public String getDataServiceUrl() { + return UrlBuilder.getUrl("/dataservice?getSolrIndividualsByVClasses=1&vclassId="); + } + /** + * For processig of JSONObject + */ + public JSONObject convertToJSON(Map map, VitroRequest vreq) { + JSONObject rObj = DataGetterUtils.processVclassResultsJSON(map, vreq, true); + return rObj; + } + + protected static void setAllClassCountsToZero(VClassGroup vcg){ + for(VClass vc : vcg){ + vc.setEntityCount(0); + } + } +} \ No newline at end of file diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/PageDataGetter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/PageDataGetter.java index ed1992ad9..724ed0353 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/PageDataGetter.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/PageDataGetter.java @@ -7,10 +7,21 @@ import java.util.Map; import javax.servlet.ServletContext; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; + +import org.json.JSONObject; public interface PageDataGetter{ - Map getData(ServletContext contect, VitroRequest vreq, String pageUri, Map page, String type ); + Map getData(ServletContext contect, VitroRequest vreq, String pageUri, Map page ); /** Gets the type that this class applies to */ + //This has been changed to return the class name for data getter used in menu management String getType(); + + //get data service url based on data getter requirements + //Get data servuice + String getDataServiceUrl(); + + /**Convert data to JSONObject based on what's required for the data processing**/ + JSONObject convertToJSON(Map map, VitroRequest vreq); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/BaseTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/BaseTemplateModel.java index e457ecfb9..b1710e141 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/BaseTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/BaseTemplateModel.java @@ -18,7 +18,7 @@ public abstract class BaseTemplateModel { private static final Log log = LogFactory.getLog(BaseTemplateModel.class); protected static ServletContext servletContext = null; - + public VitroRequest vitroRequest = null; // Convenience method so subclasses can call getUrl(path) protected String getUrl(String path) { return UrlBuilder.getUrl(path); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/DataPropertyStatementTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/DataPropertyStatementTemplateModel.java index da631e0bc..3c4eed73d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/DataPropertyStatementTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/DataPropertyStatementTemplateModel.java @@ -30,8 +30,6 @@ public class DataPropertyStatementTemplateModel extends PropertyStatementTemplat // Used for editing protected String dataPropHash = null; - //Useful in case additional params to be retrieved for URL - private VitroRequest vitroRequest= null; //Extended to include vitro request to check for special parameters DataPropertyStatementTemplateModel(String subjectUri, String propertyUri, diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/DataPropertyTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/DataPropertyTemplateModel.java index 159a095ab..11732e976 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/DataPropertyTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/DataPropertyTemplateModel.java @@ -31,7 +31,6 @@ public class DataPropertyTemplateModel extends PropertyTemplateModel { private static final String EDIT_PATH = "edit/editDatapropStmtRequestDispatch.jsp"; private List statements; - private VitroRequest vitroRequest = null; DataPropertyTemplateModel(DataProperty dp, Individual subject, VitroRequest vreq, EditingPolicyHelper policyHelper, List populatedDataPropertyList) { diff --git a/webapp/web/js/menupage/browseByVClasses.js b/webapp/web/js/menupage/browseByVClasses.js new file mode 100644 index 000000000..5001c67ab --- /dev/null +++ b/webapp/web/js/menupage/browseByVClasses.js @@ -0,0 +1,117 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +// This file extends and proxies the default behavior defined in vitro/webapp/web/js/menupage/browseByVClass.js + +// Saving the original getIndividuals function from browseByVClass +var getPersonIndividuals = browseByVClass.getIndividuals; + +browseByVClass.getIndividuals = function(vclassUri, alpha, page, scroll) { + url = encodeURIComponent(vclassUri); + var restrictClasses = $('#restrictClasses').val(); + if(restrictClasses.length > 0) { + if(restrictClasses.indexOf(",") != -1) { + var restrictClassesArray = restrictClasses.split(","); + var restrictUris = restrictClassesArray.join("&vclassId="); + url += "&vclassId=" + restrictUris; + } + else { + //does this need to be uri encoded? - assuming already url encoded + url += "&vclassId=" + restrictClasses; + } + } + url = this.dataServiceUrl + url; + //Get restriction classes from url + + if ( alpha && alpha != "all") { + url = url + '&alpha=' + alpha; + } + if ( page ) { + url += '&page=' + page; + } else { + page = 1; + } + if ( typeof scroll === "undefined" ) { + scroll = true; + } + + // Scroll to #menupage-intro page unless told otherwise + if ( scroll != false ) { + // only scroll back up if we're past the top of the #browse-by section + scrollPosition = browseByVClass.getPageScroll(); + browseByOffset = $('#browse-by').offset(); + if ( scrollPosition[1] > browseByOffset.top) { + $.scrollTo('#menupage-intro', 500); + } + } + + $.getJSON(url, function(results) { + individualList = ""; + + // Catch exceptions when empty individuals result set is returned + // This is very likely to happen now since we don't have individual counts for each letter and always allow the result set to be filtered by any letter + if ( results.individuals.length == 0 ) { + browseByVClass.emptyResultSet(results.vclass, alpha) + } else { + $.each(results.individuals, function(i, item) { + label = results.individuals[i].label; + firstName = results.individuals[i].firstName; + lastName = results.individuals[i].lastName; + if ( firstName && lastName ) { + fullName = firstName + ' ' + lastName; + } else { + fullName = label; + } + moniker = results.individuals[i].moniker; + vclassName = results.individuals[i].vclassName; + if ( results.individuals[i].preferredTitle == "") { + // Use the moniker only if it's not empty and not equal to the VClass name + if ( moniker != vclassName && moniker != "" ) { + preferredTitle = moniker; + } else { + preferredTitle = ""; + } + } else { + preferredTitle = results.individuals[i].preferredTitle; + } + uri = results.individuals[i].URI; + profileUrl = results.individuals[i].profileUrl; + if ( !results.individuals[i].thumbUrl ) { + image = browseByVClass.baseUrl + '/images/placeholders/person.thumbnail.jpg'; + } else { + image = browseByVClass.baseUrl + results.individuals[i].thumbUrl; + } + // Build the content of each list item, piecing together each component + listItem = '
  • '; + listItem += ''+ fullName +''; + listItem += '

    '+ fullName +'

    '; + // Include the calculated preferred title (see above) only if it's not empty + if ( preferredTitle != "" ) { + listItem += ''+ preferredTitle +''; + } + listItem += '
  • '; + // browseByVClass.individualsInVClass.append(listItem); + individualList += listItem; + }) + + // Remove existing content + browseByVClass.wipeSlate(); + + // And then add the new content + browseByVClass.individualsInVClass.append(individualList); + + // Check to see if we're dealing with pagination + if ( results.pages.length ) { + pages = results.pages; + browseByVClass.pagination(pages, page); + } + //Check if single vclass sent back, otherwise check for vclasses + if(results.vclass) { + selectedClassHeading = '

    '+ results.vclass.name +'

    '; + browseByVClass.individualsContainer.prepend(selectedClassHeading); + } + // set selected class, alpha and page + browseByVClass.selectedVClass(results.vclass.URI); + browseByVClass.selectedAlpha(alpha); + } + }); +}; \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/menupage/menupage--individualsforclasses.ftl b/webapp/web/templates/freemarker/body/menupage/menupage--individualsforclasses.ftl new file mode 100644 index 000000000..6426a649d --- /dev/null +++ b/webapp/web/templates/freemarker/body/menupage/menupage--individualsforclasses.ftl @@ -0,0 +1,19 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + +<#include "menupage-checkForData.ftl"> +<#--Not including data check because vclasses don't appear to return entity counts on their own --> +<#if !noData> + + + <#include "menupage-individualsforclasses-browse.ftl"> + + ${stylesheets.add('')} + + <#include "menupage-scripts.ftl"> + + ${scripts.add('')} +<#else> + <# ${noDataNotification} > + \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/partials/menupage/menupage-individualsforclasses-browse.ftl b/webapp/web/templates/freemarker/body/partials/menupage/menupage-individualsforclasses-browse.ftl new file mode 100644 index 000000000..f591e3d47 --- /dev/null +++ b/webapp/web/templates/freemarker/body/partials/menupage/menupage-individualsforclasses-browse.ftl @@ -0,0 +1,41 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + +<#-- Template for browsing individuals in class groups for menupages --> +<#import "lib-string.ftl" as str> + +
    + + +
    +
      + <#-- Will be populated dynamically via AJAX request --> +
    +
    +
    \ No newline at end of file