Source code: org/roller/presentation/tags/LinkTag.java
1 /*
2 * $Header: /cvsroot/roller/roller/src/org/roller/presentation/tags/LinkTag.java,v 1.1 2003/08/31 00:38:12 snoopdave Exp $
3 * $Revision: 1.1 $
4 * $Date: 2003/08/31 00:38:12 $
5 *
6 * ====================================================================
7 */
8
9 package org.roller.presentation.tags;
10
11 import org.apache.commons.beanutils.PropertyUtils;
12 import org.apache.log4j.Category;
13 import org.apache.struts.action.Action;
14 import org.apache.struts.action.ActionForward;
15 import org.apache.struts.action.ActionForwards;
16 import org.apache.struts.util.RequestUtils;
17 import org.apache.struts.util.ResponseUtils;
18
19 import java.lang.reflect.InvocationTargetException;
20 import java.net.MalformedURLException;
21 import java.net.URLEncoder;
22 import java.util.Iterator;
23 import java.util.Map;
24
25 import javax.servlet.http.HttpServletRequest;
26 import javax.servlet.jsp.JspException;
27 import javax.servlet.jsp.PageContext;
28
29 /**
30 * Generates an HTML link. This class adds the parameter feature to the Struts
31 * html link tag.<br/>
32 * It should be use as follow:
33 * <pre>
34 * <hm:link href="http://java.sun.com">
35 * <hm:linkparam name="action" value="submit" />
36 * <hm:linkparam name="ref" value="144532" />
37 * </hm:linl>
38 * </pre>
39 * This will produce the equivalent of
40 * <pre><href="http://java.sun.com?_action=submit&ref=144532"></pre>
41 *
42 * Title: BSquare
43 * Description: Bsquare Projects
44 * Copyright: Copyright (c) 2001
45 * Company: HubMethods
46 * @author $Author: snoopdave $
47 * @version $Revision: 1.1 $
48 */
49
50 public class LinkTag extends org.apache.struts.taglib.html.LinkTag {
51
52 // ------------------------------------------------------ Logging
53 Category cat = Category.getInstance(LinkTag.class);
54
55 // ------------------------------------------------------ Instance Vartables
56 /**
57 * The full HREF URL
58 */
59 private StringBuffer hrefURL = new StringBuffer();
60
61
62 // ------------------------------------------------------------- Properties
63
64
65 //--------------------------------------------------------- Public Methods
66
67 /**
68 * Intialize the hyperlink.
69 *
70 * @exception JspException if a JSP exception has occurred
71 */
72 public int doStartTag() throws JspException {
73
74 // Special case for name anchors
75 if (linkName != null) {
76 StringBuffer results = new StringBuffer("<a name=\"");
77 results.append(linkName);
78 results.append("\">");
79 return (EVAL_BODY_TAG);
80 }
81
82 // Generate the hyperlink URL
83 Map params = RequestUtils.computeParameters
84 (pageContext, paramId, paramName, paramProperty, paramScope,
85 name, property, scope, transaction);
86 String url = null;
87 try {
88 url = RequestUtils.computeURL(pageContext, forward, href,
89 page, params, anchor, false);
90 } catch (MalformedURLException e) {
91 RequestUtils.saveException(pageContext, e);
92 throw new JspException
93 (messages.getMessage("rewrite.url", e.toString()));
94 }
95
96 // Generate the opening anchor element
97 hrefURL = new StringBuffer("<a href=\"");
98 hrefURL.append(url);
99
100 if (cat.isDebugEnabled()) cat.debug("hrefURL = '" + hrefURL.toString());
101
102 // Evaluate the body of this tag
103 this.text = null;
104 return (EVAL_BODY_TAG);
105 }
106
107 /**
108 * Add a new parameter to the request
109 *
110 * @param name the name of the request parameter
111 * @param value the value of the request parameter
112 */
113 public void addRequestParameter(String name, String value) {
114 if (cat.isDebugEnabled()) cat.debug("Adding '" + name + "' with value '" + value + "'");
115
116 boolean question = (hrefURL.toString().indexOf('?') >= 0);
117
118 if (question) { // There are request parameter already
119 hrefURL.append('&');
120 }
121 else hrefURL.append('?');
122
123 hrefURL.append(name);
124 hrefURL.append('=');
125 hrefURL.append(URLEncoder.encode(value));
126
127 if (cat.isDebugEnabled()) cat.debug("hrefURL = '" + hrefURL.toString() + "'");
128 }
129
130 /**
131 * Render the href reference
132 *
133 * @exception JspException if a JSP exception has occurred
134 */
135 public int doEndTag() throws JspException {
136
137 hrefURL.append("\"");
138 if (target != null) {
139 hrefURL.append(" target=\"");
140 hrefURL.append(target);
141 hrefURL.append("\"");
142 }
143
144 hrefURL.append(prepareStyles());
145 hrefURL.append(prepareEventHandlers());
146 hrefURL.append(">");
147
148 if (text != null)
149 hrefURL.append(text);
150 hrefURL.append("</a>");
151
152 if (cat.isDebugEnabled()) cat.debug("Total request is = '" + hrefURL.toString() + "'");
153
154 // Print this element to our output writer
155 ResponseUtils.write(pageContext, hrefURL.toString());
156 return (EVAL_PAGE);
157 }
158
159
160 /**
161 * Release any acquired resources.
162 */
163 public void release() {
164
165 super.release();
166 forward = null;
167 href = null;
168 name = null;
169 property = null;
170 target = null;
171
172 }
173
174
175 // ----------------------------------------------------- Protected Methods
176
177 /**
178 * Return the specified hyperlink, modified as necessary with optional
179 * request parameters.
180 *
181 * @exception JspException if an error occurs preparing the hyperlink
182 */
183 protected String hyperlink() throws JspException {
184
185 String href = this.href;
186
187 // If "forward" was specified, compute the "href" to forward to
188 if (forward != null) {
189 ActionForwards forwards = (ActionForwards)
190 pageContext.getAttribute(Action.FORWARDS_KEY,
191 PageContext.APPLICATION_SCOPE);
192 if (forwards == null)
193 throw new JspException
194 (messages.getMessage("linkTag.forwards"));
195 ActionForward forward = forwards.findForward(this.forward);
196 if (forward == null)
197 throw new JspException
198 (messages.getMessage("linkTag.forward"));
199 HttpServletRequest request =
200 (HttpServletRequest) pageContext.getRequest();
201 href = request.getContextPath() + forward.getPath();
202 }
203
204 // Just return the "href" attribute if there is no bean to look up
205 if ((property != null) && (name == null))
206 throw new JspException
207 (messages.getMessage("getter.name"));
208 if (name == null)
209 return (href);
210
211 // Look up the map we will be using
212 Object bean = pageContext.findAttribute(name);
213 if (bean == null)
214 throw new JspException
215 (messages.getMessage("getter.bean", name));
216 Map map = null;
217 if (property == null) {
218 try {
219 map = (Map) bean;
220 } catch (ClassCastException e) {
221 throw new JspException
222 (messages.getMessage("linkTag.type"));
223 }
224 } else {
225 try {
226 map = (Map) PropertyUtils.getProperty(bean, property);
227 if (map == null)
228 throw new JspException
229 (messages.getMessage("getter.property", property));
230 } catch (IllegalAccessException e) {
231 throw new JspException
232 (messages.getMessage("getter.access", property, name));
233 } catch (InvocationTargetException e) {
234 Throwable t = e.getTargetException();
235 throw new JspException
236 (messages.getMessage("getter.result",
237 property, t.toString()));
238 } catch (ClassCastException e) {
239 throw new JspException
240 (messages.getMessage("linkTag.type"));
241 } catch (NoSuchMethodException e) {
242 throw new JspException
243 (messages.getMessage("getter.method", property, name));
244 }
245 }
246
247 // Append the required query parameters
248 StringBuffer sb = new StringBuffer(href);
249 boolean question = (href.indexOf("?") >= 0);
250 Iterator keys = map.keySet().iterator();
251 while (keys.hasNext()) {
252 String key = (String) keys.next();
253 Object value = map.get(key);
254 if (value instanceof String[]) {
255 String values[] = (String[]) value;
256 for (int i = 0; i < values.length; i++) {
257 if (question)
258 sb.append('&');
259 else {
260 sb.append('?');
261 question = true;
262 }
263 sb.append(key);
264 sb.append('=');
265 sb.append(URLEncoder.encode(values[i]));
266 }
267 } else {
268 if (question)
269 sb.append('&');
270 else {
271 sb.append('?');
272 question = true;
273 }
274 sb.append(key);
275 sb.append('=');
276 sb.append(URLEncoder.encode(value.toString()));
277 }
278 }
279
280 // Return the final result
281 return (sb.toString());
282
283 }
284 }