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