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
021/**
022 * Data-binding-aware JSP tag for rendering an HTML '{@code input}'
023 * element with a '{@code type}' of '{@code text}'.
024 *
025 * @author Rob Harrop
026 * @author Juergen Hoeller
027 * @author Rossen Stoyanchev
028 * @since 2.0
029 */
030@SuppressWarnings("serial")
031public class InputTag extends AbstractHtmlInputElementTag {
032
033        public static final String SIZE_ATTRIBUTE = "size";
034
035        public static final String MAXLENGTH_ATTRIBUTE = "maxlength";
036
037        public static final String ALT_ATTRIBUTE = "alt";
038
039        public static final String ONSELECT_ATTRIBUTE = "onselect";
040
041        public static final String AUTOCOMPLETE_ATTRIBUTE = "autocomplete";
042
043        @Deprecated
044        public static final String READONLY_ATTRIBUTE = "readonly";
045
046
047        private String size;
048
049        private String maxlength;
050
051        private String alt;
052
053        private String onselect;
054
055        private String autocomplete;
056
057
058        /**
059         * Set the value of the '{@code size}' attribute.
060         * May be a runtime expression.
061         */
062        public void setSize(String size) {
063                this.size = size;
064        }
065
066        /**
067         * Get the value of the '{@code size}' attribute.
068         */
069        protected String getSize() {
070                return this.size;
071        }
072
073        /**
074         * Set the value of the '{@code maxlength}' attribute.
075         * May be a runtime expression.
076         */
077        public void setMaxlength(String maxlength) {
078                this.maxlength = maxlength;
079        }
080
081        /**
082         * Get the value of the '{@code maxlength}' attribute.
083         */
084        protected String getMaxlength() {
085                return this.maxlength;
086        }
087
088        /**
089         * Set the value of the '{@code alt}' attribute.
090         * May be a runtime expression.
091         */
092        public void setAlt(String alt) {
093                this.alt = alt;
094        }
095
096        /**
097         * Get the value of the '{@code alt}' attribute.
098         */
099        protected String getAlt() {
100                return this.alt;
101        }
102
103        /**
104         * Set the value of the '{@code onselect}' attribute.
105         * May be a runtime expression.
106         */
107        public void setOnselect(String onselect) {
108                this.onselect = onselect;
109        }
110
111        /**
112         * Get the value of the '{@code onselect}' attribute.
113         */
114        protected String getOnselect() {
115                return this.onselect;
116        }
117
118        /**
119         * Set the value of the '{@code autocomplete}' attribute.
120         * May be a runtime expression.
121         */
122        public void setAutocomplete(String autocomplete) {
123                this.autocomplete = autocomplete;
124        }
125
126        /**
127         * Get the value of the '{@code autocomplete}' attribute.
128         */
129        protected String getAutocomplete() {
130                return this.autocomplete;
131        }
132
133
134        /**
135         * Writes the '{@code input}' tag to the supplied {@link TagWriter}.
136         * Uses the value returned by {@link #getType()} to determine which
137         * type of '{@code input}' element to render.
138         */
139        @Override
140        protected int writeTagContent(TagWriter tagWriter) throws JspException {
141                tagWriter.startTag("input");
142
143                writeDefaultAttributes(tagWriter);
144                if (!hasDynamicTypeAttribute()) {
145                        tagWriter.writeAttribute("type", getType());
146                }
147                writeValue(tagWriter);
148
149                // custom optional attributes
150                writeOptionalAttribute(tagWriter, SIZE_ATTRIBUTE, getSize());
151                writeOptionalAttribute(tagWriter, MAXLENGTH_ATTRIBUTE, getMaxlength());
152                writeOptionalAttribute(tagWriter, ALT_ATTRIBUTE, getAlt());
153                writeOptionalAttribute(tagWriter, ONSELECT_ATTRIBUTE, getOnselect());
154                writeOptionalAttribute(tagWriter, AUTOCOMPLETE_ATTRIBUTE, getAutocomplete());
155
156                tagWriter.endTag();
157                return SKIP_BODY;
158        }
159
160        /**
161         * Writes the '{@code value}' attribute to the supplied {@link TagWriter}.
162         * Subclasses may choose to override this implementation to control exactly
163         * when the value is written.
164         */
165        protected void writeValue(TagWriter tagWriter) throws JspException {
166                String value = getDisplayString(getBoundValue(), getPropertyEditor());
167                String type = (hasDynamicTypeAttribute() ? (String) getDynamicAttributes().get("type") : getType());
168                tagWriter.writeAttribute("value", processFieldValue(getName(), value, type));
169        }
170
171        private boolean hasDynamicTypeAttribute() {
172                return (getDynamicAttributes() != null && getDynamicAttributes().containsKey("type"));
173        }
174
175        /**
176         * Flags {@code type="checkbox"} and {@code type="radio"} as illegal
177         * dynamic attributes.
178         */
179        @Override
180        protected boolean isValidDynamicAttribute(String localName, Object value) {
181                return !("type".equals(localName) && ("checkbox".equals(value) || "radio".equals(value)));
182        }
183
184        /**
185         * Get the value of the '{@code type}' attribute. Subclasses
186         * can override this to change the type of '{@code input}' element
187         * rendered. Default value is '{@code text}'.
188         */
189        protected String getType() {
190                return "text";
191        }
192
193}