Save This Page
Home » Struts-1.3.10 » org.apache.struts.taglib » html » [javadoc | source]
    1   /*
    2    * $Id: FormTag.java 331056 2005-11-06 01:29:01Z 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;
   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: 331056 $ $Date: 2005-11-06 01:29:01 +0000 (Sun, 06 Nov 2005) $
   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       /** 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 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 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 action) {
  207   
  208           this.action = action;
  209   
  210       }
  211   
  212       /**
  213        * Return the content encoding used when submitting this form.
  214        */
  215       public String 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 enctype) {
  227   
  228           this.enctype = enctype;
  229   
  230       }
  231   
  232       /**
  233        * Return the focus field name for this form.
  234        */
  235       public String 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 focus) {
  247   
  248           this.focus = focus;
  249   
  250       }
  251   
  252       /**
  253        * Return the request method used when submitting this form.
  254        */
  255       public String 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 method) {
  267   
  268           this.method = method;
  269   
  270       }
  271   
  272       /**
  273        * Return the onReset event script.
  274        */
  275       public String 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 onReset) {
  287   
  288           this.onreset = onReset;
  289   
  290       }
  291   
  292       /**
  293        * Return the onSubmit event script.
  294        */
  295       public String 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 onSubmit) {
  307   
  308           this.onsubmit = onSubmit;
  309   
  310       }
  311   
  312       /**
  313        * Return the style attribute for this tag.
  314        */
  315       public String 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 style) {
  327   
  328           this.style = style;
  329   
  330       }
  331   
  332       /**
  333        * Return the style class for this tag.
  334        */
  335       public String 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 styleClass) {
  347   
  348           this.styleClass = styleClass;
  349   
  350       }
  351   
  352       /**
  353        * Return the style identifier for this tag.
  354        */
  355       public String 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 styleId) {
  367   
  368           this.styleId = styleId;
  369   
  370       }
  371   
  372       /**
  373        * Return the window target.
  374        */
  375       public String 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 target) {
  387   
  388           this.target = target;
  389   
  390       }
  391   
  392       /**
  393        * Return the list of character encodings accepted.
  394        */
  395       public String 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 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 {
  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 results = new StringBuffer();
  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 {
  469           int scope = PageContext.SESSION_SCOPE;
  470           if ("request".equalsIgnoreCase(beanScope)) {
  471               scope = PageContext.REQUEST_SCOPE;
  472           }
  473           
  474           Object 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) pageContext.getRequest(),
  480                       mapping,
  481                       moduleConfig,
  482                       servlet);
  483               if (bean instanceof ActionForm) {
  484                   ((ActionForm) bean).reset(mapping, (HttpServletRequest) pageContext.getRequest());
  485               }
  486               if (bean == null) {
  487                   throw new JspException(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 renderFormStartElement() {
  500               
  501           StringBuffer results = new StringBuffer("<form");
  502   
  503           // render attributes
  504           renderName(results);
  505           
  506           renderAttribute(results, "method", getMethod() == null ? "post" : getMethod());
  507           renderAction(results);
  508           renderAttribute(results, "accept-charset", getAcceptCharset());
  509           renderAttribute(results, "class", getStyleClass());
  510           renderAttribute(results, "enctype", getEnctype());
  511           renderAttribute(results, "onreset", getOnreset());
  512           renderAttribute(results, "onsubmit", getOnsubmit());
  513           renderAttribute(results, "style", getStyle());
  514           renderAttribute(results, "target", getTarget());
  515   
  516           // Hook for additional attributes
  517           renderOtherAttributes(results);
  518   
  519           results.append(">");
  520           return results.toString();
  521       }
  522   
  523       /**
  524        * Renders the name of the form.  If XHTML is set to true, the name will
  525        * be rendered as an 'id' attribute, otherwise as a 'name' attribute.
  526        */
  527       protected void renderName(StringBuffer results) {
  528           if (this.isXhtml()) {
  529               if (getStyleId() == null) {
  530                   renderAttribute(results, "id", beanName);
  531               } else {
  532                   renderAttribute(results, "id", getStyleId());
  533               }
  534           } else {    
  535               renderAttribute(results, "name", beanName);
  536               renderAttribute(results, "id", getStyleId());
  537           }    
  538       }
  539   
  540       /**
  541        * Renders the action attribute
  542        */
  543       protected void renderAction(StringBuffer results) {
  544   
  545           HttpServletResponse response =
  546               (HttpServletResponse) this.pageContext.getResponse();
  547   
  548           results.append(" action=\"");
  549           results.append(
  550               response.encodeURL(
  551                   TagUtils.getInstance().getActionMappingURL(
  552                       this.action,
  553                       this.pageContext)));
  554                   
  555           results.append("\"");
  556       }
  557   
  558       /**
  559        * 'Hook' to enable this tag to be extended and 
  560        *  additional attributes added.
  561        */
  562       protected void renderOtherAttributes(StringBuffer results) {
  563       }
  564   
  565       /**
  566        * Generates a hidden input field with token information, if any. The
  567        * field is added within a div element for HTML 4.01 Strict compliance.
  568        * @return A hidden input field containing the token.
  569        * @since Struts 1.1
  570        */
  571       protected String renderToken() {
  572           StringBuffer results = new StringBuffer();
  573           HttpSession session = pageContext.getSession();
  574   
  575           if (session != null) {
  576               String token =
  577                   (String) session.getAttribute(Globals.TRANSACTION_TOKEN_KEY);
  578                   
  579               if (token != null) {
  580                   results.append("<div><input type=\"hidden\" name=\"");
  581                   results.append(Constants.TOKEN_KEY);
  582                   results.append("\" value=\"");
  583                   results.append(token);
  584                   if (this.isXhtml()) {
  585                       results.append("\" />");
  586                   } else {
  587                       results.append("\">");
  588                   }
  589                   results.append("</div>");
  590               }
  591           }
  592   
  593           return results.toString();
  594       }
  595   
  596       /**
  597        * Renders attribute="value" if not null
  598        */
  599       protected void renderAttribute(StringBuffer results, String attribute, String value) {
  600           if (value != null) {
  601               results.append(" ");
  602               results.append(attribute);
  603               results.append("=\"");
  604               results.append(value);
  605               results.append("\"");
  606           }
  607       }
  608   
  609       /**
  610        * Render the end of this form.
  611        *
  612        * @exception JspException if a JSP exception has occurred
  613        */
  614       public int doEndTag() throws JspException {
  615   
  616           // Remove the page scope attributes we created
  617           pageContext.removeAttribute(Constants.BEAN_KEY, PageContext.REQUEST_SCOPE);
  618           pageContext.removeAttribute(Constants.FORM_KEY, PageContext.REQUEST_SCOPE);
  619   
  620           // Render a tag representing the end of our current form
  621           StringBuffer results = new StringBuffer("</form>");
  622   
  623           // Render JavaScript to set the input focus if required
  624           if (this.focus != null) {
  625               results.append(this.renderFocusJavascript());
  626           }
  627   
  628           // Print this value to our output writer
  629           JspWriter writer = pageContext.getOut();
  630           try {
  631               writer.print(results.toString());
  632           } catch (IOException e) {
  633               throw new JspException(messages.getMessage("common.io", e.toString()));
  634           }
  635   
  636           // Continue processing this page
  637           return (EVAL_PAGE);
  638   
  639       }
  640   
  641       /**
  642        * Generates javascript to set the initial focus to the form element given in the
  643        * tag's "focus" attribute.
  644        * @since Struts 1.1
  645        */
  646       protected String renderFocusJavascript() {
  647           StringBuffer results = new StringBuffer();
  648   
  649           results.append(lineEnd);
  650           results.append("<script type=\"text/javascript\"");
  651           if (!this.isXhtml() && this.scriptLanguage) {
  652               results.append(" language=\"JavaScript\"");
  653           }
  654           results.append(">");
  655           results.append(lineEnd);
  656   
  657           // xhtml script content shouldn't use the browser hiding trick
  658           if (!this.isXhtml()) {
  659               results.append("  <!--");
  660               results.append(lineEnd);
  661           }
  662   
  663           // Construct the control name that will receive focus.
  664           // This does not include any index.
  665           StringBuffer focusControl = new StringBuffer("document.forms[\"");
  666           focusControl.append(beanName);
  667           focusControl.append("\"].elements[\"");
  668           focusControl.append(this.focus);
  669           focusControl.append("\"]");
  670   
  671           results.append("  var focusControl = ");
  672           results.append(focusControl.toString());
  673           results.append(";");
  674           results.append(lineEnd);
  675           results.append(lineEnd);
  676   
  677           results.append("  if (focusControl.type != \"hidden\" && !focusControl.disabled) {");
  678           results.append(lineEnd);
  679   
  680           // Construct the index if needed and insert into focus statement
  681           String index = "";
  682           if (this.focusIndex != null) {
  683               StringBuffer sb = new StringBuffer("[");
  684               sb.append(this.focusIndex);
  685               sb.append("]");
  686               index = sb.toString();
  687           }
  688           results.append("     focusControl");
  689           results.append(index);
  690           results.append(".focus();");
  691           results.append(lineEnd);
  692   
  693           results.append("  }");
  694           results.append(lineEnd);
  695   
  696           if (!this.isXhtml()) {
  697               results.append("  // -->");
  698               results.append(lineEnd);
  699           }
  700   
  701           results.append("</script>");
  702           results.append(lineEnd);
  703           return results.toString();
  704       }
  705   
  706       /**
  707        * Release any acquired resources.
  708        */
  709       public void release() {
  710   
  711           super.release();
  712           action = null;
  713           moduleConfig = null;
  714           enctype = null;
  715           disabled = false;
  716           focus = null;
  717           focusIndex = null;
  718           mapping = null;
  719           method = null;
  720           onreset = null;
  721           onsubmit = null;
  722           readonly = false;
  723           servlet = null;
  724           style = null;
  725           styleClass = null;
  726           styleId = null;
  727           target = null;
  728           acceptCharset = null;
  729   
  730       }
  731   
  732       // ------------------------------------------------------ Protected Methods
  733   
  734   
  735       /**
  736        * Look up values for the <code>name</code>, <code>scope</code>, and
  737        * <code>type</code> properties if necessary.
  738        *
  739        * @exception JspException if a required value cannot be looked up
  740        */
  741       protected void lookup() throws JspException {
  742   
  743           // Look up the module configuration information we need
  744           moduleConfig = TagUtils.getInstance().getModuleConfig(pageContext);
  745   
  746           if (moduleConfig == null) {
  747               JspException e = new JspException(messages.getMessage("formTag.collections"));
  748               pageContext.setAttribute(Globals.EXCEPTION_KEY, e, PageContext.REQUEST_SCOPE);
  749               throw e;
  750           }
  751           servlet =
  752               (ActionServlet) pageContext.getServletContext().getAttribute(
  753                   Globals.ACTION_SERVLET_KEY);
  754   
  755           // Look up the action mapping we will be submitting to
  756           String mappingName = TagUtils.getInstance().getActionMappingName(action);
  757           mapping = (ActionMapping) moduleConfig.findActionConfig(mappingName);
  758           if (mapping == null) {
  759               JspException e = new JspException(messages.getMessage("formTag.mapping", mappingName));
  760               pageContext.setAttribute(Globals.EXCEPTION_KEY, e, PageContext.REQUEST_SCOPE);
  761               throw e;
  762           }
  763   
  764           // Look up the form bean definition
  765           FormBeanConfig formBeanConfig = moduleConfig.findFormBeanConfig(mapping.getName());
  766           if (formBeanConfig == null) {
  767               JspException e =
  768                   new JspException(messages.getMessage("formTag.formBean", mapping.getName(), action));
  769               pageContext.setAttribute(Globals.EXCEPTION_KEY, e, PageContext.REQUEST_SCOPE);
  770               throw e;
  771           }
  772   
  773           // Calculate the required values
  774           beanName = mapping.getAttribute();
  775           beanScope = mapping.getScope();
  776           beanType = formBeanConfig.getType();
  777       }
  778   
  779       /**
  780        * Returns true if this tag should render as xhtml.
  781        */
  782       private boolean isXhtml() {
  783           return TagUtils.getInstance().isXhtml(this.pageContext);
  784       }
  785   
  786       /**
  787        * Returns the focusIndex.
  788        * @return String
  789        */
  790       public String getFocusIndex() {
  791           return focusIndex;
  792       }
  793   
  794       /**
  795        * Sets the focusIndex.
  796        * @param focusIndex The focusIndex to set
  797        */
  798       public void setFocusIndex(String focusIndex) {
  799           this.focusIndex = focusIndex;
  800       }
  801   
  802       /**
  803        * Gets whether or not the focus script's &lt;script&gt; element will include the 
  804        * language attribute.
  805        * @return true if language attribute will be included.
  806        * @since Struts 1.2
  807        */
  808       public boolean getScriptLanguage() {
  809           return this.scriptLanguage;
  810       }
  811   
  812       /**
  813        * Sets whether or not the focus script's &lt;script&gt; element will include the 
  814        * language attribute.
  815        * @since Struts 1.2
  816        */
  817       public void setScriptLanguage(boolean scriptLanguage) {
  818           this.scriptLanguage = scriptLanguage;
  819       }
  820   
  821   }

Save This Page
Home » Struts-1.3.10 » org.apache.struts.taglib » html » [javadoc | source]