From 3180ed432b544a062eab769406e55ea6290af085 Mon Sep 17 00:00:00 2001 From: bdc34 Date: Thu, 2 Dec 2010 21:09:58 +0000 Subject: [PATCH] Adding menu controller, tomcat filter for menu page URL routing NIHVIVO-1073 NIHVIVO-597 --- .../freemarker/FreemarkerHttpServlet.java | 12 +- .../controller/freemarker/PageController.java | 104 ++++++++ .../mannlib/vitro/webapp/dao/MenuDao.java | 8 +- .../mannlib/vitro/webapp/dao/PageDao.java | 23 ++ .../vitro/webapp/dao/WebappDaoFactory.java | 6 +- .../filtering/WebappDaoFactoryFiltering.java | 11 +- .../vitro/webapp/dao/jena/MenuDaoJena.java | 29 ++- .../vitro/webapp/dao/jena/PageDaoJena.java | 228 ++++++++++++++++++ .../webapp/dao/jena/WebappDaoFactoryJena.java | 22 +- .../webapp/filters/PageRoutingFilter.java | 108 +++++++++ .../web/templatemodels/menu/MainMenu.java | 4 +- .../web/templatemodels/menu/MenuItem.java | 11 + .../webapp/dao/jena/MenuDaoJenaTest.java | 9 +- .../webapp/dao/jena/resources/menuForTest.n3 | 2 +- .../freemarker/body/individual/individual.ftl | 1 - 15 files changed, 551 insertions(+), 27 deletions(-) create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/PageController.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/dao/PageDao.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PageDaoJena.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/filters/PageRoutingFilter.java diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerHttpServlet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerHttpServlet.java index 861bc718f..7a09f0d77 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerHttpServlet.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerHttpServlet.java @@ -35,7 +35,7 @@ import edu.cornell.mannlib.vitro.webapp.web.PortalWebUtil; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.User; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.files.Scripts; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.files.Stylesheets; -import edu.cornell.mannlib.vitro.webapp.web.templatemodels.menu.TabMenu; +import edu.cornell.mannlib.vitro.webapp.web.templatemodels.menu.MainMenu; import freemarker.ext.beans.BeansWrapper; import freemarker.template.Configuration; import freemarker.template.DefaultObjectWrapper; @@ -323,6 +323,7 @@ public class FreemarkerHttpServlet extends VitroHttpServlet { urls.put("themeImages", urlBuilder.getPortalUrl(themeDir + "/images")); urls.put("images", urlBuilder.getUrl("/images")); urls.put("theme", urlBuilder.getUrl(themeDir)); + urls.put("index", urlBuilder.getUrl("/browse")); return urls; } @@ -414,9 +415,12 @@ public class FreemarkerHttpServlet extends VitroHttpServlet { return map; } - private TabMenu getTabMenu(VitroRequest vreq) { - int portalId = vreq.getPortal().getPortalId(); - return new TabMenu(vreq, portalId); + private MainMenu getTabMenu(VitroRequest vreq) { +// int portalId = vreq.getPortal().getPortalId(); +// return new TabMenu(vreq, portalId); + + String url = vreq.getRequestURI().substring(vreq.getContextPath().length()); + return vreq.getWebappDaoFactory().getMenuDao().getMainMenu(url); } private final Map getCopyrightInfo(Portal portal) { 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 new file mode 100644 index 000000000..8c7a8d032 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/PageController.java @@ -0,0 +1,104 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.controller.freemarker; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; + +/** + * Controller for getting data for pages defined in the display model. + */ +public class PageController extends FreemarkerHttpServlet{ + private static final Log log = LogFactory.getLog(PageController.class); + + @Override + protected ResponseValues processRequest(VitroRequest vreq) { + try { + // get URL without hostname or servlet context + String url = vreq.getRequestURI().substring(vreq.getContextPath().length()); + + Map mapForTemplate = new HashMap(); + String pageUri = ""; + try { + pageUri = getPageUri( vreq , url ); + mapForTemplate.putAll( getMapForPage( vreq, pageUri ) ); + } catch (Throwable th) { + return doNotFound(vreq); + } + + try{ + mapForTemplate.putAll( getAdditionalDataForPage( vreq, pageUri) ); + } catch( Throwable th){ + log.error(th,th); + return doError(vreq); + } + + return new TemplateResponseValues(getTemplate( mapForTemplate ), mapForTemplate); + } catch (Throwable e) { + log.error(e); + return new ExceptionResponseValues(e); + } + } + + private String getTemplate(Map mapForTemplate) { + if( mapForTemplate.containsKey("bodyTemplate")) + return (String) mapForTemplate.get("bodyTemplate"); + else + return DEFAULT_BODY_TEMPLATE; + } + + private Map getAdditionalDataForPage(VitroRequest vreq, String pageUri) { + return Collections.emptyMap(); + } + + private ResponseValues doError(VitroRequest vreq) { + Map body = new HashMap(); + body.put("title","Page could not be created"); + body.put("errorMessage", "There was an error while creating the page, please check the logs."); + return new TemplateResponseValues(Template.TITLED_ERROR_MESSAGE.toString(), body, HttpServletResponse.SC_NOT_FOUND); + } + + private ResponseValues doNotFound(VitroRequest vreq) { + Map body = new HashMap(); + body.put("title","Page Not Found"); + body.put("errorMessage", "The page was not found in the system."); + 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. + * @throws Exception + */ + private String getPageUri(VitroRequest vreq, String url) throws Exception { + //check if there is a page URI in the request. This would have + //been added by a servlet Filter. + String pageURI = (String) vreq.getAttribute("pageURI"); + if( pageURI != null && ! pageURI.isEmpty() ) + return pageURI; + else + throw new Exception("no page found for " + vreq.getRequestURI() ); + } + + public static void putPageUri(HttpServletRequest req, String pageUri){ + req.setAttribute("pageURI", pageUri); + } + + protected final static String DEFAULT_TITLE = "Page"; + + //not sure what this should default to. + protected final static String DEFAULT_BODY_TEMPLATE = "menupage.ftl"; +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/MenuDao.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/MenuDao.java index a4441b5f2..1f41b4df6 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/MenuDao.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/MenuDao.java @@ -1,8 +1,12 @@ /* $This file is distributed under the terms of the license in /doc/license.txt$ */ package edu.cornell.mannlib.vitro.webapp.dao; -import edu.cornell.mannlib.vitro.webapp.web.templatemodels.menu.Menu; +import edu.cornell.mannlib.vitro.webapp.web.templatemodels.menu.MainMenu; public interface MenuDao { - public Menu getMenu(String uri); + /** + * @param url - url of request for setting active menu items. This should start with a / and not have the context path. + * These values will be checked against urlMapping. ex. /people or /home + */ + public MainMenu getMainMenu( String url); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/PageDao.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/PageDao.java new file mode 100644 index 000000000..160e667e6 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/PageDao.java @@ -0,0 +1,23 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao; + +import java.util.Map; + +public interface PageDao { + + Map getPage(String pageUri); + + /** + * Returns a list of urlMappings to URIs. + * + * @return + */ + Map getPageMappings(); + + /** + * Returns URI of home page. + * @return + */ + String getHomePageUri(); +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactory.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactory.java index 897ca9ef8..6902c4c3b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactory.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactory.java @@ -131,5 +131,9 @@ public interface WebappDaoFactory { public NamespaceDao getNamespaceDao(); - public PropertyInstanceDao getPropertyInstanceDao(); + public PropertyInstanceDao getPropertyInstanceDao(); + + public PageDao getPageDao(); + + public MenuDao getMenuDao(); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/WebappDaoFactoryFiltering.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/WebappDaoFactoryFiltering.java index 22144b3a3..31d47416f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/WebappDaoFactoryFiltering.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/WebappDaoFactoryFiltering.java @@ -17,10 +17,12 @@ import edu.cornell.mannlib.vitro.webapp.dao.KeywordDao; import edu.cornell.mannlib.vitro.webapp.dao.KeywordIndividualRelationDao; import edu.cornell.mannlib.vitro.webapp.dao.LinksDao; import edu.cornell.mannlib.vitro.webapp.dao.LinktypeDao; +import edu.cornell.mannlib.vitro.webapp.dao.MenuDao; import edu.cornell.mannlib.vitro.webapp.dao.NamespaceDao; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao; import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao; +import edu.cornell.mannlib.vitro.webapp.dao.PageDao; import edu.cornell.mannlib.vitro.webapp.dao.PortalDao; import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao; import edu.cornell.mannlib.vitro.webapp.dao.PropertyInstanceDao; @@ -299,6 +301,13 @@ public class WebappDaoFactoryFiltering implements WebappDaoFactory { return filteringVClassDao; } + @Override + public PageDao getPageDao() { + return innerWebappDaoFactory.getPageDao(); + } - + @Override + public MenuDao getMenuDao(){ + return innerWebappDaoFactory.getMenuDao(); + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/MenuDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/MenuDaoJena.java index 5c315ddcf..689f76e82 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/MenuDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/MenuDaoJena.java @@ -18,6 +18,7 @@ import com.hp.hpl.jena.rdf.model.ResourceFactory; import edu.cornell.mannlib.vitro.webapp.dao.MenuDao; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.web.templatemodels.menu.MainMenu; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.menu.Menu; public class MenuDaoJena extends JenaBaseDao implements MenuDao { @@ -35,9 +36,9 @@ public class MenuDaoJena extends JenaBaseDao implements MenuDao { prefixes + "\n" + "SELECT ?menuItem ?linkText ?urlMapping WHERE {\n" + // " GRAPH ?g{\n"+ - " ?menu rdf:type display:Menu .\n"+ + " ?menu rdf:type display:MainMenu .\n"+ " ?menu display:hasElement ?menuItem . \n"+ - " OPTIONAL { ?menuItem display:linkText ?linkText }.\n"+ + " ?menuItem display:linkText ?linkText .\n"+ " OPTIONAL { ?menuItem display:menuPosition ?menuPosition }.\n"+ " OPTIONAL { ?menuItem display:toPage ?page . }\n"+ " OPTIONAL { ?page display:urlMapping ?urlMapping . }\n"+ @@ -61,34 +62,38 @@ public class MenuDaoJena extends JenaBaseDao implements MenuDao { } @Override - public Menu getMenu(String uri) { - return getMenu(uri, getOntModelSelector().getDisplayModel()); + public MainMenu getMainMenu( String url ) { + return getMenu( getOntModelSelector().getDisplayModel(), url ); } + - protected Menu getMenu(String uri, Model displayModel){ + protected MainMenu getMenu(Model displayModel, String url){ //setup query parameters - QuerySolutionMap initialBindings = new QuerySolutionMap(); - initialBindings.add("menu", ResourceFactory.createResource(uri)); + QuerySolutionMap initialBindings = new QuerySolutionMap(); //run SPARQL query to get menu and menu items - QueryExecution qexec = QueryExecutionFactory.create(menuQuery,displayModel,initialBindings ); + QueryExecution qexec = QueryExecutionFactory.create(menuQuery, displayModel, initialBindings ); try{ - Menu menu = new Menu(); + MainMenu menu = new MainMenu(); ResultSet results =qexec.execSelect(); for( ; results.hasNext();){ QuerySolution soln = results.nextSolution(); Literal itemText = soln.getLiteral("linkText"); Literal itemLink = soln.getLiteral("urlMapping"); String text = itemText != null ? itemText.getLexicalForm():"(undefined text)"; - String link = itemLink != null ? itemLink.getLexicalForm():"undefinedLink"; - menu.addItem(text,link); + String link = itemLink != null ? itemLink.getLexicalForm():"undefinedLink"; + + menu.addItem(text,link, isActive( url, link )); } return menu; }catch(Throwable th){ log.error(th,th); - return new Menu(); + return new MainMenu(); } } + protected boolean isActive(String url, String link){ + return url.startsWith(link); + } } 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 new file mode 100644 index 000000000..eab304e07 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PageDaoJena.java @@ -0,0 +1,228 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; + +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.Resource; +import com.hp.hpl.jena.rdf.model.ResourceFactory; + +import edu.cornell.mannlib.vitro.webapp.dao.PageDao; +import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; + +public class PageDaoJena extends JenaBaseDao implements PageDao { + + static protected Query pageQuery; + static protected Query pageMappingsQuery; + static protected Query homePageUriQuery; + + static final String prefixes = + "PREFIX rdf: <" + VitroVocabulary.RDF +"> \n" + + "PREFIX rdfs: <" + VitroVocabulary.RDFS +"> \n" + + "PREFIX xsd: \n" + + "PREFIX display: <" + VitroVocabulary.DISPLAY +"> \n"; + + + static final protected String pageQueryString = + prefixes + "\n" + + "SELECT ?pageUri ?bodyTemplate ?urlMapping ?title WHERE {\n" + +// " GRAPH ?g{\n"+ + " ?pageUri rdf:type display:Page .\n"+ + " OPTIONAL { ?pageUri display:requiresBodyTemplate ?bodyTemplate }.\n"+ + " OPTIONAL { ?pageUri display:title ?title }.\n"+ + " OPTIONAL { ?pageUri display:urlMapping ?urlMapping . }\n"+ +// " }\n"+ + "} \n" ; + + static final protected String pageMappingsQueryString = + prefixes + "\n" + + "SELECT ?pageUri ?urlMapping WHERE {\n" + +// " GRAPH ?g{\n"+ + " ?pageUri rdf:type display:Page .\n"+ + " ?pageUri display:urlMapping ?urlMapping . \n"+ +// " }\n"+ + "} \n" ; + + static final protected String homePageUriQueryString = + prefixes + "\n" + + "SELECT ?pageUri WHERE {\n" + +// " GRAPH ?g{\n"+ + " ?pageUri rdf:type display:HomePage .\n"+ +// " }\n"+ + "} \n" ; + + + static{ + try{ + pageQuery=QueryFactory.create(pageQueryString); + }catch(Throwable th){ + log.error("could not create SPARQL query for pageQuery " + th.getMessage()); + log.error(pageQueryString); + } + try{ + pageMappingsQuery=QueryFactory.create(pageMappingsQueryString); + }catch(Throwable th){ + log.error("could not create SPARQL query for pageMappingsQuery " + th.getMessage()); + log.error(pageMappingsQueryString); + } + try{ + homePageUriQuery=QueryFactory.create(homePageUriQueryString); + }catch(Throwable th){ + log.error("could not create SPARQL query for homePageUriQuery " + th.getMessage()); + log.error(homePageUriQueryString); + } + } + + public PageDaoJena(WebappDaoFactoryJena wadf) { + super(wadf); + } + + @Override + public Map getPageMappings() { + Model displayModel = getOntModelSelector().getDisplayModel(); + QueryExecution qexec = QueryExecutionFactory.create( pageQuery, displayModel ); + + Map rv = new HashMap(); + ResultSet resultSet = qexec.execSelect(); + while(resultSet.hasNext()){ + QuerySolution soln = resultSet.next(); + rv.put(nodeToString(soln.get("urlMapping")) , nodeToString( soln.get("pageUri") )); + } + return rv; + } + + /** + * Gets information about a page identified by a URI. + */ + @Override + public Map getPage(String pageUri) { + //setup query parameters + QuerySolutionMap initialBindings = new QuerySolutionMap(); + initialBindings.add("pageUri", ResourceFactory.createResource(pageUri)); + + Model displayModel = getOntModelSelector().getDisplayModel(); + QueryExecution qexec = QueryExecutionFactory.create(pageQuery,displayModel,initialBindings ); + List> list = executeQueryToCollection( qexec ); + if( list == null ){ + log.error("executeQueryToCollection returned null."); + return Collections.emptyMap(); + } + if( list.size() == 0 ){ + log.debug("no page found for " + pageUri); + return Collections.emptyMap(); + } + if( list.size() > 1 ){ + log.debug("multiple results found for " + pageUri + " using only the first."); + return list.get(0); + }else{ + return list.get(0); + } + } + + @Override + public String getHomePageUri(){ + Model displayModel = getOntModelSelector().getDisplayModel(); + QueryExecution qexec = QueryExecutionFactory.create( homePageUriQuery, displayModel ); + + List rv = new ArrayList(); + ResultSet resultSet = qexec.execSelect(); + while(resultSet.hasNext()){ + QuerySolution soln = resultSet.next(); + rv.add( nodeToString(soln.get("pageUri")) ); + } + if( rv.size() == 0 ){ + log.error("No display:HomePage defined in display model."); + return null; + } + if( rv.size() > 1 ){ + log.error("More than one display:HomePage defined in display model."); + for( String hp : rv ){ + log.error("home page: " + hp); + } + } + return rv.get(0); + } + + + /* ****************************************************************************** */ + + /** + * Converts a sparql query that returns a multiple rows to a list of maps. + * The maps will have column names as keys to the values. + */ + protected List> executeQueryToCollection( + QueryExecution qexec) { + List> rv = new ArrayList>(); + ResultSet results = qexec.execSelect(); + while (results.hasNext()) { + QuerySolution soln = results.nextSolution(); + rv.add(querySolutionToMap(soln)); + } + return rv; + } + + protected Map querySolutionToMap( QuerySolution soln ){ + Map map = new HashMap(); + Iterator varNames = soln.varNames(); + while(varNames.hasNext()){ + String varName = varNames.next(); + map.put(varName, nodeToObject( soln.get(varName))); + } + return map; + } + + protected Object nodeToObject( RDFNode node ){ + if( node == null ){ + return ""; + }else if( node.isLiteral() ){ + Literal literal = node.asLiteral(); + return literal.getValue(); + }else if( node.isURIResource() ){ + Resource resource = node.asResource(); + return resource.getURI(); + }else if( node.isAnon() ){ + Resource resource = node.asResource(); + return resource.getId().getLabelString(); //get b-node id + }else{ + return ""; + } + } + + protected String nodeToString( RDFNode node ){ + if( node == null ){ + return ""; + }else if( node.isLiteral() ){ + Literal literal = node.asLiteral(); + return literal.getLexicalForm(); + }else if( node.isURIResource() ){ + Resource resource = node.asResource(); + return resource.getURI(); + }else if( node.isAnon() ){ + Resource resource = node.asResource(); + return resource.getId().getLabelString(); //get b-node id + }else{ + return ""; + } + } + protected Map resultsToMap(){ + return null; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryJena.java index e29ca6b16..2bd24861a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryJena.java @@ -42,10 +42,12 @@ import edu.cornell.mannlib.vitro.webapp.dao.KeywordDao; import edu.cornell.mannlib.vitro.webapp.dao.KeywordIndividualRelationDao; import edu.cornell.mannlib.vitro.webapp.dao.LinksDao; import edu.cornell.mannlib.vitro.webapp.dao.LinktypeDao; +import edu.cornell.mannlib.vitro.webapp.dao.MenuDao; import edu.cornell.mannlib.vitro.webapp.dao.NamespaceDao; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao; import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao; +import edu.cornell.mannlib.vitro.webapp.dao.PageDao; import edu.cornell.mannlib.vitro.webapp.dao.PortalDao; import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao; import edu.cornell.mannlib.vitro.webapp.dao.PropertyInstanceDao; @@ -77,6 +79,9 @@ public class WebappDaoFactoryJena implements WebappDaoFactory { protected VClassGroupDao vClassGroupDao; protected PropertyGroupDao propertyGroupDao; + private PageDao pageDao; + private MenuDao menuDao; + protected OntModelSelector ontModelSelector; protected String defaultNamespace; @@ -556,7 +561,8 @@ public class WebappDaoFactoryJena implements WebappDaoFactory { return vClassDao; } - private JenaBaseDao jenaBaseDao = null; + private JenaBaseDao jenaBaseDao = null; + public JenaBaseDao getJenaBaseDao() { if (jenaBaseDao == null) { jenaBaseDao = new JenaBaseDao(this); @@ -572,4 +578,18 @@ public class WebappDaoFactoryJena implements WebappDaoFactory { return this.flag2ClassLabelMap; } + @Override + public PageDao getPageDao() { + if( pageDao == null ) + pageDao = new PageDaoJena(this); + return pageDao; + } + + @Override + public MenuDao getMenuDao(){ + if( menuDao == null ) + menuDao = new MenuDaoJena(this); + return menuDao; + } + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/PageRoutingFilter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/PageRoutingFilter.java new file mode 100644 index 000000000..a63b1c563 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/PageRoutingFilter.java @@ -0,0 +1,108 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.filters; + +import java.io.IOException; +import java.util.Map; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.controller.freemarker.PageController; +import edu.cornell.mannlib.vitro.webapp.dao.PageDao; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +/** + * This filter is intended to route requests to pages defined in the display model. + * + * It should be last in the chain of filters since it will not call filters further + * down the chain. + * + * It should only be applied to requests, not forwards, includes or errors. + */ +public class PageRoutingFilter implements Filter{ + FilterConfig filterConfig; + + private final static Log log = LogFactory.getLog( PageRoutingFilter.class) + ; + protected final static String PAGE_CONTROLLER_NAME = "PageController"; + protected final static String HOME_CONTROLLER_NAME = "HomePageController"; + + @Override + public void init(FilterConfig arg0) throws ServletException { + this.filterConfig = arg0; + log.debug("pageRoutingFilter setup"); + } + + @Override + public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain) + throws IOException, ServletException { + PageDao pageDao = getPageDao(); + Map urlMappings = pageDao.getPageMappings(); + + // get URL without hostname or servlet context + HttpServletResponse response = (HttpServletResponse) arg1; + HttpServletRequest req = (HttpServletRequest) arg0; + String path = req.getRequestURI().substring(req.getContextPath().length()); + + // check for first part of path + // ex. /hats/superHat -> /hats + String path1 = path; + if( path != null && path.indexOf("/",1) > 0 ){ + path1 = path.substring(0,path1.indexOf("/")); + } + + String pageUri = urlMappings.get(path1); + + //try it with a leading slash + if( pageUri == null ){ + pageUri = urlMappings.get("/"+path1); + } + + if( pageUri != null && ! pageUri.isEmpty() ){ + log.debug(path + "is a request to a page defined in the display model as " + pageUri ); + + //add the pageUri to the request scope for use by the PageController + PageController.putPageUri(req, pageUri); + + //This will send requests to HomePageController or PageController + String controllerName = getControllerToForwardTo(req, pageUri, pageDao); + log.debug(path + " is being forwarded to controller " + controllerName); + + RequestDispatcher rd = filterConfig.getServletContext().getNamedDispatcher( controllerName ); + rd.forward(req, response); + }else{ + log.debug(path + "this isn't a request to a page defined in the display model, handle it normally."); + chain.doFilter(arg0, arg1); + } + } + + protected String getControllerToForwardTo(HttpServletRequest req, + String pageUri, PageDao pageDao) { + String homePageUri = pageDao.getHomePageUri(); + if( pageUri != null && pageUri.equals(homePageUri) ) + return HOME_CONTROLLER_NAME; + else + return PAGE_CONTROLLER_NAME; + } + + protected PageDao getPageDao(){ + WebappDaoFactory wdf = (WebappDaoFactory) + filterConfig.getServletContext().getAttribute("webappDaoFactory"); + return wdf.getPageDao(); + } + + @Override + public void destroy() { + //nothing to do here + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/menu/MainMenu.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/menu/MainMenu.java index 0e2d931fb..53c7f3cd9 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/menu/MainMenu.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/menu/MainMenu.java @@ -19,6 +19,8 @@ public class MainMenu extends Menu { protected VitroRequest vreq; + public MainMenu(){ } + public MainMenu(VitroRequest vreq) { this.vreq = vreq; } @@ -34,6 +36,6 @@ public class MainMenu extends Menu { } protected boolean isActiveItem(String path) { - return vreq.getServletPath().equals(path); + return vreq != null && vreq.getServletPath().equals(path); } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/menu/MenuItem.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/menu/MenuItem.java index 38b7bc4ab..def4dcff8 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/menu/MenuItem.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/menu/MenuItem.java @@ -13,12 +13,19 @@ public class MenuItem extends BaseTemplateModel { private String text; private String path; + private boolean active; public MenuItem(String linkText, String path) { text = linkText; this.path = path; } + public MenuItem(String linkText, String path, boolean active){ + this.text= linkText; + this.path = path; + this.active= active; + } + public String getLinkText() { return text; } @@ -26,4 +33,8 @@ public class MenuItem extends BaseTemplateModel { public String getUrl() { return getUrl(path); } + + public boolean getActive(){ + return active; + } } diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/jena/MenuDaoJenaTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/jena/MenuDaoJenaTest.java index 6867ca55f..c398c2d7b 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/jena/MenuDaoJenaTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/jena/MenuDaoJenaTest.java @@ -20,7 +20,7 @@ import com.hp.hpl.jena.rdf.model.impl.RDFDefaultErrorHandler; import edu.cornell.mannlib.vitro.testing.AbstractTestClass; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; -import edu.cornell.mannlib.vitro.webapp.web.templatemodels.menu.Menu; +import edu.cornell.mannlib.vitro.webapp.web.templatemodels.menu.MainMenu; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.menu.MenuItem; @@ -41,8 +41,11 @@ public class MenuDaoJenaTest extends AbstractTestClass { @Test public void getMenuItemTest(){ - MenuDaoJena menuDaoJena = new MenuDaoJena(new WebappDaoFactoryJena(displayModel)); - Menu menu = menuDaoJena.getMenu(VitroVocabulary.DISPLAY+"DefaultMenu", displayModel); + SimpleOntModelSelector sos = new SimpleOntModelSelector( ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM)); + sos.setDisplayModel(displayModel); + MenuDaoJena menuDaoJena = new MenuDaoJena(new WebappDaoFactoryJena(sos)); + + MainMenu menu = menuDaoJena.getMainMenu( "notImportant" ); try{ Class clz = UrlBuilder.class; diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/jena/resources/menuForTest.n3 b/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/jena/resources/menuForTest.n3 index 6b3b72aaf..9626927af 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/jena/resources/menuForTest.n3 +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/jena/resources/menuForTest.n3 @@ -11,7 +11,7 @@ #### Default Menu #### display:DefaultMenu - a display:Menu ; + a display:MainMenu ; display:hasElement display:EventsMenuItem ; display:hasElement display:HomeMenuItem ; display:hasElement display:OrganizationsMenuItem ; diff --git a/webapp/web/templates/freemarker/body/individual/individual.ftl b/webapp/web/templates/freemarker/body/individual/individual.ftl index 0e6a67d6f..14026c2eb 100644 --- a/webapp/web/templates/freemarker/body/individual/individual.ftl +++ b/webapp/web/templates/freemarker/body/individual/individual.ftl @@ -81,7 +81,6 @@ -<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->