View Javadoc

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