From 0c32b6e4ac77d47136a9b48d768f92a7ed9fa121 Mon Sep 17 00:00:00 2001 From: hjkhjk54 Date: Wed, 29 Feb 2012 22:20:36 +0000 Subject: [PATCH] page data getter classes being redone as data getter classes --- .../utils/dataGetter/BrowseDataGetter.java | 252 +++++++++++ .../dataGetter/ClassGroupDataGetter.java | 196 +++++++++ .../utils/dataGetter/DataGetterUtils.java | 158 ++++++- .../IndividualsForClassesDataGetter.java | 406 ++++++++++++++++++ 4 files changed, 1010 insertions(+), 2 deletions(-) create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/BrowseDataGetter.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/ClassGroupDataGetter.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/IndividualsForClassesDataGetter.java diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/BrowseDataGetter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/BrowseDataGetter.java new file mode 100644 index 000000000..eb1a5560e --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/BrowseDataGetter.java @@ -0,0 +1,252 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.utils.dataGetter; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +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 com.hp.hpl.jena.rdf.model.Model; + +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.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; +import edu.cornell.mannlib.vitro.webapp.web.templatemodels.VClassGroupTemplateModel; +import edu.cornell.mannlib.vitro.webapp.web.templatemodels.VClassTemplateModel; +import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individuallist.ListedIndividual; + +public class BrowseDataGetter extends DataGetterBase implements DataGetter { + final static Log log = LogFactory.getLog(BrowseDataGetter.class); + String dataGetterURI; + + /** + * Constructor with display model and data getter URI that will be called by reflection. + */ + public BrowseDataGetter(Model displayModel, String dataGetterURI){ + this.configure(displayModel,dataGetterURI); + } + + /** + * Configure this instance based on the URI and display model. + */ + protected void configure(Model displayModel, String dataGetterURI) { + if( displayModel == null ) + throw new IllegalArgumentException("Display Model may not be null."); + if( dataGetterURI == null ) + throw new IllegalArgumentException("PageUri may not be null."); + + this.dataGetterURI = dataGetterURI; + } + + @Override + public Map getData(ServletContext context, VitroRequest vreq, Map pageData) { + try{ + Map params = vreq.getParameterMap(); + + Mode mode = getMode( vreq, params ); + switch( mode ){ + case VCLASS_ALPHA: + return doClassAlphaDisplay(params,vreq,context); + case CLASS_GROUP: + return doClassGroupDisplay(params, vreq, context); + case VCLASS: + return doClassDisplay(params, vreq, context); + case ALL_CLASS_GROUPS: + return doAllClassGroupsDisplay( params, vreq, context); + default: + return doAllClassGroupsDisplay( params, vreq, context); + } + }catch(Throwable th){ + log.error(th,th); + return Collections.emptyMap(); + } + } + + public String getType() { + 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)); + body.putAll(getClassAlphaValues(params,request,context)); + return body; + } + + private Map getClassAlphaValues( Map params, VitroRequest request, ServletContext context) throws Exception{ + Map map= new HashMap(); + + String classUri = getParam(Mode.VCLASS, request, params); + VitroRequest vreq = new VitroRequest(request); + VClass vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(classUri); + map.put("class", new VClassTemplateModel(vclass)); + + JSONObject vclassRes = JsonServlet.getSolrIndividualsByVClass(vclass.getURI(), request, context); + map.put("totalCount", JsonToFmModel.convertJSONObjectToMap( (String) vclassRes.get("totalCount") )); + map.put("alpha", JsonToFmModel.convertJSONObjectToMap( (String) vclassRes.get("alpha") )); + map.put("individuals", JsonToFmModel.convertJSONArrayToList( (JSONArray) vclassRes.get("individuals") )); + map.put("pages", JsonToFmModel.convertJSONArrayToList( (JSONArray) vclassRes.get("pages") )); + map.put("letters", JsonToFmModel.convertJSONArrayToList( (JSONArray) vclassRes.get("letters") )); + + return map; + } + + private Map getCommonValues( ServletContext context, VitroRequest vreq){ + Map values = new HashMap(); + + VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + List cgList = vcgc.getGroups(); + LinkedList cgtmList = new LinkedList(); + for( VClassGroup classGroup : cgList){ + cgtmList.add( new VClassGroupTemplateModel( classGroup )); + } + values.put("vClassGroups",cgtmList); + + return values; + } + + protected Map doAllClassGroupsDisplay( Map params, VitroRequest request, ServletContext context) { + Map body = new HashMap(); + body.putAll(getCommonValues(context,request)); + body.putAll(getAllClassGroupData(request, params, context)); + + return body; + } + + /** + * Gets a list of all VClassGroups with vclasses with individual counts. + * @param params2 + */ + protected Map getAllClassGroupData(VitroRequest request, Map params, ServletContext context){ + Map map = new HashMap(); + return map; + } + + protected Map doClassDisplay( Map params, + VitroRequest request, ServletContext context) { + Map body = new HashMap(); + + body.putAll(getCommonValues(context,request)); + body.putAll(getClassData(request,params,context)); + + return body; + } + + private Map getClassData(VitroRequest request, Map params, ServletContext context) { + Map map = new HashMap(); + + map.putAll(getClassGroupData(request, params,context)); + + String classUri = getParam(Mode.VCLASS, request, params); + VitroRequest vreq = new VitroRequest(request); + VClass vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(classUri); + map.put("class", new VClassTemplateModel(vclass)); + + List inds = vreq.getWebappDaoFactory().getIndividualDao() + .getIndividualsByVClass(vclass); + + List tInds = new ArrayList(inds.size()); + for( Individual ind : inds){ + tInds.add(new ListedIndividual(ind, vreq)); + } + map.put("individualsInClass", tInds); + + return map; + } + + protected Map doClassGroupDisplay(Map params, VitroRequest request, ServletContext context) { + Map body = new HashMap(); + body.putAll(getCommonValues(context,request)); + body.putAll( getClassGroupData(request,params, context)); + + return body; + } + + protected Map getClassGroupData(VitroRequest request, Map params, ServletContext context) { + Map map = new HashMap(); + + String vcgUri = getParam(Mode.CLASS_GROUP, request, params); + VitroRequest vreq = new VitroRequest(request); + + VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + VClassGroup vcg = vcgc.getGroup(vcgUri); + + ArrayList classes = new ArrayList(vcg.size()); + for( VClass vc : vcg){ + classes.add(new VClassTemplateModel(vc)); + } + map.put("classes", classes); + + map.put("classGroup", new VClassGroupTemplateModel(vcg)); + + return map; + } + + + enum Mode{ + VCLASS_ALPHA("vclassAlpha"), + VCLASS("vclassUri"), + CLASS_GROUP("classgroupUri"), + ALL_CLASS_GROUPS("all"); + String param; + Mode(String param){ + this.param = param; + } + } + + protected final static Mode DEFAULT_MODE = Mode.ALL_CLASS_GROUPS; + + protected Mode getMode(VitroRequest request, Map params){ + for( Mode mode : Mode.values()){ + String queryParam = request.getParameter( mode.param ); + if( queryParam != null && !queryParam.isEmpty() ){ + return mode; + } + Object obj = params.get( mode.param ); + String param = obj != null ? obj.toString():null; + if( param != null && !param.isEmpty() ){ + return mode; + } + } + return DEFAULT_MODE; + } + + public static String getParam(Mode mode, VitroRequest request, Map params){ + if( request.getParameter(mode.param) != null ) + return request.getParameter(mode.param); + if( params.get(mode.param) != null ) + return params.get(mode.param).toString(); + 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/dataGetter/ClassGroupDataGetter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/ClassGroupDataGetter.java new file mode 100644 index 000000000..145b5af49 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/ClassGroupDataGetter.java @@ -0,0 +1,196 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.utils.dataGetter; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletContext; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.json.JSONObject; + +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.query.QueryExecution; +import com.hp.hpl.jena.query.QueryExecutionFactory; +import com.hp.hpl.jena.query.QueryFactory; +import com.hp.hpl.jena.query.QuerySolution; +import com.hp.hpl.jena.query.QuerySolutionMap; +import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.rdf.model.Literal; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.RDFNode; +import com.hp.hpl.jena.rdf.model.ResourceFactory; +import com.hp.hpl.jena.shared.Lock; + +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; + +/** + * 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 ClassGroupDataGetter extends DataGetterBase implements DataGetter{ + + private static final Log log = LogFactory.getLog(ClassGroupDataGetter.class); + String dataGetterURI; + String classGroupUri; + /** + * Constructor with display model and data getter URI that will be called by reflection. + */ + public ClassGroupDataGetter(Model displayModel, String dataGetterURI){ + this.configure(displayModel,dataGetterURI); + } + + /** + * Configure this instance based on the URI and display model. + */ + protected void configure(Model displayModel, String dataGetterURI) { + if( displayModel == null ) + throw new IllegalArgumentException("Display Model may not be null."); + if( dataGetterURI == null ) + throw new IllegalArgumentException("PageUri may not be null."); + + this.dataGetterURI = dataGetterURI; + this.classGroupUri = DataGetterUtils.getClassGroupForDataGetter(displayModel, dataGetterURI); + } + + + @Override + public Map getData(ServletContext context, VitroRequest vreq, Map pageData) { + HashMap data = new HashMap(); + data.put("classGroupUri", this.classGroupUri); + + 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); + }else{ + setAllClassCountsToZero(group); + } + }else{ + log.error("classgroup " + classGroupUri + " does not exist in the system"); + } + + } + log.debug("Retrieved class group " + group.getURI() + " and returning to template"); + //if debug enabled, print out the number of entities within each class in the class gorup + if(log.isDebugEnabled()){ + List groupClasses = group.getVitroClassList(); + for(VClass v: groupClasses) { + log.debug("Class " + v.getName() + " - " + v.getURI() + " has " + v.getEntityCount() + " entities"); + } + } + data.put("vClassGroup", group); //may put null + + //This page level data getters tries to set its own template, + // not all of the data getters need to do this. + data.put("bodyTemplate", "page-classgroup.ftl"); + + //Also add data service url + //Hardcoding for now, need a more dynamic way of doing this + data.put("dataServiceUrlIndividualsByVClass", this.getDataServiceUrl()); + 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); + } + + //Get data servuice + public String getDataServiceUrl() { + return UrlBuilder.getUrl("/dataservice?getSolrIndividualsByVClass=1&vclassId="); + } + + /** + * Query to get the definition of the ClassGroupDataGetter for a given data getter URI - specifically + * the class group uri + */ + private static final String forClassGroupURI = "<" + DisplayVocabulary.FOR_CLASSGROUP + ">"; + private static final String dataGetterQuery = + "PREFIX display: <" + DisplayVocabulary.DISPLAY_NS +"> \n" + + "SELECT ?classGroupUri WHERE { \n" + + " ?dataGetterUri "+forClassGroupURI+" ?classGroupUri . \n" + + "}"; + + + + /** + * For processing of JSONObject + */ + //Currently empty, TODO: Review requirements + 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); + } + } +} \ No newline at end of file diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/DataGetterUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/DataGetterUtils.java index b62e57fd5..dbc2a5572 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/DataGetterUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/DataGetterUtils.java @@ -6,7 +6,9 @@ import java.lang.reflect.InvocationTargetException; 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; @@ -36,6 +38,7 @@ import com.hp.hpl.jena.vocabulary.OWL; 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; @@ -45,7 +48,9 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListCont 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.utils.pageDataGetter.PageDataGetterUtils; +import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache; +import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetterORIG.PageDataGetter; + public class DataGetterUtils { @@ -155,7 +160,7 @@ public class DataGetterUtils { QuerySolution soln = results.nextSolution(); Resource type = soln.getResource("type"); if( type != null && type.getURI() != null){ - types.add( PageDataGetterUtils.getClassNameFromUri( type.getURI() )); + types.add( DataGetterUtils.getClassNameFromUri( type.getURI() )); } } }finally{ qexec.close(); } @@ -402,4 +407,153 @@ public class DataGetterUtils { " ?dataGetterUri "+forClassGroupURI+" ?classGroupUri . \n" + "}"; + + /** + * + * 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? + * @throws ClassNotFoundException + * @throws IllegalAccessException + * @throws InstantiationException + */ + public static JSONObject covertDataToJSONForPage(String pageUri, Model displayModel) throws InstantiationException, IllegalAccessException, ClassNotFoundException { + //Get PageDataGetter types associated with pageUri + JSONObject rObj = null; + try{ + List dataGetters = getDataGettersForPage(displayModel, pageUri); + for(DataGetter getter: dataGetters) { + JSONObject typeObj = null; + try{ + //Assumes the data getter itself will have a convert to json method + /* + 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(getter.getType(), typeObj); + } else { + rObj = typeObj; + } + } */ + + } catch(Throwable th){ + log.error(th,th); + } + } + } catch(Throwable th) { + log.error(th, th); + } + return rObj; + } + + + /*** + * For the page, get the actual Data Getters to be employed. + * @throws ClassNotFoundException + * @throws IllegalAccessException + * @throws InstantiationException + */ + /* + public static List DataGetterObjects(VitroRequest vreq, String pageUri) throws InstantiationException, IllegalAccessException, ClassNotFoundException { + List dataGetterObjects = new ArrayList(); + + List dataGetterClassNames = vreq.getWebappDaoFactory().getPageDao().getDataGetterClass(pageUri); + if( dataGetterClassNames == null ) + return Collections.emptyList(); + + for(String dgClassName: dataGetterClassNames) { + String className = getClassNameFromUri(dgClassName); + Class clz = Class.forName(className); + + if( DataGetterUtils.isInstanceOfInterface(clz, PageDataGetter.class)){ + Object obj = clz.newInstance(); + if(obj != null && obj instanceof PageDataGetter) { + PageDataGetter pg = (PageDataGetter) obj; + dataGetterObjects.add(pg); + } + }// else skip if class does not implement PageDataGetter + } + + return dataGetterObjects; + } + */ + + //Class URIs returned include "java:" and to instantiate object need to remove java: portion + public static String getClassNameFromUri(String dataGetterClassUri) { + if( !StringUtils.isEmpty(dataGetterClassUri) && dataGetterClassUri.contains("java:")) { + String[] splitArray = dataGetterClassUri.split("java:"); + if(splitArray.length > 1) { + return splitArray[1]; + } + } + return dataGetterClassUri; + } + + + + /* + * 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; + } + + + //Get All VClass Groups information + //Used within menu management and processing + //TODO: Check if more appropriate location possible + public static List> getClassGroups(ServletContext context) { + //Wanted this to be + VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + List vcgList = vcgc.getGroups(); + //For now encoding as hashmap with label and URI as trying to retrieve class group + //results in errors for some reason + List> classGroups = new ArrayList>(); + for(VClassGroup vcg: vcgList) { + HashMap hs = new HashMap(); + hs.put("publicName", vcg.getPublicName()); + hs.put("URI", vcg.getURI()); + classGroups.add(hs); + } + return classGroups; + } + + + //TODO: Check whether this needs to be put here or elsewhere, as this is data getter specific + //with respect to class groups + //Need to use VClassGroupCache to retrieve class group information - this is the information returned from "for class group" + public static void getClassGroupForDataGetter(ServletContext context, Map pageData, Map templateData) { + //Get the class group from VClassGroup, this is the same as the class group for the class group page data getter + //and the associated class group (not custom) for individuals datagetter + String classGroupUri = (String) pageData.get("classGroupUri"); + VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + VClassGroup group = vcgc.getGroup(classGroupUri); + + templateData.put("classGroup", group); + templateData.put("associatedPage", group.getPublicName()); + templateData.put("associatedPageURI", group.getURI()); + } + + + + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/IndividualsForClassesDataGetter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/IndividualsForClassesDataGetter.java new file mode 100644 index 000000000..7a0ae2ef7 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/IndividualsForClassesDataGetter.java @@ -0,0 +1,406 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.utils.dataGetter; + +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletContext; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.json.JSONObject; + +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.query.QueryExecution; +import com.hp.hpl.jena.query.QueryExecutionFactory; +import com.hp.hpl.jena.query.QueryFactory; +import com.hp.hpl.jena.query.QuerySolution; +import com.hp.hpl.jena.query.QuerySolutionMap; +import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.RDFNode; +import com.hp.hpl.jena.rdf.model.ResourceFactory; +import com.hp.hpl.jena.rdf.model.Statement; +import com.hp.hpl.jena.rdf.model.StmtIterator; +import com.hp.hpl.jena.shared.Lock; + +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.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController; +import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; +import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.PageDao; +import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; +import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache; +import edu.cornell.mannlib.vitro.webapp.web.templatemodels.VClassGroupTemplateModel; + +/** + * 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 extends DataGetterBase implements DataGetter{ + private static final Log log = LogFactory.getLog(IndividualsForClassesDataGetter.class); + protected static String restrictClassesTemplateName = null; + String dataGetterURI; + String classGroupURI; + Map classIntersectionsMap; + + /** + * Constructor with display model and data getter URI that will be called by reflection. + */ + public IndividualsForClassesDataGetter(Model displayModel, String dataGetterURI){ + this.configure(displayModel,dataGetterURI); + } + + /** + * Configure this instance based on the URI and display model. + */ + protected void configure(Model displayModel, String dataGetterURI) { + if( displayModel == null ) + throw new IllegalArgumentException("Display Model may not be null."); + if( dataGetterURI == null ) + throw new IllegalArgumentException("PageUri may not be null."); + + this.dataGetterURI = dataGetterURI; + this.classGroupURI = DataGetterUtils.getClassGroupForDataGetter(displayModel, dataGetterURI); + this.classIntersectionsMap = getClassIntersectionsMap(displayModel); + } + + /** + * Get the classes and classes to restrict by - if any + */ + + protected Map getClassIntersectionsMap(Model displayModel) { + QuerySolutionMap initBindings = new QuerySolutionMap(); + initBindings.add("dataGetterURI", ResourceFactory.createResource(this.dataGetterURI)); + try { + QueryExecution qexec = QueryExecutionFactory.create( dataGetterQuery, displayModel , initBindings); + Map classesAndRestrictions = new HashMap(); + List classes = new ArrayList(); + displayModel.enterCriticalSection(Lock.READ); + + try{ + List restrictClasses = new ArrayList(); + HashMap restrictClassesPresentMap = new HashMap(); + ResultSet resultSet = qexec.execSelect(); + while(resultSet.hasNext()){ + QuerySolution soln = resultSet.next(); + classes.add(DataGetterUtils.nodeToString(soln.get("class"))); + String restrictClass = DataGetterUtils.nodeToString(soln.get("restrictClass")); + if(!restrictClass.isEmpty() && !restrictClassesPresentMap.containsKey(restrictClass)) { + restrictClasses.add(restrictClass); + restrictClassesPresentMap.put(restrictClass, "true"); + } + } + + if( classes.size() == 0 ){ + log.debug("No classes defined in display model for "+ this.dataGetterURI); + this.classIntersectionsMap = null; + } + classesAndRestrictions.put("classes", classes); + classesAndRestrictions.put("restrictClasses", restrictClasses); + return classesAndRestrictions; + + }finally{ + qexec.close(); + } + }finally{ + displayModel.leaveCriticalSection(); + } + + } + + @Override + public Map getData(ServletContext context, VitroRequest vreq, Map pageData) { + this.setTemplateName(); + HashMap data = new HashMap(); + + try{ + List classes = retrieveClasses(context, classIntersectionsMap); + List restrictClasses = retrieveRestrictClasses(context, classIntersectionsMap); + log.debug("Retrieving classes for " + classes.toString() + " and restricting by " + restrictClasses.toString()); + processClassesAndRestrictions(vreq, context, data, classes, restrictClasses); + //Also add data service url + //Hardcoding for now, need a more dynamic way of doing this + data.put("dataServiceUrlIndividualsByVClass", this.getDataServiceUrl()); + //this is the class group associated with the data getter utilized for display on menu editing, not the custom one created + data.put("classGroupUri",this.classGroupURI); + } catch(Exception ex) { + log.error("An error occurred retrieving Vclass Intersection individuals", ex); + } + + return data; + } + + protected void setTemplateName() { + this.restrictClassesTemplateName = "restricted"; + } + + + protected List retrieveClasses( + ServletContext context, Map classIntersectionsMap) { + List restrictClasses = (List) classIntersectionsMap.get("classes"); + return restrictClasses; + } + + protected List retrieveRestrictClasses( + ServletContext context, Map classIntersectionsMap) { + List restrictClasses = (List) classIntersectionsMap.get("restrictClasses"); + return restrictClasses; + } + + protected void processClassesAndRestrictions(VitroRequest vreq, ServletContext context, + HashMap data, List classes, List restrictClasses ) { + processClassesForDisplay(vreq, context, data, classes); + processRestrictionClasses(vreq, context, data, restrictClasses); + processIntersections(vreq, context, data); + + } + + + + //At this point, data specifices whether or not intersections included + private void processIntersections(VitroRequest vreq, + ServletContext context, HashMap data) { + VClassGroup classesGroup = (VClassGroup) data.get("vClassGroup"); + List vclassList = classesGroup.getVitroClassList(); + List restrictClasses = (List) data.get("restrictVClasses"); + //if there are restrict classes, then update counts + if(restrictClasses.size() > 0) { + log.debug("Restriction classes exist"); + List newVClassList = new ArrayList(); + //Iterate through vclasses and get updated counts, iterated and saved in same order as initially included + for(VClass v: vclassList) { + int oldCount = v.getEntityCount(); + //Making a copy so as to ensure we don't touch the values in the cache + VClass copyVClass = makeCopyVClass(v); + int count = retrieveCount(vreq, context, v, restrictClasses); + if(oldCount != count) { + log.debug("Old count was " + v.getEntityCount() + " and New count for " + v.getURI() + " is " + count); + copyVClass.setEntityCount(count); + } + newVClassList.add(copyVClass); + } + classesGroup.setVitroClassList(newVClassList); + //TODO: Do we need to do this again or will this already be reset? + data.put("vClassGroup", classesGroup); + } + } + + private VClass makeCopyVClass(VClass v) { + VClass copyVClass = new VClass(v.getURI()); + copyVClass.setLocalName(copyVClass.getLocalName()); + copyVClass.setDisplayRank(v.getDisplayRank()); + copyVClass.setName(v.getName()); + copyVClass.setNamespace(v.getNamespace()); + copyVClass.setEntityCount(v.getEntityCount()); + return copyVClass; + } + + //update class count based on restrict classes + private int retrieveCount(VitroRequest vreq, ServletContext context, VClass v, List restrictClasses) { + //Execute solr query that returns only count of individuals + log.debug("Entity count is " + v.getEntityCount()); + List classUris = new ArrayList(); + classUris.add(v.getURI()); + for(VClass r: restrictClasses) { + classUris.add(r.getURI()); + } + long count = DataGetterUtils.getIndividualCountForIntersection(vreq, context, classUris); + return new Long(count).intValue(); + + } + + private void processClassesForDisplay(VitroRequest vreq, ServletContext context, HashMap data, List classes) { + VClassGroup classesGroup = new VClassGroup(); + classesGroup.setURI("displayClasses"); + log.debug("Processing classes that will be displayed"); + List vClasses = new ArrayList(); + + VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + for(String classUri: classes) { + //Retrieve vclass from cache to get the count + VClass vclass = vcgc.getCachedVClass(classUri); + //if not found in cache, possibly due to not being in any class group + if(vclass == null) { + vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(classUri); + } + if(vclass != null) { + log.debug("VClass does exist for " + classUri + " and entity count is " + vclass.getEntityCount()); + vClasses.add(vclass); + } else { + log.debug("Vclass " + classUri + " does not exist in the cache"); + log.error("Error occurred, vclass does not exist for this uri " + classUri); + //Throw exception here + } + } + //Sort these classes + Collections.sort(vClasses); + log.debug("Sorting complete for V Classes"); + classesGroup.setVitroClassList(vClasses); + log.debug("Returning vitro class list in data for template"); + //Set vclass group + data.put("vClassGroup", classesGroup); + } + + private void processRestrictionClasses(VitroRequest vreq, ServletContext context, + HashMap data, List restrictClasses) { + try { + VClassGroup restrictClassesGroup = new VClassGroup(); + restrictClassesGroup.setURI("restrictClasses"); + + List restrictVClasses = new ArrayList(); + + List urlEncodedRestrictClasses = new ArrayList(); + VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + + if(restrictClasses.size() > 0) { + //classes for restriction are not displayed so don't need to include their class individual counts + for(String restrictClassUri: restrictClasses) { + //Also uses cache to remain consistent with process classes and also allow + //vclasses to be returned even if switched to display model, although + //uris used within display model editing and not vclass objects + VClass vclass = vcgc.getCachedVClass(restrictClassUri); + //if not found in cache, possibly due to not being in any class group + if(vclass == null) { + vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(restrictClassUri); + } + if(vclass != null) { + log.debug("Found restrict class and adding to list " + restrictClassUri); + 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")); + } + + restrictClassesGroup.setVitroClassList(restrictVClasses); + restrictClassesGroup.setIndividualCount(restrictVClasses.size()); + } else { + + } + String[] restrictClassesArray = new String[urlEncodedRestrictClasses.size()]; + restrictClassesArray = urlEncodedRestrictClasses.toArray(restrictClassesArray); + + //In case just want uris + log.debug("Variable name for including restriction classes " + getRestrictClassesTemplateName()); + data.put(getRestrictClassesTemplateName(), StringUtils.join(restrictClassesArray, ",")); + data.put("restrictVClasses", restrictVClasses); + //not sure if this is useful + data.put("restrictVClassGroup", restrictClassesGroup); + } catch(Exception ex) { + log.error("An error occurred in processing restriction classes ", ex); + } + } + + 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 DataGetterUtils.generateDataGetterTypeURI(IndividualsForClassesDataGetter.class.getName()); + } + + //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); + } + } + + protected static String getAlphaParameter(VitroRequest request){ + return request.getParameter("alpha"); + } + + protected static int getPageParameter(VitroRequest request) { + String pageStr = request.getParameter("page"); + if( pageStr != null ){ + try{ + return Integer.parseInt(pageStr); + }catch(NumberFormatException nfe){ + log.debug("could not parse page parameter"); + return 1; + } + }else{ + return 1; + } + } + + //Get template parameter + private static String getRestrictClassesTemplateName() { + return restrictClassesTemplateName; + + } + + private static final String prefixes = + "PREFIX rdf: <" + VitroVocabulary.RDF +"> \n" + + "PREFIX rdfs: <" + VitroVocabulary.RDFS +"> \n" + + "PREFIX xsd: \n" + + "PREFIX display: <" + DisplayVocabulary.DISPLAY_NS +"> \n"; + + private static final String dataGetterQuery = + prefixes + "\n" + + "SELECT ?class ?restrictClass WHERE {\n" + + " ?dataGetterUri <" + DisplayVocabulary.GETINDIVIDUALS_FOR_CLASS + "> ?class . \n" + + " OPTIONAL {?dg <"+ DisplayVocabulary.RESTRICT_RESULTS_BY + "> ?restrictClass } .\n" + + "} \n" ; +} \ No newline at end of file