KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > web > servlet > tags > form > AbstractDataBoundFormElementTag


1 /*
2  * Copyright 2002-2007 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.web.servlet.tags.form;
18
19 import java.beans.PropertyEditor JavaDoc;
20
21 import javax.servlet.jsp.JspException JavaDoc;
22 import javax.servlet.jsp.PageContext JavaDoc;
23
24 import org.springframework.beans.PropertyAccessor;
25 import org.springframework.core.Conventions;
26 import org.springframework.util.Assert;
27 import org.springframework.util.ObjectUtils;
28 import org.springframework.util.StringUtils;
29 import org.springframework.web.servlet.support.BindStatus;
30 import org.springframework.web.servlet.tags.NestedPathTag;
31
32 /**
33  * Base tag for all data-binding aware JSP form tags.
34  *
35  * <p>Provides the common {@link #setPath path} and {@link #setId id} properties.
36  * Provides sub-classes with utility methods for accessing the {@link BindStatus}
37  * of their bound value and also for {@link #writeOptionalAttribute interacting}
38  * with the {@link TagWriter}.
39  *
40  * @author Rob Harrop
41  * @author Juergen Hoeller
42  * @since 2.0
43  */

44 public abstract class AbstractDataBoundFormElementTag extends AbstractFormTag {
45
46     /**
47      * The '<code>id</code>' attribute of the rendered HTML tag.
48      */

49     public static final String JavaDoc ID_ATTRIBUTE = "id";
50
51     /**
52      * The name of the '<code>commandName</code>' attribute.
53      */

54     public static final String JavaDoc COMMAND_NAME_ATTRIBUTE = "commandName";
55
56     /**
57      * The name of the {@link javax.servlet.jsp.PageContext} attribute under which the
58      * command object name is exposed.
59      */

60     public static final String JavaDoc COMMAND_NAME_VARIABLE_NAME =
61             Conventions.getQualifiedAttributeName(AbstractFormTag.class, COMMAND_NAME_ATTRIBUTE);
62
63
64     /**
65      * The property path from the {@link FormTag#setCommandName command object}.
66      */

67     private String JavaDoc path;
68
69     /**
70      * The value of the '<code>id</code>' attribute.
71      */

72     private String JavaDoc id;
73
74     /**
75      * The {@link BindStatus} of this tag.
76      */

77     private BindStatus bindStatus;
78
79
80     /**
81      * Set the property path from the {@link FormTag#setCommandName command object}.
82      * May be a runtime expression. Required.
83      */

84     public void setPath(String JavaDoc path) {
85         Assert.hasText(path, "'path' must not be empty");
86         this.path = path;
87     }
88
89     /**
90      * Get the {@link #evaluate resolved} property path for the
91      * {@link FormTag#setCommandName command object}.
92      */

93     protected final String JavaDoc getPath() throws JspException JavaDoc {
94         return (String JavaDoc) evaluate("path", this.path);
95     }
96
97     /**
98      * Set the value of the '<code>id</code>' attribute.
99      * <p>Defaults to the value of {@link #getName}; may be a runtime expression.
100      * Note that the default value may not be valid for certain tags.
101      */

102     public void setId(String JavaDoc id) {
103         this.id = id;
104     }
105
106     /**
107      * Get the value of the '<code>id</code>' attribute.
108      * <p>May be a runtime expression.
109      */

110     public String JavaDoc getId() {
111         return this.id;
112     }
113
114
115     /**
116      * Writes the default set of attributes to the supplied {@link TagWriter}.
117      * Further abstract sub-classes should override this method to add in
118      * any additional default attributes but <strong>must</strong> remember
119      * to call the <code>super</code> method.
120      * <p>Concrete sub-classes should call this method when/if they want
121      * to render default attributes.
122      * @param tagWriter the {@link TagWriter} to which any attributes are to be {@link TagWriter#writeAttribute(String, String) written}
123      */

124     protected void writeDefaultAttributes(TagWriter tagWriter) throws JspException JavaDoc {
125         String JavaDoc id = getId();
126         if (StringUtils.hasText(id)) {
127             tagWriter.writeAttribute(ID_ATTRIBUTE, ObjectUtils.getDisplayString(evaluate(ID_ATTRIBUTE, id)));
128         }
129         else {
130             writeOptionalAttribute(tagWriter, ID_ATTRIBUTE, autogenerateId());
131         }
132         writeOptionalAttribute(tagWriter, "name", getName());
133     }
134
135     /**
136      * Autogenerate the '<code>id</code>' attribute value for this tag.
137      * <p>The default implementation simply delegates to {@link #getName}.
138      */

139     protected String JavaDoc autogenerateId() throws JspException JavaDoc {
140         return getName();
141     }
142
143     /**
144      * Get the value for the HTML '<code>name</code>' attribute.
145      * <p>The default implementation simply delegates to
146      * {@link #getCompletePath()} to use the property path as the name.
147      * For the most part this is desirable as it links with the server-side
148      * expectation for databinding. However, some subclasses may wish to change
149      * the value of the '<code>name</code>' attribute without changing the bind path.
150      * @return the value for the HTML '<code>name</code>' attribute
151      */

152     protected String JavaDoc getName() throws JspException JavaDoc {
153         return getCompletePath();
154     }
155
156     /**
157      * Get the bound value.
158      * @see #getBindStatus()
159      */

160     protected final Object JavaDoc getBoundValue() throws JspException JavaDoc {
161         return getBindStatus().getValue();
162     }
163
164     /**
165      * Get the {@link PropertyEditor}, if any, in use for value bound to this tag.
166      */

167     protected PropertyEditor JavaDoc getPropertyEditor() throws JspException JavaDoc {
168         return getBindStatus().getEditor();
169     }
170
171     /**
172      * Get the {@link BindStatus} for this tag.
173      */

174     protected BindStatus getBindStatus() throws JspException JavaDoc {
175         if (this.bindStatus == null) {
176             String JavaDoc resolvedPropertyPath = getPath();
177             String JavaDoc bindPath = getBindPath(resolvedPropertyPath);
178             // HTML escaping in tags is performed by the ValueFormatter class.
179
this.bindStatus = new BindStatus(getRequestContext(), bindPath, false);
180         }
181         return this.bindStatus;
182     }
183
184     /**
185      * Get the final bind path including the exposed {@link FormTag command name} and
186      * any {@link NestedPathTag nested paths}.
187      */

188     private String JavaDoc getBindPath(String JavaDoc resolvedSubPath) {
189         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
190         addBindPathElement(sb, getCommandName());
191         addBindPathElement(sb, getNestedPath());
192         addBindPathElement(sb, resolvedSubPath);
193         return sb.toString();
194     }
195
196     private void addBindPathElement(StringBuffer JavaDoc sb, String JavaDoc pathElement) {
197         if (StringUtils.hasLength(pathElement)) {
198             int length = sb.length();
199             if (length > 0 && sb.charAt(length - 1) != PropertyAccessor.NESTED_PROPERTY_SEPARATOR_CHAR) {
200                 sb.append(PropertyAccessor.NESTED_PROPERTY_SEPARATOR_CHAR);
201             }
202             sb.append(pathElement);
203         }
204     }
205
206     /**
207      * Get the value of the nested path that may have been exposed by the
208      * {@link NestedPathTag}.
209      */

210     protected String JavaDoc getNestedPath() {
211         return (String JavaDoc) this.pageContext.getAttribute(NestedPathTag.NESTED_PATH_VARIABLE_NAME, PageContext.REQUEST_SCOPE);
212     }
213
214     /**
215      * Build the complete path for this tag, including the nested path.
216      * @see #getNestedPath()
217      * @see #getPath()
218      */

219     protected String JavaDoc getCompletePath() throws JspException JavaDoc {
220         String JavaDoc nestedPath = getNestedPath();
221         return (nestedPath != null ? nestedPath + getPath() : getPath());
222     }
223
224     private String JavaDoc getCommandName() {
225         return (String JavaDoc) this.pageContext.getAttribute(COMMAND_NAME_VARIABLE_NAME, PageContext.REQUEST_SCOPE);
226     }
227
228     /**
229      * Disposes of the {@link BindStatus} instance.
230      */

231     public void doFinally() {
232         super.doFinally();
233         this.bindStatus = null;
234     }
235
236 }
237
Popular Tags