Save This Page
Home » struts-2.1.8.1-src » org.apache » struts2 » components » [javadoc | source]
    1   /*
    2    * $Id: UIBean.java 754994 2009-03-16 20:09:51Z musachy $
    3    *
    4    * Licensed to the Apache Software Foundation (ASF) under one
    5    * or more contributor license agreements.  See the NOTICE file
    6    * distributed with this work for additional information
    7    * regarding copyright ownership.  The ASF licenses this file
    8    * to you under the Apache License, Version 2.0 (the
    9    * "License"); you may not use this file except in compliance
   10    * with the License.  You may obtain a copy of the License at
   11    *
   12    *  http://www.apache.org/licenses/LICENSE-2.0
   13    *
   14    * Unless required by applicable law or agreed to in writing,
   15    * software distributed under the License is distributed on an
   16    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   17    * KIND, either express or implied.  See the License for the
   18    * specific language governing permissions and limitations
   19    * under the License.
   20    */
   21   
   22   package org.apache.struts2.components;
   23   
   24   import java.io.Writer;
   25   import java.util.HashMap;
   26   import java.util.Iterator;
   27   import java.util.LinkedHashMap;
   28   import java.util.List;
   29   import java.util.Map;
   30   
   31   import javax.servlet.http.HttpServletRequest;
   32   import javax.servlet.http.HttpServletResponse;
   33   
   34   import org.apache.struts2.StrutsConstants;
   35   import org.apache.struts2.StrutsException;
   36   import org.apache.struts2.util.TextProviderHelper;
   37   import org.apache.struts2.components.template.Template;
   38   import org.apache.struts2.components.template.TemplateEngine;
   39   import org.apache.struts2.components.template.TemplateEngineManager;
   40   import org.apache.struts2.components.template.TemplateRenderingContext;
   41   import org.apache.struts2.views.annotations.StrutsTagAttribute;
   42   import org.apache.struts2.views.util.ContextUtil;
   43   
   44   import com.opensymphony.xwork2.config.ConfigurationException;
   45   import com.opensymphony.xwork2.inject.Inject;
   46   import com.opensymphony.xwork2.util.ValueStack;
   47   import com.opensymphony.xwork2.util.logging.Logger;
   48   import com.opensymphony.xwork2.util.logging.LoggerFactory;
   49   
   50   /**
   51    * UIBean is the standard superclass of all Struts UI componentns.
   52    * It defines common Struts and html properties all UI components should present for usage.
   53    *
   54    * <!-- START SNIPPET: templateRelatedAttributes -->
   55    *
   56    * <table border="1">
   57    *    <thead>
   58    *       <tr>
   59    *          <td>Attribute</td>
   60    *          <td>Theme</td>
   61    *          <td>Data Types</td>
   62    *          <td>Description</td>
   63    *       </tr>
   64    *    </thead>
   65    *    <tbody>
   66    *       <tr>
   67    *          <td>templateDir</td>
   68    *          <td>n/a</td>
   69    *          <td>String</td>
   70    *          <td>define the template directory</td>
   71    *       </td>
   72    *       <tr>
   73    *          <td>theme</td>
   74    *          <td>n/a</td>
   75    *          <td>String</td>
   76    *          <td>define the theme name</td>
   77    *       </td>
   78    *       <tr>
   79    *          <td>template</td>
   80    *          <td>n/a</td>
   81    *          <td>String</td>
   82    *          <td>define the template name</td>
   83    *       </td>
   84    *    </tbody>
   85    * </table>
   86    *
   87    * <!-- END SNIPPET: templateRelatedAttributes -->
   88    *
   89    * <p/>
   90    *
   91    * <!-- START SNIPPET: generalAttributes -->
   92    *
   93    * <table border="1">
   94    *    <thead>
   95    *       <tr>
   96    *          <td>Attribute</td>
   97    *          <td>Theme</td>
   98    *          <td>Data Types</td>
   99    *          <td>Description</td>
  100    *       </tr>
  101    *    </thead>
  102    *    <tbody>
  103    *       <tr>
  104    *          <td>cssClass</td>
  105    *          <td>simple</td>
  106    *          <td>String</td>
  107    *          <td>define html class attribute</td>
  108    *       </tr>
  109    *       <tr>
  110    *          <td>cssStyle</td>
  111    *          <td>simple</td>
  112    *          <td>String</td>
  113    *          <td>define html style attribute</td>
  114    *       </tr>
  115    *       <tr>
  116    *          <td>cssClass</td>
  117    *          <td>simple</td>
  118    *          <td>String</td>
  119    *          <td>error class attribute</td>
  120    *       </tr>
  121    *       <tr>
  122    *          <td>cssStyle</td>
  123    *          <td>simple</td>
  124    *          <td>String</td>
  125    *          <td>error style attribute</td>
  126    *       </tr>
  127    *       <tr>
  128    *          <td>title</td>
  129    *          <td>simple</td>
  130    *          <td>String</td>
  131    *          <td>define html title attribute</td>
  132    *       </tr>
  133    *       <tr>
  134    *          <td>disabled</td>
  135    *          <td>simple</td>
  136    *          <td>String</td>
  137    *          <td>define html disabled attribute</td>
  138    *       </tr>
  139    *       <tr>
  140    *          <td>label</td>
  141    *          <td>xhtml</td>
  142    *          <td>String</td>
  143    *          <td>define label of form element</td>
  144    *       </tr>
  145    *       <tr>
  146    *          <td>labelPosition</td>
  147    *          <td>xhtml</td>
  148    *          <td>String</td>
  149    *          <td>define label position of form element (top/left), default to left</td>
  150    *       </tr>
  151    *       <tr>
  152    *          <td>requiredposition</td>
  153    *          <td>xhtml</td>
  154    *          <td>String</td>
  155    *          <td>define required label position of form element (left/right), default to right</td>
  156    *       </tr>
  157    *       <tr>
  158    *          <td>name</td>
  159    *          <td>simple</td>
  160    *          <td>String</td>
  161    *          <td>Form Element's field name mapping</td>
  162    *       </tr>
  163    *       <tr>
  164    *          <td>required</td>
  165    *          <td>xhtml</td>
  166    *          <td>Boolean</td>
  167    *          <td>add * to label (true to add false otherwise)</td>
  168    *       </tr>
  169    *       <tr>
  170    *          <td>tabIndex</td>
  171    *          <td>simple</td>
  172    *          <td>String</td>
  173    *          <td>define html tabindex attribute</td>
  174    *       </tr>
  175    *       <tr>
  176    *          <td>value</td>
  177    *          <td>simple</td>
  178    *          <td>Object</td>
  179    *          <td>define value of form element</td>
  180    *       </tr>
  181    *    </tbody>
  182    * </table>
  183    *
  184    * <!-- END SNIPPET: generalAttributes -->
  185    *
  186    * <p/>
  187    *
  188    * <!-- START SNIPPET: javascriptRelatedAttributes -->
  189    *
  190    * <table border="1">
  191    *    <thead>
  192    *       <tr>
  193    *          <td>Attribute</td>
  194    *          <td>Theme</td>
  195    *          <td>Data Types</td>
  196    *          <td>Description</td>
  197    *       </tr>
  198    *    </thead>
  199    *    <tbody>
  200    *       <tr>
  201    *          <td>onclick</td>
  202    *          <td>simple</td>
  203    *          <td>String</td>
  204    *          <td>html javascript onclick attribute</td>
  205    *       </tr>
  206    *       <tr>
  207    *          <td>ondblclick</td>
  208    *          <td>simple</td>
  209    *          <td>String</td>
  210    *          <td>html javascript ondbclick attribute</td>
  211    *       </tr>
  212    *       <tr>
  213    *          <td>onmousedown</td>
  214    *          <td>simple</td>
  215    *          <td>String</td>
  216    *          <td>html javascript onmousedown attribute</td>
  217    *       </tr>
  218    *       <tr>
  219    *          <td>onmouseup</td>
  220    *          <td>simple</td>
  221    *          <td>String</td>
  222    *          <td>html javascript onmouseup attribute</td>
  223    *       </tr>
  224    *       <tr>
  225    *          <td>onmouseover</td>
  226    *          <td>simple</td>
  227    *          <td>String</td>
  228    *          <td>html javascript onmouseover attribute</td>
  229    *       </tr>
  230    *       <tr>
  231    *          <td>onmouseout</td>
  232    *          <td>simple</td>
  233    *          <td>String</td>
  234    *          <td>html javascript onmouseout attribute</td>
  235    *       </tr>
  236    *       <tr>
  237    *          <td>onfocus</td>
  238    *          <td>simple</td>
  239    *          <td>String</td>
  240    *          <td>html javascript onfocus attribute</td>
  241    *       </tr>
  242    *       <tr>
  243    *          <td>onblur</td>
  244    *          <td>simple</td>
  245    *          <td>String</td>
  246    *          <td>html javascript onblur attribute</td>
  247    *       </tr>
  248    *       <tr>
  249    *          <td>onkeypress</td>
  250    *          <td>simple</td>
  251    *          <td>String</td>
  252    *          <td>html javascript onkeypress attribute</td>
  253    *       </tr>
  254    *       <tr>
  255    *          <td>onkeyup</td>
  256    *          <td>simple</td>
  257    *          <td>String</td>
  258    *          <td>html javascript onkeyup attribute</td>
  259    *       </tr>
  260    *       <tr>
  261    *          <td>onkeydown</td>
  262    *          <td>simple</td>
  263    *          <td>String</td>
  264    *          <td>html javascript onkeydown attribute</td>
  265    *       </tr>
  266    *       <tr>
  267    *          <td>onselect</td>
  268    *          <td>simple</td>
  269    *          <td>String</td>
  270    *          <td>html javascript onselect attribute</td>
  271    *       </tr>
  272    *       <tr>
  273    *          <td>onchange</td>
  274    *          <td>simple</td>
  275    *          <td>String</td>
  276    *          <td>html javascript onchange attribute</td>
  277    *       </tr>
  278    *    </tbody>
  279    * </table>
  280    *
  281    * <!-- END SNIPPET: javascriptRelatedAttributes -->
  282    *
  283    * <p/>
  284    *
  285    * <!-- START SNIPPET: tooltipattributes -->
  286    *
  287    * <table border="1">
  288    *  <tr>
  289    *     <td>Attribute</td>
  290    *     <td>Data Type</td>
  291    *     <td>Default</td>
  292    *     <td>Description</td>
  293    *  </tr>
  294    *  <tr>
  295    *      <td>tooltip</td>
  296    *      <td>String</td>
  297    *      <td>none</td>
  298    *      <td>Set the tooltip of this particular component</td>
  299    *  </tr>
  300    *  <tr>
  301    *      <td>jsTooltipEnabled</td>
  302    *      <td>String</td>
  303    *      <td>false</td>
  304    *      <td>Enable js tooltip rendering</td>
  305    *  </tr>
  306    *    <tr>
  307    *      <td>tooltipIcon</td>
  308    *      <td>String</td>
  309    *      <td>/struts/static/tooltip/tooltip.gif</td>
  310    *      <td>The url to the tooltip icon</td>
  311    *   <tr>
  312    *      <td>tooltipDelay</td>
  313    *      <td>String</td>
  314    *      <td>500</td>
  315    *      <td>Tooltip shows up after the specified timeout (miliseconds). A behavior similar to that of OS based tooltips.</td>
  316    *   </tr>
  317    *   <tr>
  318    *      <td>key</td>
  319    *      <td>simple</td>
  320    *      <td>String</td>
  321    *      <td>The name of the property this input field represents.  This will auto populate the name, label, and value</td>
  322    *   </tr>
  323    * </table>
  324    *
  325    * <!-- END SNIPPET: tooltipattributes -->
  326    *
  327    *
  328    * <!-- START SNIPPET: tooltipdescription -->
  329    * <b>tooltipConfig is deprecated, use individual tooltip configuration attributes instead </b>
  330    *
  331    * Every Form UI component (in xhtml / css_xhtml or any other that extends them) can
  332    * have tooltips assigned to them. The Form component's tooltip related attribute, once
  333    * defined, will be applied to all form UI components that are created under it unless
  334    * explicitly overriden by having the Form UI component itself defined with their own tooltip attribute.
  335    *
  336    * <p/>
  337    *
  338    * In Example 1, the textfield will inherit the tooltipDelay and tooltipIconPath attribte from
  339    * its containing form. In other words, although it doesn't define a tooltipIconPath
  340    * attribute, it will have that attribute inherited from its containing form.
  341    *
  342    * <p/>
  343    *
  344    * In Example 2, the  textfield will inherite both the tooltipDelay and
  345    * tooltipIconPath attribute from its containing form, but the tooltipDelay
  346    * attribute is overriden at the textfield itself. Hence, the textfield actually will
  347    * have its tooltipIcon defined as /myImages/myIcon.gif, inherited from its containing form, and
  348    * tooltipDelay defined as 5000.
  349    *
  350    * <p/>
  351    *
  352    * Example 3, 4 and 5 show different ways of setting the tooltip configuration attribute.<br/>
  353    * <b>Example 3:</b> Set tooltip config through the body of the param tag<br/>
  354    * <b>Example 4:</b> Set tooltip config through the value attribute of the param tag<br/>
  355    * <b>Example 5:</b> Set tooltip config through the tooltip attributes of the component tag<br/>
  356    *
  357    * <!-- END SNIPPET: tooltipdescription -->
  358    *
  359    *
  360    * <pre>
  361    * <!-- START SNIPPET: tooltipexample -->
  362    *
  363    * &lt;!-- Example 1: --&gt;
  364    * &lt;s:form
  365    *          tooltipDelay="500"
  366    *          tooltipIconPath="/myImages/myIcon.gif" .... &gt;
  367    *   ....
  368    *     &lt;s:textfield label="Customer Name" tooltip="Enter the customer name" .... /&gt;
  369    *   ....
  370    * &lt;/s:form&gt;
  371    *
  372    * &lt;!-- Example 2: --&gt;
  373    * &lt;s:form
  374    *          tooltipDelay="500"
  375    *          tooltipIconPath="/myImages/myIcon.gif" .... &gt;
  376    *   ....
  377    *     &lt;s:textfield label="Address"
  378    *          tooltip="Enter your address"
  379    *          tooltipDelay="5000" /&gt;
  380    *   ....
  381    * &lt;/s:form&gt;
  382    *
  383    *
  384    * &lt;-- Example 3: --&gt;
  385    * &lt;s:textfield
  386    *        label="Customer Name"
  387    *        tooltip="One of our customer Details"&gt;
  388    *        &lt;s:param name="tooltipDelay"&gt;
  389    *             500
  390    *        &lt;/s:param&gt;
  391    *        &lt;s:param name="tooltipIconPath"&gt;
  392    *             /myImages/myIcon.gif
  393    *        &lt;/s:param&gt;
  394    * &lt;/s:textfield&gt;
  395    *
  396    *
  397    * &lt;-- Example 4: --&gt;
  398    * &lt;s:textfield
  399    *          label="Customer Address"
  400    *          tooltip="Enter The Customer Address" &gt;
  401    *          &lt;s:param
  402    *              name="tooltipDelay"
  403    *              value="500" /&gt;
  404    * &lt;/s:textfield&gt;
  405    *
  406    *
  407    * &lt;-- Example 5: --&gt;
  408    * &lt;s:textfield
  409    *          label="Customer Telephone Number"
  410    *          tooltip="Enter customer Telephone Number"
  411    *          tooltipDelay="500"
  412    *          tooltipIconPath="/myImages/myIcon.gif" /&gt;
  413    *
  414    * <!-- END SNIPPET: tooltipexample -->
  415    * </pre>
  416    *
  417    */
  418   public abstract class UIBean extends Component {
  419       private static final Logger LOG = LoggerFactory.getLogger(UIBean.class);
  420   
  421       protected HttpServletRequest request;
  422       protected HttpServletResponse response;
  423   
  424       public UIBean(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
  425           super(stack);
  426           this.request = request;
  427           this.response = response;
  428           this.templateSuffix = ContextUtil.getTemplateSuffix(stack.getContext());
  429       }
  430   
  431       // The templateSuffic to use, overrides the default one if not null.
  432       protected String templateSuffix;
  433   
  434       // The template to use, overrides the default one.
  435       protected String template;
  436   
  437       // templateDir and theme attributes
  438       protected String templateDir;
  439       protected String theme;
  440   
  441       // shortcut, sets label, name, and value
  442       protected String key;
  443   
  444       protected String id;
  445       protected String cssClass;
  446       protected String cssStyle;
  447       protected String cssErrorClass;
  448       protected String cssErrorStyle;
  449       protected String disabled;
  450       protected String label;
  451       protected String labelPosition;
  452       protected String labelSeparator;
  453       protected String requiredposition;
  454       protected String name;
  455       protected String required;
  456       protected String tabindex;
  457       protected String value;
  458       protected String title;
  459   
  460       // HTML scripting events attributes
  461       protected String onclick;
  462       protected String ondblclick;
  463       protected String onmousedown;
  464       protected String onmouseup;
  465       protected String onmouseover;
  466       protected String onmousemove;
  467       protected String onmouseout;
  468       protected String onfocus;
  469       protected String onblur;
  470       protected String onkeypress;
  471       protected String onkeydown;
  472       protected String onkeyup;
  473       protected String onselect;
  474       protected String onchange;
  475   
  476       // common html attributes
  477       protected String accesskey;
  478   
  479       // javascript tooltip attribute
  480       protected String tooltip;
  481       protected String tooltipConfig;
  482       protected String javascriptTooltip;
  483       protected String tooltipDelay;
  484       protected String tooltipCssClass;
  485       protected String tooltipIconPath;
  486   
  487       // dynamic attributes
  488       protected Map<String,Object> dynamicAttributes = new HashMap<String,Object>();
  489   
  490       protected String defaultTemplateDir;
  491       protected String defaultUITheme;
  492       protected TemplateEngineManager templateEngineManager;
  493   
  494       @Inject(StrutsConstants.STRUTS_UI_TEMPLATEDIR)
  495       public void setDefaultTemplateDir(String dir) {
  496           this.defaultTemplateDir = dir;
  497       }
  498   
  499       @Inject(StrutsConstants.STRUTS_UI_THEME)
  500       public void setDefaultUITheme(String theme) {
  501           this.defaultUITheme = theme;
  502       }
  503   
  504       @Inject
  505       public void setTemplateEngineManager(TemplateEngineManager mgr) {
  506           this.templateEngineManager = mgr;
  507       }
  508   
  509       public boolean end(Writer writer, String body) {
  510           evaluateParams();
  511           try {
  512               super.end(writer, body, false);
  513               mergeTemplate(writer, buildTemplateName(template, getDefaultTemplate()));
  514           } catch (Exception e) {
  515               throw new StrutsException(e);
  516           }
  517           finally {
  518               popComponentStack();
  519           }
  520   
  521           return false;
  522       }
  523   
  524       /**
  525        * A contract that requires each concrete UI Tag to specify which template should be used as a default.  For
  526        * example, the CheckboxTab might return "checkbox.vm" while the RadioTag might return "radio.vm".  This value
  527        * <strong>not</strong> begin with a '/' unless you intend to make the path absolute rather than relative to the
  528        * current theme.
  529        *
  530        * @return The name of the template to be used as the default.
  531        */
  532       protected abstract String getDefaultTemplate();
  533   
  534       protected Template buildTemplateName(String myTemplate, String myDefaultTemplate) {
  535           String template = myDefaultTemplate;
  536   
  537           if (myTemplate != null) {
  538               template = findString(myTemplate);
  539           }
  540   
  541           String templateDir = getTemplateDir();
  542           String theme = getTheme();
  543   
  544           return new Template(templateDir, theme, template);
  545   
  546       }
  547   
  548       protected void mergeTemplate(Writer writer, Template template) throws Exception {
  549           final TemplateEngine engine = templateEngineManager.getTemplateEngine(template, templateSuffix);
  550           if (engine == null) {
  551               throw new ConfigurationException("Unable to find a TemplateEngine for template " + template);
  552           }
  553   
  554           if (LOG.isDebugEnabled()) {
  555               LOG.debug("Rendering template " + template);
  556           }
  557   
  558           final TemplateRenderingContext context = new TemplateRenderingContext(template, writer, getStack(), getParameters(), this);
  559           engine.renderTemplate(context);
  560       }
  561   
  562       public String getTemplateDir() {
  563           String templateDir = null;
  564   
  565           if (this.templateDir != null) {
  566               templateDir = findString(this.templateDir);
  567           }
  568   
  569           // If templateDir is not explicitly given,
  570           // try to find attribute which states the dir set to use
  571           if ((templateDir == null) || (templateDir.equals(""))) {
  572               templateDir = stack.findString("#attr.templateDir");
  573           }
  574   
  575           // Default template set
  576           if ((templateDir == null) || (templateDir.equals(""))) {
  577               templateDir = defaultTemplateDir;
  578           }
  579   
  580           // Defaults to 'template'
  581           if ((templateDir == null) || (templateDir.equals(""))) {
  582               templateDir = "template";
  583           }
  584   
  585           return templateDir;
  586       }
  587   
  588       public String getTheme() {
  589           String theme = null;
  590   
  591           if (this.theme != null) {
  592               theme = findString(this.theme);
  593           }
  594   
  595           if ( theme == null || theme.equals("") ) {
  596               Form form = (Form) findAncestor(Form.class);
  597               if (form != null) {
  598                   theme = form.getTheme();
  599               }
  600           }
  601   
  602           // If theme set is not explicitly given,
  603           // try to find attribute which states the theme set to use
  604           if ((theme == null) || (theme.equals(""))) {
  605               theme = stack.findString("#attr.theme");
  606           }
  607   
  608           // Default theme set
  609           if ((theme == null) || (theme.equals(""))) {
  610               theme = defaultUITheme;
  611           }
  612   
  613           return theme;
  614       }
  615   
  616       public void evaluateParams() {
  617           addParameter("templateDir", getTemplateDir());
  618           addParameter("theme", getTheme());
  619           addParameter("dynamicAttributes", dynamicAttributes);
  620   
  621           String name = null;
  622           String providedLabel = null;
  623   
  624           if (this.key != null) {
  625   
  626               if(this.name == null) {
  627                   this.name = key;
  628               }
  629   
  630               if(this.label == null) {
  631                   // lookup the label from a TextProvider (default value is the key)
  632                   providedLabel = TextProviderHelper.getText(key, key, stack);
  633               }
  634   
  635           }
  636   
  637           if (this.name != null) {
  638               name = findString(this.name);
  639               addParameter("name", name);
  640           }
  641   
  642           if (label != null) {
  643               addParameter("label", findString(label));
  644           } else {
  645               if (providedLabel != null) {
  646                   // label found via a TextProvider
  647                   addParameter("label", providedLabel);
  648               }
  649           }
  650   
  651           if (labelSeparator != null) {
  652               addParameter("labelseparator", findString(labelSeparator));
  653           }
  654   
  655           if (labelPosition != null) {
  656               addParameter("labelposition", findString(labelPosition));
  657           }
  658   
  659           if (requiredposition != null) {
  660               addParameter("requiredposition", findString(requiredposition));
  661           }
  662   
  663           if (required != null) {
  664               addParameter("required", findValue(required, Boolean.class));
  665           }
  666   
  667           if (disabled != null) {
  668               addParameter("disabled", findValue(disabled, Boolean.class));
  669           }
  670   
  671           if (tabindex != null) {
  672               addParameter("tabindex", findString(tabindex));
  673           }
  674   
  675           if (onclick != null) {
  676               addParameter("onclick", findString(onclick));
  677           }
  678   
  679           if (ondblclick != null) {
  680               addParameter("ondblclick", findString(ondblclick));
  681           }
  682   
  683           if (onmousedown != null) {
  684               addParameter("onmousedown", findString(onmousedown));
  685           }
  686   
  687           if (onmouseup != null) {
  688               addParameter("onmouseup", findString(onmouseup));
  689           }
  690   
  691           if (onmouseover != null) {
  692               addParameter("onmouseover", findString(onmouseover));
  693           }
  694   
  695           if (onmousemove != null) {
  696               addParameter("onmousemove", findString(onmousemove));
  697           }
  698   
  699           if (onmouseout != null) {
  700               addParameter("onmouseout", findString(onmouseout));
  701           }
  702   
  703           if (onfocus != null) {
  704               addParameter("onfocus", findString(onfocus));
  705           }
  706   
  707           if (onblur != null) {
  708               addParameter("onblur", findString(onblur));
  709           }
  710   
  711           if (onkeypress != null) {
  712               addParameter("onkeypress", findString(onkeypress));
  713           }
  714   
  715           if (onkeydown != null) {
  716               addParameter("onkeydown", findString(onkeydown));
  717           }
  718   
  719           if (onkeyup != null) {
  720               addParameter("onkeyup", findString(onkeyup));
  721           }
  722   
  723           if (onselect != null) {
  724               addParameter("onselect", findString(onselect));
  725           }
  726   
  727           if (onchange != null) {
  728               addParameter("onchange", findString(onchange));
  729           }
  730   
  731           if (accesskey != null) {
  732               addParameter("accesskey", findString(accesskey));
  733           }
  734   
  735           if (cssClass != null) {
  736               addParameter("cssClass", findString(cssClass));
  737           }
  738   
  739           if (cssStyle != null) {
  740               addParameter("cssStyle", findString(cssStyle));
  741           }
  742   
  743           if (cssErrorClass != null) {
  744               addParameter("cssErrorClass", findString(cssErrorClass));
  745           }
  746   
  747           if (cssErrorStyle != null) {
  748               addParameter("cssErrorStyle", findString(cssErrorStyle));
  749           }
  750   
  751           if (title != null) {
  752               addParameter("title", findString(title));
  753           }
  754   
  755   
  756           // see if the value was specified as a parameter already
  757           if (parameters.containsKey("value")) {
  758               parameters.put("nameValue", parameters.get("value"));
  759           } else {
  760               if (evaluateNameValue()) {
  761                   final Class valueClazz = getValueClassType();
  762   
  763                   if (valueClazz != null) {
  764                       if (value != null) {
  765                           addParameter("nameValue", findValue(value, valueClazz));
  766                       } else if (name != null) {
  767                           String expr = completeExpressionIfAltSyntax(name);
  768   
  769                           addParameter("nameValue", findValue(expr, valueClazz));
  770                       }
  771                   } else {
  772                       if (value != null) {
  773                           addParameter("nameValue", findValue(value));
  774                       } else if (name != null) {
  775                           addParameter("nameValue", findValue(name));
  776                       }
  777                   }
  778               }
  779           }
  780   
  781           final Form form = (Form) findAncestor(Form.class);
  782   
  783           // create HTML id element
  784           populateComponentHtmlId(form);
  785   
  786           if (form != null ) {
  787               addParameter("form", form.getParameters());
  788   
  789               if ( name != null ) {
  790                   // list should have been created by the form component
  791                   List tags = (List) form.getParameters().get("tagNames");
  792                   tags.add(name);
  793               }
  794           }
  795   
  796   
  797           // tooltip & tooltipConfig
  798           if (tooltipConfig != null) {
  799               addParameter("tooltipConfig", findValue(tooltipConfig));
  800           }
  801           if (tooltip != null) {
  802               addParameter("tooltip", findString(tooltip));
  803   
  804               Map tooltipConfigMap = getTooltipConfig(this);
  805   
  806               if (form != null) { // inform the containing form that we need tooltip javascript included
  807                   form.addParameter("hasTooltip", Boolean.TRUE);
  808   
  809                   // tooltipConfig defined in component itseilf will take precedence
  810                   // over those defined in the containing form
  811                   Map overallTooltipConfigMap = getTooltipConfig(form);
  812                   overallTooltipConfigMap.putAll(tooltipConfigMap); // override parent form's tooltip config
  813   
  814                   for (Iterator i = overallTooltipConfigMap.entrySet().iterator(); i.hasNext(); ) {
  815                       Map.Entry entry = (Map.Entry) i.next();
  816                       addParameter((String) entry.getKey(), entry.getValue());
  817                   }
  818               }
  819               else {
  820                   LOG.warn("No ancestor Form found, javascript based tooltip will not work, however standard HTML tooltip using alt and title attribute will still work ");
  821               }
  822   
  823               //TODO: this is to keep backward compatibility, remove once when tooltipConfig is dropped
  824               String  jsTooltipEnabled = (String) getParameters().get("jsTooltipEnabled");
  825               if (jsTooltipEnabled != null)
  826                   this.javascriptTooltip = jsTooltipEnabled;
  827   
  828               //TODO: this is to keep backward compatibility, remove once when tooltipConfig is dropped
  829               String tooltipIcon = (String) getParameters().get("tooltipIcon");
  830               if (tooltipIcon != null)
  831                   this.addParameter("tooltipIconPath", tooltipIcon);
  832               if (this.tooltipIconPath != null)
  833                   this.addParameter("tooltipIconPath", findString(this.tooltipIconPath));
  834   
  835               //TODO: this is to keep backward compatibility, remove once when tooltipConfig is dropped
  836               String tooltipDelayParam = (String) getParameters().get("tooltipDelay");
  837               if (tooltipDelayParam != null)
  838                   this.addParameter("tooltipDelay", tooltipDelayParam);
  839               if (this.tooltipDelay != null)
  840                   this.addParameter("tooltipDelay", findString(this.tooltipDelay));
  841   
  842               if (this.javascriptTooltip != null) {
  843                   Boolean jsTooltips = (Boolean) findValue(this.javascriptTooltip, Boolean.class);
  844                   //TODO use a Boolean model when tooltipConfig is dropped
  845                   this.addParameter("jsTooltipEnabled", jsTooltips.toString());
  846   
  847                   if (form != null)
  848                       form.addParameter("hasTooltip", jsTooltips);
  849                   if (this.tooltipCssClass != null)
  850                       this.addParameter("tooltipCssClass", findString(this.tooltipCssClass));
  851               }
  852   
  853   
  854           }
  855   
  856           evaluateExtraParams();
  857       }
  858   
  859   	protected String escape(String name) {
  860           // escape any possible values that can make the ID painful to work with in JavaScript
  861           if (name != null) {
  862               return name.replaceAll("[\\/\\.\\[\\]]", "_");
  863           } else {
  864               return "";
  865           }
  866       }
  867   
  868       /**
  869        * Ensures an unescaped attribute value cannot be vulnerable to XSS attacks
  870        *
  871        * @param val The value to check
  872        * @return The escaped value
  873        */
  874       protected String ensureAttributeSafelyNotEscaped(String val) {
  875           if (val != null) {
  876               return val.replaceAll("\"", "&#34;");
  877           } else {
  878               return "";
  879           }
  880       }
  881   
  882       protected void evaluateExtraParams() {
  883       }
  884   
  885       protected boolean evaluateNameValue() {
  886           return true;
  887       }
  888   
  889       protected Class getValueClassType() {
  890           return String.class;
  891       }
  892   
  893       public void addFormParameter(String key, Object value) {
  894           Form form = (Form) findAncestor(Form.class);
  895           if (form != null) {
  896               form.addParameter(key, value);
  897           }
  898       }
  899   
  900       protected void enableAncestorFormCustomOnsubmit() {
  901           Form form = (Form) findAncestor(Form.class);
  902           if (form != null) {
  903               form.addParameter("customOnsubmitEnabled", Boolean.TRUE);
  904           } else {
  905               LOG.warn("Cannot find an Ancestor form, custom onsubmit is NOT enabled");
  906           }
  907       }
  908   
  909       protected Map getTooltipConfig(UIBean component) {
  910           Object tooltipConfigObj = component.getParameters().get("tooltipConfig");
  911           Map tooltipConfig = new LinkedHashMap();
  912   
  913           if (tooltipConfigObj instanceof Map) {
  914               // we get this if its configured using
  915               // 1] UI component's tooltipConfig attribute  OR
  916               // 2] <param name="tooltip" value="" /> param tag value attribute
  917   
  918               tooltipConfig = new LinkedHashMap((Map)tooltipConfigObj);
  919           } else if (tooltipConfigObj instanceof String) {
  920   
  921               // we get this if its configured using
  922               // <param name="tooltipConfig"> ... </param> tag's body
  923               String tooltipConfigStr = (String) tooltipConfigObj;
  924               String[] tooltipConfigArray = tooltipConfigStr.split("\\|");
  925   
  926               for (int a=0; a<tooltipConfigArray.length; a++) {
  927                   String[] configEntry = ((String)tooltipConfigArray[a].trim()).split("=");
  928                   String key = configEntry[0].trim();
  929                   String value = null;
  930                   if (configEntry.length > 1) {
  931                       value = configEntry[1].trim();
  932                       tooltipConfig.put(key, value);
  933                   }
  934                   else {
  935                       LOG.warn("component "+component+" tooltip config param "+key+" has no value defined, skipped");
  936                   }
  937               }
  938           }
  939           if (component.javascriptTooltip != null)
  940               tooltipConfig.put("jsTooltipEnabled", component.javascriptTooltip);
  941           if (component.tooltipIconPath != null)
  942               tooltipConfig.put("tooltipIcon", component.tooltipIconPath);
  943           if (component.tooltipDelay != null)
  944               tooltipConfig.put("tooltipDelay", component.tooltipDelay);
  945           return tooltipConfig;
  946       }
  947   
  948       /**
  949        * Create HTML id element for the component and populate this component parmaeter
  950        * map. Additionally, a parameter named escapedId is populated which contains the found id value filtered by
  951        * {@link #escape(String)}, needed eg. for naming Javascript identifiers based on the id value.
  952        *
  953        * The order is as follows :-
  954        * <ol>
  955        *   <li>This component id attribute</li>
  956        *   <li>[containing_form_id]_[this_component_name]</li>
  957        *   <li>[this_component_name]</li>
  958        * </ol>
  959        *
  960        * @param form
  961        */
  962       protected void populateComponentHtmlId(Form form) {
  963           String tryId;
  964           if (id != null) {
  965               // this check is needed for backwards compatibility with 2.1.x
  966               tryId = findStringIfAltSyntax(id);
  967           } else if (form != null) {
  968               tryId = form.getParameters().get("id") + "_"
  969                       + escape(name != null ? findString(name) : null);
  970           } else {
  971               tryId = escape(name != null ? findString(name) : null);
  972           }
  973           addParameter("id", tryId);
  974           addParameter("escapedId", escape(tryId));
  975       }
  976   
  977       /**
  978        * Get's the id for referencing element.
  979        * @return the id for referencing element.
  980        */
  981       public String getId() {
  982           return id;
  983       }
  984   
  985       @StrutsTagAttribute(description="HTML id attribute")
  986       public void setId(String id) {
  987           if (id != null) {
  988               this.id = findString(id);
  989           }
  990       }
  991   
  992       @StrutsTagAttribute(description="The template directory.")
  993       public void setTemplateDir(String templateDir) {
  994           this.templateDir = templateDir;
  995       }
  996   
  997       @StrutsTagAttribute(description="The theme (other than default) to use for rendering the element")
  998       public void setTheme(String theme) {
  999           this.theme = theme;
 1000       }
 1001   
 1002       public String getTemplate() {
 1003           return template;
 1004       }
 1005   
 1006       @StrutsTagAttribute(description="The template (other than default) to use for rendering the element")
 1007       public void setTemplate(String template) {
 1008           this.template = template;
 1009       }
 1010   
 1011       @StrutsTagAttribute(description="The css class to use for element")
 1012       public void setCssClass(String cssClass) {
 1013           this.cssClass = cssClass;
 1014       }
 1015   
 1016       @StrutsTagAttribute(description="The css style definitions for element to use")
 1017       public void setCssStyle(String cssStyle) {
 1018           this.cssStyle = cssStyle;
 1019       }
 1020   
 1021       @StrutsTagAttribute(description="The css error class to use for element")
 1022       public void setCssErrorClass(String cssErrorClass) {
 1023           this.cssErrorClass = cssErrorClass;
 1024       }
 1025   
 1026       @StrutsTagAttribute(description="The css error style definitions for element to use")
 1027       public void setCssErrorStyle(String cssErrorStyle) {
 1028           this.cssErrorStyle = cssErrorStyle;
 1029       }
 1030   
 1031       @StrutsTagAttribute(description="Set the html title attribute on rendered html element")
 1032       public void setTitle(String title) {
 1033           this.title = title;
 1034       }
 1035   
 1036       @StrutsTagAttribute(description="Set the html disabled attribute on rendered html element")
 1037       public void setDisabled(String disabled) {
 1038           this.disabled = disabled;
 1039       }
 1040   
 1041       @StrutsTagAttribute(description="Label expression used for rendering an element specific label")
 1042       public void setLabel(String label) {
 1043           this.label = label;
 1044       }
 1045   
 1046       @StrutsTagAttribute(description="String that will be appended to the label", defaultValue=":")
 1047       public void setLabelSeparator(String labelseparator) {
 1048           this.labelSeparator = labelseparator;
 1049       }
 1050   
 1051       @StrutsTagAttribute(description="Define label position of form element (top/left)")
 1052       public void setLabelposition(String labelPosition) {
 1053           this.labelPosition = labelPosition;
 1054       }
 1055   
 1056       @StrutsTagAttribute(description="Define required position of required form element (left|right)")
 1057       public void setRequiredposition(String requiredposition) {
 1058           this.requiredposition = requiredposition;
 1059       }
 1060   
 1061       @StrutsTagAttribute(description="The name to set for element")
 1062       public void setName(String name) {
 1063           this.name = name;
 1064       }
 1065   
 1066       @StrutsTagAttribute(description="If set to true, the rendered element will indicate that input is required", type="Boolean", defaultValue="false")
 1067       public void setRequired(String required) {
 1068           this.required = required;
 1069       }
 1070   
 1071       @StrutsTagAttribute(description="Set the html tabindex attribute on rendered html element")
 1072       public void setTabindex(String tabindex) {
 1073           this.tabindex = tabindex;
 1074       }
 1075   
 1076       @StrutsTagAttribute(description="Preset the value of input element.")
 1077       public void setValue(String value) {
 1078           this.value = value;
 1079       }
 1080   
 1081       @StrutsTagAttribute(description="Set the html onclick attribute on rendered html element")
 1082       public void setOnclick(String onclick) {
 1083           this.onclick = onclick;
 1084       }
 1085   
 1086       @StrutsTagAttribute(description="Set the html ondblclick attribute on rendered html element")
 1087       public void setOndblclick(String ondblclick) {
 1088           this.ondblclick = ondblclick;
 1089       }
 1090   
 1091       @StrutsTagAttribute(description="Set the html onmousedown attribute on rendered html element")
 1092       public void setOnmousedown(String onmousedown) {
 1093           this.onmousedown = onmousedown;
 1094       }
 1095   
 1096       @StrutsTagAttribute(description="Set the html onmouseup attribute on rendered html element")
 1097       public void setOnmouseup(String onmouseup) {
 1098           this.onmouseup = onmouseup;
 1099       }
 1100   
 1101       @StrutsTagAttribute(description="Set the html onmouseover attribute on rendered html element")
 1102       public void setOnmouseover(String onmouseover) {
 1103           this.onmouseover = onmouseover;
 1104       }
 1105   
 1106       @StrutsTagAttribute(description="Set the html onmousemove attribute on rendered html element")
 1107       public void setOnmousemove(String onmousemove) {
 1108           this.onmousemove = onmousemove;
 1109       }
 1110   
 1111       @StrutsTagAttribute(description="Set the html onmouseout attribute on rendered html element")
 1112       public void setOnmouseout(String onmouseout) {
 1113           this.onmouseout = onmouseout;
 1114       }
 1115   
 1116       @StrutsTagAttribute(description="Set the html onfocus attribute on rendered html element")
 1117       public void setOnfocus(String onfocus) {
 1118           this.onfocus = onfocus;
 1119       }
 1120   
 1121       @StrutsTagAttribute(description=" Set the html onblur attribute on rendered html element")
 1122       public void setOnblur(String onblur) {
 1123           this.onblur = onblur;
 1124       }
 1125   
 1126       @StrutsTagAttribute(description="Set the html onkeypress attribute on rendered html element")
 1127       public void setOnkeypress(String onkeypress) {
 1128           this.onkeypress = onkeypress;
 1129       }
 1130   
 1131       @StrutsTagAttribute(description="Set the html onkeydown attribute on rendered html element")
 1132       public void setOnkeydown(String onkeydown) {
 1133           this.onkeydown = onkeydown;
 1134       }
 1135   
 1136       @StrutsTagAttribute(description="Set the html onkeyup attribute on rendered html element")
 1137       public void setOnkeyup(String onkeyup) {
 1138           this.onkeyup = onkeyup;
 1139       }
 1140   
 1141       @StrutsTagAttribute(description="Set the html onselect attribute on rendered html element")
 1142       public void setOnselect(String onselect) {
 1143           this.onselect = onselect;
 1144       }
 1145   
 1146       @StrutsTagAttribute(description="Set the html onchange attribute on rendered html element")
 1147       public void setOnchange(String onchange) {
 1148           this.onchange = onchange;
 1149       }
 1150   
 1151       @StrutsTagAttribute(description="Set the html accesskey attribute on rendered html element")
 1152       public void setAccesskey(String accesskey) {
 1153           this.accesskey = accesskey;
 1154       }
 1155   
 1156       @StrutsTagAttribute(description="Set the tooltip of this particular component")
 1157       public void setTooltip(String tooltip) {
 1158           this.tooltip = tooltip;
 1159       }
 1160   
 1161       @StrutsTagAttribute(description="Deprecated. Use individual tooltip configuration attributes instead.")
 1162       public void setTooltipConfig(String tooltipConfig) {
 1163           this.tooltipConfig = tooltipConfig;
 1164       }
 1165   
 1166       @StrutsTagAttribute(description="Set the key (name, value, label) for this particular component")
 1167       public void setKey(String key) {
 1168           this.key = key;
 1169       }
 1170   
 1171       @StrutsTagAttribute(description="Use JavaScript to generate tooltips", type="Boolean", defaultValue="false")
 1172       public void setJavascriptTooltip(String javascriptTooltip) {
 1173           this.javascriptTooltip = javascriptTooltip;
 1174       }
 1175   
 1176       @StrutsTagAttribute(description="CSS class applied to JavaScrip tooltips", defaultValue="StrutsTTClassic")
 1177       public void setTooltipCssClass(String tooltipCssClass) {
 1178           this.tooltipCssClass = tooltipCssClass;
 1179       }
 1180   
 1181       @StrutsTagAttribute(description="Delay in milliseconds, before showing JavaScript tooltips ",
 1182           defaultValue="Classic")
 1183       public void setTooltipDelay(String tooltipDelay) {
 1184           this.tooltipDelay = tooltipDelay;
 1185       }
 1186   
 1187       @StrutsTagAttribute(description="Icon path used for image that will have the tooltip")
 1188       public void setTooltipIconPath(String tooltipIconPath) {
 1189           this.tooltipIconPath = tooltipIconPath;
 1190       }
 1191   
 1192       public void setDynamicAttributes(Map<String,Object> dynamicAttributes) {
 1193           this.dynamicAttributes = dynamicAttributes;
 1194       }
 1195   }

Save This Page
Home » struts-2.1.8.1-src » org.apache » struts2 » components » [javadoc | source]