KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > struts > taglib > html > FormTag


1 /*
2  * $Id: FormTag.java 164530 2005-04-25 03:11:07Z niallp $
3  *
4  * Copyright 1999-2005 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19 package org.apache.struts.taglib.html;
20
21 import java.io.IOException JavaDoc;
22
23 import javax.servlet.http.HttpServletRequest JavaDoc;
24 import javax.servlet.http.HttpServletResponse JavaDoc;
25 import javax.servlet.http.HttpSession JavaDoc;
26 import javax.servlet.jsp.JspException JavaDoc;
27 import javax.servlet.jsp.JspWriter JavaDoc;
28 import javax.servlet.jsp.PageContext JavaDoc;
29 import javax.servlet.jsp.tagext.TagSupport JavaDoc;
30
31 import org.apache.struts.Globals;
32 import org.apache.struts.action.ActionForm;
33 import org.apache.struts.action.ActionMapping;
34 import org.apache.struts.action.ActionServlet;
35 import org.apache.struts.config.FormBeanConfig;
36 import org.apache.struts.config.ModuleConfig;
37 import org.apache.struts.taglib.TagUtils;
38 import org.apache.struts.util.MessageResources;
39 import org.apache.struts.util.RequestUtils;
40
41 /**
42  * Custom tag that represents an input form, associated with a bean whose
43  * properties correspond to the various fields of the form.
44  *
45  * @version $Rev: 164530 $ $Date: 2005-04-25 04:11:07 +0100 (Mon, 25 Apr 2005) $
46  */

47 public class FormTag extends TagSupport JavaDoc {
48
49     // ----------------------------------------------------- Instance Variables
50

51     /**
52      * The action URL to which this form should be submitted, if any.
53      */

54     protected String JavaDoc action = null;
55
56     /**
57      * The module configuration for our module.
58      */

59     protected ModuleConfig moduleConfig = null;
60
61     /**
62      * The content encoding to be used on a POST submit.
63      */

64     protected String JavaDoc enctype = null;
65
66     /**
67      * The name of the field to receive focus, if any.
68      */

69     protected String JavaDoc focus = null;
70
71     /**
72      * The index in the focus field array to receive focus. This only applies if the field
73      * given in the focus attribute is actually an array of fields. This allows a specific
74      * field in a radio button array to receive focus while still allowing indexed field
75      * names like "myRadioButtonField[1]" to be passed in the focus attribute.
76      * @since Struts 1.1
77      */

78     protected String JavaDoc focusIndex = null;
79
80     /**
81      * The line ending string.
82      */

83     protected static String JavaDoc lineEnd = System.getProperty("line.separator");
84
85     /**
86      * The ActionMapping defining where we will be submitting this form
87      */

88     protected ActionMapping mapping = null;
89
90     /**
91      * The message resources for this package.
92      */

93     protected static MessageResources messages =
94         MessageResources.getMessageResources(Constants.Package + ".LocalStrings");
95
96     /**
97      * The request method used when submitting this form.
98      */

99     protected String JavaDoc method = null;
100
101     /**
102      * The onReset event script.
103      */

104     protected String JavaDoc onreset = null;
105
106     /**
107      * The onSubmit event script.
108      */

109     protected String JavaDoc onsubmit = null;
110
111     /**
112      * Include language attribute in the focus script's <script> element. This
113      * property is ignored in XHTML mode.
114      * @since Struts 1.2
115      */

116     protected boolean scriptLanguage = true;
117
118     /**
119      * The ActionServlet instance we are associated with (so that we can
120      * initialize the <code>servlet</code> property on any form bean that
121      * we create).
122      */

123     protected ActionServlet servlet = null;
124
125     /**
126      * The style attribute associated with this tag.
127      */

128     protected String JavaDoc style = null;
129
130     /**
131      * The style class associated with this tag.
132      */

133     protected String JavaDoc styleClass = null;
134
135     /**
136      * The identifier associated with this tag.
137      */

138     protected String JavaDoc styleId = null;
139
140     /**
141      * The window target.
142      */

143     protected String JavaDoc target = null;
144
145     /**
146      * The name of the form bean to (create and) use. This is either the same
147      * as the 'name' attribute, if that was specified, or is obtained from the
148      * associated <code>ActionMapping</code> otherwise.
149      */

150     protected String JavaDoc beanName = null;
151
152     /**
153      * The scope of the form bean to (create and) use. This is either the same
154      * as the 'scope' attribute, if that was specified, or is obtained from the
155      * associated <code>ActionMapping</code> otherwise.
156      */

157     protected String JavaDoc beanScope = null;
158
159     /**
160      * The type of the form bean to (create and) use. This is either the same
161      * as the 'type' attribute, if that was specified, or is obtained from the
162      * associated <code>ActionMapping</code> otherwise.
163      */

164     protected String JavaDoc beanType = null;
165
166     /**
167      * The list of character encodings for input data that the server should
168      * accept.
169      */

170     protected String JavaDoc acceptCharset = null;
171
172     /** Controls whether child controls should be 'disabled'. */
173     private boolean disabled = false;
174
175     /** Controls whether child controls should be 'readonly'. */
176     protected boolean readonly = false;
177
178     // ------------------------------------------------------------- Properties
179

180     /**
181      * Return the name of the form bean corresponding to this tag. There is
182      * no corresponding setter method; this method exists so that the nested
183      * tag classes can obtain the actual bean name derived from other
184      * attributes of the tag.
185      */

186     public String JavaDoc getBeanName() {
187
188         return beanName;
189
190     }
191
192     /**
193      * Return the action URL to which this form should be submitted.
194      */

195     public String JavaDoc getAction() {
196
197         return (this.action);
198
199     }
200
201     /**
202      * Set the action URL to which this form should be submitted.
203      *
204      * @param action The new action URL
205      */

206     public void setAction(String JavaDoc action) {
207
208         this.action = action;
209
210     }
211
212     /**
213      * Return the content encoding used when submitting this form.
214      */

215     public String JavaDoc getEnctype() {
216
217         return (this.enctype);
218
219     }
220
221     /**
222      * Set the content encoding used when submitting this form.
223      *
224      * @param enctype The new content encoding
225      */

226     public void setEnctype(String JavaDoc enctype) {
227
228         this.enctype = enctype;
229
230     }
231
232     /**
233      * Return the focus field name for this form.
234      */

235     public String JavaDoc getFocus() {
236
237         return (this.focus);
238
239     }
240
241     /**
242      * Set the focus field name for this form.
243      *
244      * @param focus The new focus field name
245      */

246     public void setFocus(String JavaDoc focus) {
247
248         this.focus = focus;
249
250     }
251
252     /**
253      * Return the request method used when submitting this form.
254      */

255     public String JavaDoc getMethod() {
256
257         return (this.method);
258
259     }
260
261     /**
262      * Set the request method used when submitting this form.
263      *
264      * @param method The new request method
265      */

266     public void setMethod(String JavaDoc method) {
267
268         this.method = method;
269
270     }
271
272     /**
273      * Return the onReset event script.
274      */

275     public String JavaDoc getOnreset() {
276
277         return (this.onreset);
278
279     }
280
281     /**
282      * Set the onReset event script.
283      *
284      * @param onReset The new event script
285      */

286     public void setOnreset(String JavaDoc onReset) {
287
288         this.onreset = onReset;
289
290     }
291
292     /**
293      * Return the onSubmit event script.
294      */

295     public String JavaDoc getOnsubmit() {
296
297         return (this.onsubmit);
298
299     }
300
301     /**
302      * Set the onSubmit event script.
303      *
304      * @param onSubmit The new event script
305      */

306     public void setOnsubmit(String JavaDoc onSubmit) {
307
308         this.onsubmit = onSubmit;
309
310     }
311
312     /**
313      * Return the style attribute for this tag.
314      */

315     public String JavaDoc getStyle() {
316
317         return (this.style);
318
319     }
320
321     /**
322      * Set the style attribute for this tag.
323      *
324      * @param style The new style attribute
325      */

326     public void setStyle(String JavaDoc style) {
327
328         this.style = style;
329
330     }
331
332     /**
333      * Return the style class for this tag.
334      */

335     public String JavaDoc getStyleClass() {
336
337         return (this.styleClass);
338
339     }
340
341     /**
342      * Set the style class for this tag.
343      *
344      * @param styleClass The new style class
345      */

346     public void setStyleClass(String JavaDoc styleClass) {
347
348         this.styleClass = styleClass;
349
350     }
351
352     /**
353      * Return the style identifier for this tag.
354      */

355     public String JavaDoc getStyleId() {
356
357         return (this.styleId);
358
359     }
360
361     /**
362      * Set the style identifier for this tag.
363      *
364      * @param styleId The new style identifier
365      */

366     public void setStyleId(String JavaDoc styleId) {
367
368         this.styleId = styleId;
369
370     }
371
372     /**
373      * Return the window target.
374      */

375     public String JavaDoc getTarget() {
376
377         return (this.target);
378
379     }
380
381     /**
382      * Set the window target.
383      *
384      * @param target The new window target
385      */

386     public void setTarget(String JavaDoc target) {
387
388         this.target = target;
389
390     }
391
392     /**
393      * Return the list of character encodings accepted.
394      */

395     public String JavaDoc getAcceptCharset() {
396
397         return acceptCharset;
398
399     }
400
401     /**
402      * Set the list of character encodings accepted.
403      *
404      * @param acceptCharset The list of character encodings
405      */

406     public void setAcceptCharset(String JavaDoc acceptCharset) {
407
408         this.acceptCharset= acceptCharset;
409
410     }
411
412     /** Sets the disabled event handler. */
413     public void setDisabled(boolean disabled) {
414         this.disabled = disabled;
415     }
416
417     /** Returns the disabled event handler. */
418     public boolean isDisabled() {
419         return disabled;
420     }
421
422     /** Sets the readonly event handler. */
423     public void setReadonly(boolean readonly) {
424         this.readonly = readonly;
425     }
426
427     /** Returns the readonly event handler. */
428     public boolean isReadonly() {
429         return readonly;
430     }
431
432
433     // --------------------------------------------------------- Public Methods
434

435     /**
436      * Render the beginning of this form.
437      *
438      * @exception JspException if a JSP exception has occurred
439      */

440     public int doStartTag() throws JspException JavaDoc {
441
442         // Look up the form bean name, scope, and type if necessary
443
this.lookup();
444
445         // Create an appropriate "form" element based on our parameters
446
StringBuffer JavaDoc results = new StringBuffer JavaDoc();
447         
448         results.append(this.renderFormStartElement());
449
450         results.append(this.renderToken());
451
452         TagUtils.getInstance().write(pageContext, results.toString());
453
454         // Store this tag itself as a page attribute
455
pageContext.setAttribute(Constants.FORM_KEY, this, PageContext.REQUEST_SCOPE);
456
457         this.initFormBean();
458
459         return (EVAL_BODY_INCLUDE);
460
461     }
462
463     /**
464      * Locate or create the bean associated with our form.
465      * @throws JspException
466      * @since Struts 1.1
467      */

468     protected void initFormBean() throws JspException JavaDoc {
469         int scope = PageContext.SESSION_SCOPE;
470         if ("request".equalsIgnoreCase(beanScope)) {
471             scope = PageContext.REQUEST_SCOPE;
472         }
473         
474         Object JavaDoc bean = pageContext.getAttribute(beanName, scope);
475         if (bean == null) {
476             // New and improved - use the values from the action mapping
477
bean =
478                 RequestUtils.createActionForm(
479                     (HttpServletRequest JavaDoc) pageContext.getRequest(),
480                     mapping,
481                     moduleConfig,
482                     servlet);
483             if (bean instanceof ActionForm) {
484                 ((ActionForm) bean).reset(mapping, (HttpServletRequest JavaDoc) pageContext.getRequest());
485             }
486             if (bean == null) {
487                 throw new JspException JavaDoc(messages.getMessage("formTag.create", beanType));
488             }
489             pageContext.setAttribute(beanName, bean, scope);
490         }
491         pageContext.setAttribute(Constants.BEAN_KEY, bean, PageContext.REQUEST_SCOPE);
492     }
493
494     /**
495      * Generates the opening <code>&lt;form&gt;</code> element with appropriate
496      * attributes.
497      * @since Struts 1.1
498      */

499     protected String JavaDoc renderFormStartElement() {
500             
501         StringBuffer JavaDoc results = new StringBuffer JavaDoc("<form");
502
503         // render attributes
504
if (!this.isXhtml()) {
505             renderName(results);
506         }
507         renderAttribute(results, "method", getMethod() == null ? "post" : getMethod());
508         renderAction(results);
509         renderAttribute(results, "accept-charset", getAcceptCharset());
510         renderAttribute(results, "class", getStyleClass());
511         renderAttribute(results, "enctype", getEnctype());
512         renderAttribute(results, "onreset", getOnreset());
513         renderAttribute(results, "onsubmit", getOnsubmit());
514         renderAttribute(results, "style", getStyle());
515         renderAttribute(results, "id", getStyleId());
516         renderAttribute(results, "target", getTarget());
517
518         // Hook for additional attributes
519
renderOtherAttributes(results);
520
521         results.append(">");
522         return results.toString();
523     }
524
525     /**
526      * Renders the name attribute
527      */

528     protected void renderName(StringBuffer JavaDoc results) {
529         results.append(" name=\"");
530         results.append(beanName);
531         results.append("\"");
532     }
533
534     /**
535      * Renders the action attribute
536      */

537     protected void renderAction(StringBuffer JavaDoc results) {
538
539         HttpServletResponse JavaDoc response =
540             (HttpServletResponse JavaDoc) this.pageContext.getResponse();
541
542         results.append(" action=\"");
543         results.append(
544             response.encodeURL(
545                 TagUtils.getInstance().getActionMappingURL(
546                     this.action,
547                     this.pageContext)));
548                 
549         results.append("\"");
550     }
551
552     /**
553      * 'Hook' to enable this tag to be extended and
554      * additional attributes added.
555      */

556     protected void renderOtherAttributes(StringBuffer JavaDoc results) {
557     }
558
559     /**
560      * Generates a hidden input field with token information, if any. The
561      * field is added within a div element for HTML 4.01 Strict compliance.
562      * @return A hidden input field containing the token.
563      * @since Struts 1.1
564      */

565     protected String JavaDoc renderToken() {
566         StringBuffer JavaDoc results = new StringBuffer JavaDoc();
567         HttpSession JavaDoc session = pageContext.getSession();
568
569         if (session != null) {
570             String JavaDoc token =
571                 (String JavaDoc) session.getAttribute(Globals.TRANSACTION_TOKEN_KEY);
572                 
573             if (token != null) {
574                 results.append("<div><input type=\"hidden\" name=\"");
575                 results.append(Constants.TOKEN_KEY);
576                 results.append("\" value=\"");
577                 results.append(token);
578                 if (this.isXhtml()) {
579                     results.append("\" />");
580                 } else {
581                     results.append("\">");
582                 }
583                 results.append("</div>");
584             }
585         }
586
587         return results.toString();
588     }
589
590     /**
591      * Renders attribute="value" if not null
592      */

593     protected void renderAttribute(StringBuffer JavaDoc results, String JavaDoc attribute, String JavaDoc value) {
594         if (value != null) {
595             results.append(" ");
596             results.append(attribute);
597             results.append("=\"");
598             results.append(value);
599             results.append("\"");
600         }
601     }
602
603     /**
604      * Render the end of this form.
605      *
606      * @exception JspException if a JSP exception has occurred
607      */

608     public int doEndTag() throws JspException JavaDoc {
609
610         // Remove the page scope attributes we created
611
pageContext.removeAttribute(Constants.BEAN_KEY, PageContext.REQUEST_SCOPE);
612         pageContext.removeAttribute(Constants.FORM_KEY, PageContext.REQUEST_SCOPE);
613
614         // Render a tag representing the end of our current form
615
StringBuffer JavaDoc results = new StringBuffer JavaDoc("</form>");
616
617         // Render JavaScript to set the input focus if required
618
if (this.focus != null) {
619             results.append(this.renderFocusJavascript());
620         }
621
622         // Print this value to our output writer
623
JspWriter JavaDoc writer = pageContext.getOut();
624         try {
625             writer.print(results.toString());
626         } catch (IOException JavaDoc e) {
627             throw new JspException JavaDoc(messages.getMessage("common.io", e.toString()));
628         }
629
630         // Continue processing this page
631
return (EVAL_PAGE);
632
633     }
634
635     /**
636      * Generates javascript to set the initial focus to the form element given in the
637      * tag's "focus" attribute.
638      * @since Struts 1.1
639      */

640     protected String JavaDoc renderFocusJavascript() {
641         StringBuffer JavaDoc results = new StringBuffer JavaDoc();
642
643         results.append(lineEnd);
644         results.append("<script type=\"text/javascript\"");
645         if (!this.isXhtml() && this.scriptLanguage) {
646             results.append(" language=\"JavaScript\"");
647         }
648         results.append(">");
649         results.append(lineEnd);
650
651         // xhtml script content shouldn't use the browser hiding trick
652
if (!this.isXhtml()) {
653             results.append(" <!--");
654             results.append(lineEnd);
655         }
656
657         // Construct the control name that will receive focus.
658
// This does not include any index.
659
StringBuffer JavaDoc focusControl = new StringBuffer JavaDoc("document.forms[\"");
660         focusControl.append(beanName);
661         focusControl.append("\"].elements[\"");
662         focusControl.append(this.focus);
663         focusControl.append("\"]");
664
665         results.append(" var focusControl = ");
666         results.append(focusControl.toString());
667         results.append(";");
668         results.append(lineEnd);
669         results.append(lineEnd);
670
671         results.append(" if (focusControl.type != \"hidden\" && !focusControl.disabled) {");
672         results.append(lineEnd);
673
674         // Construct the index if needed and insert into focus statement
675
String JavaDoc index = "";
676         if (this.focusIndex != null) {
677             StringBuffer JavaDoc sb = new StringBuffer JavaDoc("[");
678             sb.append(this.focusIndex);
679             sb.append("]");
680             index = sb.toString();
681         }
682         results.append(" focusControl");
683         results.append(index);
684         results.append(".focus();");
685         results.append(lineEnd);
686
687         results.append(" }");
688         results.append(lineEnd);
689
690         if (!this.isXhtml()) {
691             results.append(" // -->");
692             results.append(lineEnd);
693         }
694
695         results.append("</script>");
696         results.append(lineEnd);
697         return results.toString();
698     }
699
700     /**
701      * Release any acquired resources.
702      */

703     public void release() {
704
705         super.release();
706         action = null;
707         moduleConfig = null;
708         enctype = null;
709         disabled = false;
710         focus = null;
711         focusIndex = null;
712         mapping = null;
713         method = null;
714         onreset = null;
715         onsubmit = null;
716         readonly = false;
717         servlet = null;
718         style = null;
719         styleClass = null;
720         styleId = null;
721         target = null;
722         acceptCharset = null;
723
724     }
725
726     // ------------------------------------------------------ Protected Methods
727

728
729     /**
730      * Look up values for the <code>name</code>, <code>scope</code>, and
731      * <code>type</code> properties if necessary.
732      *
733      * @exception JspException if a required value cannot be looked up
734      */

735     protected void lookup() throws JspException JavaDoc {
736
737         // Look up the module configuration information we need
738
moduleConfig = TagUtils.getInstance().getModuleConfig(pageContext);
739
740         if (moduleConfig == null) {
741             JspException JavaDoc e = new JspException JavaDoc(messages.getMessage("formTag.collections"));
742             pageContext.setAttribute(Globals.EXCEPTION_KEY, e, PageContext.REQUEST_SCOPE);
743             throw e;
744         }
745         servlet =
746             (ActionServlet) pageContext.getServletContext().getAttribute(
747                 Globals.ACTION_SERVLET_KEY);
748
749         // Look up the action mapping we will be submitting to
750
String JavaDoc mappingName = TagUtils.getInstance().getActionMappingName(action);
751         mapping = (ActionMapping) moduleConfig.findActionConfig(mappingName);
752         if (mapping == null) {
753             JspException JavaDoc e = new JspException JavaDoc(messages.getMessage("formTag.mapping", mappingName));
754             pageContext.setAttribute(Globals.EXCEPTION_KEY, e, PageContext.REQUEST_SCOPE);
755             throw e;
756         }
757
758         // Look up the form bean definition
759
FormBeanConfig formBeanConfig = moduleConfig.findFormBeanConfig(mapping.getName());
760         if (formBeanConfig == null) {
761             JspException JavaDoc e =
762                 new JspException JavaDoc(messages.getMessage("formTag.formBean", mapping.getName(), action));
763             pageContext.setAttribute(Globals.EXCEPTION_KEY, e, PageContext.REQUEST_SCOPE);
764             throw e;
765         }
766
767         // Calculate the required values
768
beanName = mapping.getAttribute();
769         beanScope = mapping.getScope();
770         beanType = formBeanConfig.getType();
771     }
772
773     /**
774      * Returns true if this tag should render as xhtml.
775      */

776     private boolean isXhtml() {
777         return TagUtils.getInstance().isXhtml(this.pageContext);
778     }
779
780     /**
781      * Returns the focusIndex.
782      * @return String
783      */

784     public String JavaDoc getFocusIndex() {
785         return focusIndex;
786     }
787
788     /**
789      * Sets the focusIndex.
790      * @param focusIndex The focusIndex to set
791      */

792     public void setFocusIndex(String JavaDoc focusIndex) {
793         this.focusIndex = focusIndex;
794     }
795
796     /**
797      * Gets whether or not the focus script's &lt;script&gt; element will include the
798      * language attribute.
799      * @return true if language attribute will be included.
800      * @since Struts 1.2
801      */

802     public boolean getScriptLanguage() {
803         return this.scriptLanguage;
804     }
805
806     /**
807      * Sets whether or not the focus script's &lt;script&gt; element will include the
808      * language attribute.
809      * @since Struts 1.2
810      */

811     public void setScriptLanguage(boolean scriptLanguage) {
812         this.scriptLanguage = scriptLanguage;
813     }
814
815 }
816
Popular Tags