KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > riotfamily > forms > element > AbstractTextElement


1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1
3  * The contents of this file are subject to the Mozilla Public License Version
4  * 1.1 (the "License"); you may not use this file except in compliance with
5  * the License. You may obtain a copy of the License at
6  * http://www.mozilla.org/MPL/
7  *
8  * Software distributed under the License is distributed on an "AS IS" basis,
9  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
10  * for the specific language governing rights and limitations under the
11  * License.
12  *
13  * The Original Code is Riot.
14  *
15  * The Initial Developer of the Original Code is
16  * Neteye GmbH.
17  * Portions created by the Initial Developer are Copyright (C) 2006
18  * the Initial Developer. All Rights Reserved.
19  *
20  * Contributor(s):
21  * Felix Gnass [fgnass at neteye dot de]
22  *
23  * ***** END LICENSE BLOCK ***** */

24 package org.riotfamily.forms.element;
25
26 import java.beans.PropertyEditor JavaDoc;
27 import java.io.PrintWriter JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.List JavaDoc;
31
32 import org.riotfamily.common.markup.Html;
33 import org.riotfamily.common.markup.TagWriter;
34 import org.riotfamily.common.util.PasswordGenerator;
35 import org.riotfamily.forms.AbstractEditorBase;
36 import org.riotfamily.forms.AbstractElement;
37 import org.riotfamily.forms.Editor;
38 import org.riotfamily.forms.ErrorUtils;
39 import org.riotfamily.forms.event.ChangeEvent;
40 import org.riotfamily.forms.event.ChangeListener;
41 import org.riotfamily.forms.event.JavaScriptEvent;
42 import org.riotfamily.forms.event.JavaScriptEventAdapter;
43 import org.riotfamily.forms.request.FormRequest;
44 import org.springframework.util.Assert;
45 import org.springframework.util.ObjectUtils;
46 import org.springframework.util.StringUtils;
47
48
49 /**
50  * Abstract base class for elements that handle textual input from a single HTTP
51  * parameter. Optionally a <code>PropertyEditor</code> can be set to convert
52  * the text into an arbitrary object.
53  *
54  * @see org.riotfamily.forms.EditorBinder#bind(Editor, String)
55  */

56 public abstract class AbstractTextElement extends AbstractEditorBase
57         implements Editor JavaDoc, JavaScriptEventAdapter {
58
59     private String JavaDoc type = "text";
60
61     private Integer JavaDoc maxLength;
62
63     private boolean trim = true;
64
65     private boolean randomParamName;
66
67     private List JavaDoc listeners;
68
69     private String JavaDoc text;
70
71     private Object JavaDoc value;
72
73     private PropertyEditor JavaDoc propertyEditor;
74
75     private boolean validateOnChange = false;
76
77     public AbstractTextElement() {
78     }
79
80     public AbstractTextElement(String JavaDoc type) {
81         this.type = type;
82     }
83
84     public String JavaDoc getType() {
85         return type;
86     }
87
88     public void setType(String JavaDoc type) {
89         this.type = type;
90     }
91
92     /**
93      * Overrides {@link AbstractElement#getStyleClass()} and returns the
94      * element's type if no custom style has been set.
95      *
96      * @see #getType()
97      */

98     public String JavaDoc getStyleClass() {
99         String JavaDoc styleClass = super.getStyleClass();
100         return styleClass != null ? styleClass : type;
101     }
102
103     public Integer JavaDoc getMaxLength() {
104         return this.maxLength;
105     }
106
107     /**
108      * Sets the maximum string length.
109      */

110     public void setMaxLength(Integer JavaDoc maxLength) {
111         this.maxLength = maxLength;
112     }
113
114     /**
115      * Sets whether the user input should be trimmed.
116      */

117     public void setTrim(boolean trim) {
118         this.trim = trim;
119     }
120
121     /**
122      * Sets whether a random (nonce) word should be used as parameter name
123      * to disable the browser's autocompletion feature.
124      */

125     public void setRandomParamName(boolean randomParamName) {
126         //REVIST Consider using setAttribute("autocomlete", "off") instead
127
this.randomParamName = randomParamName;
128     }
129
130     /**
131      * Sets whether the element should be validated as soon as a change event
132      * is received.
133      */

134     public void setValidateOnChange(boolean validateOnChange) {
135         this.validateOnChange = validateOnChange;
136     }
137
138     public final void setPropertyEditor(PropertyEditor JavaDoc propertyEditor) {
139         this.propertyEditor = propertyEditor;
140     }
141
142     protected final PropertyEditor JavaDoc getPropertyEditor() {
143         return propertyEditor;
144     }
145
146     protected void initPropertyEditor() {
147         if (propertyEditor == null) {
148             this.propertyEditor = getEditorBinding().getPropertyEditor();
149         }
150     }
151
152     protected void afterBindingSet() {
153         initPropertyEditor();
154     }
155
156     public final String JavaDoc getText() {
157         return text;
158     }
159
160     /**
161      * Sets the element's text value. If {@link #setTrim(boolean)} is set to
162      * <code>true</code>, leading and trailing whitespaces are stripped.
163      */

164     public void setText(String JavaDoc text) {
165         if (trim && text != null) {
166             this.text = text.trim();
167         }
168         else {
169             this.text = text;
170         }
171     }
172
173     public final Object JavaDoc getValue() {
174         return value;
175     }
176
177     public void setValue(Object JavaDoc value) {
178         this.value = value;
179         setTextFromValue();
180     }
181
182     protected void setTextFromValue() {
183         if (value == null) {
184             text = null;
185         }
186         else if (value instanceof String JavaDoc) {
187             text = (String JavaDoc) value;
188         }
189         else {
190             if (propertyEditor == null) {
191                 initPropertyEditor();
192                 Assert.notNull(propertyEditor, "Can't handle value of type "
193                         + value.getClass().getName() + " - no PropertyEditor "
194                         + "present");
195             }
196             propertyEditor.setValue(value);
197             text = propertyEditor.getAsText();
198         }
199     }
200
201     public void processRequest(FormRequest request) {
202         text = request.getParameter(getParamName());
203         validate(true);
204         if (!ErrorUtils.hasErrors(this)) {
205             setValueFromText();
206         }
207     }
208
209     public void handleJavaScriptEvent(JavaScriptEvent event) {
210         if (event.getType() == JavaScriptEvent.ON_CHANGE) {
211             text = event.getValue();
212             ErrorUtils.removeErrors(this);
213             validate(false);
214             if (!ErrorUtils.hasErrors(this)) {
215                 setValueFromText();
216             }
217         }
218     }
219
220     protected void setValueFromText() {
221         Object JavaDoc oldValue = value;
222         if (!StringUtils.hasText(text)) {
223             value = null;
224         }
225         else {
226             if (propertyEditor != null) {
227                 propertyEditor.setAsText(text);
228                 value = propertyEditor.getValue();
229             }
230             else {
231                 value = text;
232             }
233         }
234         if (!ObjectUtils.nullSafeEquals(value, oldValue)) {
235             fireChangeEvent(value, oldValue);
236         }
237     }
238
239     protected void validate(boolean formSubmitted) {
240         if (isRequired() && !StringUtils.hasLength(text)) {
241             ErrorUtils.reject(this, "required");
242         }
243     }
244
245     protected String JavaDoc getDesiredParamName() {
246         if (randomParamName) {
247             return PasswordGenerator.getDefaultInstance().generate();
248         }
249         return super.getDesiredParamName();
250     }
251
252     public void renderInternal(PrintWriter JavaDoc writer) {
253         TagWriter input = new TagWriter(writer);
254         input.startEmpty(Html.INPUT)
255                 .attribute(Html.INPUT_TYPE, getType())
256                 .attribute(Html.COMMON_CLASS, getStyleClass())
257                 .attribute(Html.COMMON_ID, getId())
258                 .attribute(Html.INPUT_NAME, getParamName())
259                 .attribute(Html.INPUT_VALUE, getText());
260         if (getMaxLength() != null) {
261             input.attribute(Html.INPUT_MAX_LENGTH, getMaxLength().intValue());
262         }
263         input.end();
264     }
265
266     public void addChangeListener(ChangeListener listener) {
267         if (listeners == null) {
268             listeners = new ArrayList JavaDoc();
269         }
270         listeners.add(listener);
271     }
272
273     protected void fireChangeEvent(Object JavaDoc newValue, Object JavaDoc oldValue) {
274         if (listeners != null) {
275             ChangeEvent event = new ChangeEvent(this, newValue, oldValue);
276             Iterator JavaDoc it = listeners.iterator();
277             while (it.hasNext()) {
278                 ChangeListener listener = (ChangeListener) it.next();
279                 listener.valueChanged(event);
280             }
281         }
282     }
283
284     public int getEventTypes() {
285         if (validateOnChange || listeners != null) {
286             return JavaScriptEvent.ON_CHANGE;
287         }
288         return JavaScriptEvent.NONE;
289     }
290
291 }
Popular Tags