Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/struts/taglib/html/FormTag.java


1   /*
2    * $Id: FormTag.java 54929 2004-10-16 16:38:42Z germuska $ 
3    *
4    * Copyright 1999-2004 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;
22  
23  import javax.servlet.http.HttpServletRequest;
24  import javax.servlet.http.HttpServletResponse;
25  import javax.servlet.http.HttpSession;
26  import javax.servlet.jsp.JspException;
27  import javax.servlet.jsp.JspWriter;
28  import javax.servlet.jsp.PageContext;
29  import javax.servlet.jsp.tagext.TagSupport;
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: 54929 $ $Date: 2004-10-16 09:38:42 -0700 (Sat, 16 Oct 2004) $
46   */
47  public class FormTag extends TagSupport {
48  
49      // ----------------------------------------------------- Instance Variables
50  
51      /**
52       * The action URL to which this form should be submitted, if any.
53       */
54      protected String 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 enctype = null;
65  
66      /**
67       * The name of the field to receive focus, if any.
68       */
69      protected String 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 focusIndex = null;
79  
80      /**
81       * The line ending string.
82       */
83      protected static String 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 method = null;
100 
101     /**
102      * The onReset event script.
103      */
104     protected String onreset = null;
105 
106     /**
107      * The onSubmit event script.
108      */
109     protected String 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 style = null;
129 
130     /**
131      * The style class associated with this tag.
132      */
133     protected String styleClass = null;
134 
135     /**
136      * The identifier associated with this tag.
137      */
138     protected String styleId = null;
139 
140     /**
141      * The window target.
142      */
143     protected String 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 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 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 beanType = null;
165 
166     /**
167      * The list of character encodings for input data that the server should
168      * accept.
169      */
170     protected String acceptCharset = null;
171 
172     // ------------------------------------------------------------- Properties
173 
174     /**
175      * Return the name of the form bean corresponding to this tag. There is
176      * no corresponding setter method; this method exists so that the nested
177      * tag classes can obtain the actual bean name derived from other
178      * attributes of the tag.
179      */
180     public String getBeanName() {
181 
182         return beanName;
183 
184     }
185 
186     /**
187      * Return the action URL to which this form should be submitted.
188      */
189     public String getAction() {
190 
191         return (this.action);
192 
193     }
194 
195     /**
196      * Set the action URL to which this form should be submitted.
197      *
198      * @param action The new action URL
199      */
200     public void setAction(String action) {
201 
202         this.action = action;
203 
204     }
205 
206     /**
207      * Return the content encoding used when submitting this form.
208      */
209     public String getEnctype() {
210 
211         return (this.enctype);
212 
213     }
214 
215     /**
216      * Set the content encoding used when submitting this form.
217      *
218      * @param enctype The new content encoding
219      */
220     public void setEnctype(String enctype) {
221 
222         this.enctype = enctype;
223 
224     }
225 
226     /**
227      * Return the focus field name for this form.
228      */
229     public String getFocus() {
230 
231         return (this.focus);
232 
233     }
234 
235     /**
236      * Set the focus field name for this form.
237      *
238      * @param focus The new focus field name
239      */
240     public void setFocus(String focus) {
241 
242         this.focus = focus;
243 
244     }
245 
246     /**
247      * Return the request method used when submitting this form.
248      */
249     public String getMethod() {
250 
251         return (this.method);
252 
253     }
254 
255     /**
256      * Set the request method used when submitting this form.
257      *
258      * @param method The new request method
259      */
260     public void setMethod(String method) {
261 
262         this.method = method;
263 
264     }
265 
266     /**
267      * Return the onReset event script.
268      */
269     public String getOnreset() {
270 
271         return (this.onreset);
272 
273     }
274 
275     /**
276      * Set the onReset event script.
277      *
278      * @param onReset The new event script
279      */
280     public void setOnreset(String onReset) {
281 
282         this.onreset = onReset;
283 
284     }
285 
286     /**
287      * Return the onSubmit event script.
288      */
289     public String getOnsubmit() {
290 
291         return (this.onsubmit);
292 
293     }
294 
295     /**
296      * Set the onSubmit event script.
297      *
298      * @param onSubmit The new event script
299      */
300     public void setOnsubmit(String onSubmit) {
301 
302         this.onsubmit = onSubmit;
303 
304     }
305 
306     /**
307      * Return the style attribute for this tag.
308      */
309     public String getStyle() {
310 
311         return (this.style);
312 
313     }
314 
315     /**
316      * Set the style attribute for this tag.
317      *
318      * @param style The new style attribute
319      */
320     public void setStyle(String style) {
321 
322         this.style = style;
323 
324     }
325 
326     /**
327      * Return the style class for this tag.
328      */
329     public String getStyleClass() {
330 
331         return (this.styleClass);
332 
333     }
334 
335     /**
336      * Set the style class for this tag.
337      *
338      * @param styleClass The new style class
339      */
340     public void setStyleClass(String styleClass) {
341 
342         this.styleClass = styleClass;
343 
344     }
345 
346     /**
347      * Return the style identifier for this tag.
348      */
349     public String getStyleId() {
350 
351         return (this.styleId);
352 
353     }
354 
355     /**
356      * Set the style identifier for this tag.
357      *
358      * @param styleId The new style identifier
359      */
360     public void setStyleId(String styleId) {
361 
362         this.styleId = styleId;
363 
364     }
365 
366     /**
367      * Return the window target.
368      */
369     public String getTarget() {
370 
371         return (this.target);
372 
373     }
374 
375     /**
376      * Set the window target.
377      *
378      * @param target The new window target
379      */
380     public void setTarget(String target) {
381 
382         this.target = target;
383 
384     }
385 
386     /**
387      * Return the list of character encodings accepted.
388      */
389     public String getAcceptCharset() {
390 
391         return acceptCharset;
392 
393     }
394 
395     /**
396      * Set the list of character encodings accepted.
397      *
398      * @param acceptCharset The list of character encodings
399      */
400     public void setAcceptCharset(String acceptCharset) {
401 
402         this.acceptCharset= acceptCharset;
403 
404     }
405 
406 
407     // --------------------------------------------------------- Public Methods
408 
409     /**
410      * Render the beginning of this form.
411      *
412      * @exception JspException if a JSP exception has occurred
413      */
414     public int doStartTag() throws JspException {
415 
416         // Look up the form bean name, scope, and type if necessary
417         this.lookup();
418 
419         // Create an appropriate "form" element based on our parameters
420         StringBuffer results = new StringBuffer();
421         
422         results.append(this.renderFormStartElement());
423 
424         results.append(this.renderToken());
425 
426         TagUtils.getInstance().write(pageContext, results.toString());
427 
428         // Store this tag itself as a page attribute
429         pageContext.setAttribute(Constants.FORM_KEY, this, PageContext.REQUEST_SCOPE);
430 
431         this.initFormBean();
432 
433         return (EVAL_BODY_INCLUDE);
434 
435     }
436 
437     /**
438      * Locate or create the bean associated with our form.
439      * @throws JspException
440      * @since Struts 1.1
441      */
442     protected void initFormBean() throws JspException {
443         int scope = PageContext.SESSION_SCOPE;
444         if ("request".equalsIgnoreCase(beanScope)) {
445             scope = PageContext.REQUEST_SCOPE;
446         }
447         
448         Object bean = pageContext.getAttribute(beanName, scope);
449         if (bean == null) {
450             // New and improved - use the values from the action mapping
451             bean =
452                 RequestUtils.createActionForm(
453                     (HttpServletRequest) pageContext.getRequest(),
454                     mapping,
455                     moduleConfig,
456                     servlet);
457             if (bean instanceof ActionForm) {
458                 ((ActionForm) bean).reset(mapping, (HttpServletRequest) pageContext.getRequest());
459             }
460             if (bean == null) {
461                 throw new JspException(messages.getMessage("formTag.create", beanType));
462             }
463             pageContext.setAttribute(beanName, bean, scope);
464         }
465         pageContext.setAttribute(Constants.BEAN_KEY, bean, PageContext.REQUEST_SCOPE);
466     }
467 
468     /**
469      * Generates the opening <code>&lt;form&gt;</code> element with appropriate
470      * attributes.
471      * @since Struts 1.1
472      */
473     protected String renderFormStartElement() {
474             
475         StringBuffer results = new StringBuffer("<form");
476 
477         // render attributes
478         renderName(results);
479         renderAttribute(results, "method", getMethod() == null ? "post" : getMethod());
480         renderAction(results);
481         renderAttribute(results, "accept-charset", getAcceptCharset());
482         renderAttribute(results, "class", getStyleClass());
483         renderAttribute(results, "enctype", getEnctype());
484         renderAttribute(results, "onreset", getOnreset());
485         renderAttribute(results, "onsubmit", getOnsubmit());
486         renderAttribute(results, "style", getStyle());
487         renderAttribute(results, "id", getStyleId());
488         renderAttribute(results, "target", getTarget());
489 
490         // Hook for additional attributes
491         renderOtherAttributes(results);
492 
493         results.append(">");
494         return results.toString();
495     }
496 
497     /**
498      * Renders the name attribute
499      */
500     protected void renderName(StringBuffer results) {
501         results.append(" name=\"");
502         results.append(beanName);
503         results.append("\"");
504     }
505 
506     /**
507      * Renders the action attribute
508      */
509     protected void renderAction(StringBuffer results) {
510 
511         HttpServletResponse response =
512             (HttpServletResponse) this.pageContext.getResponse();
513 
514         results.append(" action=\"");
515         results.append(
516             response.encodeURL(
517                 TagUtils.getInstance().getActionMappingURL(
518                     this.action,
519                     this.pageContext)));
520                 
521         results.append("\"");
522     }
523 
524     /**
525      * 'Hook' to enable this tag to be extended and 
526      *  additional attributes added.
527      */
528     protected void renderOtherAttributes(StringBuffer results) {
529     }
530 
531     /**
532      * Generates a hidden input field with token information, if any.
533      * @return A hidden input field containing the token.
534      * @since Struts 1.1
535      */
536     protected String renderToken() {
537         StringBuffer results = new StringBuffer();
538         HttpSession session = pageContext.getSession();
539 
540         if (session != null) {
541             String token =
542                 (String) session.getAttribute(Globals.TRANSACTION_TOKEN_KEY);
543                 
544             if (token != null) {
545                 results.append("<input type=\"hidden\" name=\"");
546                 results.append(Constants.TOKEN_KEY);
547                 results.append("\" value=\"");
548                 results.append(token);
549                 if (this.isXhtml()) {
550                     results.append("\" />");
551                 } else {
552                     results.append("\">");
553                 }
554             }
555         }
556 
557         return results.toString();
558     }
559 
560     /**
561      * Renders attribute="value" if not null
562      */
563     protected void renderAttribute(StringBuffer results, String attribute, String value) {
564         if (value != null) {
565             results.append(" ");
566             results.append(attribute);
567             results.append("=\"");
568             results.append(value);
569             results.append("\"");
570         }
571     }
572 
573     /**
574      * Render the end of this form.
575      *
576      * @exception JspException if a JSP exception has occurred
577      */
578     public int doEndTag() throws JspException {
579 
580         // Remove the page scope attributes we created
581         pageContext.removeAttribute(Constants.BEAN_KEY, PageContext.REQUEST_SCOPE);
582         pageContext.removeAttribute(Constants.FORM_KEY, PageContext.REQUEST_SCOPE);
583 
584         // Render a tag representing the end of our current form
585         StringBuffer results = new StringBuffer("</form>");
586 
587         // Render JavaScript to set the input focus if required
588         if (this.focus != null) {
589             results.append(this.renderFocusJavascript());
590         }
591 
592         // Print this value to our output writer
593         JspWriter writer = pageContext.getOut();
594         try {
595             writer.print(results.toString());
596         } catch (IOException e) {
597             throw new JspException(messages.getMessage("common.io", e.toString()));
598         }
599 
600         // Continue processing this page
601         return (EVAL_PAGE);
602 
603     }
604 
605     /**
606      * Generates javascript to set the initial focus to the form element given in the
607      * tag's "focus" attribute.
608      * @since Struts 1.1
609      */
610     protected String renderFocusJavascript() {
611         StringBuffer results = new StringBuffer();
612 
613         results.append(lineEnd);
614         results.append("<script type=\"text/javascript\"");
615         if (!this.isXhtml() && this.scriptLanguage) {
616             results.append(" language=\"JavaScript\"");
617         }
618         results.append(">");
619         results.append(lineEnd);
620 
621         // xhtml script content shouldn't use the browser hiding trick
622         if (!this.isXhtml()) {
623             results.append("  <!--");
624             results.append(lineEnd);
625         }
626 
627         // Construct the control name that will receive focus.
628         // This does not include any index.
629         StringBuffer focusControl = new StringBuffer("document.forms[\"");
630         focusControl.append(beanName);
631         focusControl.append("\"].elements[\"");
632         focusControl.append(this.focus);
633         focusControl.append("\"]");
634 
635         results.append("  var focusControl = ");
636         results.append(focusControl.toString());
637         results.append(";");
638         results.append(lineEnd);
639         results.append(lineEnd);
640 
641         results.append("  if (focusControl.type != \"hidden\" && !focusControl.disabled) {");
642         results.append(lineEnd);
643 
644         // Construct the index if needed and insert into focus statement
645         String index = "";
646         if (this.focusIndex != null) {
647             StringBuffer sb = new StringBuffer("[");
648             sb.append(this.focusIndex);
649             sb.append("]");
650             index = sb.toString();
651         }
652         results.append("     focusControl");
653         results.append(index);
654         results.append(".focus();");
655         results.append(lineEnd);
656 
657         results.append("  }");
658         results.append(lineEnd);
659 
660         if (!this.isXhtml()) {
661             results.append("  // -->");
662             results.append(lineEnd);
663         }
664 
665         results.append("</script>");
666         results.append(lineEnd);
667         return results.toString();
668     }
669 
670     /**
671      * Release any acquired resources.
672      */
673     public void release() {
674 
675         super.release();
676         action = null;
677         moduleConfig = null;
678         enctype = null;
679         focus = null;
680         focusIndex = null;
681         mapping = null;
682         method = null;
683         onreset = null;
684         onsubmit = null;
685         servlet = null;
686         style = null;
687         styleClass = null;
688         styleId = null;
689         target = null;
690         acceptCharset = null;
691 
692     }
693 
694     // ------------------------------------------------------ Protected Methods
695 
696 
697     /**
698      * Look up values for the <code>name</code>, <code>scope</code>, and
699      * <code>type</code> properties if necessary.
700      *
701      * @exception JspException if a required value cannot be looked up
702      */
703     protected void lookup() throws JspException {
704 
705         // Look up the module configuration information we need
706         moduleConfig = TagUtils.getInstance().getModuleConfig(pageContext);
707 
708         if (moduleConfig == null) {
709             JspException e = new JspException(messages.getMessage("formTag.collections"));
710             pageContext.setAttribute(Globals.EXCEPTION_KEY, e, PageContext.REQUEST_SCOPE);
711             throw e;
712         }
713         servlet =
714             (ActionServlet) pageContext.getServletContext().getAttribute(
715                 Globals.ACTION_SERVLET_KEY);
716 
717         // Look up the action mapping we will be submitting to
718         String mappingName = TagUtils.getInstance().getActionMappingName(action);
719         mapping = (ActionMapping) moduleConfig.findActionConfig(mappingName);
720         if (mapping == null) {
721             JspException e = new JspException(messages.getMessage("formTag.mapping", mappingName));
722             pageContext.setAttribute(Globals.EXCEPTION_KEY, e, PageContext.REQUEST_SCOPE);
723             throw e;
724         }
725 
726         // Look up the form bean definition
727         FormBeanConfig formBeanConfig = moduleConfig.findFormBeanConfig(mapping.getName());
728         if (formBeanConfig == null) {
729             JspException e =
730                 new JspException(messages.getMessage("formTag.formBean", mapping.getName(), action));
731             pageContext.setAttribute(Globals.EXCEPTION_KEY, e, PageContext.REQUEST_SCOPE);
732             throw e;
733         }
734 
735         // Calculate the required values
736         beanName = mapping.getAttribute();
737         beanScope = mapping.getScope();
738         beanType = formBeanConfig.getType();
739     }
740 
741     /**
742      * Returns true if this tag should render as xhtml.
743      */
744     private boolean isXhtml() {
745         return TagUtils.getInstance().isXhtml(this.pageContext);
746     }
747 
748     /**
749      * Returns the focusIndex.
750      * @return String
751      */
752     public String getFocusIndex() {
753         return focusIndex;
754     }
755 
756     /**
757      * Sets the focusIndex.
758      * @param focusIndex The focusIndex to set
759      */
760     public void setFocusIndex(String focusIndex) {
761         this.focusIndex = focusIndex;
762     }
763 
764     /**
765      * Gets whether or not the focus script's &lt;script&gt; element will include the 
766      * language attribute.
767      * @return true if language attribute will be included.
768      * @since Struts 1.2
769      */
770     public boolean getScriptLanguage() {
771         return this.scriptLanguage;
772     }
773 
774     /**
775      * Sets whether or not the focus script's &lt;script&gt; element will include the 
776      * language attribute.
777      * @since Struts 1.2
778      */
779     public void setScriptLanguage(boolean scriptLanguage) {
780         this.scriptLanguage = scriptLanguage;
781     }
782 
783 }