/* * LayoutTag.java * * Version: $Revision: 3705 $ * * Date: $Date: 2009-04-11 17:02:24 +0000 (Sat, 11 Apr 2009) $ * * Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts * Institute of Technology. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of the Hewlett-Packard Company nor the name of the * Massachusetts Institute of Technology nor the names of their * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. */ package org.dspace.app.webui.jsptag; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.servlet.RequestDispatcher; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletResponse; import javax.servlet.jsp.JspException; import javax.servlet.jsp.jstl.fmt.LocaleSupport; import javax.servlet.jsp.tagext.TagSupport; import org.apache.log4j.Logger; import org.dspace.content.Collection; import org.dspace.content.Community; import org.dspace.core.ConfigurationManager; import org.dspace.app.webui.servlet.FeedServlet; /** * Tag for HTML page layout ("skin"). * <P> * This tag <em>sets</em> request attributes that should be used by the header * and footer to render the page appropriately: * <P> * <ul> * <li><code>dspace.layout.title</code> - title of page</li> * <li><code>dspace.layout.locbar</code> - value will Boolean true or false * </li> * <li><code>dspace.layout.parenttitles</code> - a <code>List</code> of * <code>String</code>s corresponding with titles to put in the location bar. * Only set if <code>dspace.layout.locbar</code> is true</li> * <li><code>dspace.layout.parentlinks</code> - a <code>List</code> of * <code>String</code>s corresponding with links to put in the location bar. * Empty strings mean no link. Will only be set if * <code>dspace.layout.locbar</code> is true.</li> * <li><code>dspace.layout.navbar</code> - value will be "off", or the * navigation bar to include, e.g. "/layout/navbar_default.jsp"</li> * <li><code>dspace.layout.sidebar</code> - contents of the sidebar</li> * <li><code>dspace.current.user</code> - the EPerson currently logged in, or * <code>null</code> if anonymous access</li> * <li><code>dspace.layout.feeddata</code> - <code>String</code>. "NONE" * means no feed from this page; otherwise the Handle of object (community or * collection) the feed is from</li> * <li><code>dspace.layout.linkparts</code> - <code>String[]</code>. A * cycling sequence of: 2nd part of MIME type (e.g. <code>rdf+rss</code>); * title of feed; path component to go after /feed/ for the actual feed URL * (e.g. <code>rss_1.0</code>). Hence, this array will have 3<i>n</i> * elements where <i>n</i> is the number of feeds.</li> * </ul> * <p> * * * Additionally the following parameter may be set elsewhere in a Servlet. * <p> * <ul> * <li><code>dspace.layout.head</code> - extra data to include verbatim in * the <head> element of the page</li> * </ul> * * Furthermore it sets the content type of the response to text/html using UTF-8 * to ensure this will be returned in the HTTP header. * </p> * * @author Robert Tansley * @version $Revision: 3705 $ */ public class LayoutTag extends TagSupport { /** log4j logger */ private static Logger log = Logger.getLogger(LayoutTag.class); /** layout style name */ private String style; /** title */ private String title; /** title key (from message dictionary) */ private String titleKey; /** Navigation bar type, null means none */ private String navbar; /** Location bar type */ private String locbar; /** Name of "parent" page */ private String parentTitle; /** Name of "parent" page key (from message dictionary) */ private String parentTitleKey; /** Link to "parent" page */ private String parentLink; /** Contents of side bar */ private String sidebar; /** Whether to add headers to prevent browsers caching the page */ private String noCache; /** Syndication feed "autodiscovery" link data */ private String feedData; public LayoutTag() { super(); } public int doStartTag() throws JspException { ServletRequest request = pageContext.getRequest(); // header file String header = "/layout/header-default.jsp"; // Choose default style unless one is specified if (style != null) { header = "/layout/header-" + style.toLowerCase() + ".jsp"; } // Sort out location bar if (locbar == null) { locbar = "auto"; } // These lists will contain titles and links to put in the location // bar List parents = new ArrayList(); List parentLinks = new ArrayList(); if (locbar.equalsIgnoreCase("off")) { // No location bar request.setAttribute("dspace.layout.locbar", new Boolean(false)); } else { // We'll always add "DSpace Home" to the a location bar parents.add(ConfigurationManager.getProperty("dspace.name")); if (locbar.equalsIgnoreCase("nolink")) { parentLinks.add(""); } else { parentLinks.add("/"); } // Add other relevant components to the location bar if (locbar.equalsIgnoreCase("link")) { // "link" mode - next thing in location bar is taken from // parameters of tag, with a link if (parentTitle != null) { parents.add(parentTitle); parentLinks.add(parentLink); } else if (parentTitleKey != null) { parents.add(LocaleSupport.getLocalizedMessage(pageContext, parentTitleKey)); parentLinks.add(parentLink); } } else if (locbar.equalsIgnoreCase("commLink")) { // "commLink" mode - show all parent communities Community[] comms = (Community[]) request .getAttribute("dspace.communities"); if (comms != null) { for (int i = 0; i < comms.length; i++) { parents.add(comms[i].getMetadata("name")); parentLinks.add("/handle/" + comms[i].getHandle()); } } } else if (locbar.equalsIgnoreCase("nolink")) { // "nolink" mode - next thing in location bar is taken from // parameters of tag, with no link if (parentTitle != null) { parents.add(parentTitle); parentLinks.add(""); } } else { // Grab parents from the URL - these should have been picked up // by the HandleServlet Collection col = (Collection) request .getAttribute("dspace.collection"); Community[] comms = (Community[]) request .getAttribute("dspace.communities"); if (comms != null) { for (int i = 0; i < comms.length; i++) { parents.add(comms[i].getMetadata("name")); parentLinks.add("/handle/" + comms[i].getHandle()); } if (col != null) { parents.add(col.getMetadata("name")); parentLinks.add("/handle/" + col.getHandle()); } } } request.setAttribute("dspace.layout.locbar", new Boolean(true)); } request.setAttribute("dspace.layout.parenttitles", parents); request.setAttribute("dspace.layout.parentlinks", parentLinks); // Navigation bar: "default" is default :) if (navbar == null) { navbar = "default"; } if (navbar.equals("off")) { request.setAttribute("dspace.layout.navbar", "off"); } else { request.setAttribute("dspace.layout.navbar", "/layout/navbar-" + navbar + ".jsp"); } // Set title if (title != null) { request.setAttribute("dspace.layout.title", title); } else if (titleKey != null) { request.setAttribute("dspace.layout.title", LocaleSupport .getLocalizedMessage(pageContext, titleKey)); } else { request.setAttribute("dspace.layout.title", "NO TITLE"); } // Set feedData if present if (feedData != null && ! "NONE".equals(feedData)) { // set the links' reference - community or collection boolean commLinks = feedData.startsWith("comm:"); boolean collLinks = feedData.startsWith("coll:"); if ( commLinks ) { Community com = (Community)request.getAttribute("dspace.community"); request.setAttribute("dspace.layout.feedref", com.getHandle()); } else if( collLinks ) { Collection col = (Collection)request.getAttribute("dspace.collection"); request.setAttribute("dspace.layout.feedref", col.getHandle()); } else //feed is across all of DSpace and not Community/Collection specific { request.setAttribute("dspace.layout.feedref", FeedServlet.SITE_FEED_KEY); } // build a list of link attributes for each link format String[] formats = feedData.substring(feedData.indexOf(":")+1).split(","); List linkParts = new ArrayList(); // each link has a mime-type, title, and format (used in href URL) for (int i = 0; i < formats.length; i++) { if("rss_1.0".equals(formats[i])) { linkParts.add("rdf+xml"); } else { linkParts.add("rss+xml"); } if (commLinks) { linkParts.add("Items in Community"); } else if(collLinks) { linkParts.add("Items in Collection"); } else { linkParts.add("Items in " + ConfigurationManager.getProperty("dspace.name")); } linkParts.add(formats[i]); } request.setAttribute("dspace.layout.linkparts", linkParts); } else { request.setAttribute("dspace.layout.feedref", "NONE" ); } // Now include the header try { HttpServletResponse response = (HttpServletResponse) pageContext .getResponse(); // Set headers to prevent browser caching, if appropriate if ((noCache != null) && noCache.equalsIgnoreCase("true")) { response.addDateHeader("expires", 1); response.addHeader("Pragma", "no-cache"); response.addHeader("Cache-control", "no-store"); } // Ensure the HTTP header will declare that UTF-8 is used // in the response. response.setContentType("text/html; charset=UTF-8"); ServletConfig config = pageContext.getServletConfig(); RequestDispatcher rd = config.getServletContext() .getRequestDispatcher(header); rd.include(request, response); } catch (IOException ioe) { throw new JspException("Got IOException: " + ioe); } catch (ServletException se) { log.warn("Exception", se.getRootCause()); throw new JspException("Got ServletException: " + se); } return EVAL_BODY_INCLUDE; } public int doEndTag() throws JspException { // Footer file to use String footer = "/layout/footer-default.jsp"; // Choose default flavour unless one is specified if (style != null) { footer = "/layout/footer-" + style.toLowerCase() + ".jsp"; } try { // Ensure body is included before footer pageContext.getOut().flush(); // Context objects ServletRequest request = pageContext.getRequest(); ServletResponse response = pageContext.getResponse(); ServletConfig config = pageContext.getServletConfig(); if (sidebar != null) { request.setAttribute("dspace.layout.sidebar", sidebar); } RequestDispatcher rd = config.getServletContext() .getRequestDispatcher(footer); rd.include(request, response); } catch (ServletException se) { throw new JspException("Got ServletException: " + se); } catch (IOException ioe) { throw new JspException("Got IOException: " + ioe); } return EVAL_PAGE; } /** * Get the value of title. * * @return Value of title. */ public String getTitle() { return title; } /** * Set the value of title. * * @param v * Value to assign to title. */ public void setTitle(String v) { this.title = v; } /** * @return Returns the titleKey. */ public String getTitlekey() { return titleKey; } /** * @param titleKey The titleKey to set. */ public void setTitlekey(String titleKey) { this.titleKey = titleKey; } /** * Get the value of navbar. * * @return Value of navbar. */ public String getNavbar() { return navbar; } /** * Set the value of navbar. * * @param v * Value to assign to navbar. */ public void setNavbar(String v) { this.navbar = v; } /** * Get the value of locbar. * * @return Value of locbar. */ public String getLocbar() { return locbar; } /** * Set the value of locbar. * * @param v * Value to assign to locbar. */ public void setLocbar(String v) { this.locbar = v; } /** * Get the value of parentTitle. * * @return Value of parentTitle. */ public String getParenttitle() { return parentTitle; } /** * Set the value of parent. * * @param v * Value to assign to parent. */ public void setParenttitle(String v) { this.parentTitle = v; } /** * get parent title key (from message dictionary) * * @return Returns the parentTitleKey. */ public String getParenttitlekey() { return parentTitleKey; } /** * set parent title key (from message dictionary) * * @param parentTitleKey The parentTitleKey to set. */ public void setParenttitlekey(String parentTitleKey) { this.parentTitleKey = parentTitleKey; } /** * Get the value of parentlink. * * @return Value of parentlink. */ public String getParentlink() { return parentLink; } /** * Set the value of parentlink. * * @param v * Value to assign to parentlink. */ public void setParentlink(String v) { this.parentLink = v; } /** * Get the value of style. * * @return Value of style. */ public String getStyle() { return style; } /** * Set the value of style. * * @param v * Value to assign to style. */ public void setStyle(String v) { this.style = v; } /** * Get the value of sidebar. * * @return Value of sidebar. */ public String getSidebar() { return sidebar; } /** * Set the value of sidebar. * * @param v * Value to assign to sidebar. */ public void setSidebar(String v) { this.sidebar = v; } /** * Get the value of sidebar. * * @return Value of sidebar. */ public String getNocache() { return noCache; } /** * Set the value of sidebar. * * @param v * Value to assign to sidebar. */ public void setNocache(String v) { this.noCache = v; } /** * Get the value of feedData. * * @return Value of feedData. */ public String getFeedData() { return feedData; } /** * Set the value of feedData. * * @param v * Value to assign to feedData. */ public void setFeedData(String v) { this.feedData = v; } public void release() { style = null; title = null; sidebar = null; navbar = null; locbar = null; parentTitle = null; parentLink = null; noCache = null; feedData = null; } }