0001: /*
0002: * $Id: UIBean.java 561831 2007-08-01 15:16:04Z jholmes $
0003: *
0004: * Licensed to the Apache Software Foundation (ASF) under one
0005: * or more contributor license agreements. See the NOTICE file
0006: * distributed with this work for additional information
0007: * regarding copyright ownership. The ASF licenses this file
0008: * to you under the Apache License, Version 2.0 (the
0009: * "License"); you may not use this file except in compliance
0010: * with the License. You may obtain a copy of the License at
0011: *
0012: * http://www.apache.org/licenses/LICENSE-2.0
0013: *
0014: * Unless required by applicable law or agreed to in writing,
0015: * software distributed under the License is distributed on an
0016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0017: * KIND, either express or implied. See the License for the
0018: * specific language governing permissions and limitations
0019: * under the License.
0020: */
0021: package org.apache.struts2.components;
0022:
0023: import java.io.Writer;
0024: import java.util.Iterator;
0025: import java.util.LinkedHashMap;
0026: import java.util.List;
0027: import java.util.Map;
0028:
0029: import javax.servlet.http.HttpServletRequest;
0030: import javax.servlet.http.HttpServletResponse;
0031:
0032: import org.apache.commons.logging.Log;
0033: import org.apache.commons.logging.LogFactory;
0034: import org.apache.struts2.views.annotations.StrutsTagAttribute;
0035: import org.apache.struts2.StrutsConstants;
0036: import org.apache.struts2.components.template.Template;
0037: import org.apache.struts2.components.template.TemplateEngine;
0038: import org.apache.struts2.components.template.TemplateEngineManager;
0039: import org.apache.struts2.components.template.TemplateRenderingContext;
0040: import org.apache.struts2.views.util.ContextUtil;
0041:
0042: import com.opensymphony.xwork2.config.ConfigurationException;
0043: import com.opensymphony.xwork2.inject.Inject;
0044: import com.opensymphony.xwork2.util.ValueStack;
0045:
0046: /**
0047: * UIBean is the standard superclass of all Struts UI componentns.
0048: * It defines common Struts and html properties all UI components should present for usage.
0049: *
0050: * <!-- START SNIPPET: templateRelatedAttributes -->
0051: *
0052: * <table border="1">
0053: * <thead>
0054: * <tr>
0055: * <td>Attribute</td>
0056: * <td>Theme</td>
0057: * <td>Data Types</td>
0058: * <td>Description</td>
0059: * </tr>
0060: * </thead>
0061: * <tbody>
0062: * <tr>
0063: * <td>templateDir</td>
0064: * <td>n/a</td>
0065: * <td>String</td>
0066: * <td>define the template directory</td>
0067: * </td>
0068: * <tr>
0069: * <td>theme</td>
0070: * <td>n/a</td>
0071: * <td>String</td>
0072: * <td>define the theme name</td>
0073: * </td>
0074: * <tr>
0075: * <td>template</td>
0076: * <td>n/a</td>
0077: * <td>String</td>
0078: * <td>define the template name</td>
0079: * </td>
0080: * </tbody>
0081: * </table>
0082: *
0083: * <!-- END SNIPPET: templateRelatedAttributes -->
0084: *
0085: * <p/>
0086: *
0087: * <!-- START SNIPPET: generalAttributes -->
0088: *
0089: * <table border="1">
0090: * <thead>
0091: * <tr>
0092: * <td>Attribute</td>
0093: * <td>Theme</td>
0094: * <td>Data Types</td>
0095: * <td>Description</td>
0096: * </tr>
0097: * </thead>
0098: * <tbody>
0099: * <tr>
0100: * <td>cssClass</td>
0101: * <td>simple</td>
0102: * <td>String</td>
0103: * <td>define html class attribute</td>
0104: * </tr>
0105: * <tr>
0106: * <td>cssStyle</td>
0107: * <td>simple</td>
0108: * <td>String</td>
0109: * <td>define html style attribute</td>
0110: * </tr>
0111: * <tr>
0112: * <td>title</td>
0113: * <td>simple</td>
0114: * <td>String</td>
0115: * <td>define html title attribute</td>
0116: * </tr>
0117: * <tr>
0118: * <td>disabled</td>
0119: * <td>simple</td>
0120: * <td>String</td>
0121: * <td>define html disabled attribute</td>
0122: * </tr>
0123: * <tr>
0124: * <td>label</td>
0125: * <td>xhtml</td>
0126: * <td>String</td>
0127: * <td>define label of form element</td>
0128: * </tr>
0129: * <tr>
0130: * <td>labelPosition</td>
0131: * <td>xhtml</td>
0132: * <td>String</td>
0133: * <td>define label position of form element (top/left), default to left</td>
0134: * </tr>
0135: * <tr>
0136: * <td>requiredposition</td>
0137: * <td>xhtml</td>
0138: * <td>String</td>
0139: * <td>define required label position of form element (left/right), default to right</td>
0140: * </tr>
0141: * <tr>
0142: * <td>name</td>
0143: * <td>simple</td>
0144: * <td>String</td>
0145: * <td>Form Element's field name mapping</td>
0146: * </tr>
0147: * <tr>
0148: * <td>required</td>
0149: * <td>xhtml</td>
0150: * <td>Boolean</td>
0151: * <td>add * to label (true to add false otherwise)</td>
0152: * </tr>
0153: * <tr>
0154: * <td>tabIndex</td>
0155: * <td>simple</td>
0156: * <td>String</td>
0157: * <td>define html tabindex attribute</td>
0158: * </tr>
0159: * <tr>
0160: * <td>value</td>
0161: * <td>simple</td>
0162: * <td>Object</td>
0163: * <td>define value of form element</td>
0164: * </tr>
0165: * </tbody>
0166: * </table>
0167: *
0168: * <!-- END SNIPPET: generalAttributes -->
0169: *
0170: * <p/>
0171: *
0172: * <!-- START SNIPPET: javascriptRelatedAttributes -->
0173: *
0174: * <table border="1">
0175: * <thead>
0176: * <tr>
0177: * <td>Attribute</td>
0178: * <td>Theme</td>
0179: * <td>Data Types</td>
0180: * <td>Description</td>
0181: * </tr>
0182: * </thead>
0183: * <tbody>
0184: * <tr>
0185: * <td>onclick</td>
0186: * <td>simple</td>
0187: * <td>String</td>
0188: * <td>html javascript onclick attribute</td>
0189: * </tr>
0190: * <tr>
0191: * <td>ondbclick</td>
0192: * <td>simple</td>
0193: * <td>String</td>
0194: * <td>html javascript ondbclick attribute</td>
0195: * </tr>
0196: * <tr>
0197: * <td>onmousedown</td>
0198: * <td>simple</td>
0199: * <td>String</td>
0200: * <td>html javascript onmousedown attribute</td>
0201: * </tr>
0202: * <tr>
0203: * <td>onmouseup</td>
0204: * <td>simple</td>
0205: * <td>String</td>
0206: * <td>html javascript onmouseup attribute</td>
0207: * </tr>
0208: * <tr>
0209: * <td>onmouseover</td>
0210: * <td>simple</td>
0211: * <td>String</td>
0212: * <td>html javascript onmouseover attribute</td>
0213: * </tr>
0214: * <tr>
0215: * <td>onmouseout</td>
0216: * <td>simple</td>
0217: * <td>String</td>
0218: * <td>html javascript onmouseout attribute</td>
0219: * </tr>
0220: * <tr>
0221: * <td>onfocus</td>
0222: * <td>simple</td>
0223: * <td>String</td>
0224: * <td>html javascript onfocus attribute</td>
0225: * </tr>
0226: * <tr>
0227: * <td>onblur</td>
0228: * <td>simple</td>
0229: * <td>String</td>
0230: * <td>html javascript onblur attribute</td>
0231: * </tr>
0232: * <tr>
0233: * <td>onkeypress</td>
0234: * <td>simple</td>
0235: * <td>String</td>
0236: * <td>html javascript onkeypress attribute</td>
0237: * </tr>
0238: * <tr>
0239: * <td>onkeyup</td>
0240: * <td>simple</td>
0241: * <td>String</td>
0242: * <td>html javascript onkeyup attribute</td>
0243: * </tr>
0244: * <tr>
0245: * <td>onkeydown</td>
0246: * <td>simple</td>
0247: * <td>String</td>
0248: * <td>html javascript onkeydown attribute</td>
0249: * </tr>
0250: * <tr>
0251: * <td>onselect</td>
0252: * <td>simple</td>
0253: * <td>String</td>
0254: * <td>html javascript onselect attribute</td>
0255: * </tr>
0256: * <tr>
0257: * <td>onchange</td>
0258: * <td>simple</td>
0259: * <td>String</td>
0260: * <td>html javascript onchange attribute</td>
0261: * </tr>
0262: * </tbody>
0263: * </table>
0264: *
0265: * <!-- END SNIPPET: javascriptRelatedAttributes -->
0266: *
0267: * <p/>
0268: *
0269: * <!-- START SNIPPET: tooltipattributes -->
0270: *
0271: * <table border="1">
0272: * <tr>
0273: * <td>Attribute</td>
0274: * <td>Data Type</td>
0275: * <td>Default</td>
0276: * <td>Description</td>
0277: * </tr>
0278: * <tr>
0279: * <td>tooltip</td>
0280: * <td>String</td>
0281: * <td>none</td>
0282: * <td>Set the tooltip of this particular component</td>
0283: * </tr>
0284: * <tr>
0285: * <td>jsTooltipEnabled</td>
0286: * <td>String</td>
0287: * <td>false</td>
0288: * <td>Enable js tooltip rendering</td>
0289: * </tr>
0290: * <tr>
0291: * <td>tooltipIcon</td>
0292: * <td>String</td>
0293: * <td>/struts/static/tooltip/tooltip.gif</td>
0294: * <td>The url to the tooltip icon</td>
0295: * <tr>
0296: * <td>tooltipDelay</td>
0297: * <td>String</td>
0298: * <td>500</td>
0299: * <td>Tooltip shows up after the specified timeout (miliseconds). A behavior similar to that of OS based tooltips.</td>
0300: * </tr>
0301: * <tr>
0302: * <td>key</td>
0303: * <td>simple</td>
0304: * <td>String</td>
0305: * <td>The name of the property this input field represents. This will auto populate the name, label, and value</td>
0306: * </tr>
0307: * </table>
0308: *
0309: * <!-- END SNIPPET: tooltipattributes -->
0310: *
0311: *
0312: * <!-- START SNIPPET: tooltipdescription -->
0313: *
0314: * Every Form UI component (in xhtml / css_xhtml or any others that extends of them) could
0315: * have tooltip assigned to a them. The Form component's tooltip related attribute once
0316: * defined will be applicable to all form UI component that is created under it unless
0317: * explicitly overriden by having the Form UI component itself defined that tooltip attribute.
0318: *
0319: * <p/>
0320: *
0321: * In Example 1, the textfield will inherit the tooltipDelay adn tooltipIcon attribte from
0322: * its containing form. In other words, although it doesn't defined a tooltipAboveMousePointer
0323: * attribute, it will have that attributes inherited from its containing form.
0324: *
0325: * <p/>
0326: *
0327: * In Example 2, the the textfield will inherite both the tooltipDelay and
0328: * tooltipIcon attribute from its containing form but tooltipDelay
0329: * attribute is overriden at the textfield itself. Hence, the textfield actually will
0330: * have tooltipIcon defined as /myImages/myIcon.gif, inherited from its containing form and
0331: * tooltipDelay defined as 5000, due to overriden at the textfield itself.
0332: *
0333: * <p/>
0334: *
0335: * Example 3, 4 and 5 shows different way of setting the tooltipConfig attribute.<br/>
0336: * <b>Example 3:</b>Set tooltip config through body of param tag<br/>
0337: * <b>Example 4:</b>Set tooltip config through value attribute of param tag<br/>
0338: * <b>Example 5:</b>Set tooltip config through tooltipConfig attribute of component tag<br/>
0339: *
0340: * <!-- END SNIPPET: tooltipdescription -->
0341: *
0342: *
0343: * <pre>
0344: * <!-- START SNIPPET: tooltipexample -->
0345: *
0346: * <!-- Example 1: -->
0347: * <s:form
0348: * tooltipConfig="#{'tooltipDelay':'500',
0349: * 'tooltipIcon='/myImages/myIcon.gif'}" .... >
0350: * ....
0351: * <s:textfield label="Customer Name" tooltip="Enter the customer name" .... />
0352: * ....
0353: * </s:form>
0354: *
0355: * <!-- Example 2: -->
0356: * <s:form
0357: * tooltipConfig="#{'tooltipDelay':'500',
0358: * 'tooltipIcon':'/myImages/myIcon.gif'}" ... >
0359: * ....
0360: * <s:textfield label="Address"
0361: * tooltip="Enter your address"
0362: * tooltipConfig="#{'tooltipDelay':'5000'}" />
0363: * ....
0364: * </s:form>
0365: *
0366: *
0367: * <-- Example 3: -->
0368: * <s:textfield
0369: * label="Customer Name"
0370: * tooltip="One of our customer Details'">
0371: * <s:param name="tooltipConfig">
0372: * tooltipDelay = 500 |
0373: * tooltipIcon = /myImages/myIcon.gif
0374: * </s:param>
0375: * </s:textfield>
0376: *
0377: *
0378: * <-- Example 4: -->
0379: * <s:textfield
0380: * label="Customer Address"
0381: * tooltip="Enter The Customer Address" >
0382: * <s:param
0383: * name="tooltipConfig"
0384: * value="#{'tooltipDelay':'500',
0385: * 'tooltipIcon':'/myImages/myIcon.gif'}" />
0386: * </s:textfield>
0387: *
0388: *
0389: * <-- Example 5: -->
0390: * <s:textfield
0391: * label="Customer Telephone Number"
0392: * tooltip="Enter customer Telephone Number"
0393: * tooltipConfig="#{'tooltipDelay':'500',
0394: * 'tooltipIcon':'/myImages/myIcon.gif'}" />
0395: *
0396: * <!-- END SNIPPET: tooltipexample -->
0397: * </pre>
0398: *
0399: */
0400: public abstract class UIBean extends Component {
0401: private static final Log LOG = LogFactory.getLog(UIBean.class);
0402:
0403: protected HttpServletRequest request;
0404: protected HttpServletResponse response;
0405:
0406: public UIBean(ValueStack stack, HttpServletRequest request,
0407: HttpServletResponse response) {
0408: super (stack);
0409: this .request = request;
0410: this .response = response;
0411: this .templateSuffix = ContextUtil.getTemplateSuffix(stack
0412: .getContext());
0413: }
0414:
0415: // The templateSuffic to use, overrides the default one if not null.
0416: protected String templateSuffix;
0417:
0418: // The template to use, overrides the default one.
0419: protected String template;
0420:
0421: // templateDir and theme attributes
0422: protected String templateDir;
0423: protected String theme;
0424:
0425: // shortcut, sets label, name, and value
0426: protected String key;
0427:
0428: protected String cssClass;
0429: protected String cssStyle;
0430: protected String disabled;
0431: protected String label;
0432: protected String labelPosition;
0433: protected String requiredposition;
0434: protected String name;
0435: protected String required;
0436: protected String tabindex;
0437: protected String value;
0438: protected String title;
0439:
0440: // HTML scripting events attributes
0441: protected String onclick;
0442: protected String ondblclick;
0443: protected String onmousedown;
0444: protected String onmouseup;
0445: protected String onmouseover;
0446: protected String onmousemove;
0447: protected String onmouseout;
0448: protected String onfocus;
0449: protected String onblur;
0450: protected String onkeypress;
0451: protected String onkeydown;
0452: protected String onkeyup;
0453: protected String onselect;
0454: protected String onchange;
0455:
0456: // common html attributes
0457: protected String accesskey;
0458:
0459: // javascript tooltip attribute
0460: protected String tooltip;
0461: protected String tooltipConfig;
0462:
0463: protected String defaultTemplateDir;
0464: protected String defaultUITheme;
0465: protected TemplateEngineManager templateEngineManager;
0466:
0467: @Inject(StrutsConstants.STRUTS_UI_TEMPLATEDIR)
0468: public void setDefaultTemplateDir(String dir) {
0469: this .defaultTemplateDir = dir;
0470: }
0471:
0472: @Inject(StrutsConstants.STRUTS_UI_THEME)
0473: public void setDefaultUITheme(String theme) {
0474: this .defaultUITheme = theme;
0475: }
0476:
0477: @Inject
0478: public void setTemplateEngineManager(TemplateEngineManager mgr) {
0479: this .templateEngineManager = mgr;
0480: }
0481:
0482: public boolean end(Writer writer, String body) {
0483: evaluateParams();
0484: try {
0485: super .end(writer, body, false);
0486: mergeTemplate(writer, buildTemplateName(template,
0487: getDefaultTemplate()));
0488: } catch (Exception e) {
0489: LOG.error("error when rendering", e);
0490: } finally {
0491: popComponentStack();
0492: }
0493:
0494: return false;
0495: }
0496:
0497: /**
0498: * A contract that requires each concrete UI Tag to specify which template should be used as a default. For
0499: * example, the CheckboxTab might return "checkbox.vm" while the RadioTag might return "radio.vm". This value
0500: * <strong>not</strong> begin with a '/' unless you intend to make the path absolute rather than relative to the
0501: * current theme.
0502: *
0503: * @return The name of the template to be used as the default.
0504: */
0505: protected abstract String getDefaultTemplate();
0506:
0507: protected Template buildTemplateName(String myTemplate,
0508: String myDefaultTemplate) {
0509: String template = myDefaultTemplate;
0510:
0511: if (myTemplate != null) {
0512: template = findString(myTemplate);
0513: }
0514:
0515: String templateDir = getTemplateDir();
0516: String theme = getTheme();
0517:
0518: return new Template(templateDir, theme, template);
0519:
0520: }
0521:
0522: protected void mergeTemplate(Writer writer, Template template)
0523: throws Exception {
0524: final TemplateEngine engine = templateEngineManager
0525: .getTemplateEngine(template, templateSuffix);
0526: if (engine == null) {
0527: throw new ConfigurationException(
0528: "Unable to find a TemplateEngine for template "
0529: + template);
0530: }
0531:
0532: if (LOG.isDebugEnabled()) {
0533: LOG.debug("Rendering template " + template);
0534: }
0535:
0536: final TemplateRenderingContext context = new TemplateRenderingContext(
0537: template, writer, getStack(), getParameters(), this );
0538: engine.renderTemplate(context);
0539: }
0540:
0541: public String getTemplateDir() {
0542: String templateDir = null;
0543:
0544: if (this .templateDir != null) {
0545: templateDir = findString(this .templateDir);
0546: }
0547:
0548: // If templateDir is not explicitly given,
0549: // try to find attribute which states the dir set to use
0550: if ((templateDir == null) || (templateDir.equals(""))) {
0551: templateDir = (String) stack.findValue("#attr.templateDir");
0552: }
0553:
0554: // Default template set
0555: if ((templateDir == null) || (templateDir.equals(""))) {
0556: templateDir = defaultTemplateDir;
0557: }
0558:
0559: // Defaults to 'template'
0560: if ((templateDir == null) || (templateDir.equals(""))) {
0561: templateDir = "template";
0562: }
0563:
0564: return templateDir;
0565: }
0566:
0567: public String getTheme() {
0568: String theme = null;
0569:
0570: if (this .theme != null) {
0571: theme = findString(this .theme);
0572: }
0573:
0574: if (theme == null || theme.equals("")) {
0575: Form form = (Form) findAncestor(Form.class);
0576: if (form != null) {
0577: theme = form.getTheme();
0578: }
0579: }
0580:
0581: // If theme set is not explicitly given,
0582: // try to find attribute which states the theme set to use
0583: if ((theme == null) || (theme.equals(""))) {
0584: theme = (String) stack.findValue("#attr.theme");
0585: }
0586:
0587: // Default theme set
0588: if ((theme == null) || (theme.equals(""))) {
0589: theme = defaultUITheme;
0590: }
0591:
0592: return theme;
0593: }
0594:
0595: public void evaluateParams() {
0596: addParameter("templateDir", getTemplateDir());
0597: addParameter("theme", getTheme());
0598:
0599: String name = null;
0600:
0601: if (this .key != null) {
0602:
0603: if (this .name == null) {
0604: this .name = key;
0605: }
0606:
0607: if (this .label == null) {
0608: this .label = "%{getText('" + key + "')}";
0609: }
0610:
0611: }
0612:
0613: if (this .name != null) {
0614: name = findString(this .name);
0615: addParameter("name", name);
0616: }
0617:
0618: if (label != null) {
0619: addParameter("label", findString(label));
0620: }
0621:
0622: if (labelPosition != null) {
0623: addParameter("labelposition", findString(labelPosition));
0624: }
0625:
0626: if (requiredposition != null) {
0627: addParameter("requiredposition",
0628: findString(requiredposition));
0629: }
0630:
0631: if (required != null) {
0632: addParameter("required", findValue(required, Boolean.class));
0633: }
0634:
0635: if (disabled != null) {
0636: addParameter("disabled", findValue(disabled, Boolean.class));
0637: }
0638:
0639: if (tabindex != null) {
0640: addParameter("tabindex", findString(tabindex));
0641: }
0642:
0643: if (onclick != null) {
0644: addParameter("onclick", findString(onclick));
0645: }
0646:
0647: if (ondblclick != null) {
0648: addParameter("ondblclick", findString(ondblclick));
0649: }
0650:
0651: if (onmousedown != null) {
0652: addParameter("onmousedown", findString(onmousedown));
0653: }
0654:
0655: if (onmouseup != null) {
0656: addParameter("onmouseup", findString(onmouseup));
0657: }
0658:
0659: if (onmouseover != null) {
0660: addParameter("onmouseover", findString(onmouseover));
0661: }
0662:
0663: if (onmousemove != null) {
0664: addParameter("onmousemove", findString(onmousemove));
0665: }
0666:
0667: if (onmouseout != null) {
0668: addParameter("onmouseout", findString(onmouseout));
0669: }
0670:
0671: if (onfocus != null) {
0672: addParameter("onfocus", findString(onfocus));
0673: }
0674:
0675: if (onblur != null) {
0676: addParameter("onblur", findString(onblur));
0677: }
0678:
0679: if (onkeypress != null) {
0680: addParameter("onkeypress", findString(onkeypress));
0681: }
0682:
0683: if (onkeydown != null) {
0684: addParameter("onkeydown", findString(onkeydown));
0685: }
0686:
0687: if (onkeyup != null) {
0688: addParameter("onkeyup", findString(onkeyup));
0689: }
0690:
0691: if (onselect != null) {
0692: addParameter("onselect", findString(onselect));
0693: }
0694:
0695: if (onchange != null) {
0696: addParameter("onchange", findString(onchange));
0697: }
0698:
0699: if (accesskey != null) {
0700: addParameter("accesskey", findString(accesskey));
0701: }
0702:
0703: if (cssClass != null) {
0704: addParameter("cssClass", findString(cssClass));
0705: }
0706:
0707: if (cssStyle != null) {
0708: addParameter("cssStyle", findString(cssStyle));
0709: }
0710:
0711: if (title != null) {
0712: addParameter("title", findString(title));
0713: }
0714:
0715: // see if the value was specified as a parameter already
0716: if (parameters.containsKey("value")) {
0717: parameters.put("nameValue", parameters.get("value"));
0718: } else {
0719: if (evaluateNameValue()) {
0720: final Class valueClazz = getValueClassType();
0721:
0722: if (valueClazz != null) {
0723: if (value != null) {
0724: addParameter("nameValue", findValue(value,
0725: valueClazz));
0726: } else if (name != null) {
0727: String expr = name;
0728: if (altSyntax()) {
0729: expr = "%{" + expr + "}";
0730: }
0731:
0732: addParameter("nameValue", findValue(expr,
0733: valueClazz));
0734: }
0735: } else {
0736: if (value != null) {
0737: addParameter("nameValue", findValue(value));
0738: } else if (name != null) {
0739: addParameter("nameValue", findValue(name));
0740: }
0741: }
0742: }
0743: }
0744:
0745: final Form form = (Form) findAncestor(Form.class);
0746:
0747: // create HTML id element
0748: populateComponentHtmlId(form);
0749:
0750: if (form != null) {
0751: addParameter("form", form.getParameters());
0752:
0753: if (name != null) {
0754: // list should have been created by the form component
0755: List tags = (List) form.getParameters().get("tagNames");
0756: tags.add(name);
0757: }
0758: }
0759:
0760: // tooltip & tooltipConfig
0761: if (tooltipConfig != null) {
0762: addParameter("tooltipConfig", findValue(tooltipConfig));
0763: }
0764: if (tooltip != null) {
0765: addParameter("tooltip", findString(tooltip));
0766:
0767: Map tooltipConfigMap = getTooltipConfig(this );
0768:
0769: if (form != null) { // inform the containing form that we need tooltip javascript included
0770: form.addParameter("hasTooltip", Boolean.TRUE);
0771:
0772: // tooltipConfig defined in component itseilf will take precedence
0773: // over those defined in the containing form
0774: Map overallTooltipConfigMap = getTooltipConfig(form);
0775: overallTooltipConfigMap.putAll(tooltipConfigMap); // override parent form's tooltip config
0776:
0777: for (Iterator i = overallTooltipConfigMap.entrySet()
0778: .iterator(); i.hasNext();) {
0779: Map.Entry entry = (Map.Entry) i.next();
0780: addParameter((String) entry.getKey(), entry
0781: .getValue());
0782: }
0783: } else {
0784: LOG
0785: .warn("No ancestor Form found, javascript based tooltip will not work, however standard HTML tooltip using alt and title attribute will still work ");
0786: }
0787: }
0788: evaluateExtraParams();
0789:
0790: }
0791:
0792: protected String escape(String name) {
0793: // escape any possible values that can make the ID painful to work with in JavaScript
0794: if (name != null) {
0795: return name.replaceAll("[\\.\\[\\]]", "_");
0796: } else {
0797: return "";
0798: }
0799: }
0800:
0801: protected void evaluateExtraParams() {
0802: }
0803:
0804: protected boolean evaluateNameValue() {
0805: return true;
0806: }
0807:
0808: protected Class getValueClassType() {
0809: return String.class;
0810: }
0811:
0812: public void addFormParameter(String key, Object value) {
0813: Form form = (Form) findAncestor(Form.class);
0814: if (form != null) {
0815: form.addParameter(key, value);
0816: }
0817: }
0818:
0819: protected void enableAncestorFormCustomOnsubmit() {
0820: Form form = (Form) findAncestor(Form.class);
0821: if (form != null) {
0822: form.addParameter("customOnsubmitEnabled", Boolean.TRUE);
0823: } else {
0824: LOG
0825: .warn("Cannot find an Ancestor form, custom onsubmit is NOT enabled");
0826: }
0827: }
0828:
0829: protected Map getTooltipConfig(UIBean component) {
0830: Object tooltipConfigObj = component.getParameters().get(
0831: "tooltipConfig");
0832: Map tooltipConfig = new LinkedHashMap();
0833:
0834: if (tooltipConfigObj instanceof Map) {
0835: // we get this if its configured using
0836: // 1] UI component's tooltipConfig attribute OR
0837: // 2] <param name="tooltip" value="" /> param tag value attribute
0838:
0839: tooltipConfig = new LinkedHashMap((Map) tooltipConfigObj);
0840: } else if (tooltipConfigObj instanceof String) {
0841:
0842: // we get this if its configured using
0843: // <param name="tooltipConfig"> ... </param> tag's body
0844: String tooltipConfigStr = (String) tooltipConfigObj;
0845: String[] tooltipConfigArray = tooltipConfigStr.split("\\|");
0846:
0847: for (int a = 0; a < tooltipConfigArray.length; a++) {
0848: String[] configEntry = ((String) tooltipConfigArray[a]
0849: .trim()).split("=");
0850: String key = configEntry[0].trim();
0851: String value = null;
0852: if (configEntry.length > 1) {
0853: value = configEntry[1].trim();
0854: tooltipConfig.put(key, value.toString());
0855: } else {
0856: LOG.warn("component " + component
0857: + " tooltip config param " + key
0858: + " has no value defined, skipped");
0859: }
0860: }
0861: }
0862: return tooltipConfig;
0863: }
0864:
0865: /**
0866: * Create HTML id element for the component and populate this component parmaeter
0867: * map. Additionally, a parameter named escapedId is populated which contains the found id value filtered by
0868: * {@link #escape(String)}, needed eg. for naming Javascript identifiers based on the id value.
0869: *
0870: * The order is as follows :-
0871: * <ol>
0872: * <li>This component id attribute</li>
0873: * <li>[containing_form_id]_[this_component_name]</li>
0874: * <li>[this_component_name]</li>
0875: * </ol>
0876: *
0877: * @param form
0878: */
0879: protected void populateComponentHtmlId(Form form) {
0880: String tryId;
0881: if (id != null) {
0882: // this check is needed for backwards compatibility with 2.1.x
0883: if (altSyntax()) {
0884: tryId = findString(id);
0885: } else {
0886: tryId = id;
0887: }
0888: } else if (form != null) {
0889: tryId = form.getParameters().get("id") + "_"
0890: + escape(name != null ? findString(name) : null);
0891: } else {
0892: tryId = escape(name != null ? findString(name) : null);
0893: }
0894: addParameter("id", tryId);
0895: addParameter("escapedId", escape(tryId));
0896: }
0897:
0898: @StrutsTagAttribute(description="The template directory.")
0899: public void setTemplateDir(String templateDir) {
0900: this .templateDir = templateDir;
0901: }
0902:
0903: @StrutsTagAttribute(description="The theme (other than default) to use for rendering the element")
0904: public void setTheme(String theme) {
0905: this .theme = theme;
0906: }
0907:
0908: public String getTemplate() {
0909: return template;
0910: }
0911:
0912: @StrutsTagAttribute(description="The template (other than default) to use for rendering the element")
0913: public void setTemplate(String template) {
0914: this .template = template;
0915: }
0916:
0917: @StrutsTagAttribute(description="The css class to use for element")
0918: public void setCssClass(String cssClass) {
0919: this .cssClass = cssClass;
0920: }
0921:
0922: @StrutsTagAttribute(description="The css style definitions for element to use")
0923: public void setCssStyle(String cssStyle) {
0924: this .cssStyle = cssStyle;
0925: }
0926:
0927: @StrutsTagAttribute(description="Set the html title attribute on rendered html element")
0928: public void setTitle(String title) {
0929: this .title = title;
0930: }
0931:
0932: @StrutsTagAttribute(description="Set the html disabled attribute on rendered html element")
0933: public void setDisabled(String disabled) {
0934: this .disabled = disabled;
0935: }
0936:
0937: @StrutsTagAttribute(description="Label expression used for rendering a element specific label")
0938: public void setLabel(String label) {
0939: this .label = label;
0940: }
0941:
0942: @StrutsTagAttribute(description="Define label position of form element (top/left)")
0943: public void setLabelposition(String labelPosition) {
0944: this .labelPosition = labelPosition;
0945: }
0946:
0947: @StrutsTagAttribute(description="Define required position of required form element (left|right)")
0948: public void setRequiredposition(String requiredposition) {
0949: this .requiredposition = requiredposition;
0950: }
0951:
0952: @StrutsTagAttribute(description="The name to set for element")
0953: public void setName(String name) {
0954: this .name = name;
0955: }
0956:
0957: @StrutsTagAttribute(description="If set to true, the rendered element will indicate that input is required",type="Boolean",defaultValue="false")
0958: public void setRequired(String required) {
0959: this .required = required;
0960: }
0961:
0962: @StrutsTagAttribute(description="Set the html tabindex attribute on rendered html element")
0963: public void setTabindex(String tabindex) {
0964: this .tabindex = tabindex;
0965: }
0966:
0967: @StrutsTagAttribute(description="Preset the value of input element.")
0968: public void setValue(String value) {
0969: this .value = value;
0970: }
0971:
0972: @StrutsTagAttribute(description="Set the html onclick attribute on rendered html element")
0973: public void setOnclick(String onclick) {
0974: this .onclick = onclick;
0975: }
0976:
0977: @StrutsTagAttribute(description="Set the html ondblclick attribute on rendered html element")
0978: public void setOndblclick(String ondblclick) {
0979: this .ondblclick = ondblclick;
0980: }
0981:
0982: @StrutsTagAttribute(description="Set the html onmousedown attribute on rendered html element")
0983: public void setOnmousedown(String onmousedown) {
0984: this .onmousedown = onmousedown;
0985: }
0986:
0987: @StrutsTagAttribute(description="Set the html onmouseup attribute on rendered html element")
0988: public void setOnmouseup(String onmouseup) {
0989: this .onmouseup = onmouseup;
0990: }
0991:
0992: @StrutsTagAttribute(description="Set the html onmouseover attribute on rendered html element")
0993: public void setOnmouseover(String onmouseover) {
0994: this .onmouseover = onmouseover;
0995: }
0996:
0997: @StrutsTagAttribute(description="Set the html onmousemove attribute on rendered html element")
0998: public void setOnmousemove(String onmousemove) {
0999: this .onmousemove = onmousemove;
1000: }
1001:
1002: @StrutsTagAttribute(description="Set the html onmouseout attribute on rendered html element")
1003: public void setOnmouseout(String onmouseout) {
1004: this .onmouseout = onmouseout;
1005: }
1006:
1007: @StrutsTagAttribute(description="Set the html onfocus attribute on rendered html element")
1008: public void setOnfocus(String onfocus) {
1009: this .onfocus = onfocus;
1010: }
1011:
1012: @StrutsTagAttribute(description=" Set the html onblur attribute on rendered html element")
1013: public void setOnblur(String onblur) {
1014: this .onblur = onblur;
1015: }
1016:
1017: @StrutsTagAttribute(description="Set the html onkeypress attribute on rendered html element")
1018: public void setOnkeypress(String onkeypress) {
1019: this .onkeypress = onkeypress;
1020: }
1021:
1022: @StrutsTagAttribute(description="Set the html onkeydown attribute on rendered html element")
1023: public void setOnkeydown(String onkeydown) {
1024: this .onkeydown = onkeydown;
1025: }
1026:
1027: @StrutsTagAttribute(description="Set the html onkeyup attribute on rendered html element")
1028: public void setOnkeyup(String onkeyup) {
1029: this .onkeyup = onkeyup;
1030: }
1031:
1032: @StrutsTagAttribute(description="Set the html onselect attribute on rendered html element")
1033: public void setOnselect(String onselect) {
1034: this .onselect = onselect;
1035: }
1036:
1037: @StrutsTagAttribute(description="Set the html onchange attribute on rendered html element")
1038: public void setOnchange(String onchange) {
1039: this .onchange = onchange;
1040: }
1041:
1042: @StrutsTagAttribute(description="Set the html accesskey attribute on rendered html element")
1043: public void setAccesskey(String accesskey) {
1044: this .accesskey = accesskey;
1045: }
1046:
1047: @StrutsTagAttribute(description="Set the tooltip of this particular component")
1048: public void setTooltip(String tooltip) {
1049: this .tooltip = tooltip;
1050: }
1051:
1052: @StrutsTagAttribute(description="Set the tooltip configuration")
1053: public void setTooltipConfig(String tooltipConfig) {
1054: this .tooltipConfig = tooltipConfig;
1055: }
1056:
1057: @StrutsTagAttribute(description="Set the key (name, value, label) for this particular component")
1058: public void setKey(String key) {
1059: this.key = key;
1060: }
1061: }
|