View Javadoc

1   /*
2    * $Id: UIBean.java 498091 2007-01-20 08:44:14Z mrdon $
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     protected void evaluateExtraParams() {
794     }
795 
796     protected boolean evaluateNameValue() {
797         return true;
798     }
799 
800     protected Class getValueClassType() {
801         return String.class;
802     }
803 
804     public void addFormParameter(String key, Object value) {
805         Form form = (Form) findAncestor(Form.class);
806         if (form != null) {
807             form.addParameter(key, value);
808         }
809     }
810 
811     protected void enableAncestorFormCustomOnsubmit() {
812         Form form = (Form) findAncestor(Form.class);
813         if (form != null) {
814             form.addParameter("customOnsubmitEnabled", Boolean.TRUE);
815         } else {
816             LOG.warn("Cannot find an Ancestor form, custom onsubmit is NOT enabled");
817         }
818     }
819 
820     protected Map getTooltipConfig(UIBean component) {
821         Object tooltipConfigObj = component.getParameters().get("tooltipConfig");
822         Map tooltipConfig = new LinkedHashMap();
823 
824         if (tooltipConfigObj instanceof Map) {
825             // we get this if its configured using
826             // 1] UI component's tooltipConfig attribute  OR
827             // 2] <param name="tooltip" value="" /> param tag value attribute
828 
829             tooltipConfig = new LinkedHashMap((Map)tooltipConfigObj);
830         } else if (tooltipConfigObj instanceof String) {
831 
832             // we get this if its configured using
833             // <param name="tooltipConfig"> ... </param> tag's body
834             String tooltipConfigStr = (String) tooltipConfigObj;
835             String[] tooltipConfigArray = tooltipConfigStr.split("//|");
836 
837             for (int a=0; a<tooltipConfigArray.length; a++) {
838                 String[] configEntry = ((String)tooltipConfigArray[a].trim()).split("=");
839                 String key = configEntry[0].trim();
840                 String value = null;
841                 if (configEntry.length > 1) {
842                     value = configEntry[1].trim();
843                     tooltipConfig.put(key, value.toString());
844                 }
845                 else {
846                     LOG.warn("component "+component+" tooltip config param "+key+" has no value defined, skipped");
847                 }
848             }
849         }
850         return tooltipConfig;
851     }
852 
853     /***
854      * Create HTML id element for the component and populate this component parmaeter
855      * map.
856      *
857      * The order is as follows :-
858      * <ol>
859      *   <li>This component id attribute</li>
860      *   <li>[containing_form_id]_[this_component_name]</li>
861      *   <li>[this_component_name]</li>
862      * </ol>
863      *
864      * @param form
865      */
866     protected void populateComponentHtmlId(Form form) {
867         if (id != null) {
868             // this check is needed for backwards compatibility with 2.1.x
869             if (altSyntax()) {
870                 addParameter("id", findString(id));
871             } else {
872                 addParameter("id", id);
873             }
874         } else if (form != null) {
875             addParameter("id", form.getParameters().get("id") + "_" 
876                     + escape(name != null ? findString(name) : null));
877         } else {
878             addParameter("id", escape(name != null ? findString(name) : null));
879         }
880     }
881 
882     @StrutsTagAttribute(description="The template directory.")
883     public void setTemplateDir(String templateDir) {
884         this.templateDir = templateDir;
885     }
886 
887     @StrutsTagAttribute(description="The theme (other than default) to use for rendering the element")
888     public void setTheme(String theme) {
889         this.theme = theme;
890     }
891 
892     public String getTemplate() {
893         return template;
894     }
895 
896     @StrutsTagAttribute(description="The template (other than default) to use for rendering the element")
897     public void setTemplate(String template) {
898         this.template = template;
899     }
900 
901     @StrutsTagAttribute(description="The css class to use for element")
902     public void setCssClass(String cssClass) {
903         this.cssClass = cssClass;
904     }
905 
906     @StrutsTagAttribute(description="The css style definitions for element ro use")
907     public void setCssStyle(String cssStyle) {
908         this.cssStyle = cssStyle;
909     }
910 
911     @StrutsTagAttribute(description="Set the html title attribute on rendered html element")
912     public void setTitle(String title) {
913         this.title = title;
914     }
915 
916     @StrutsTagAttribute(description="Set the html disabled attribute on rendered html element")
917     public void setDisabled(String disabled) {
918         this.disabled = disabled;
919     }
920 
921     @StrutsTagAttribute(description="Label expression used for rendering a element specific label")
922     public void setLabel(String label) {
923         this.label = label;
924     }
925 
926     @StrutsTagAttribute(description="Define label position of form element (top/left)")
927     public void setLabelposition(String labelPosition) {
928         this.labelPosition = labelPosition;
929     }
930 
931     @StrutsTagAttribute(description="Define required position of required form element (left|right)")
932     public void setRequiredposition(String requiredposition) {
933         this.requiredposition = requiredposition;
934     }
935 
936     @StrutsTagAttribute(description="The name to set for element")
937     public void setName(String name) {
938         this.name = name;
939     }
940 
941     @StrutsTagAttribute(description="If set to true, the rendered element will indicate that input is required", type="Boolean", defaultValue="false")
942     public void setRequired(String required) {
943         this.required = required;
944     }
945 
946     @StrutsTagAttribute(description="Set the html tabindex attribute on rendered html element")
947     public void setTabindex(String tabindex) {
948         this.tabindex = tabindex;
949     }
950 
951     @StrutsTagAttribute(description="Preset the value of input element.")
952     public void setValue(String value) {
953         this.value = value;
954     }
955 
956     @StrutsTagAttribute(description="Set the html onclick attribute on rendered html element")
957     public void setOnclick(String onclick) {
958         this.onclick = onclick;
959     }
960 
961     @StrutsTagAttribute(description="Set the html ondblclick attribute on rendered html element")
962     public void setOndblclick(String ondblclick) {
963         this.ondblclick = ondblclick;
964     }
965 
966     @StrutsTagAttribute(description="Set the html onmousedown attribute on rendered html element")
967     public void setOnmousedown(String onmousedown) {
968         this.onmousedown = onmousedown;
969     }
970 
971     @StrutsTagAttribute(description="Set the html onmouseup attribute on rendered html element")
972     public void setOnmouseup(String onmouseup) {
973         this.onmouseup = onmouseup;
974     }
975 
976     @StrutsTagAttribute(description="Set the html onmouseover attribute on rendered html element")
977     public void setOnmouseover(String onmouseover) {
978         this.onmouseover = onmouseover;
979     }
980 
981     @StrutsTagAttribute(description="Set the html onmousemove attribute on rendered html element")
982     public void setOnmousemove(String onmousemove) {
983         this.onmousemove = onmousemove;
984     }
985 
986     @StrutsTagAttribute(description="Set the html onmouseout attribute on rendered html element")
987     public void setOnmouseout(String onmouseout) {
988         this.onmouseout = onmouseout;
989     }
990 
991     @StrutsTagAttribute(description="Set the html onfocus attribute on rendered html element")
992     public void setOnfocus(String onfocus) {
993         this.onfocus = onfocus;
994     }
995 
996     @StrutsTagAttribute(description=" Set the html onblur attribute on rendered html element")
997     public void setOnblur(String onblur) {
998         this.onblur = onblur;
999     }
1000 
1001     @StrutsTagAttribute(description="Set the html onkeypress attribute on rendered html element")
1002     public void setOnkeypress(String onkeypress) {
1003         this.onkeypress = onkeypress;
1004     }
1005 
1006     @StrutsTagAttribute(description="Set the html onkeydown attribute on rendered html element")
1007     public void setOnkeydown(String onkeydown) {
1008         this.onkeydown = onkeydown;
1009     }
1010 
1011     @StrutsTagAttribute(description="Set the html onkeyup attribute on rendered html element")
1012     public void setOnkeyup(String onkeyup) {
1013         this.onkeyup = onkeyup;
1014     }
1015 
1016     @StrutsTagAttribute(description="Set the html onselect attribute on rendered html element")
1017     public void setOnselect(String onselect) {
1018         this.onselect = onselect;
1019     }
1020 
1021     @StrutsTagAttribute(description="Set the html onchange attribute on rendered html element")
1022     public void setOnchange(String onchange) {
1023         this.onchange = onchange;
1024     }
1025 
1026     @StrutsTagAttribute(description="Set the html accesskey attribute on rendered html element")
1027     public void setAccesskey(String accesskey) {
1028         this.accesskey = accesskey;
1029     }
1030 
1031     @StrutsTagAttribute(description="Set the tooltip of this particular component")
1032     public void setTooltip(String tooltip) {
1033         this.tooltip = tooltip;
1034     }
1035 
1036     @StrutsTagAttribute(description="Set the tooltip configuration")
1037     public void setTooltipConfig(String tooltipConfig) {
1038         this.tooltipConfig = tooltipConfig;
1039     }
1040 
1041     @StrutsTagAttribute(description="Set the key (name, value, label) for this particular component")
1042     public void setKey(String key) {
1043         this.key = key;
1044     }
1045 }