Source code: javax/faces/component/UIInput.java
1 /*
2 * Copyright 2004 The Apache Software Foundation.
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 package javax.faces.component;
17
18 import javax.faces.application.FacesMessage;
19 import javax.faces.context.FacesContext;
20 import javax.faces.convert.Converter;
21 import javax.faces.convert.ConverterException;
22 import javax.faces.el.EvaluationException;
23 import javax.faces.el.MethodBinding;
24 import javax.faces.el.ValueBinding;
25 import javax.faces.event.AbortProcessingException;
26 import javax.faces.event.FacesEvent;
27 import javax.faces.event.ValueChangeEvent;
28 import javax.faces.event.ValueChangeListener;
29 import javax.faces.render.Renderer;
30 import javax.faces.validator.Validator;
31 import java.util.ArrayList;
32 import java.util.List;
33
34 /**
35 * see Javadoc of JSF Specification
36 *
37 * @author Manfred Geiler (latest modification by $Author: mbr $)
38 * @version $Revision: 231024 $ $Date: 2005-08-09 08:37:36 -0400 (Tue, 09 Aug 2005) $
39 */
40 public class UIInput
41 extends UIOutput
42 implements EditableValueHolder
43 {
44 public static final String CONVERSION_MESSAGE_ID = "javax.faces.component.UIInput.CONVERSION";
45 public static final String REQUIRED_MESSAGE_ID = "javax.faces.component.UIInput.REQUIRED";
46
47 private static final Validator[] EMPTY_VALIDATOR_ARRAY = new Validator[0];
48
49 private Object _submittedValue = null;
50 private boolean _localValueSet = false;
51 private boolean _valid = true;
52 private MethodBinding _validator = null;
53 private MethodBinding _valueChangeListener = null;
54 private List _validatorList = null;
55
56 public Object getSubmittedValue()
57 {
58 return _submittedValue;
59 }
60
61 public void setSubmittedValue(Object submittedValue)
62 {
63 _submittedValue = submittedValue;
64 }
65
66 public void setValue(Object value)
67 {
68 setLocalValueSet(true);
69 super.setValue(value);
70 }
71
72 public boolean isLocalValueSet()
73 {
74 return _localValueSet;
75 }
76
77 public void setLocalValueSet(boolean localValueSet)
78 {
79 _localValueSet = localValueSet;
80 }
81
82 public boolean isValid()
83 {
84 return _valid;
85 }
86
87 public void setValid(boolean valid)
88 {
89 _valid = valid;
90 }
91
92 public MethodBinding getValidator()
93 {
94 return _validator;
95 }
96
97 public void setValidator(MethodBinding validator)
98 {
99 _validator = validator;
100 }
101
102 public MethodBinding getValueChangeListener()
103 {
104 return _valueChangeListener;
105 }
106
107 public void setValueChangeListener(MethodBinding valueChangeListener)
108 {
109 _valueChangeListener = valueChangeListener;
110 }
111
112 public void processDecodes(FacesContext context)
113 {
114 if (context == null) throw new NullPointerException("context");
115 if (!isRendered()) return;
116 super.processDecodes(context);
117 if (isImmediate())
118 {
119 try
120 {
121 validate(context);
122 }
123 catch (RuntimeException e)
124 {
125 context.renderResponse();
126 throw e;
127 }
128 if (!isValid())
129 {
130 context.renderResponse();
131 }
132 }
133 }
134
135 public void processValidators(FacesContext context)
136 {
137 if (context == null) throw new NullPointerException("context");
138 if (!isRendered()) return;
139 super.processValidators(context);
140 if (!isImmediate())
141 {
142 try
143 {
144 validate(context);
145 }
146 catch (RuntimeException e)
147 {
148 context.renderResponse();
149 throw e;
150 }
151 if (!isValid())
152 {
153 context.renderResponse();
154 }
155 }
156 }
157
158 public void processUpdates(FacesContext context)
159 {
160 if (context == null) throw new NullPointerException("context");
161 if (!isRendered()) return;
162 super.processUpdates(context);
163 try
164 {
165 updateModel(context);
166 }
167 catch (RuntimeException e)
168 {
169 context.renderResponse();
170 throw e;
171 }
172 if (!isValid())
173 {
174 context.renderResponse();
175 }
176 }
177
178 public void decode(FacesContext context)
179 {
180 //We (re)set to valid, so that component automatically gets (re)validated
181 setValid(true);
182 super.decode(context);
183 }
184
185 public void broadcast(FacesEvent event)
186 throws AbortProcessingException
187 {
188 if (!(event instanceof ValueChangeEvent))
189 {
190 throw new IllegalArgumentException("FacesEvent of class " + event.getClass().getName() + " not supported by UIInput");
191 }
192
193 super.broadcast(event);
194
195 MethodBinding valueChangeListenerBinding = getValueChangeListener();
196 if (valueChangeListenerBinding != null)
197 {
198 try
199 {
200 valueChangeListenerBinding.invoke(getFacesContext(),
201 new Object[]{event});
202 }
203 catch (EvaluationException e)
204 {
205 Throwable cause = e.getCause();
206 if (cause != null && cause instanceof AbortProcessingException)
207 {
208 throw (AbortProcessingException)cause;
209 }
210 else
211 {
212 throw e;
213 }
214 }
215 }
216 }
217
218 public void updateModel(FacesContext context)
219 {
220 if (!isValid()) return;
221 if (!isLocalValueSet()) return;
222 ValueBinding vb = getValueBinding("value");
223 if (vb == null) return;
224 try
225 {
226 vb.setValue(context, getLocalValue());
227 setValue(null);
228 setLocalValueSet(false);
229 }
230 catch (RuntimeException e)
231 {
232 //Object[] args = {getId()};
233 context.getExternalContext().log(e.getMessage(), e);
234 _MessageUtils.addErrorMessage(context, this,CONVERSION_MESSAGE_ID,new Object[]{getId()});
235 setValid(false);
236 }
237 }
238
239 protected void validateValue(FacesContext context,Object convertedValue)
240 {
241 boolean empty = convertedValue == null ||
242 (convertedValue instanceof String
243 && ((String)convertedValue).length() == 0);
244
245 if (isRequired() && empty)
246 {
247 _MessageUtils.addErrorMessage(context, this, REQUIRED_MESSAGE_ID,new Object[]{getId()});
248 setValid(false);
249 return;
250 }
251
252 if (!empty)
253 {
254 _ComponentUtils.callValidators(context, this, convertedValue);
255 }
256
257 }
258
259 public void validate(FacesContext context)
260 {
261 if (context == null) throw new NullPointerException("context");
262 Object submittedValue = getSubmittedValue();
263 if (submittedValue == null) return;
264
265 Object convertedValue = getConvertedValue(context, submittedValue);
266
267 if (!isValid()) return;
268
269 validateValue(context, convertedValue);
270
271 if (!isValid()) return;
272
273 Object previousValue = getValue();
274 setValue(convertedValue);
275 setSubmittedValue(null);
276 if (compareValues(previousValue, convertedValue))
277 {
278 queueEvent(new ValueChangeEvent(this, previousValue, convertedValue));
279 }
280 }
281
282 protected Object getConvertedValue(FacesContext context, Object submittedValue)
283 {
284 try
285 {
286 Renderer renderer = getRenderer(context);
287 if (renderer != null)
288 {
289 return renderer.getConvertedValue(context, this, submittedValue);
290 }
291 else if (submittedValue instanceof String)
292 {
293 Converter converter = _SharedRendererUtils.findUIOutputConverter(context, this);
294 if (converter != null)
295 {
296 return converter.getAsObject(context, this, (String)submittedValue);
297 }
298 }
299 }
300 catch (ConverterException e)
301 {
302 FacesMessage facesMessage = e.getFacesMessage();
303 if (facesMessage != null)
304 {
305 context.addMessage(getClientId(context), facesMessage);
306 }
307 else
308 {
309 _MessageUtils.addErrorMessage(context, this, CONVERSION_MESSAGE_ID,new Object[]{getId()});
310 }
311 setValid(false);
312 }
313 return submittedValue;
314 }
315
316
317
318 protected boolean compareValues(Object previous,
319 Object value)
320 {
321 return !((previous == null && value == null) ||
322 (previous != null && value != null && previous.equals(value)));
323 }
324
325 public void addValidator(Validator validator)
326 {
327 if (validator == null) throw new NullPointerException("validator");
328 if (_validatorList == null)
329 {
330 _validatorList = new ArrayList();
331 }
332 _validatorList.add(validator);
333 }
334
335 public Validator[] getValidators()
336 {
337 return _validatorList != null ?
338 (Validator[])_validatorList.toArray(new Validator[_validatorList.size()]) :
339 EMPTY_VALIDATOR_ARRAY;
340 }
341
342 public void removeValidator(Validator validator)
343 {
344 if (validator == null) throw new NullPointerException("validator");
345 if (_validatorList != null)
346 {
347 _validatorList.remove(validator);
348 }
349 }
350
351 public void addValueChangeListener(ValueChangeListener listener)
352 {
353 addFacesListener(listener);
354 }
355
356 public ValueChangeListener[] getValueChangeListeners()
357 {
358 return (ValueChangeListener[])getFacesListeners(ValueChangeListener.class);
359 }
360
361 public void removeValueChangeListener(ValueChangeListener listener)
362 {
363 removeFacesListener(listener);
364 }
365
366 public Object saveState(FacesContext context)
367 {
368 Object values[] = new Object[9];
369 values[0] = super.saveState(context);
370 values[1] = _immediate;
371 values[2] = Boolean.valueOf(_localValueSet);
372 values[3] = _required;
373 values[4] = _submittedValue;
374 values[5] = Boolean.valueOf(_valid);
375 values[6] = saveAttachedState(context, _validator);
376 values[7] = saveAttachedState(context, _valueChangeListener);
377 values[8] = saveAttachedState(context, _validatorList);
378 return ((Object)(values));
379 }
380
381 public void restoreState(FacesContext context, Object state)
382 {
383 Object values[] = (Object[])state;
384 super.restoreState(context, values[0]);
385 _immediate = (Boolean)values[1];
386 _localValueSet = ((Boolean)values[2]).booleanValue();
387 _required = (Boolean)values[3];
388 _submittedValue = (Object)values[4];
389 _valid = ((Boolean)values[5]).booleanValue();
390 _validator = (MethodBinding)restoreAttachedState(context, values[6]);
391 _valueChangeListener = (MethodBinding)restoreAttachedState(context, values[7]);
392 _validatorList = (List)restoreAttachedState(context, values[8]);
393 }
394
395
396 //------------------ GENERATED CODE BEGIN (do not modify!) --------------------
397
398 public static final String COMPONENT_TYPE = "javax.faces.Input";
399 public static final String COMPONENT_FAMILY = "javax.faces.Input";
400 private static final String DEFAULT_RENDERER_TYPE = "javax.faces.Text";
401 private static final boolean DEFAULT_IMMEDIATE = false;
402 private static final boolean DEFAULT_REQUIRED = false;
403
404 private Boolean _immediate = null;
405 private Boolean _required = null;
406
407 public UIInput()
408 {
409 setRendererType(DEFAULT_RENDERER_TYPE);
410 }
411
412 public String getFamily()
413 {
414 return COMPONENT_FAMILY;
415 }
416
417 public void setImmediate(boolean immediate)
418 {
419 _immediate = Boolean.valueOf(immediate);
420 }
421
422 public boolean isImmediate()
423 {
424 if (_immediate != null) return _immediate.booleanValue();
425 ValueBinding vb = getValueBinding("immediate");
426 Boolean v = vb != null ? (Boolean)vb.getValue(getFacesContext()) : null;
427 return v != null ? v.booleanValue() : DEFAULT_IMMEDIATE;
428 }
429
430 public void setRequired(boolean required)
431 {
432 _required = Boolean.valueOf(required);
433 }
434
435 public boolean isRequired()
436 {
437 if (_required != null) return _required.booleanValue();
438 ValueBinding vb = getValueBinding("required");
439 Boolean v = vb != null ? (Boolean)vb.getValue(getFacesContext()) : null;
440 return v != null ? v.booleanValue() : DEFAULT_REQUIRED;
441 }
442
443
444 //------------------ GENERATED CODE END ---------------------------------------
445 }