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