/*
 * Copyright 2002-2018 the original author or authors.
 *
 * Licensed 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
 *
 *      https://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.springframework.web.servlet.tags.form;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.DynamicAttributes;

import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

Base class for databinding-aware JSP tags that render HTML element. Provides a set of properties corresponding to the set of HTML attributes that are common across elements.

Additionally, this base class allows for rendering non-standard attributes as part of the tag's output. These attributes are accessible to subclasses if needed via the dynamicAttributes map.

Author:Rob Harrop, Jeremy Grelle, Rossen Stoyanchev
Since:2.0
/** * Base class for databinding-aware JSP tags that render HTML element. Provides * a set of properties corresponding to the set of HTML attributes that are common * across elements. * * <p>Additionally, this base class allows for rendering non-standard attributes * as part of the tag's output. These attributes are accessible to subclasses if * needed via the {@link AbstractHtmlElementTag#getDynamicAttributes() dynamicAttributes} * map. * * @author Rob Harrop * @author Jeremy Grelle * @author Rossen Stoyanchev * @since 2.0 */
@SuppressWarnings("serial") public abstract class AbstractHtmlElementTag extends AbstractDataBoundFormElementTag implements DynamicAttributes { public static final String CLASS_ATTRIBUTE = "class"; public static final String STYLE_ATTRIBUTE = "style"; public static final String LANG_ATTRIBUTE = "lang"; public static final String TITLE_ATTRIBUTE = "title"; public static final String DIR_ATTRIBUTE = "dir"; public static final String TABINDEX_ATTRIBUTE = "tabindex"; public static final String ONCLICK_ATTRIBUTE = "onclick"; public static final String ONDBLCLICK_ATTRIBUTE = "ondblclick"; public static final String ONMOUSEDOWN_ATTRIBUTE = "onmousedown"; public static final String ONMOUSEUP_ATTRIBUTE = "onmouseup"; public static final String ONMOUSEOVER_ATTRIBUTE = "onmouseover"; public static final String ONMOUSEMOVE_ATTRIBUTE = "onmousemove"; public static final String ONMOUSEOUT_ATTRIBUTE = "onmouseout"; public static final String ONKEYPRESS_ATTRIBUTE = "onkeypress"; public static final String ONKEYUP_ATTRIBUTE = "onkeyup"; public static final String ONKEYDOWN_ATTRIBUTE = "onkeydown"; @Nullable private String cssClass; @Nullable private String cssErrorClass; @Nullable private String cssStyle; @Nullable private String lang; @Nullable private String title; @Nullable private String dir; @Nullable private String tabindex; @Nullable private String onclick; @Nullable private String ondblclick; @Nullable private String onmousedown; @Nullable private String onmouseup; @Nullable private String onmouseover; @Nullable private String onmousemove; @Nullable private String onmouseout; @Nullable private String onkeypress; @Nullable private String onkeyup; @Nullable private String onkeydown; @Nullable private Map<String, Object> dynamicAttributes;
Set the value of the 'class' attribute. May be a runtime expression.
/** * Set the value of the '{@code class}' attribute. * May be a runtime expression. */
public void setCssClass(String cssClass) { this.cssClass = cssClass; }
Get the value of the 'class' attribute. May be a runtime expression.
/** * Get the value of the '{@code class}' attribute. * May be a runtime expression. */
@Nullable protected String getCssClass() { return this.cssClass; }
The CSS class to use when the field bound to a particular tag has errors. May be a runtime expression.
/** * The CSS class to use when the field bound to a particular tag has errors. * May be a runtime expression. */
public void setCssErrorClass(String cssErrorClass) { this.cssErrorClass = cssErrorClass; }
The CSS class to use when the field bound to a particular tag has errors. May be a runtime expression.
/** * The CSS class to use when the field bound to a particular tag has errors. * May be a runtime expression. */
@Nullable protected String getCssErrorClass() { return this.cssErrorClass; }
Set the value of the 'style' attribute. May be a runtime expression.
/** * Set the value of the '{@code style}' attribute. * May be a runtime expression. */
public void setCssStyle(String cssStyle) { this.cssStyle = cssStyle; }
Get the value of the 'style' attribute. May be a runtime expression.
/** * Get the value of the '{@code style}' attribute. * May be a runtime expression. */
@Nullable protected String getCssStyle() { return this.cssStyle; }
Set the value of the 'lang' attribute. May be a runtime expression.
/** * Set the value of the '{@code lang}' attribute. * May be a runtime expression. */
public void setLang(String lang) { this.lang = lang; }
Get the value of the 'lang' attribute. May be a runtime expression.
/** * Get the value of the '{@code lang}' attribute. * May be a runtime expression. */
@Nullable protected String getLang() { return this.lang; }
Set the value of the 'title' attribute. May be a runtime expression.
/** * Set the value of the '{@code title}' attribute. * May be a runtime expression. */
public void setTitle(String title) { this.title = title; }
Get the value of the 'title' attribute. May be a runtime expression.
/** * Get the value of the '{@code title}' attribute. * May be a runtime expression. */
@Nullable protected String getTitle() { return this.title; }
Set the value of the 'dir' attribute. May be a runtime expression.
/** * Set the value of the '{@code dir}' attribute. * May be a runtime expression. */
public void setDir(String dir) { this.dir = dir; }
Get the value of the 'dir' attribute. May be a runtime expression.
/** * Get the value of the '{@code dir}' attribute. * May be a runtime expression. */
@Nullable protected String getDir() { return this.dir; }
Set the value of the 'tabindex' attribute. May be a runtime expression.
/** * Set the value of the '{@code tabindex}' attribute. * May be a runtime expression. */
public void setTabindex(String tabindex) { this.tabindex = tabindex; }
Get the value of the 'tabindex' attribute. May be a runtime expression.
/** * Get the value of the '{@code tabindex}' attribute. * May be a runtime expression. */
@Nullable protected String getTabindex() { return this.tabindex; }
Set the value of the 'onclick' attribute. May be a runtime expression.
/** * Set the value of the '{@code onclick}' attribute. * May be a runtime expression. */
public void setOnclick(String onclick) { this.onclick = onclick; }
Get the value of the 'onclick' attribute. May be a runtime expression.
/** * Get the value of the '{@code onclick}' attribute. * May be a runtime expression. */
@Nullable protected String getOnclick() { return this.onclick; }
Set the value of the 'ondblclick' attribute. May be a runtime expression.
/** * Set the value of the '{@code ondblclick}' attribute. * May be a runtime expression. */
public void setOndblclick(String ondblclick) { this.ondblclick = ondblclick; }
Get the value of the 'ondblclick' attribute. May be a runtime expression.
/** * Get the value of the '{@code ondblclick}' attribute. * May be a runtime expression. */
@Nullable protected String getOndblclick() { return this.ondblclick; }
Set the value of the 'onmousedown' attribute. May be a runtime expression.
/** * Set the value of the '{@code onmousedown}' attribute. * May be a runtime expression. */
public void setOnmousedown(String onmousedown) { this.onmousedown = onmousedown; }
Get the value of the 'onmousedown' attribute. May be a runtime expression.
/** * Get the value of the '{@code onmousedown}' attribute. * May be a runtime expression. */
@Nullable protected String getOnmousedown() { return this.onmousedown; }
Set the value of the 'onmouseup' attribute. May be a runtime expression.
/** * Set the value of the '{@code onmouseup}' attribute. * May be a runtime expression. */
public void setOnmouseup(String onmouseup) { this.onmouseup = onmouseup; }
Get the value of the 'onmouseup' attribute. May be a runtime expression.
/** * Get the value of the '{@code onmouseup}' attribute. * May be a runtime expression. */
@Nullable protected String getOnmouseup() { return this.onmouseup; }
Set the value of the 'onmouseover' attribute. May be a runtime expression.
/** * Set the value of the '{@code onmouseover}' attribute. * May be a runtime expression. */
public void setOnmouseover(String onmouseover) { this.onmouseover = onmouseover; }
Get the value of the 'onmouseover' attribute. May be a runtime expression.
/** * Get the value of the '{@code onmouseover}' attribute. * May be a runtime expression. */
@Nullable protected String getOnmouseover() { return this.onmouseover; }
Set the value of the 'onmousemove' attribute. May be a runtime expression.
/** * Set the value of the '{@code onmousemove}' attribute. * May be a runtime expression. */
public void setOnmousemove(String onmousemove) { this.onmousemove = onmousemove; }
Get the value of the 'onmousemove' attribute. May be a runtime expression.
/** * Get the value of the '{@code onmousemove}' attribute. * May be a runtime expression. */
@Nullable protected String getOnmousemove() { return this.onmousemove; }
Set the value of the 'onmouseout' attribute. May be a runtime expression.
/** * Set the value of the '{@code onmouseout}' attribute. * May be a runtime expression. */
public void setOnmouseout(String onmouseout) { this.onmouseout = onmouseout; }
Get the value of the 'onmouseout' attribute. May be a runtime expression.
/** * Get the value of the '{@code onmouseout}' attribute. * May be a runtime expression. */
@Nullable protected String getOnmouseout() { return this.onmouseout; }
Set the value of the 'onkeypress' attribute. May be a runtime expression.
/** * Set the value of the '{@code onkeypress}' attribute. * May be a runtime expression. */
public void setOnkeypress(String onkeypress) { this.onkeypress = onkeypress; }
Get the value of the 'onkeypress' attribute. May be a runtime expression.
/** * Get the value of the '{@code onkeypress}' attribute. * May be a runtime expression. */
@Nullable protected String getOnkeypress() { return this.onkeypress; }
Set the value of the 'onkeyup' attribute. May be a runtime expression.
/** * Set the value of the '{@code onkeyup}' attribute. * May be a runtime expression. */
public void setOnkeyup(String onkeyup) { this.onkeyup = onkeyup; }
Get the value of the 'onkeyup' attribute. May be a runtime expression.
/** * Get the value of the '{@code onkeyup}' attribute. * May be a runtime expression. */
@Nullable protected String getOnkeyup() { return this.onkeyup; }
Set the value of the 'onkeydown' attribute. May be a runtime expression.
/** * Set the value of the '{@code onkeydown}' attribute. * May be a runtime expression. */
public void setOnkeydown(String onkeydown) { this.onkeydown = onkeydown; }
Get the value of the 'onkeydown' attribute. May be a runtime expression.
/** * Get the value of the '{@code onkeydown}' attribute. * May be a runtime expression. */
@Nullable protected String getOnkeydown() { return this.onkeydown; }
Get the map of dynamic attributes.
/** * Get the map of dynamic attributes. */
@Nullable protected Map<String, Object> getDynamicAttributes() { return this.dynamicAttributes; }
{@inheritDoc}
/** * {@inheritDoc} */
@Override public void setDynamicAttribute(String uri, String localName, Object value) throws JspException { if (this.dynamicAttributes == null) { this.dynamicAttributes = new HashMap<>(); } if (!isValidDynamicAttribute(localName, value)) { throw new IllegalArgumentException( "Attribute " + localName + "=\"" + value + "\" is not allowed"); } this.dynamicAttributes.put(localName, value); }
Whether the given name-value pair is a valid dynamic attribute.
/** * Whether the given name-value pair is a valid dynamic attribute. */
protected boolean isValidDynamicAttribute(String localName, Object value) { return true; }
Writes the default attributes configured via this base class to the supplied TagWriter. Subclasses should call this when they want the base attribute set to be written to the output.
/** * Writes the default attributes configured via this base class to the supplied {@link TagWriter}. * Subclasses should call this when they want the base attribute set to be written to the output. */
@Override protected void writeDefaultAttributes(TagWriter tagWriter) throws JspException { super.writeDefaultAttributes(tagWriter); writeOptionalAttributes(tagWriter); }
Writes the optional attributes configured via this base class to the supplied TagWriter. The set of optional attributes that will be rendered includes any non-standard dynamic attributes. Called by writeDefaultAttributes(TagWriter).
/** * Writes the optional attributes configured via this base class to the supplied {@link TagWriter}. * The set of optional attributes that will be rendered includes any non-standard dynamic attributes. * Called by {@link #writeDefaultAttributes(TagWriter)}. */
protected void writeOptionalAttributes(TagWriter tagWriter) throws JspException { tagWriter.writeOptionalAttributeValue(CLASS_ATTRIBUTE, resolveCssClass()); tagWriter.writeOptionalAttributeValue(STYLE_ATTRIBUTE, ObjectUtils.getDisplayString(evaluate("cssStyle", getCssStyle()))); writeOptionalAttribute(tagWriter, LANG_ATTRIBUTE, getLang()); writeOptionalAttribute(tagWriter, TITLE_ATTRIBUTE, getTitle()); writeOptionalAttribute(tagWriter, DIR_ATTRIBUTE, getDir()); writeOptionalAttribute(tagWriter, TABINDEX_ATTRIBUTE, getTabindex()); writeOptionalAttribute(tagWriter, ONCLICK_ATTRIBUTE, getOnclick()); writeOptionalAttribute(tagWriter, ONDBLCLICK_ATTRIBUTE, getOndblclick()); writeOptionalAttribute(tagWriter, ONMOUSEDOWN_ATTRIBUTE, getOnmousedown()); writeOptionalAttribute(tagWriter, ONMOUSEUP_ATTRIBUTE, getOnmouseup()); writeOptionalAttribute(tagWriter, ONMOUSEOVER_ATTRIBUTE, getOnmouseover()); writeOptionalAttribute(tagWriter, ONMOUSEMOVE_ATTRIBUTE, getOnmousemove()); writeOptionalAttribute(tagWriter, ONMOUSEOUT_ATTRIBUTE, getOnmouseout()); writeOptionalAttribute(tagWriter, ONKEYPRESS_ATTRIBUTE, getOnkeypress()); writeOptionalAttribute(tagWriter, ONKEYUP_ATTRIBUTE, getOnkeyup()); writeOptionalAttribute(tagWriter, ONKEYDOWN_ATTRIBUTE, getOnkeydown()); if (!CollectionUtils.isEmpty(this.dynamicAttributes)) { for (Map.Entry<String, Object> entry : this.dynamicAttributes.entrySet()) { tagWriter.writeOptionalAttributeValue(entry.getKey(), getDisplayString(entry.getValue())); } } }
Gets the appropriate CSS class to use based on the state of the current BindStatus object.
/** * Gets the appropriate CSS class to use based on the state of the current * {@link org.springframework.web.servlet.support.BindStatus} object. */
protected String resolveCssClass() throws JspException { if (getBindStatus().isError() && StringUtils.hasText(getCssErrorClass())) { return ObjectUtils.getDisplayString(evaluate("cssErrorClass", getCssErrorClass())); } else { return ObjectUtils.getDisplayString(evaluate("cssClass", getCssClass())); } } }