Source code: com/RuntimeCollective/webapps/tag/CrumbTrailTag.java
1 /* $Header: /home/CVS/rjp/src/com/RuntimeCollective/webapps/tag/CrumbTrailTag.java,v 1.12 2003/09/30 15:13:16 joe Exp $
2 * $Revision: 1.12 $
3 * $Date: 2003/09/30 15:13:16 $
4 *
5 * ====================================================================
6 *
7 * Josephine : http://www.runtime-collective.com/josephine/index.html
8 *
9 * Copyright (C) 2003 Runtime Collective
10 *
11 * This product includes software developed by the
12 * Apache Software Foundation (http://www.apache.org/).
13 *
14 * This library is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Lesser General Public
16 * License as published by the Free Software Foundation; either
17 * version 2.1 of the License, or (at your option) any later version.
18 *
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 *
28 */
29
30 package com.RuntimeCollective.webapps.tag;
31
32 import com.RuntimeCollective.webapps.bean.Crumb;
33 import com.RuntimeCollective.webapps.CrumbTrail;
34
35 import java.io.IOException;
36 import java.io.PrintStream;
37 import javax.servlet.jsp.JspWriter;
38 import javax.servlet.jsp.PageContext;
39 import javax.servlet.jsp.JspException;
40 import javax.servlet.jsp.JspTagException;
41 import javax.servlet.jsp.tagext.Tag;
42 import javax.servlet.jsp.tagext.TagSupport;
43 import javax.servlet.http.HttpServletRequest;
44 import javax.servlet.http.HttpServletResponse;
45 import org.apache.struts.taglib.html.BaseHandlerTag;
46 import org.apache.commons.beanutils.PropertyUtils;
47
48 /** A custom JSP tag that adds the current page to the crumb trail and displays the result. Why not just hard-code the crumb trail into the jsp (or html)? This is OK for simple sites in which the same page is only accessed by a single path (i.e. which form a non-recurrent tree.) The advantage with this tag is that it can cope with more complex site graphs in which the same page can be access by multiple routes.
49 *
50 * <p> This tag takes two attributes:
51 * <ul>
52 * <li> <code> label </code> - the label to be given to the current page [Optional].</li>
53 * <li> <code> labelName, labelProperty </code> - If <code>label</code> is not set, then the label can be taken from a bean of the given name and property [].</li>
54 * <li> <code> forward </code> - the name of the <code>ActionForward</code> that points to the current page [Mandatory].</li>
55 * <li> <code> delimiter </code> - The delimiter used to seperate the crumbs of the trail. Defaults to " > " [Optional].</li>
56 * <li> <code> formAction </code> - The name of the <code>CrumbTrailAction</code> that will handle the jump. Defaults to "/crumbTrailAction" [Optional].</li>
57 * </ul>
58 * <p><strong>Note</strong> The trail is only printed if it has more than one crumb.
59 * @version $Id: CrumbTrailTag.java,v 1.12 2003/09/30 15:13:16 joe Exp $
60 */
61 public class CrumbTrailTag extends BaseHandlerTag {
62
63 // == Properties ===================================================
64
65 /** The label for the current page. */
66 protected String label = "";
67 /** Get the label for the current page. */
68 public String getLabel() { return this.label; }
69 /** Set the label for the current page. */
70 public void setLabel(String label) { this.label = label; }
71
72 /** The forward for the current page. */
73 protected String forward = "";
74 /** Get the forward for the current page. */
75 public String getForward() { return this.forward; }
76 /** Set the forward for the current page. */
77 public void setForward(String forward) { this.forward = forward; }
78
79 /** The crumb delimiter. */
80 protected String delimiter = " > ";
81 /** Get the crumb delimiter. */
82 public String getDelimiter() { return this.delimiter; }
83 /** Set the crumb delimiter. */
84 public void setDelimiter(String delimiter) { this.delimiter = delimiter; }
85
86 /** The name of the action that handles the trail. */
87 protected String action = "/crumbTrailAction";
88 /** Get the name of the action that handles the trail. */
89 public String getFormAction() { return this.action; }
90 /** Set the name of the action that handles the trail. */
91 public void setFormAction(String action) { this.action = action; }
92
93 /** Whether this page is a home page -- ie whether the crumb trail will be reset on this page. */
94 protected String home = "";
95 /** Get whether this page is a home page -- ie whether the crumb trail will be reset on this page. */
96 public String getHome() { return this.home; }
97 /** Set whether this page is a home page -- ie whether the crumb trail will be reset on this page. */
98 public void setHome(String home) { this.home = home; }
99
100 /** The name of the bean that holds the label to display. */
101 protected String labelName = "";
102 /** Get the name of the bean that holds the label to display. */
103 public String getLabelName() { return this.labelName; }
104 /** Set the name of the bean that holds the label to display. */
105 public void setLabelName(String labelName) { this.labelName = labelName; }
106
107 /** The property of the named bean that holds the label to display. */
108 protected String labelProperty = "";
109 /** Get the property of the named bean that holds the label to display. */
110 public String getLabelProperty() { return this.labelProperty; }
111 /** Set the property of the named bean that holds the label to display. */
112 public void setLabelProperty(String labelProperty) { this.labelProperty = labelProperty; }
113
114
115 // == Tag methods ==================================
116
117 public int doStartTag() throws JspException {
118
119 HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
120
121 // Find the label to display
122 if ( label.equals("") ) {
123 // Find the bean that carries the label
124 Object bean = pageContext.findAttribute(labelName);
125 if (bean == null) throw new JspException ("Can't access bean! "+labelName);
126 try {
127 // find the label
128 label = (String) PropertyUtils.getProperty(bean, labelProperty).toString();
129 } catch (Exception e) {
130 throw new JspException ("Error in crumbtrail tag: "+e);
131 }
132 }
133
134 // Create a new crumb for this label
135 Crumb crumb = new Crumb(label,forward);
136
137 // Find the trail to add it to
138 CrumbTrail trail = (CrumbTrail) request.getSession().getAttribute( CrumbTrail.KEY );
139 if ( trail==null ) trail = new CrumbTrail();
140
141 // Reset the trail if necessary
142 if ( home.equals("true") ) trail.jump(0);
143
144 // Add the current crumb to the trail
145 trail.addCrumb( crumb );
146
147 // Encode the action into an href.
148 HttpServletResponse response = (HttpServletResponse) pageContext.getResponse();
149 String href = response.encodeURL( TagUtils.getActionMappingURL( pageContext, action ) );
150
151 // If there is more than one crumb on the trail then print each crumb except the last, as a link.
152 StringBuffer html = new StringBuffer(400);
153 if ( trail!=null ) {
154 if ( trail.size()>1 ) {
155 int size = trail.size() - 1;
156 for (int i=0; i<size; i++) {
157 html.append("<a href=\"").append(href).append("?crumb=" + i).append("\" ").append(prepareStyles()).append(prepareEventHandlers()).append(">").append(trail.get(i).getLabel()).append("</a>"+delimiter);
158 }
159 // And the current page (non-clickable)
160 html.append(label);
161 // print the result
162 try {
163 pageContext.getOut().println( html.toString() );
164 } catch (IOException e) {
165 throw new JspTagException("I/O Exception "+e.getMessage() );
166 }
167 }
168 }
169
170 // Add crumb to trail and save back on the session;
171 request.getSession().setAttribute( CrumbTrail.KEY, trail );
172
173 return SKIP_BODY;
174 }
175
176 public void release() {
177 super.release();
178 forward = "";
179 delimiter = " > ";
180 label = "";
181 labelName = "";
182 labelProperty = "";
183 home = "";
184 action = "/crumbTrailAction";
185 }
186 }