Source code: com/RuntimeCollective/webapps/tag/ImageSubmitTag.java
1 /* $Header: /home/CVS/rjp/src/com/RuntimeCollective/webapps/tag/ImageSubmitTag.java,v 1.4 2003/09/30 15:13:18 joe Exp $
2 * $Revision: 1.4 $
3 * $Date: 2003/09/30 15:13:18 $
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
33
34 import com.RuntimeCollective.webapps.RuntimeParameters;
35
36 import java.io.IOException;
37 import java.io.PrintStream;
38 import java.util.Locale;
39 import javax.servlet.jsp.JspWriter;
40 import javax.servlet.jsp.PageContext;
41 import javax.servlet.jsp.JspException;
42 import javax.servlet.jsp.JspTagException;
43 import javax.servlet.jsp.tagext.Tag;
44 import javax.servlet.jsp.tagext.TagSupport;
45 import javax.servlet.http.HttpServletRequest;
46 import javax.servlet.http.HttpServletResponse;
47 import org.apache.struts.action.Action;
48 import org.apache.commons.beanutils.BeanUtils;
49 import org.apache.struts.util.RequestUtils;
50 import org.apache.struts.util.ResponseUtils;
51 import org.apache.struts.util.MessageResources;
52 import org.apache.struts.taglib.html.BaseHandlerTag;
53
54 /** A custom JSP tag that produces a submit button which uses an image rather than a button and behaves otherwise the same as SubmitTag, but also has all the same attributes as org.apache.struts.taglib.html.ImageTag
55 * Note this tag will not work if it sits next to a Struts html:submit tag.
56 * Convert other tags to rs:submit, to make sure it all works fine!
57 * <p>
58 * This tag takes the following attributes:
59 * <ul>
60 * <li> <code> name </code> - The name of the current form. [Mandatory]. </li>
61 * <li> <code> src </code> - The absolute url of the image file. [Optional]. <li>
62 * <li> <code> srcKey </code> - The key of the message resources string specifying the source URL of the image for this input tag. [Optional] </li>
63 * <br><strong>Note</strong> You cannot specify both src and srcKey.
64 * <li> <code> page </code> - The path to the image. The tag will make this context relative. [Optional] <li>
65 * <li> <code> pageKey </code> - The key of the message resources string specifying the context-relative path of the image for this input tag. [Optional] </li>
66 * <br> <strong>Note</strong> - You cannot specify both page and pageKey.
67 * <br> <strong>Note</strong> - You'll need either a src/srcKey or page/pageKey attribute for this tag to work.
68 * <li> <code> value </code> - The value of property to submit. Defaults to property's current value. [Optional]. </li>
69 * <li> <code> property </code> - The property to be set to value. Defaults to "formAction". [Optional].
70 * <br><strong>Note</strong> a javascript bug means that property must <strong>not</strong> be set to "submit" or "action". </li>
71 * <li> <code> paramName </code> - The name of a bean whose paramProperty will be appended to the value of the property to submit, with a blank space in front. [Optional]. </li>
72 * <li> <code> paramProperty </code> - The bean property which will be appended to the value of the property to submit, with a blank space in front. paramName must be set. Defaults to using the toString() value of paramBean. [Optional].
73 * <li> <code> confirm </code> - If this is set, then it will be used as the confirmation message in a popup window with 'OK/Cancel' buttons. The form will only be submitted if the user hits 'OK'. Defaults to "" (i.e. no confirmation required) [Optional]. </li>
74 * <li> <code> htmlJSInput </code> - You must set this to true if the form contains an <code>htmlJSInput</code> tag [Optional]. </li>
75 * <li> <code>alt</code> - The alternate text for this image. [Optional] </li>
76 * <li> <code>altKey</code> - The message resources key of the alternate text for this image. [Optional] </li>
77 * <br> <strong>Note</strong> - You cannot specify both alt and altKey.
78 * <li> <code>Border</code> - The width (in pixels) of the border around this image. [Optional]
79 * </ul>
80 * This allows you to either specify the value explicitly, or take it from a bean's property.
81 * <p><strong>Note</strong> this tag must be used inside a form.
82 * <p><b>Examples:</b>
83 * <blockquote><code><rs:imageSubmit name="lessonForm" src="http://imageServer/imageDir/imageFile.jpg" /></code></blockquote>
84 * The submitted form will contain a parameter "formAction" (the default) that has the existing value of <code>lessonForm</code>'s "formAction" property.
85 * <p>
86 * <blockquote><code><rs:imageSubmit name="lessonForm" page"/imageDir/imageFile.jpg" value="delete"/></code></blockquote>
87 * The submitted form will contain a parameter "formAction" (the default) that has the value "delete".
88 *
89 * @version $Id: ImageSubmitTag.java,v 1.4 2003/09/30 15:13:18 joe Exp $
90 */
91 public class ImageSubmitTag extends SubmitTag {
92
93 // == Properties ===================================================
94
95 /**
96 * The default Locale for our server.
97 */
98 protected static final Locale defaultLocale = Locale.getDefault();
99
100
101 /**
102 * The alternate text for this image.
103 */
104 protected String alt = null;
105
106 public String getAlt() {
107 return (this.alt);
108 }
109
110 public void setAlt(String alt) {
111 this.alt = alt;
112 }
113
114
115 /**
116 * The message resources key for the alternate text for this image.
117 */
118 protected String altKey = null;
119
120 public String getAltKey() {
121 return (this.altKey);
122 }
123
124 public void setAltKey(String altKey) {
125 this.altKey = altKey;
126 }
127
128
129 /**
130 * The border size around the image.
131 */
132 protected String border = null;
133
134 public String getBorder() {
135 return (this.border);
136 }
137
138 public void setBorder(String border) {
139 this.border = border;
140 }
141
142
143 /**
144 * The servlet context attribute key for our resources.
145 */
146 protected String bundle = Action.MESSAGES_KEY;
147
148 public String getBundle() {
149 return (this.bundle);
150 }
151
152 public void setBundle(String bundle) {
153 this.bundle = bundle;
154 }
155
156
157 /**
158 * The session attribute key for our locale.
159 */
160 protected String locale = Action.LOCALE_KEY;
161
162 public String getLocale() {
163 return (this.locale);
164 }
165
166 public void setLocale(String locale) {
167 this.locale = locale;
168 }
169
170 /** page */
171 protected String page = null;
172
173 public String getPage() { return this.page; }
174
175 public void setPage(String s) { this.page = s; }
176
177 /**
178 * The message resources key of the context-relative URI of the image.
179 */
180 protected String pageKey = null;
181
182 public String getPageKey() {
183 return (this.pageKey);
184 }
185
186 public void setPageKey(String pageKey) {
187 this.pageKey = pageKey;
188 }
189
190
191 /** src */
192 protected String src = null;
193
194 public String getSrc() { return this.src; }
195
196 public void setSrc(String s) { this.src = s; }
197
198 /**
199 * The message resources key for the URL of this image.
200 */
201 protected String srcKey = null;
202
203 public String getSrcKey() {
204 return (this.srcKey);
205 }
206
207 public void setSrcKey(String srcKey) {
208 this.srcKey = srcKey;
209 }
210
211
212
213 /**
214 * Return the src for the image using either src or srcKey, returns null if neither are specified.
215 * @exception JspException if both src and srcKey are specified.
216 */
217 protected String src() throws JspException {
218 // Deal with an absolute source that has been specified
219 if (this.src != null) {
220 if (this.srcKey != null) {
221 RuntimeParameters.logError(this,"[ImageSubmitTag:src] you cannot specify a src and srcKey");
222 JspException e = new JspException("[ImageSubmitTag:src] you cannot specify a src and srcKey");
223 RequestUtils.saveException(pageContext, e);
224 throw e;
225 }
226 return (this.src);
227 } else {
228
229 if (this.srcKey != null) {
230 return (RequestUtils.message(pageContext, bundle, locale, this.srcKey));
231 }
232 // guess theres neither src nor srcKey
233 return null;
234 }
235 }
236
237 /**
238 * Return the src for the image using either page or pageKey, returns null if neither are specified.
239 * @exception JspException if both src and srcKey are specified.
240 */
241 protected String page() throws JspException {
242 // Deal with an absolute source that has been specified
243 if (this.page != null) {
244 if (this.pageKey != null) {
245 RuntimeParameters.logError(this,"[ImageSubmitTag:page] you cannot specify a page and pageKey");
246 JspException e = new JspException("[ImageSubmitTag:page] you cannot specify a page and pageKey");
247 RequestUtils.saveException(pageContext, e);
248 throw e;
249 }
250 return (this.page);
251 } else {
252
253 if (this.pageKey != null) {
254 return (RequestUtils.message(pageContext, bundle, locale, this.pageKey));
255 }
256 // guess theres neither page or pageKey
257 return null;
258 }
259 }
260
261
262
263
264 protected String getImageUrl() {
265 try {
266 return RequestUtils.computeURL(pageContext, null, src(), page(), null, null, false);
267 } catch (Exception e) {
268 RuntimeParameters.logError(this,"[ImageSubmitTag:getImageUrl] this was probably either a MalformedURLException or a JspException");
269 e.printStackTrace(System.out);
270 return "";
271 }
272 }
273
274 /**
275 * Return the alternate text to be included on this generated element,
276 * or <code>null</code> if there is no such text.
277 */
278 protected String alt() {
279
280 if (this.alt != null) {
281 if (this.altKey != null) {
282 RuntimeParameters.logError(this,"[ImageSubmitTag:alt] you cannot specify both alt and altKey");
283 return null;
284 } else {
285 return (this.alt);
286 }
287 } else if (this.altKey != null) {
288 MessageResources resources = (MessageResources) pageContext.getAttribute(this.bundle,PageContext.APPLICATION_SCOPE);
289 if (resources == null) {
290 RuntimeParameters.logError(this, "[ImageSubmitTag:alt] weird! no messages set up");
291 return null;
292 }
293 Locale locale = null;
294 try {
295 locale = (Locale)
296 pageContext.getAttribute(this.locale,
297 PageContext.SESSION_SCOPE);
298 } catch (IllegalStateException e) {
299 locale = null; // Invalidated session
300 }
301 if (locale == null)
302 locale = defaultLocale;
303 return (resources.getMessage(locale, this.altKey));
304 } else {
305 return (null);
306 }
307
308 }
309
310 protected String prepareAlt() {
311 if (alt() != null) {
312 return " alt=\""+alt()+"\" ";
313 }
314 return "";
315 }
316
317 protected String prepareBorder() {
318 if (getBorder() != null) {
319 return " border=\""+getBorder()+"\" ";
320 }
321 return "";
322 }
323
324 // // == Tag methods ==================================
325
326 public int doStartTag() throws JspException {
327
328 // If the value is null, try and get it from
329 // the named bean's property
330 if ( value.equals("") ) {
331 Object bean = pageContext.findAttribute(name);
332 if (bean == null)
333 throw new JspException ("Can't access bean! "+name);
334 try {
335 String beanValue = BeanUtils.getSimpleProperty(bean, property);
336 if (beanValue == null)
337 beanValue = "";
338 setValue(beanValue);
339 } catch (Exception e) {
340 throw new JspException ("Error in submit tag: "+e);
341 }
342 }
343
344 // append the paramName's paramProperty if it has been specified
345 if (paramName != null && !paramName.equals("")) {
346 Object paramBean = pageContext.findAttribute(paramName);
347 if (paramBean == null)
348 throw new JspException ("Can't access paramBean! "+paramName);
349 try {
350 String paramBeanValue;
351 if (paramProperty == null || paramProperty.equals(""))
352 paramBeanValue = paramBean.toString();
353 else
354 paramBeanValue = BeanUtils.getSimpleProperty(paramBean, paramProperty);
355 if (paramBeanValue == null)
356 paramBeanValue = "";
357 setValue(this.getValue()+" "+paramBeanValue);
358 } catch (Exception e) {
359 throw new JspException ("Error in submit tag: "+e);
360 }
361 }
362
363
364
365 StringBuffer html = new StringBuffer(600);
366 String submitnameproperty = (new StringBuffer(60)).append("submit_").append(name).append("_").append(property).toString();
367
368 // first check whether this is the first submit button for this form property
369 if (pageContext.getAttribute(submitnameproperty) == null) {
370
371 // create the javascript for the submit function for this form.
372 html.append("\n <script language=\"javascript\" type=\"text/javascript\"><!-- \n");
373 html.append(" function ").append(submitnameproperty).append("(newValue,message) { \n");
374 html.append(" document.").append(name).append(".").append(property).append(".value=newValue;\n");
375
376 // If this form contains an htmlJSInput tag, we also need to call its JavaScript method
377 if (htmlJSInput.equals("true")) {
378 html.append("getHTMLEditorAppletValue()\n");
379 }
380
381 html.append(" if ( message==\"\" ) { document.").append(name).append(".submit(); }\n");
382 html.append(" else if ( confirm(message) ) { document.").append(name).append(".submit(); }\n");
383 html.append(" }\n");
384 html.append("//--></script>\n");
385
386
387
388 // Add the attribute we're changing, with a dummy value
389 html.append("<input type=\"hidden\" name=\"").append(property).append("\" value=\"dummy\">\n");
390
391 }
392
393 // add the button code.
394 html.append("<input type=\"image\" src=\"").append(getImageUrl()).append("\" onclick=\"").append(submitnameproperty).append("('").append(value).append("','").append(confirm).append("');\"").append(prepareStyles()).append(prepareEventHandlers()).append(prepareAlt()).append(prepareBorder()).append(" >");
395
396 // write the code.
397 try {
398 pageContext.getOut().print( html.toString() );
399 } catch (IOException e) {
400 throw new JspTagException("I/O Exception " + e.getMessage() );
401 }
402
403 // and add the page context flag indicating that the javascript for this property is available
404 pageContext.setAttribute(submitnameproperty, "true");
405
406 return SKIP_BODY;
407 }
408
409
410 public void release() {
411 super.release();
412 src = "";
413 page = "";
414 }
415 }
416
417
418
419
420
421
422
423
424