001/*
002 * Copyright 2002-2012 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.web.servlet.tags.form;
018
019import javax.servlet.jsp.JspException;
020
021/**
022 * Abstract base class to provide common methods for
023 * implementing databinding-aware JSP tags for rendering an HTML '{@code input}'
024 * element with a '{@code type}' of '{@code checkbox}' or '{@code radio}'.
025 *
026 * @author Thomas Risberg
027 * @author Juergen Hoeller
028 * @author Rossen Stoyanchev
029 * @since 2.5
030 */
031@SuppressWarnings("serial")
032public abstract class AbstractCheckedElementTag extends AbstractHtmlInputElementTag {
033
034        /**
035         * Render the '{@code input(checkbox)}' with the supplied value, marking the
036         * '{@code input}' element as 'checked' if the supplied value matches the
037         * bound value.
038         */
039        protected void renderFromValue(Object value, TagWriter tagWriter) throws JspException {
040                renderFromValue(value, value, tagWriter);
041        }
042
043        /**
044         * Render the '{@code input(checkbox)}' with the supplied value, marking the
045         * '{@code input}' element as 'checked' if the supplied value matches the
046         * bound value.
047         */
048        protected void renderFromValue(Object item, Object value, TagWriter tagWriter) throws JspException {
049                String displayValue = convertToDisplayString(value);
050                tagWriter.writeAttribute("value", processFieldValue(getName(), displayValue, getInputType()));
051                if (isOptionSelected(value) || (value != item && isOptionSelected(item))) {
052                        tagWriter.writeAttribute("checked", "checked");
053                }
054        }
055
056        /**
057         * Determines whether the supplied value matched the selected value
058         * through delegating to {@link SelectedValueComparator#isSelected}.
059         */
060        private boolean isOptionSelected(Object value) throws JspException {
061                return SelectedValueComparator.isSelected(getBindStatus(), value);
062        }
063
064        /**
065         * Render the '{@code input(checkbox)}' with the supplied value, marking
066         * the '{@code input}' element as 'checked' if the supplied Boolean is
067         * {@code true}.
068         */
069        protected void renderFromBoolean(Boolean boundValue, TagWriter tagWriter) throws JspException {
070                tagWriter.writeAttribute("value", processFieldValue(getName(), "true", getInputType()));
071                if (boundValue) {
072                        tagWriter.writeAttribute("checked", "checked");
073                }
074        }
075
076        /**
077         * Return a unique ID for the bound name within the current PageContext.
078         */
079        @Override
080        protected String autogenerateId() throws JspException {
081                return TagIdGenerator.nextId(super.autogenerateId(), this.pageContext);
082        }
083
084
085        /**
086         * Writes the '{@code input}' element to the supplied
087         * {@link TagWriter},
088         * marking it as 'checked' if appropriate.
089         */
090        @Override
091        protected abstract int writeTagContent(TagWriter tagWriter) throws JspException;
092
093        /**
094         * Flags "type" as an illegal dynamic attribute.
095         */
096        @Override
097        protected boolean isValidDynamicAttribute(String localName, Object value) {
098                return !"type".equals(localName);
099        }
100
101        /**
102         * Return the type of the HTML input element to generate:
103         * "checkbox" or "radio".
104         */
105        protected abstract String getInputType();
106
107}