001/*
002 * Copyright 2002-2018 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
021import org.springframework.lang.Nullable;
022import org.springframework.util.Assert;
023
024/**
025 * Abstract base class to provide common methods for implementing databinding-aware
026 * JSP tags for rendering a <i>single</i> HTML '{@code input}' element with a
027 * '{@code type}' of '{@code checkbox}' or '{@code radio}'.
028 *
029 * @author Juergen Hoeller
030 * @since 2.5.2
031 */
032@SuppressWarnings("serial")
033public abstract class AbstractSingleCheckedElementTag extends AbstractCheckedElementTag {
034
035        /**
036         * The value of the '{@code value}' attribute.
037         */
038        @Nullable
039        private Object value;
040
041        /**
042         * The value of the '{@code label}' attribute.
043         */
044        @Nullable
045        private Object label;
046
047
048        /**
049         * Set the value of the '{@code value}' attribute.
050         * May be a runtime expression.
051         */
052        public void setValue(Object value) {
053                this.value = value;
054        }
055
056        /**
057         * Get the value of the '{@code value}' attribute.
058         */
059        @Nullable
060        protected Object getValue() {
061                return this.value;
062        }
063
064        /**
065         * Set the value of the '{@code label}' attribute.
066         * May be a runtime expression.
067         */
068        public void setLabel(Object label) {
069                this.label = label;
070        }
071
072        /**
073         * Get the value of the '{@code label}' attribute.
074         */
075        @Nullable
076        protected Object getLabel() {
077                return this.label;
078        }
079
080
081        /**
082         * Renders the '{@code input(radio)}' element with the configured
083         * {@link #setValue(Object) value}. Marks the element as checked if the
084         * value matches the {@link #getValue bound value}.
085         */
086        @Override
087        protected int writeTagContent(TagWriter tagWriter) throws JspException {
088                tagWriter.startTag("input");
089                String id = resolveId();
090                writeOptionalAttribute(tagWriter, "id", id);
091                writeOptionalAttribute(tagWriter, "name", getName());
092                writeOptionalAttributes(tagWriter);
093                writeTagDetails(tagWriter);
094                tagWriter.endTag();
095
096                Object resolvedLabel = evaluate("label", getLabel());
097                if (resolvedLabel != null) {
098                        Assert.state(id != null, "Label id is required");
099                        tagWriter.startTag("label");
100                        tagWriter.writeAttribute("for", id);
101                        tagWriter.appendValue(convertToDisplayString(resolvedLabel));
102                        tagWriter.endTag();
103                }
104
105                return SKIP_BODY;
106        }
107
108        /**
109         * Write the details for the given primary tag:
110         * i.e. special attributes and the tag's value.
111         */
112        protected abstract void writeTagDetails(TagWriter tagWriter) throws JspException;
113
114}