/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.struts2.components;

import com.opensymphony.xwork2.config.ConfigurationException;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.ValueStack;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.struts2.StrutsConstants;
import org.apache.struts2.StrutsException;
import org.apache.struts2.components.template.Template;
import org.apache.struts2.components.template.TemplateEngine;
import org.apache.struts2.components.template.TemplateEngineManager;
import org.apache.struts2.components.template.TemplateRenderingContext;
import org.apache.struts2.dispatcher.StaticContentLoader;
import org.apache.struts2.util.TextProviderHelper;
import org.apache.struts2.views.annotations.StrutsTagAttribute;
import org.apache.struts2.views.util.ContextUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Writer;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * UIBean is the standard superclass of all Struts UI components.
 * It defines common Struts and html properties all UI components should present for usage.
 * </p>
 * <!-- START SNIPPET: templateRelatedAttributes -->
 *
 * <table border="1" summary="">
 *    <thead>
 *       <tr>
 *          <td>Attribute</td>
 *          <td>Theme</td>
 *          <td>Data Types</td>
 *          <td>Description</td>
 *       </tr>
 *    </thead>
 *    <tbody>
 *       <tr>
 *          <td>templateDir</td>
 *          <td>n/a</td>
 *          <td>String</td>
 *          <td>define the template directory</td>
 *       </tr>
 *       <tr>
 *          <td>theme</td>
 *          <td>n/a</td>
 *          <td>String</td>
 *          <td>define the theme name</td>
 *       </tr>
 *       <tr>
 *          <td>template</td>
 *          <td>n/a</td>
 *          <td>String</td>
 *          <td>define the template name</td>
 *       </tr>
 *       <tr>
 *          <td>themeExpansionToken</td>
 *          <td>n/a</td>
 *          <td>String</td>
 *          <td>special token (defined with struts.ui.theme.expansion.token) used to search for template in parent theme
 *          (don't use it separately!)</td>
 *       </tr>
 *       <tr>
 *          <td>expandTheme</td>
 *          <td>n/a</td>
 *          <td>String</td>
 *          <td>concatenation of themeExpansionToken and theme which tells internal template loader mechanism
 *          to try load template from current theme and then from parent theme (and parent theme, and so on)
 *          when used with &lt;#include/&gt; directive</td>
 *       </tr>
 *    </tbody>
 * </table>
 *
 * <!-- END SNIPPET: templateRelatedAttributes -->
 *
 * <!-- START SNIPPET: generalAttributes -->
 *
 * <table border="1" summary="">
 *    <thead>
 *       <tr>
 *          <td>Attribute</td>
 *          <td>Theme</td>
 *          <td>Data Types</td>
 *          <td>Description</td>
 *       </tr>
 *    </thead>
 *    <tbody>
 *       <tr>
 *          <td>cssClass</td>
 *          <td>simple</td>
 *          <td>String</td>
 *          <td>define html class attribute</td>
 *       </tr>
 *       <tr>
 *          <td>cssStyle</td>
 *          <td>simple</td>
 *          <td>String</td>
 *          <td>define html style attribute</td>
 *       </tr>
 *       <tr>
 *          <td>cssErrorClass</td>
 *          <td>simple</td>
 *          <td>String</td>
 *          <td>error class attribute</td>
 *       </tr>
 *       <tr>
 *          <td>cssErrorStyle</td>
 *          <td>simple</td>
 *          <td>String</td>
 *          <td>error style attribute</td>
 *       </tr>
 *       <tr>
 *          <td>title</td>
 *          <td>simple</td>
 *          <td>String</td>
 *          <td>define html title attribute</td>
 *       </tr>
 *       <tr>
 *          <td>disabled</td>
 *          <td>simple</td>
 *          <td>String</td>
 *          <td>define html disabled attribute</td>
 *       </tr>
 *       <tr>
 *          <td>label</td>
 *          <td>xhtml</td>
 *          <td>String</td>
 *          <td>define label of form element</td>
 *       </tr>
 *       <tr>
 *          <td>labelPosition</td>
 *          <td>xhtml</td>
 *          <td>String</td>
 *          <td>define label position of form element (top/left), default to left</td>
 *       </tr>
 *       <tr>
 *          <td>requiredPosition</td>
 *          <td>xhtml</td>
 *          <td>String</td>
 *          <td>define required label position of form element (left/right), default to right</td>
 *       </tr>
  *       <tr>
 *          <td>errorPosition</td>
 *          <td>xhtml</td>
 *          <td>String</td>
 *          <td>define error position of form element (top|bottom), default to top</td>
 *       </tr>
 *       <tr>
 *          <td>name</td>
 *          <td>simple</td>
 *          <td>String</td>
 *          <td>Form Element's field name mapping</td>
 *       </tr>
 *       <tr>
 *          <td>requiredLabel</td>
 *          <td>xhtml</td>
 *          <td>Boolean</td>
 *          <td>add * to label (true to add false otherwise)</td>
 *       </tr>
 *       <tr>
 *          <td>tabIndex</td>
 *          <td>simple</td>
 *          <td>String</td>
 *          <td>define html tabindex attribute</td>
 *       </tr>
 *       <tr>
 *          <td>value</td>
 *          <td>simple</td>
 *          <td>Object</td>
 *          <td>define value of form element</td>
 *       </tr>
 *    </tbody>
 * </table>
 *
 * <!-- END SNIPPET: generalAttributes -->
 *
 * <!-- START SNIPPET: javascriptRelatedAttributes -->
 *
 * <table border="1" summary="">
 *    <thead>
 *       <tr>
 *          <td>Attribute</td>
 *          <td>Theme</td>
 *          <td>Data Types</td>
 *          <td>Description</td>
 *       </tr>
 *    </thead>
 *    <tbody>
 *       <tr>
 *          <td>onclick</td>
 *          <td>simple</td>
 *          <td>String</td>
 *          <td>html javascript onclick attribute</td>
 *       </tr>
 *       <tr>
 *          <td>ondblclick</td>
 *          <td>simple</td>
 *          <td>String</td>
 *          <td>html javascript ondbclick attribute</td>
 *       </tr>
 *       <tr>
 *          <td>onmousedown</td>
 *          <td>simple</td>
 *          <td>String</td>
 *          <td>html javascript onmousedown attribute</td>
 *       </tr>
 *       <tr>
 *          <td>onmouseup</td>
 *          <td>simple</td>
 *          <td>String</td>
 *          <td>html javascript onmouseup attribute</td>
 *       </tr>
 *       <tr>
 *          <td>onmouseover</td>
 *          <td>simple</td>
 *          <td>String</td>
 *          <td>html javascript onmouseover attribute</td>
 *       </tr>
 *       <tr>
 *          <td>onmouseout</td>
 *          <td>simple</td>
 *          <td>String</td>
 *          <td>html javascript onmouseout attribute</td>
 *       </tr>
 *       <tr>
 *          <td>onfocus</td>
 *          <td>simple</td>
 *          <td>String</td>
 *          <td>html javascript onfocus attribute</td>
 *       </tr>
 *       <tr>
 *          <td>onblur</td>
 *          <td>simple</td>
 *          <td>String</td>
 *          <td>html javascript onblur attribute</td>
 *       </tr>
 *       <tr>
 *          <td>onkeypress</td>
 *          <td>simple</td>
 *          <td>String</td>
 *          <td>html javascript onkeypress attribute</td>
 *       </tr>
 *       <tr>
 *          <td>onkeyup</td>
 *          <td>simple</td>
 *          <td>String</td>
 *          <td>html javascript onkeyup attribute</td>
 *       </tr>
 *       <tr>
 *          <td>onkeydown</td>
 *          <td>simple</td>
 *          <td>String</td>
 *          <td>html javascript onkeydown attribute</td>
 *       </tr>
 *       <tr>
 *          <td>onselect</td>
 *          <td>simple</td>
 *          <td>String</td>
 *          <td>html javascript onselect attribute</td>
 *       </tr>
 *       <tr>
 *          <td>onchange</td>
 *          <td>simple</td>
 *          <td>String</td>
 *          <td>html javascript onchange attribute</td>
 *       </tr>
 *    </tbody>
 * </table>
 *
 * <!-- END SNIPPET: javascriptRelatedAttributes -->
 *
 * <!-- START SNIPPET: tooltipattributes -->
 *
 * <table border="1" summary="">
 *  <tr>
 *     <td>Attribute</td>
 *     <td>Data Type</td>
 *     <td>Default</td>
 *     <td>Description</td>
 *  </tr>
 *  <tr>
 *      <td>tooltip</td>
 *      <td>String</td>
 *      <td>none</td>
 *      <td>Set the tooltip of this particular component</td>
 *  </tr>
 *  <tr>
 *      <td>jsTooltipEnabled</td>
 *      <td>String</td>
 *      <td>false</td>
 *      <td>Enable js tooltip rendering</td>
 *  </tr>
 *    <tr>
 *      <td>tooltipIcon</td>
 *      <td>String</td>
 *      <td>/static/tooltip/tooltip.gif</td>
 *      <td>The url to the tooltip icon</td>
 *   <tr>
 *      <td>tooltipDelay</td>
 *      <td>String</td>
 *      <td>500</td>
 *      <td>Tooltip shows up after the specified timeout (miliseconds). A behavior similar to that of OS based tooltips.</td>
 *   </tr>
 *   <tr>
 *      <td>key</td>
 *      <td>simple</td>
 *      <td>String</td>
 *      <td>The name of the property this input field represents.  This will auto populate the name, label, and value</td>
 *   </tr>
 * </table>
 *
 * <!-- END SNIPPET: tooltipattributes -->
 *
 *
 * <!-- START SNIPPET: tooltipdescription -->
 * <p>
 * <b>tooltipConfig is deprecated, use individual tooltip configuration attributes instead </b>
 * </p>
 *
 * <p>
 * Every Form UI component (in xhtml / css_xhtml or any other that extends them) can
 * have tooltips assigned to them. The Form component's tooltip related attribute, once
 * defined, will be applied to all form UI components that are created under it unless
 * explicitly overridden by having the Form UI component itself defined with their own tooltip attribute.
 * </p>
 *
 * <p>
 * In Example 1, the textfield will inherit the tooltipDelay and tooltipIconPath attribute from
 * its containing form. In other words, although it doesn't define a tooltipIconPath
 * attribute, it will have that attribute inherited from its containing form.
 * </p>
 *
 * <p>
 * In Example 2, the  textfield will inherit both the tooltipDelay and
 * tooltipIconPath attribute from its containing form, but the tooltipDelay
 * attribute is overridden at the textfield itself. Hence, the textfield actually will
 * have its tooltipIcon defined as /myImages/myIcon.gif, inherited from its containing form, and
 * tooltipDelay defined as 5000.
 * </p>
 *
 * <p>
 * Example 3, 4 and 5 show different ways of setting the tooltip configuration attribute.<br>
 * <b>Example 3:</b> Set tooltip config through the body of the param tag<br>
 * <b>Example 4:</b> Set tooltip config through the value attribute of the param tag<br>
 * <b>Example 5:</b> Set tooltip config through the tooltip attributes of the component tag<br>
 * </p>
 *
 * <!-- END SNIPPET: tooltipdescription -->
 *
 *
 * <pre>
 * <!-- START SNIPPET: tooltipexample -->
 *
 * &lt;!-- Example 1: --&gt;
 * &lt;s:form
 *          tooltipDelay="500"
 *          tooltipIconPath="/myImages/myIcon.gif" .... &gt;
 *   ....
 *     &lt;s:textfield label="Customer Name" tooltip="Enter the customer name" .... /&gt;
 *   ....
 * &lt;/s:form&gt;
 *
 * &lt;!-- Example 2: --&gt;
 * &lt;s:form
 *          tooltipDelay="500"
 *          tooltipIconPath="/myImages/myIcon.gif" .... &gt;
 *   ....
 *     &lt;s:textfield label="Address"
 *          tooltip="Enter your address"
 *          tooltipDelay="5000" /&gt;
 *   ....
 * &lt;/s:form&gt;
 *
 *
 * &lt;-- Example 3: --&gt;
 * &lt;s:textfield
 *        label="Customer Name"
 *        tooltip="One of our customer Details"&gt;
 *        &lt;s:param name="tooltipDelay"&gt;
 *             500
 *        &lt;/s:param&gt;
 *        &lt;s:param name="tooltipIconPath"&gt;
 *             /myImages/myIcon.gif
 *        &lt;/s:param&gt;
 * &lt;/s:textfield&gt;
 *
 *
 * &lt;-- Example 4: --&gt;
 * &lt;s:textfield
 *          label="Customer Address"
 *          tooltip="Enter The Customer Address" &gt;
 *          &lt;s:param
 *              name="tooltipDelay"
 *              value="500" /&gt;
 * &lt;/s:textfield&gt;
 *
 *
 * &lt;-- Example 5: --&gt;
 * &lt;s:textfield
 *          label="Customer Telephone Number"
 *          tooltip="Enter customer Telephone Number"
 *          tooltipDelay="500"
 *          tooltipIconPath="/myImages/myIcon.gif" /&gt;
 *
 * <!-- END SNIPPET: tooltipexample -->
 * </pre>
 *
 */
public abstract class UIBean extends Component {
    private static final Logger LOG = LogManager.getLogger(UIBean.class);

    protected HttpServletRequest request;
    protected HttpServletResponse response;

    public UIBean(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
        super(stack);
        this.request = request;
        this.response = response;
        this.templateSuffix = ContextUtil.getTemplateSuffix(stack.getContext());
    }

    // The templateSuffic to use, overrides the default one if not null.
    protected String templateSuffix;

    // The template to use, overrides the default one.
    protected String template;

    // templateDir and theme attributes
    protected String templateDir;
    protected String theme;

    // shortcut, sets label, name, and value
    protected String key;

    protected String id;
    protected String cssClass;
    protected String cssStyle;
    protected String cssErrorClass;
    protected String cssErrorStyle;
    protected String disabled;
    protected String label;
    protected String labelPosition;
    protected String labelSeparator;
    protected String requiredPosition;
    protected String errorPosition;
    protected String name;
    protected String requiredLabel;
    protected String tabindex;
    protected String value;
    protected String title;

    // HTML scripting events attributes
    protected String onclick;
    protected String ondblclick;
    protected String onmousedown;
    protected String onmouseup;
    protected String onmouseover;
    protected String onmousemove;
    protected String onmouseout;
    protected String onfocus;
    protected String onblur;
    protected String onkeypress;
    protected String onkeydown;
    protected String onkeyup;
    protected String onselect;
    protected String onchange;

    // common html attributes
    protected String accesskey;

    // javascript tooltip attribute
    protected String tooltip;
    protected String tooltipConfig;
    protected String javascriptTooltip;
    protected String tooltipDelay;
    protected String tooltipCssClass;
    protected String tooltipIconPath;

    // dynamic attributes
    protected Map<String, Object> dynamicAttributes = new HashMap<>();

    protected String defaultTemplateDir;
    protected String defaultUITheme;
    protected String uiThemeExpansionToken;
    protected String uiStaticContentPath;

    protected TemplateEngineManager templateEngineManager;

    @Inject(StrutsConstants.STRUTS_UI_TEMPLATEDIR)
    public void setDefaultTemplateDir(String dir) {
        this.defaultTemplateDir = dir;
    }

    @Inject(StrutsConstants.STRUTS_UI_THEME)
    public void setDefaultUITheme(String theme) {
        this.defaultUITheme = theme;
    }

    @Inject(StrutsConstants.STRUTS_UI_THEME_EXPANSION_TOKEN)
    public void setUIThemeExpansionToken(String uiThemeExpansionToken) {
        this.uiThemeExpansionToken = uiThemeExpansionToken;
    }

    @Inject(StrutsConstants.STRUTS_UI_STATIC_CONTENT_PATH)
    public void setStaticContentPath(String uiStaticContentPath) {
        this.uiStaticContentPath = StaticContentLoader.Validator.validateStaticContentPath(uiStaticContentPath);
    }

    @Inject
    public void setTemplateEngineManager(TemplateEngineManager mgr) {
        this.templateEngineManager = mgr;
    }

    @Override
    public boolean end(Writer writer, String body) {
        evaluateParams();
        try {
            super.end(writer, body, false);
            mergeTemplate(writer, buildTemplateName(template, getDefaultTemplate()));
        } catch (Exception e) {
            throw new StrutsException(e);
        }
        finally {
            popComponentStack();
        }

        return false;
    }

    /**
     * A contract that requires each concrete UI Tag to specify which template should be used as a default.  For
     * example, the CheckboxTab might return "checkbox.vm" while the RadioTag might return "radio.vm".  This value
     * <strong>not</strong> begin with a '/' unless you intend to make the path absolute rather than relative to the
     * current theme.
     *
     * @return The name of the template to be used as the default.
     */
    protected abstract String getDefaultTemplate();

    protected Template buildTemplateName(String myTemplate, String myDefaultTemplate) {
        String template = myDefaultTemplate;

        if (myTemplate != null) {
            template = findString(myTemplate);
        }

        String templateDir = getTemplateDir();
        String theme = getTheme();

        return new Template(templateDir, theme, template);

    }

    protected void mergeTemplate(Writer writer, Template template) throws Exception {
        final TemplateEngine engine = templateEngineManager.getTemplateEngine(template, templateSuffix);
        if (engine == null) {
            throw new ConfigurationException("Unable to find a TemplateEngine for template " + template);
        }

        LOG.debug("Rendering template {}", template);

        final TemplateRenderingContext context = new TemplateRenderingContext(template, writer, getStack(), getParameters(), this);
        engine.renderTemplate(context);
    }

    public String getTemplateDir() {
        String templateDir = null;

        if (this.templateDir != null) {
            templateDir = findString(this.templateDir);
        }

        // If templateDir is not explicitly given,
        // try to find attribute which states the dir set to use
        if (StringUtils.isBlank(templateDir)) {
            templateDir = stack.findString("#attr.templateDir");
        }

        // Default template set
        if (StringUtils.isBlank(templateDir)) {
            templateDir = defaultTemplateDir;
        }

        // Defaults to 'template'
        if (StringUtils.isBlank(templateDir)) {
            templateDir = "template";
        }

        return templateDir;
    }

    public String getTheme() {
        String theme = null;

        if (this.theme != null) {
            theme = findString(this.theme);
        }

        if (StringUtils.isBlank(theme)) {
            Form form = (Form) findAncestor(Form.class);
            if (form != null) {
                theme = form.getTheme();
            }
        }

        // If theme set is not explicitly given,
        // try to find attribute which states the theme set to use
        if (StringUtils.isBlank(theme)) {
            theme = stack.findString("#attr.theme");
        }

        // Default theme set
        if (StringUtils.isBlank(theme)) {
            theme = defaultUITheme;
        }

        return theme;
    }

    public void evaluateParams() {
        String templateDir = getTemplateDir();
        String theme = getTheme();

        addParameter("templateDir", templateDir);
        addParameter("theme", theme);
        addParameter("template", template != null ? findString(template) : getDefaultTemplate());
        addParameter("dynamicAttributes", dynamicAttributes);
        addParameter("themeExpansionToken", uiThemeExpansionToken);
        addParameter("expandTheme", uiThemeExpansionToken + theme);

        addParameter("staticContentPath", findString(uiStaticContentPath));

        String name = null;
        String providedLabel = null;

        if (this.key != null) {

            if(this.name == null) {
                this.name = key;
            }

            if(this.label == null) {
                // lookup the label from a TextProvider (default value is the key)
                providedLabel = TextProviderHelper.getText(key, key, stack);
            }
        }

        if (this.name != null) {
            name = findString(this.name);
            addParameter("name", name);
        }

        if (label != null) {
            addParameter("label", findString(label));
        } else {
            if (providedLabel != null) {
                // label found via a TextProvider
                addParameter("label", providedLabel);
            }
        }

        if (labelSeparator != null) {
            addParameter("labelseparator", findString(labelSeparator));
        }

        if (labelPosition != null) {
            String labelPosition = findString(this.labelPosition);
            addParameter("labelposition", labelPosition);
            addParameter("labelPosition", labelPosition);
        }

        if (requiredPosition != null) {
            addParameter("requiredPosition", findString(requiredPosition));
        }

        if (errorPosition != null) {
            addParameter("errorposition", findString(errorPosition));
        }

        if (requiredLabel != null) {
            addParameter("required", findValue(requiredLabel, Boolean.class));
        }

        if (disabled != null) {
            addParameter("disabled", findValue(disabled, Boolean.class));
        }

        if (tabindex != null) {
            addParameter("tabindex", findString(tabindex));
        }

        if (onclick != null) {
            addParameter("onclick", findString(onclick));
        }

        if (ondblclick != null) {
            addParameter("ondblclick", findString(ondblclick));
        }

        if (onmousedown != null) {
            addParameter("onmousedown", findString(onmousedown));
        }

        if (onmouseup != null) {
            addParameter("onmouseup", findString(onmouseup));
        }

        if (onmouseover != null) {
            addParameter("onmouseover", findString(onmouseover));
        }

        if (onmousemove != null) {
            addParameter("onmousemove", findString(onmousemove));
        }

        if (onmouseout != null) {
            addParameter("onmouseout", findString(onmouseout));
        }

        if (onfocus != null) {
            addParameter("onfocus", findString(onfocus));
        }

        if (onblur != null) {
            addParameter("onblur", findString(onblur));
        }

        if (onkeypress != null) {
            addParameter("onkeypress", findString(onkeypress));
        }

        if (onkeydown != null) {
            addParameter("onkeydown", findString(onkeydown));
        }

        if (onkeyup != null) {
            addParameter("onkeyup", findString(onkeyup));
        }

        if (onselect != null) {
            addParameter("onselect", findString(onselect));
        }

        if (onchange != null) {
            addParameter("onchange", findString(onchange));
        }

        if (accesskey != null) {
            addParameter("accesskey", findString(accesskey));
        }

        if (cssClass != null) {
            addParameter("cssClass", findString(cssClass));
        }

        if (cssStyle != null) {
            addParameter("cssStyle", findString(cssStyle));
        }

        if (cssErrorClass != null) {
            addParameter("cssErrorClass", findString(cssErrorClass));
        }

        if (cssErrorStyle != null) {
            addParameter("cssErrorStyle", findString(cssErrorStyle));
        }

        if (title != null) {
            addParameter("title", findString(title));
        }


        // see if the value was specified as a parameter already
        if (parameters.containsKey("value")) {
            parameters.put("nameValue", parameters.get("value"));
        } else {
            if (evaluateNameValue()) {
                final Class<?> valueClazz = getValueClassType();

                if (valueClazz != null) {
                    if (value != null) {
                        addParameter("nameValue", findValue(value, valueClazz));
                    } else if (name != null) {
                        String expr = completeExpression(name);
                        if (recursion(name)) {
                            addParameter("nameValue", expr);
                        } else {
                            addParameter("nameValue", findValue(expr, valueClazz));
                        }
                    }
                } else {
                    if (value != null) {
                        addParameter("nameValue", findValue(value));
                    } else if (name != null) {
                        addParameter("nameValue", findValue(name));
                    }
                }
            }
        }

        final Form form = (Form) findAncestor(Form.class);

        // create HTML id element
        populateComponentHtmlId(form);

        if (form != null ) {
            addParameter("form", form.getParameters());

            if ( name != null ) {
                // list should have been created by the form component
                List<String> tags = (List<String>) form.getParameters().get("tagNames");
                tags.add(name);
            }
        }


        // tooltip & tooltipConfig
        if (tooltipConfig != null) {
            addParameter("tooltipConfig", findValue(tooltipConfig));
        }
        if (tooltip != null) {
            addParameter("tooltip", findString(tooltip));

            Map<String, String> tooltipConfigMap = getTooltipConfig(this);

            if (form != null) { // inform the containing form that we need tooltip javascript included
                form.addParameter("hasTooltip", Boolean.TRUE);

                // tooltipConfig defined in component itself will take precedence
                // over those defined in the containing form
                Map<String, String> overallTooltipConfigMap = getTooltipConfig(form);
                overallTooltipConfigMap.putAll(tooltipConfigMap); // override parent form's tooltip config

                for (Map.Entry<String, String> entry : overallTooltipConfigMap.entrySet()) {
                    addParameter(entry.getKey(), entry.getValue());
                }
            }
            else {
                LOG.warn("No ancestor Form found, javascript based tooltip will not work, however standard HTML tooltip using alt and title attribute will still work");
            }

            //TODO: this is to keep backward compatibility, remove once when tooltipConfig is dropped
            String  jsTooltipEnabled = (String) getParameters().get("jsTooltipEnabled");
            if (jsTooltipEnabled != null)
                this.javascriptTooltip = jsTooltipEnabled;

            //TODO: this is to keep backward compatibility, remove once when tooltipConfig is dropped
            String tooltipIcon = (String) getParameters().get("tooltipIcon");
            if (tooltipIcon != null)
                this.addParameter("tooltipIconPath", tooltipIcon);
            if (this.tooltipIconPath != null)
                this.addParameter("tooltipIconPath", findString(this.tooltipIconPath));

            //TODO: this is to keep backward compatibility, remove once when tooltipConfig is dropped
            String tooltipDelayParam = (String) getParameters().get("tooltipDelay");
            if (tooltipDelayParam != null)
                this.addParameter("tooltipDelay", tooltipDelayParam);
            if (this.tooltipDelay != null)
                this.addParameter("tooltipDelay", findString(this.tooltipDelay));

            if (this.javascriptTooltip != null) {
                Boolean jsTooltips = (Boolean) findValue(this.javascriptTooltip, Boolean.class);
                //TODO use a Boolean model when tooltipConfig is dropped
                this.addParameter("jsTooltipEnabled", jsTooltips.toString());

                if (form != null)
                    form.addParameter("hasTooltip", jsTooltips);
                if (this.tooltipCssClass != null)
                    this.addParameter("tooltipCssClass", findString(this.tooltipCssClass));
            }
        }

        // to be used with the CSP interceptor - adds the nonce value as a parameter to be accessed from ftl files
        Map<String, Object> session = stack.getActionContext().getSession();
        if (session != null) {
            if (session.containsKey("nonce")) {
                String nonceValue = session.get("nonce").toString();
                addParameter("nonce", nonceValue);
            }
        }

        evaluateExtraParams();
    }

    protected String escape(String name) {
        // escape any possible values that can make the ID painful to work with in JavaScript
        if (name != null) {
            return name.replaceAll("[/.\\[\\]'\"]", "_");
        } else {
            return null;
        }
    }

    /**
     * Ensures an unescaped attribute value cannot be vulnerable to XSS attacks
     *
     * @param val The value to check
     * @return The escaped value
     */
    protected String ensureAttributeSafelyNotEscaped(String val) {
        if (val != null) {
            return val.replaceAll("\"", "&#34;");
        } else {
            return null;
        }
    }

    protected void evaluateExtraParams() {
    }

    protected boolean evaluateNameValue() {
        return true;
    }

    protected Class<?> getValueClassType() {
        return String.class;
    }

    public void addFormParameter(String key, Object value) {
        Form form = (Form) findAncestor(Form.class);
        if (form != null) {
            form.addParameter(key, value);
        }
    }

    protected void enableAncestorFormCustomOnsubmit() {
        Form form = (Form) findAncestor(Form.class);
        if (form != null) {
            form.addParameter("customOnsubmitEnabled", Boolean.TRUE);
        } else {
            if (LOG.isWarnEnabled()) {
                LOG.warn("Cannot find an Ancestor form, custom onsubmit is NOT enabled");
            }
        }
    }

    protected Map<String, String> getTooltipConfig(UIBean component) {
        Object tooltipConfigObj = component.getParameters().get("tooltipConfig");
        Map<String, String> tooltipConfig = new LinkedHashMap<>();

        if (tooltipConfigObj instanceof Map) {
            // we get this if its configured using
            // 1] UI component's tooltipConfig attribute  OR
            // 2] <param name="tooltip" value="" /> param tag value attribute

            tooltipConfig = new LinkedHashMap<>((Map) tooltipConfigObj);
        } else if (tooltipConfigObj instanceof String) {

            // we get this if its configured using
            // <param name="tooltipConfig"> ... </param> tag's body
            String tooltipConfigStr = (String) tooltipConfigObj;
            String[] tooltipConfigArray = tooltipConfigStr.split("\\|");

            for (String aTooltipConfigArray : tooltipConfigArray) {
                String[] configEntry = aTooltipConfigArray.trim().split("=");
                String key = configEntry[0].trim();
                String value;
                if (configEntry.length > 1) {
                    value = configEntry[1].trim();
                    tooltipConfig.put(key, value);
                } else {
                    LOG.warn("component {} tooltip config param {} has no value defined, skipped", component, key);
                }
            }
        }
        if (component.javascriptTooltip != null)
            tooltipConfig.put("jsTooltipEnabled", component.javascriptTooltip);
        if (component.tooltipIconPath != null)
            tooltipConfig.put("tooltipIcon", component.tooltipIconPath);
        if (component.tooltipDelay != null)
            tooltipConfig.put("tooltipDelay", component.tooltipDelay);
        return tooltipConfig;
    }

    /**
     * Create HTML id element for the component and populate this component parameter
     * map. Additionally, a parameter named escapedId is populated which contains the found id value filtered by
     * {@link #escape(String)}, needed eg. for naming Javascript identifiers based on the id value.
     *
     * The order is as follows :-
     * <ol>
     *   <li>This component id attribute</li>
     *   <li>[containing_form_id]_[this_component_name]</li>
     *   <li>[this_component_name]</li>
     * </ol>
     *
     * @param form enclosing form tag
     */
    protected void populateComponentHtmlId(Form form) {
        String tryId;
        String generatedId;
        if (id != null) {
            // this check is needed for backwards compatibility with 2.1.x
            tryId = findString(id);
        } else if (null == (generatedId = escape(name != null ? findString(name) : null))) {
            LOG.debug("Cannot determine id attribute for [{}], consider defining id, name or key attribute!", this);
            tryId = null;
        } else if (form != null) {
            tryId = form.getParameters().get("id") + "_" + generatedId;
        } else {
            tryId = generatedId;
        }

        //fix for https://issues.apache.org/jira/browse/WW-4299
        //do not assign value to id if tryId is null
        if (tryId != null) {
          addParameter("id", tryId);
          addParameter("escapedId", escape(tryId));
        }
    }

    /**
     * Get's the id for referencing element.
     * @return the id for referencing element.
     */
    public String getId() {
        return id;
    }

    @StrutsTagAttribute(description="HTML id attribute")
    public void setId(String id) {
        this.id = id;
    }

    @StrutsTagAttribute(description="The template directory.")
    public void setTemplateDir(String templateDir) {
        this.templateDir = templateDir;
    }

    @StrutsTagAttribute(description="The theme (other than default) to use for rendering the element")
    public void setTheme(String theme) {
        this.theme = theme;
    }

    public String getTemplate() {
        return template;
    }

    @StrutsTagAttribute(description="The template (other than default) to use for rendering the element")
    public void setTemplate(String template) {
        this.template = template;
    }

    @StrutsTagAttribute(description="The css class to use for element")
    public void setCssClass(String cssClass) {
        this.cssClass = cssClass;
    }

    @Deprecated
    @StrutsTagAttribute(description="(Deprecated) The css class to use for element - it's an alias of cssClass attribute.")
    public void setClass(String cssClass) {
        this.cssClass = cssClass;
    }

    @StrutsTagAttribute(description="The css style definitions for element to use")
    public void setCssStyle(String cssStyle) {
        this.cssStyle = cssStyle;
    }

    @StrutsTagAttribute(description="The css style definitions for element to use - it's an alias of cssStyle attribute.")
    public void setStyle(String cssStyle) {
        this.cssStyle = cssStyle;
    }

    @StrutsTagAttribute(description="The css error class to use for element")
    public void setCssErrorClass(String cssErrorClass) {
        this.cssErrorClass = cssErrorClass;
    }

    @StrutsTagAttribute(description="The css error style definitions for element to use")
    public void setCssErrorStyle(String cssErrorStyle) {
        this.cssErrorStyle = cssErrorStyle;
    }

    @StrutsTagAttribute(description="Set the html title attribute on rendered html element")
    public void setTitle(String title) {
        this.title = title;
    }

    @StrutsTagAttribute(description="Set the html disabled attribute on rendered html element")
    public void setDisabled(String disabled) {
        this.disabled = disabled;
    }

    @StrutsTagAttribute(description="Label expression used for rendering an element specific label")
    public void setLabel(String label) {
        this.label = label;
    }

    @StrutsTagAttribute(description="String that will be appended to the label", defaultValue=":")
    public void setLabelSeparator(String labelseparator) {
        this.labelSeparator = labelseparator;
    }

    /**
     * Deprecated since 2.5.27
     * @deprecated use {@link #setLabelPosition(String)} instead
     */
    @StrutsTagAttribute(description="(Deprecated) Define label position of form element (top/left)")
    @Deprecated
    public void setLabelposition(String labelPosition) {
        this.labelPosition = labelPosition;
    }

    @StrutsTagAttribute(description="Define label position of form element (top/left)")
    public void setLabelPosition(String labelPosition) {
        this.labelPosition = labelPosition;
    }

    @StrutsTagAttribute(description="Define required position of required form element (left|right)")
    public void setRequiredPosition(String requiredPosition) {
        this.requiredPosition = requiredPosition;
    }

    @StrutsTagAttribute(description="Define error position of form element (top|bottom)")
    public void setErrorPosition(String errorPosition) {
        this.errorPosition = errorPosition;
    }

    @StrutsTagAttribute(description="The name to set for element")
    public void setName(String name) {
        this.name = name;
    }

    @StrutsTagAttribute(description="If set to true, the rendered element will indicate that input is required", type="Boolean", defaultValue="false")
    public void setRequiredLabel(String requiredLabel) {
        this.requiredLabel = requiredLabel;
    }

    @StrutsTagAttribute(description="Set the html tabindex attribute on rendered html element")
    public void setTabindex(String tabindex) {
        this.tabindex = tabindex;
    }

    @StrutsTagAttribute(description="Preset the value of input element.")
    public void setValue(String value) {
        this.value = value;
    }

    @StrutsTagAttribute(description="Set the html onclick attribute on rendered html element")
    public void setOnclick(String onclick) {
        this.onclick = onclick;
    }

    @StrutsTagAttribute(description="Set the html ondblclick attribute on rendered html element")
    public void setOndblclick(String ondblclick) {
        this.ondblclick = ondblclick;
    }

    @StrutsTagAttribute(description="Set the html onmousedown attribute on rendered html element")
    public void setOnmousedown(String onmousedown) {
        this.onmousedown = onmousedown;
    }

    @StrutsTagAttribute(description="Set the html onmouseup attribute on rendered html element")
    public void setOnmouseup(String onmouseup) {
        this.onmouseup = onmouseup;
    }

    @StrutsTagAttribute(description="Set the html onmouseover attribute on rendered html element")
    public void setOnmouseover(String onmouseover) {
        this.onmouseover = onmouseover;
    }

    @StrutsTagAttribute(description="Set the html onmousemove attribute on rendered html element")
    public void setOnmousemove(String onmousemove) {
        this.onmousemove = onmousemove;
    }

    @StrutsTagAttribute(description="Set the html onmouseout attribute on rendered html element")
    public void setOnmouseout(String onmouseout) {
        this.onmouseout = onmouseout;
    }

    @StrutsTagAttribute(description="Set the html onfocus attribute on rendered html element")
    public void setOnfocus(String onfocus) {
        this.onfocus = onfocus;
    }

    @StrutsTagAttribute(description=" Set the html onblur attribute on rendered html element")
    public void setOnblur(String onblur) {
        this.onblur = onblur;
    }

    @StrutsTagAttribute(description="Set the html onkeypress attribute on rendered html element")
    public void setOnkeypress(String onkeypress) {
        this.onkeypress = onkeypress;
    }

    @StrutsTagAttribute(description="Set the html onkeydown attribute on rendered html element")
    public void setOnkeydown(String onkeydown) {
        this.onkeydown = onkeydown;
    }

    @StrutsTagAttribute(description="Set the html onkeyup attribute on rendered html element")
    public void setOnkeyup(String onkeyup) {
        this.onkeyup = onkeyup;
    }

    @StrutsTagAttribute(description="Set the html onselect attribute on rendered html element")
    public void setOnselect(String onselect) {
        this.onselect = onselect;
    }

    @StrutsTagAttribute(description="Set the html onchange attribute on rendered html element")
    public void setOnchange(String onchange) {
        this.onchange = onchange;
    }

    @StrutsTagAttribute(description="Set the html accesskey attribute on rendered html element")
    public void setAccesskey(String accesskey) {
        this.accesskey = accesskey;
    }

    @StrutsTagAttribute(description="Set the tooltip of this particular component")
    public void setTooltip(String tooltip) {
        this.tooltip = tooltip;
    }

    @StrutsTagAttribute(description="Deprecated. Use individual tooltip configuration attributes instead.")
    public void setTooltipConfig(String tooltipConfig) {
        this.tooltipConfig = tooltipConfig;
    }

    @StrutsTagAttribute(description="Set the key (name, value, label) for this particular component")
    public void setKey(String key) {
        this.key = key;
    }

    @StrutsTagAttribute(description="Use JavaScript to generate tooltips", type="Boolean", defaultValue="false")
    public void setJavascriptTooltip(String javascriptTooltip) {
        this.javascriptTooltip = javascriptTooltip;
    }

    @StrutsTagAttribute(description="CSS class applied to JavaScrip tooltips", defaultValue="StrutsTTClassic")
    public void setTooltipCssClass(String tooltipCssClass) {
        this.tooltipCssClass = tooltipCssClass;
    }

    @StrutsTagAttribute(description="Delay in milliseconds, before showing JavaScript tooltips ",
        defaultValue="Classic")
    public void setTooltipDelay(String tooltipDelay) {
        this.tooltipDelay = tooltipDelay;
    }

    @StrutsTagAttribute(description="Icon path used for image that will have the tooltip")
    public void setTooltipIconPath(String tooltipIconPath) {
        this.tooltipIconPath = tooltipIconPath;
    }

    public void setDynamicAttributes(Map<String, String> tagDynamicAttributes) {
        for (Map.Entry<String, String> entry : tagDynamicAttributes.entrySet()) {
            String key = entry.getKey();

            if (!isValidTagAttribute(key)) {
                dynamicAttributes.put(key, entry.getValue());
            }
        }
    }

    /**
     * supports dynamic attributes for freemarker ui tags
     * @see <a href="https://issues.apache.org/jira/browse/WW-3174">WW-3174</a>
     * @see <a href="https://issues.apache.org/jira/browse/WW-4166">WW-4166</a>
     */
    @Override
    public void copyParams(Map<String, Object> params) {
        super.copyParams(params);
        for (Map.Entry<String, Object>entry : params.entrySet()) {
            String key = entry.getKey();
            if (!isValidTagAttribute(key) && !key.equals("dynamicAttributes")) {
                dynamicAttributes.put(key, entry.getValue());
            }
        }
    }

}
