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

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