From 377ca449408f672e8f88f0da9869f85fa93b2c99 Mon Sep 17 00:00:00 2001 From: bdc34 Date: Thu, 9 Dec 2010 23:53:56 +0000 Subject: [PATCH] Adding XML search results NIHVIVO-1303. Adding menu page browse NIHVIVO-632. --- .../freemarker/BrowseController.java | 41 +-- .../vitro/webapp/dao/VClassGroupDao.java | 2 + .../webapp/filters/PageRoutingFilter.java | 18 ++ .../FreemarkerPagedSearchController.java | 300 ++++++++++++------ .../templatemodels/VClassTemplateModel.java | 4 + .../webapp/web/widgets/BrowseWidget.java | 176 ++++++++++ .../vitro/webapp/filters/VitroURLTest.java | 26 +- .../menupage/menupage--classgroup-people.ftl | 4 + .../body/search/search-xmlResults.ftl | 21 ++ .../freemarker/widgets/widget-browse.ftl | 52 +++ 10 files changed, 503 insertions(+), 141 deletions(-) create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/BrowseWidget.java create mode 100644 webapp/web/templates/freemarker/body/search/search-xmlResults.ftl create mode 100644 webapp/web/templates/freemarker/widgets/widget-browse.ftl diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/BrowseController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/BrowseController.java index fad82a808..eaeaf7d15 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/BrowseController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/BrowseController.java @@ -123,55 +123,22 @@ public class BrowseController extends FreemarkerHttpServlet { // Get all classgroups, each populated with a list of their member vclasses List groups = vcgDao.getPublicGroupsWithVClasses(ORDER_BY_DISPLAYRANK, !INCLUDE_UNINSTANTIATED, includeIndividualCount); - // remove classes that have been configured to be hidden - // from search results - removeClassesHiddenFromSearch(groups); + // remove classes that have been configured to be hidden from search results + vcgDao.removeClassesHiddenFromSearch(groups); - // now cull out the groups with no populated classes - //removeUnpopulatedClasses( groups); + // now cull out the groups with no populated classes vcgDao.removeUnpopulatedGroups(groups); - //_groupListMap.put(portalId, groups); return groups; } else { return grp; } - } - - private void removeClassesHiddenFromSearch(List groups) { - OntModel displayOntModel = - (OntModel) getServletConfig().getServletContext() - .getAttribute("displayOntModel"); - ProhibitedFromSearch pfs = new ProhibitedFromSearch( - DisplayVocabulary.PRIMARY_LUCENE_INDEX_URI, displayOntModel); - for (VClassGroup group : groups) { - List classList = new ArrayList(); - for (VClass vclass : group.getVitroClassList()) { - if (!pfs.isClassProhibited(vclass.getURI())) { - classList.add(vclass); - } - } - group.setVitroClassList(classList); - } - - } + } private static boolean ORDER_BY_DISPLAYRANK = true; private static boolean INCLUDE_UNINSTANTIATED = true; private static boolean INCLUDE_INDIVIDUAL_COUNT = true; -// private void removeUnpopulatedClasses( List groups){ -// if( groups == null || groups.size() == 0 ) return; -// for( VClassGroup grp : groups ){ -// ListIterator it = grp.listIterator(); -// while(it.hasNext()){ -// VClass claz = (VClass)it.next(); -// if( claz.getEntityCount() < 1 ) -// it.remove(); -// } -// } -// } - void requestCacheUpdate(String portalUri){ log.debug("requesting update for portal " + portalUri); _rebuildQueue.add(portalUri); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VClassGroupDao.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VClassGroupDao.java index 72e169e69..ecfbea7ab 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VClassGroupDao.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VClassGroupDao.java @@ -54,6 +54,8 @@ public interface VClassGroupDao { public abstract int removeUnpopulatedGroups(List groups); + public void removeClassesHiddenFromSearch(List groups); + int insertNewVClassGroup(VClassGroup vcg); void updateVClassGroup(VClassGroup vcg); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/PageRoutingFilter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/PageRoutingFilter.java index 0f516cfee..ac7d76590 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/PageRoutingFilter.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/PageRoutingFilter.java @@ -39,6 +39,7 @@ public class PageRoutingFilter implements Filter{ protected final static String URL_PART_PATTERN = "(/[^/]*).*"; protected final static String PAGE_CONTROLLER_NAME = "PageController"; protected final static String HOME_CONTROLLER_NAME = "HomePageController"; + protected final static String TAB_CONTROLLER_NAME = "TabController"; protected final Pattern urlPartPattern = Pattern.compile(URL_PART_PATTERN); @@ -101,6 +102,9 @@ public class PageRoutingFilter implements Filter{ protected String getControllerToForwardTo(HttpServletRequest req, String pageUri, PageDao pageDao) { + + if( isTabController(req) ) + return TAB_CONTROLLER_NAME; String homePageUri = pageDao.getHomePageUri(); if( pageUri != null && pageUri.equals(homePageUri) ) return HOME_CONTROLLER_NAME; @@ -108,6 +112,20 @@ public class PageRoutingFilter implements Filter{ return PAGE_CONTROLLER_NAME; } + /** + * Checks to see if this is a request to the old tab controller + */ + protected boolean isTabController( HttpServletRequest req ){ + if( req.getParameter("primary") != null || + req.getParameter("secondary") != null || + req.getParameter("collection") != null || + req.getParameter("subcollection") != null ){ + String path = req.getRequestURI().substring(req.getContextPath().length()); + return "/".equals(path) ; + } + return false; + } + protected PageDao getPageDao(){ WebappDaoFactory wdf = (WebappDaoFactory) filterConfig.getServletContext().getAttribute("webappDaoFactory"); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/FreemarkerPagedSearchController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/FreemarkerPagedSearchController.java index c26af2d20..7d6e6b193 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/FreemarkerPagedSearchController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/FreemarkerPagedSearchController.java @@ -19,6 +19,8 @@ import java.util.Set; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -77,6 +79,7 @@ import edu.cornell.mannlib.vitro.webapp.utils.Html2Text; import edu.cornell.mannlib.vitro.webapp.utils.StringUtils; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.LinkTemplateModel; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.IndividualTemplateModel; +import freemarker.template.Configuration; /** * PagedSearchController is the new search controller that interacts @@ -91,43 +94,84 @@ public class FreemarkerPagedSearchController extends FreemarkerHttpServlet imple private static final long serialVersionUID = 1L; private static final Log log = LogFactory.getLog(FreemarkerPagedSearchController.class.getName()); + private static final String XML_REQUEST_PARAM = "xml"; private IndexSearcher searcher = null; private int defaultHitsPerPage = 25; private int defaultMaxSearchSize= 1000; - protected enum SearchTemplate { - PAGED_RESULTS("search-pagedResults.ftl"), - FORM("search-form.ftl"), - ERROR("search-error.ftl"), - BAD_QUERY("search-badQuery.ftl"); - - private final String filename; - - SearchTemplate(String filename) { - this.filename = filename; - } - - public String toString() { - return filename; + protected static final Map> templateTable; + + protected enum Format{ + HTML, XML; + } + + protected enum Result{ + PAGED, FORM, ERROR, BAD_QUERY + } + + static{ + templateTable = setupTemplateTable(); + } + +// protected enum SearchTemplate { +// PAGED_RESULTS("search-pagedResults.ftl"), +// FORM("search-form.ftl"), +// ERROR("search-error.ftl"), +// BAD_QUERY("search-badQuery.ftl"), +// XML_RESULT("search-xmlResults.ftl"); +// +// private final String filename; +// +// SearchTemplate(String filename) { +// this.filename = filename; +// } +// +// public String toString() { +// return filename; +// } +// } + + /** + * Overriding doGet from FreemarkerHttpController to do a page template (as + * opposed to body template) style output for XML requests. + * + * This follows the pattern in AutocompleteController.java. + */ + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) + throws IOException, ServletException { + boolean wasXmlRequested = isRequesedFormatXml(request); + if( ! wasXmlRequested ){ + super.doGet(request,response); + }else{ + VitroRequest vreq = new VitroRequest(request); + Configuration config = getConfig(vreq); + ResponseValues rvalues = processRequest(vreq); + + response.setCharacterEncoding("UTF-8"); + response.setContentType("text/xml;charset=UTF-8"); + writeTemplate(rvalues.getTemplateName(), rvalues.getMap(), config, request, response); } } @Override - protected ResponseValues processRequest(VitroRequest vreq) { - - Map body = new HashMap(); + protected ResponseValues processRequest(VitroRequest vreq) { + //There may be other non-html formats in the future + Format format = getFormat(vreq); + boolean wasXmlRequested = Format.XML == format; + log.debug("xml was the requested format"); + boolean wasHtmlRequested = ! wasXmlRequested; try { - Portal portal = vreq.getPortal(); PortalFlag portalFlag = vreq.getPortalFlag(); //make sure an IndividualDao is available if( vreq.getWebappDaoFactory() == null || vreq.getWebappDaoFactory().getIndividualDao() == null ){ - log.error("makeUsableBeans() could not get IndividualDao "); - return doSearchError("Could not access Model."); + log.error("Could not get webappDaoFactory or IndividualDao"); + throw new Exception("Could not access model."); } IndividualDao iDao = vreq.getWebappDaoFactory().getIndividualDao(); VClassGroupDao grpDao = vreq.getWebappDaoFactory().getVClassGroupDao(); @@ -140,7 +184,7 @@ public class FreemarkerPagedSearchController extends FreemarkerHttpServlet imple }catch (Throwable e) { startIndex = 0; } - log.debug("startIndex is " + startIndex); + log.debug("startIndex is " + startIndex); int hitsPerPage = defaultHitsPerPage; try{ @@ -167,7 +211,7 @@ public class FreemarkerPagedSearchController extends FreemarkerHttpServlet imple query = getQuery(vreq, portalFlag, analyzer, qtxt); log.debug("query for '" + qtxt +"' is " + query.toString()); } catch (ParseException e) { - return doBadQuery(portal, qtxt); + return doBadQuery(portal, qtxt,format); } IndexSearcher searcherForRequest = LuceneIndexFactory.getIndexSearcher(getServletContext()); @@ -187,19 +231,19 @@ public class FreemarkerPagedSearchController extends FreemarkerHttpServlet imple if (msg == null) { msg = "The search request contained errors."; } - return doFailedSearch(msg, qtxt); + return doFailedSearch(msg, qtxt,format); } } if( topDocs == null || topDocs.scoreDocs == null){ log.error("topDocs for a search was null"); String msg = "The search request contained errors."; - return doFailedSearch(msg, qtxt); + return doFailedSearch(msg, qtxt,format); } int hitsLength = topDocs.scoreDocs.length; if ( hitsLength < 1 ){ - return doNoHits(qtxt); + return doNoHits(qtxt,format); } log.debug("found "+hitsLength+" hits"); @@ -231,78 +275,100 @@ public class FreemarkerPagedSearchController extends FreemarkerHttpServlet imple ParamMap pagingLinkParams = new ParamMap(); pagingLinkParams.put("querytext", qtxt); pagingLinkParams.put("hitsPerPage", String.valueOf(hitsPerPage)); - - String classGroupParam = vreq.getParameter("classgroup"); - String typeParam = vreq.getParameter("type"); - // Search request includes no classgroup and no type, so add classgroup search refinement links. - if ( classGroupParam == null && typeParam == null) { - List classgroups = getClassGroups(grpDao, topDocs, searcherForRequest); - List classGroupLinks = new ArrayList(classgroups.size()); - for (VClassGroup vcg : classgroups) { - classGroupLinks.add(new VClassGroupSearchLink(qtxt, vcg)); - } - body.put("classGroupLinks", classGroupLinks); - - // Search request is for a classgroup, so add rdf:type search refinement links - // but try to filter out classes that are subclasses - } else if ( classGroupParam != null && typeParam == null ) { - List vClasses = getVClasses(vclassDao,topDocs,searcherForRequest); - List vClassLinks = new ArrayList(vClasses.size()); - for (VClass vc : vClasses) { - vClassLinks.add(new VClassSearchLink(qtxt, vc)); - } - body.put("classLinks", vClassLinks); - pagingLinkParams.put("classgroup", classGroupParam); - - // This case is never displayed - } else if ( !StringUtils.isEmpty(alphaFilter) ) { - body.put("alphas", getAlphas(topDocs, searcherForRequest)); - alphaSortIndividuals(beans); - - } else { - pagingLinkParams.put("type", typeParam); - } + if( wasXmlRequested ){ + pagingLinkParams.put(XML_REQUEST_PARAM,"1"); + } - beans = highlightBeans( beans , - vreq.getWebappDaoFactory().getDataPropertyDao(), - vreq.getWebappDaoFactory().getObjectPropertyDao(), - new SimpleLuceneHighlighter(query,analyzer) ); - - // Convert search result individuals to template model objects - body.put("individuals", IndividualTemplateModel.getIndividualTemplateModelList(beans, vreq)); + /* Start putting together the data for the templates */ - body.put("querytext", qtxt); - body.put("title", qtxt+" - "+portal.getAppName()+" Search Results" ); - - if ( !StringUtils.isEmpty(classGroupParam) ) { + Map body = new HashMap(); + + String classGroupParam = vreq.getParameter("classgroup"); + if (!StringUtils.isEmpty(classGroupParam)) { VClassGroup grp = grpDao.getGroupByURI(classGroupParam); - if( grp != null && grp.getPublicName() != null ) + if (grp != null && grp.getPublicName() != null) body.put("classGroupName", grp.getPublicName()); } - if ( !StringUtils.isEmpty(typeParam) ) { + String typeParam = vreq.getParameter("type"); + if (!StringUtils.isEmpty(typeParam)) { VClass type = vclassDao.getVClassByURI(typeParam); - if( type != null && type.getName() != null ) + if (type != null && type.getName() != null) body.put("typeName", type.getName()); } - body.put("pagingLinks", getPagingLinks(startIndex, hitsPerPage, hitsLength, maxHitSize, vreq.getServletPath(), pagingLinkParams)); + /* Add classgroup and type refinement links to body */ + if( wasHtmlRequested ){ + // Search request includes no classgroup and no type, so add classgroup search refinement links. + if ( classGroupParam == null && typeParam == null) { + List classgroups = getClassGroups(grpDao, topDocs, searcherForRequest); + List classGroupLinks = new ArrayList(classgroups.size()); + for (VClassGroup vcg : classgroups) { + classGroupLinks.add(new VClassGroupSearchLink(qtxt, vcg)); + } + body.put("classGroupLinks", classGroupLinks); + + // Search request is for a classgroup, so add rdf:type search refinement links + // but try to filter out classes that are subclasses + } else if ( classGroupParam != null && typeParam == null ) { + List vClasses = getVClasses(vclassDao,topDocs,searcherForRequest); + List vClassLinks = new ArrayList(vClasses.size()); + for (VClass vc : vClasses) { + vClassLinks.add(new VClassSearchLink(qtxt, vc)); + } + body.put("classLinks", vClassLinks); + pagingLinkParams.put("classgroup", classGroupParam); + + // This case is never displayed + } else if (!StringUtils.isEmpty(alphaFilter)) { + body.put("alphas", getAlphas(topDocs, searcherForRequest)); + alphaSortIndividuals(beans); + } else { + pagingLinkParams.put("type", typeParam); + } + } + + /* Adding html hightlighting */ + if( wasHtmlRequested ){ + beans = highlightBeans(beans, vreq.getWebappDaoFactory() + .getDataPropertyDao(), vreq.getWebappDaoFactory() + .getObjectPropertyDao(), new SimpleLuceneHighlighter(query, + analyzer)); + } + + // Convert search result individuals to template model objects + body.put("individuals", IndividualTemplateModel + .getIndividualTemplateModelList(beans, vreq)); + + body.put("querytext", qtxt); + body.put("title", qtxt + " - " + portal.getAppName() + + " Search Results"); + body.put("hitsLength",hitsLength); + body.put("startIndex", startIndex); + + body.put("pagingLinks", getPagingLinks(startIndex, hitsPerPage, + hitsLength, maxHitSize, vreq.getServletPath(), + pagingLinkParams)); + if (startIndex != 0) { - body.put("prevPage", getPreviousPageLink(startIndex, hitsPerPage, vreq.getServletPath(), pagingLinkParams)); + body.put("prevPage", getPreviousPageLink(startIndex, + hitsPerPage, vreq.getServletPath(), pagingLinkParams)); } if (startIndex < (hitsLength - hitsPerPage)) { - body.put("nextPage", getNextPageLink(startIndex, hitsPerPage, vreq.getServletPath(), pagingLinkParams)); + body.put("nextPage", getNextPageLink(startIndex, hitsPerPage, + vreq.getServletPath(), pagingLinkParams)); } - - } catch (Throwable e) { - return doSearchError(e); - } - - return new TemplateResponseValues(SearchTemplate.PAGED_RESULTS.toString(), body); - } + String template = templateTable.get(format).get(Result.PAGED); + + return new TemplateResponseValues(template, body); + } catch (Throwable e) { + return doSearchError(e,format); + } + } + private void alphaSortIndividuals(List beans) { Collections.sort(beans, new Comparator< Individual >(){ public int compare(Individual o1, Individual o2) { @@ -760,40 +826,34 @@ public class FreemarkerPagedSearchController extends FreemarkerHttpServlet imple } } - private TemplateResponseValues doSearchError(String message) { - Map body = new HashMap(); - body.put("message", "Search failed: " + message); - return new TemplateResponseValues(SearchTemplate.ERROR.toString(), body); - } - - private ExceptionResponseValues doSearchError(Throwable e) { + private ExceptionResponseValues doSearchError(Throwable e, Format f) { Map body = new HashMap(); body.put("message", "Search failed: " + e.getMessage()); - return new ExceptionResponseValues(SearchTemplate.ERROR.toString(), body, e); + return new ExceptionResponseValues(getTemplate(f,Result.ERROR), body, e); } - private TemplateResponseValues doBadQuery(Portal portal, String query) { + private TemplateResponseValues doBadQuery(Portal portal, String query, Format f) { Map body = new HashMap(); body.put("title", "Search " + portal.getAppName()); body.put("query", query); - return new TemplateResponseValues(SearchTemplate.BAD_QUERY.toString(), body); + return new TemplateResponseValues(getTemplate(f,Result.BAD_QUERY), body); } - private TemplateResponseValues doFailedSearch(String message, String querytext) { + private TemplateResponseValues doFailedSearch(String message, String querytext, Format f) { Map body = new HashMap(); body.put("title", "Search for '" + querytext + "'"); if ( StringUtils.isEmpty(message) ) { message = "Search failed."; } body.put("message", message); - return new TemplateResponseValues(SearchTemplate.ERROR.toString(), body); + return new TemplateResponseValues(getTemplate(f,Result.ERROR), body); } - private TemplateResponseValues doNoHits(String querytext) { + private TemplateResponseValues doNoHits(String querytext, Format f) { Map body = new HashMap(); body.put("title", "Search for '" + querytext + "'"); body.put("message", "No matching results."); - return new TemplateResponseValues(SearchTemplate.ERROR.toString(), body); + return new TemplateResponseValues(getTemplate(f,Result.ERROR), body); } /** @@ -876,4 +936,56 @@ public class FreemarkerPagedSearchController extends FreemarkerHttpServlet imple throw new Error("PagedSearchController.search() is unimplemented"); } + protected boolean isRequesedFormatXml(HttpServletRequest req){ + if( req != null ){ + String param = req.getParameter(XML_REQUEST_PARAM); + if( param != null && "1".equals(param)){ + return true; + }else{ + return false; + } + }else{ + return false; + } + } + + protected Format getFormat(HttpServletRequest req){ + if( req != null && req.getParameter("xml") != null && "1".equals(req.getParameter("xml"))) + return Format.XML; + else + return Format.HTML; + } + + protected static String getTemplate(Format format, Result result){ + if( format != null && result != null) + return templateTable.get(format).get(result); + else{ + log.error("getTemplate() must not have a null format or result."); + return templateTable.get(Format.HTML).get(Result.ERROR); + } + } + + protected static Map> setupTemplateTable(){ + Map> templateTable = + new HashMap>(); + + HashMap resultsToTemplates = new HashMap(); + + //setup HTML format + resultsToTemplates.put(Result.PAGED, "search-pagedResults.ftl"); + resultsToTemplates.put(Result.FORM, "search-form.ftl"); + resultsToTemplates.put(Result.ERROR, "search-error.ftl"); + resultsToTemplates.put(Result.BAD_QUERY, "search-badQuery.ftl"); + templateTable.put(Format.HTML, Collections.unmodifiableMap(resultsToTemplates)); + + //setup XML format + resultsToTemplates = new HashMap(); + resultsToTemplates.put(Result.PAGED, "search-xmlResults.ftl"); + resultsToTemplates.put(Result.FORM, "search-xmlForm.ftl"); + resultsToTemplates.put(Result.ERROR, "search-xmlError.ftl"); + resultsToTemplates.put(Result.BAD_QUERY, "search-xmlBadQuery.ftl"); + templateTable.put(Format.XML, Collections.unmodifiableMap(resultsToTemplates)); + + return Collections.unmodifiableMap(templateTable); + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/VClassTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/VClassTemplateModel.java index 2c0edb396..898ef1cb5 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/VClassTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/VClassTemplateModel.java @@ -20,6 +20,10 @@ public class VClassTemplateModel extends BaseTemplateModel { this.vclass = vclass; } + public String getUri(){ + return vclass.getURI(); + } + public String getName() { return vclass.getName(); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/BrowseWidget.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/BrowseWidget.java new file mode 100644 index 000000000..fd572cd2d --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/BrowseWidget.java @@ -0,0 +1,176 @@ +package edu.cornell.mannlib.vitro.webapp.web.widgets; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; + +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.web.templatemodels.VClassGroupTemplateModel; +import edu.cornell.mannlib.vitro.webapp.web.templatemodels.VClassTemplateModel; +import freemarker.core.Environment; +import freemarker.template.TemplateModelException; + +/** + * This is a widget to display a classgroups, + * classes in classgroup, and indviduals in class. + * + * @author bdc34 + * + */ +public class BrowseWidget extends Widget { + + @Override + protected WidgetTemplateValues process(Environment env, Map params, + HttpServletRequest request, ServletContext context) throws Exception + { + Mode mode = getMode( request, params ); + switch( mode ){ + case VCLASS_ALPHA: + return doClassAlphaDisplay(env,params,request,context); + case CLASS_GROUP: + return doClassGroupDisplay(env, params, request, context); + case VCLASS: + return doClassDisplay(env, params, request, context); + case ALL_CLASS_GROUPS: + return doAllClassGroupsDisplay(env, params, request, context); + default: + return doAllClassGroupsDisplay(env, params, request, context); + } + } + + private WidgetTemplateValues doClassAlphaDisplay(Environment env, + Map params, HttpServletRequest request, ServletContext context) { + // TODO Auto-generated method stub + return null; + } + + protected WidgetTemplateValues doAllClassGroupsDisplay(Environment env, Map params, + HttpServletRequest request, ServletContext context) { + Map body = getAllClassGroupData(request); + try { + body.put("urls",env.getDataModel().get("urls")); + body.put("urlMapping",env.getDataModel().get("urlMapping")); + } catch (TemplateModelException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + String macroName = Mode.ALL_CLASS_GROUPS.macroName; + return new WidgetTemplateValues(macroName, body); + } + + protected Map getAllClassGroupData(HttpServletRequest request){ + Map map = new HashMap(); + + VitroRequest vreq = new VitroRequest(request); + List classGroups = + vreq.getWebappDaoFactory().getVClassGroupDao().getPublicGroupsWithVClasses(); + + LinkedList cgList = new LinkedList(); + for( VClassGroup classGroup : classGroups){ + cgList.add( new VClassGroupTemplateModel( classGroup )); + } + map.put("vclassGroupList",cgList); + return map; + } + + protected WidgetTemplateValues doClassDisplay(Environment env, Map params, + HttpServletRequest request, ServletContext context) { + Map body = getClassData(request); + try { + body.put("urls",env.getDataModel().get("urls")); + body.put("urlMapping",env.getDataModel().get("urlMapping")); + } catch (TemplateModelException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + String macroName = Mode.VCLASS.macroName; + return new WidgetTemplateValues(macroName, body); + } + + private Map getClassData(HttpServletRequest request) { + Map map = new HashMap(); + map.putAll(getClassGroupData(request)); + String classUri = request.getParameter(Mode.VCLASS.param); + VitroRequest vreq = new VitroRequest(request); + VClass vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(classUri); + map.put("class", new VClassTemplateModel(vclass)); + + //TODO: add list of individuals for class? + return map; + } + + protected WidgetTemplateValues doClassGroupDisplay(Environment env, + Map params, HttpServletRequest request, ServletContext context) { + + Map body = getClassGroupData(request); + try { + body.put("urls",env.getDataModel().get("urls")); + body.put("urlMapping",env.getDataModel().get("urlMapping")); + } catch (TemplateModelException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + String macroName = Mode.CLASS_GROUP.macroName; + return new WidgetTemplateValues(macroName, body); + } + + protected Map getClassGroupData(HttpServletRequest request) { + Map map = new HashMap(); + + String vcgUri = request.getParameter(Mode.CLASS_GROUP.param); + VitroRequest vreq = new VitroRequest(request); + VClassGroup vcg = vreq.getWebappDaoFactory().getVClassGroupDao().getGroupByURI(vcgUri); + vreq.getWebappDaoFactory().getVClassDao().addVClassesToGroup(vcg, false, true); + 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)); + map.put(Mode.CLASS_GROUP.param, vcgUri); + + return map; + } + + enum Mode{ + VCLASS_ALPHA("vclassAlpha","vclassAlpha"), + VCLASS("vclass","vclassUri"), + CLASS_GROUP("classGroup","classgroupUri"), + ALL_CLASS_GROUPS("allClassGroups","all"); + + String macroName; + String param; + Mode(String macroName, String param){ + this.macroName = macroName; + this.param = param; + } + } + + protected final static Mode DEFAULT_MODE = Mode.ALL_CLASS_GROUPS; + + protected Mode getMode(HttpServletRequest request, Map params){ + for( Mode mode : Mode.values()){ + String param = request.getParameter( mode.param ); + if( param != null && !param.isEmpty() ){ + return mode; + } + } + + for( Mode mode : Mode.values()){ + String param = (String)params.get( mode.param ); + if( param != null && !param.isEmpty() ){ + return mode; + } + } + + return DEFAULT_MODE; + } +} diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/filters/VitroURLTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/filters/VitroURLTest.java index 5cc716864..bdb51c30d 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/filters/VitroURLTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/filters/VitroURLTest.java @@ -42,18 +42,24 @@ public class VitroURLTest { * Test of toString method, of class VitroURL. * This test includes a Individual URI with a '=' and a '?' * This test is from David Cliff via sourceforge. - * It isn't clear if the double URLencoding is correct. */ -// @Test -// public void testToString() -// { -// String MelbUniStr = "/entity?home=1&uri=HTTPS://bida.themis.unimelb.edu.au/pls/apex/f?p=mrw2rdf:org:::::org_id:145"; -// VitroURL instance = new VitroURL(MelbUniStr, "UTF-8"); -// String expResult = "/entity?home=1&uri=HTTPS%253A%252F%252Fbida.themis.unimelb.edu.au%252Fpls%252Fapex%252Ff%253Fp%253Dmrw2rdf%253Aorg%253A%253A%253A%253A%253Aorg_id%253A145"; -// String result = instance.toString(); -// assertEquals(expResult, result); -// } + @Test + public void testToString() + { + String MelbUniStr = "/entity?home=1&uri=HTTPS://bida.themis.unimelb.edu.au/pls/apex/f?p=mrw2rdf:org:::::org_id:145"; + VitroURL instance = new VitroURL(MelbUniStr, "UTF-8"); + String expResult = "/entity?home=1&uri=HTTPS%3A%2F%2Fbida.themis.unimelb.edu.au%2Fpls%2Fapex%2Ff%3Fp%3Dmrw2rdf%3Aorg%3A%3A%3A%3A%3Aorg_id%3A145"; + String result = instance.toString(); + assertEquals(expResult, result); + String defaultTestStr = "/entity?home=1&uri=http://aims.fao.org/aos/geopolitical.owl#Afghanistan"; + instance = new VitroURL(defaultTestStr, "UTF-8"); + expResult = "/entity?home=1&uri=http%3A%2F%2Faims.fao.org%2Faos%2Fgeopolitical.owl%23Afghanistan"; + result = instance.toString(); + assertEquals(expResult, result); + } + + /** * This is a test similar to testToString() * in that it has a = and a ? but it doesn't diff --git a/webapp/web/templates/freemarker/body/menupage/menupage--classgroup-people.ftl b/webapp/web/templates/freemarker/body/menupage/menupage--classgroup-people.ftl index cc61f9a7e..a7ec63e54 100644 --- a/webapp/web/templates/freemarker/body/menupage/menupage--classgroup-people.ftl +++ b/webapp/web/templates/freemarker/body/menupage/menupage--classgroup-people.ftl @@ -2,6 +2,8 @@

People

+ <@widget name="browse" /> +

Visual Graph

@@ -141,4 +143,6 @@

foaf:lastName, foaf:fisrtName
core:preferredTitle
Albert Mann Library

+ <@dumpAll/>
+ diff --git a/webapp/web/templates/freemarker/body/search/search-xmlResults.ftl b/webapp/web/templates/freemarker/body/search/search-xmlResults.ftl new file mode 100644 index 000000000..60eb4461f --- /dev/null +++ b/webapp/web/templates/freemarker/body/search/search-xmlResults.ftl @@ -0,0 +1,21 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + + + + + ${querytext?xml} + <#if nextPage??> + ${nextPage?xml} + + + + + <#list individuals as individual> + + ${individual.uri} + ${individual.name} + + + + + \ No newline at end of file diff --git a/webapp/web/templates/freemarker/widgets/widget-browse.ftl b/webapp/web/templates/freemarker/widgets/widget-browse.ftl new file mode 100644 index 000000000..a9e4b72e9 --- /dev/null +++ b/webapp/web/templates/freemarker/widgets/widget-browse.ftl @@ -0,0 +1,52 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + +<#-- Browse widget --> + +<#macro assets> + <#-- + Are there stylesheets or scripts needed? + ${stylesheets.add("/css/browse.css")} + ${scripts.add("/js/browse.js")} + --> + + +<#macro allClassGroups> +
+

Macro allClassGroups from widget-browse.ftl

+ +
+ + + +<#macro classGroup> +
+

Macro classGroup from widget-browse.ftl

+
+ There are ${classes?size} classes in classGroup ${classGroup.publicName}. + Only classes with instances are included. +
+ +
+ + + +<#macro vclass> +
+

vclass ${class.name} from ${classGroup.publicName}

+ This has classGroup, classes, and class. It doesn't yet have a list of individuals in the class. +
+ + +<#macro vclassAlpha> +
+

vclassAlpha

+
+