1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.trinidad.validator;
20
21 import java.util.Date;
22
23 import javax.el.ValueExpression;
24
25 import javax.faces.application.FacesMessage;
26 import javax.faces.component.StateHolder;
27 import javax.faces.component.UIComponent;
28 import javax.faces.component.ValueHolder;
29 import javax.faces.context.FacesContext;
30 import javax.faces.convert.Converter;
31 import javax.faces.convert.DateTimeConverter;
32 import javax.faces.el.ValueBinding;
33 import javax.faces.validator.Validator;
34 import javax.faces.validator.ValidatorException;
35
36 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
37 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFValidator;
38 import org.apache.myfaces.trinidad.bean.FacesBean;
39 import org.apache.myfaces.trinidad.bean.PropertyKey;
40 import org.apache.myfaces.trinidad.util.ComponentUtils;
41 import org.apache.myfaces.trinidad.util.MessageFactory;
42 import org.apache.myfaces.trinidad.logging.TrinidadLogger;
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84 @JSFValidator(configExcluded=true)
85 public class DateTimeRangeValidator implements Validator, StateHolder {
86
87
88 public static final String VALIDATOR_ID = "org.apache.myfaces.trinidad.DateTimeRange";
89
90
91
92
93
94
95
96
97
98
99 public static final String MAXIMUM_MESSAGE_ID =
100 "org.apache.myfaces.trinidad.validator.DateTimeRangeValidator.MAXIMUM";
101
102
103
104
105
106
107
108
109 public static final String MINIMUM_MESSAGE_ID =
110 "org.apache.myfaces.trinidad.validator.DateTimeRangeValidator.MINIMUM";
111
112
113
114
115
116
117
118
119
120
121
122 public static final String NOT_IN_RANGE_MESSAGE_ID =
123 "org.apache.myfaces.trinidad.validator.DateTimeRangeValidator.NOT_IN_RANGE";
124
125
126
127
128
129 public DateTimeRangeValidator()
130 {
131 super();
132 }
133
134
135
136
137
138
139
140 public DateTimeRangeValidator(Date maximum)
141 {
142 super();
143 setMaximum(maximum);
144 }
145
146
147
148
149
150
151
152
153
154 public DateTimeRangeValidator(Date maximum, Date minimum)
155 {
156 super();
157 setMaximum(maximum);
158 setMinimum(minimum);
159 }
160
161
162
163
164
165
166 @JSFProperty
167 public Date getMaximum()
168 {
169 Object maxDate = _facesBean.getProperty(_MAXIMUM_KEY);
170 return ComponentUtils.resolveDate(maxDate);
171 }
172
173
174
175
176
177
178
179 public void setMaximum(Date maximum)
180 {
181 _facesBean.setProperty(_MAXIMUM_KEY, maximum);
182 }
183
184
185
186
187
188
189
190 @JSFProperty
191 public Date getMinimum()
192 {
193 Object minDate = _facesBean.getProperty(_MINIMUM_KEY);
194 return ComponentUtils.resolveDate(minDate);
195 }
196
197
198
199
200
201
202
203 public void setMinimum(Date minimum)
204 {
205 _facesBean.setProperty(_MINIMUM_KEY, minimum);
206 }
207
208
209
210
211
212
213
214 public void setMessageDetailMaximum(String maximumMessageDetail)
215 {
216 _facesBean.setProperty(_MAXIMUM_MESSAGE_DETAIL_KEY, maximumMessageDetail);
217 }
218
219
220
221
222
223
224
225 @JSFProperty
226 public String getMessageDetailMaximum()
227 {
228 Object maxMsgDet = _facesBean.getProperty(_MAXIMUM_MESSAGE_DETAIL_KEY);
229 return ComponentUtils.resolveString(maxMsgDet);
230 }
231
232
233
234
235
236
237
238
239 public void setMessageDetailMinimum(String minimumMessageDetail)
240 {
241 _facesBean.setProperty(_MINIMUM_MESSAGE_DETAIL_KEY, minimumMessageDetail);
242 }
243
244
245
246
247
248
249
250 @JSFProperty
251 public String getMessageDetailMinimum()
252 {
253 Object minMsgDet = _facesBean.getProperty(_MINIMUM_MESSAGE_DETAIL_KEY);
254 return ComponentUtils.resolveString(minMsgDet);
255 }
256
257
258
259
260
261
262
263
264 public void setMessageDetailNotInRange(String notInRangeMessageDetail)
265 {
266 _facesBean.setProperty(_NOT_IN_RANGE_MESSAGE_DETAIL_KEY, notInRangeMessageDetail);
267 }
268
269
270
271
272
273
274
275
276 @JSFProperty
277 public String getMessageDetailNotInRange()
278 {
279 Object notInRngMsg = _facesBean.getProperty(_NOT_IN_RANGE_MESSAGE_DETAIL_KEY);
280 return ComponentUtils.resolveString(notInRngMsg);
281 }
282
283
284
285
286
287
288 public void setHintMaximum(String hintMaximum)
289 {
290 _facesBean.setProperty(_HINT_MAXIMUM_KEY, hintMaximum);
291 }
292
293
294
295
296
297
298 @JSFProperty(tagExcluded=true)
299 public String getHintMaximum()
300 {
301 Object obj = _facesBean.getProperty(_HINT_MAXIMUM_KEY);
302 return ComponentUtils.resolveString(obj);
303 }
304
305
306
307
308
309
310 public void setHintMinimum(String hintMinimum)
311 {
312 _facesBean.setProperty(_HINT_MINIMUM_KEY, hintMinimum);
313 }
314
315
316
317
318
319
320 @JSFProperty(tagExcluded=true)
321 public String getHintMinimum()
322 {
323 Object obj = _facesBean.getProperty(_HINT_MINIMUM_KEY);
324 return ComponentUtils.resolveString(obj);
325 }
326
327
328
329
330
331
332 public void setHintNotInRange(String hintNotInRange)
333 {
334 _facesBean.setProperty(_HINT_NOT_IN_RANGE, hintNotInRange);
335 }
336
337
338
339
340
341
342 @JSFProperty(tagExcluded=true)
343 public String getHintNotInRange()
344 {
345 Object obj = _facesBean.getProperty(_HINT_NOT_IN_RANGE);
346 return ComponentUtils.resolveString(obj);
347 }
348
349
350
351
352
353 public void validate(
354 FacesContext context,
355 UIComponent component,
356 Object value) throws ValidatorException
357 {
358 if (isDisabled())
359 return;
360
361 if ((context == null) || (component == null))
362 {
363 throw new NullPointerException(_LOG.getMessage(
364 "NULL_FACESCONTEXT_OR_UICOMPONENT"));
365 }
366
367 if (value != null)
368 {
369
370 Date converted = _getDateValue(value);
371
372
373 Date max = getMaximum();
374 Date min = getMinimum();
375 if (max != null && (converted.after(max)))
376 {
377 if (min != null)
378 {
379 throw new ValidatorException
380 (_getNotInRangeMessage(context, component, value, min, max));
381 }
382 else
383 {
384 throw new ValidatorException
385 (_getMaximumMessage(context, component, value, max));
386 }
387 }
388
389 if (min != null && (converted.before(min)))
390 {
391 if (max != null)
392 {
393 throw new ValidatorException
394 (_getNotInRangeMessage(context, component, value, min, max));
395 }
396 else
397 {
398 FacesMessage msg = _getMinimumMessage(context, component, value, min);
399 throw new ValidatorException(msg);
400 }
401 }
402 }
403 }
404
405
406
407
408
409 public Object saveState(FacesContext context)
410 {
411 return _facesBean.saveState(context);
412 }
413
414
415 public void restoreState(FacesContext context, Object state)
416 {
417 _facesBean.restoreState(context, state);
418 }
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434 public void setValueExpression(String name, ValueExpression expression)
435 {
436 ValidatorUtils.setValueExpression(_facesBean, name, expression) ;
437 }
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452 public ValueExpression getValueExpression(String name)
453 {
454 return ValidatorUtils.getValueExpression(_facesBean, name);
455 }
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472 public void setValueBinding(String name, ValueBinding binding)
473 {
474 ValidatorUtils.setValueBinding(_facesBean, name, binding) ;
475 }
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490 public ValueBinding getValueBinding(String name)
491 {
492 return ValidatorUtils.getValueBinding(_facesBean, name);
493 }
494
495 @Override
496 public boolean equals(Object o)
497 {
498 if ( o instanceof DateTimeRangeValidator)
499 {
500 DateTimeRangeValidator that = (DateTimeRangeValidator)o;
501
502 if ( _transientValue == that._transientValue &&
503 isDisabled() == that.isDisabled() &&
504 (ValidatorUtils.equals(getMinimum(), that.getMinimum())) &&
505 (ValidatorUtils.equals(getMaximum(), that.getMaximum())) &&
506 (ValidatorUtils.equals(getMessageDetailMaximum(),
507 that.getMessageDetailMaximum())) &&
508 (ValidatorUtils.equals(getMessageDetailMinimum(),
509 that.getMessageDetailMinimum())) &&
510 (ValidatorUtils.equals(getMessageDetailNotInRange(),
511 that.getMessageDetailNotInRange()))
512 )
513 {
514 return true;
515 }
516 }
517 return false;
518 }
519
520 @Override
521 public int hashCode()
522 {
523 int result = 17;
524 Object max = getMaximum();
525 Object min = getMinimum();
526 Object maxMsgDet = getMessageDetailMaximum();
527 Object minMsgDet = getMessageDetailMinimum();
528 Object notInRangeMsgDet = getMessageDetailNotInRange();
529
530 result = 37 * result + ( max == null ? 0 : max.hashCode());
531 result = 37 * result + ( min == null ? 0 : min.hashCode());
532 result = 37 * result + ( _transientValue ? 0 : 1);
533 result = 37 * result + (isDisabled() ? 1 : 0);
534 result = 37 * result + ( maxMsgDet == null ? 0: maxMsgDet.hashCode());
535 result = 37 * result + ( minMsgDet == null ? 0: minMsgDet.hashCode());
536 result = 37 * result + ( notInRangeMsgDet == null ? 0: notInRangeMsgDet.hashCode());
537 return result;
538 }
539
540 @JSFProperty(istransient=true,tagExcluded=true)
541 public boolean isTransient()
542 {
543 return (_transientValue);
544 }
545
546 public void setTransient(boolean transientValue)
547 {
548 _transientValue = transientValue;
549 }
550
551
552
553
554
555 public void setDisabled(boolean isDisabled)
556 {
557 _facesBean.setProperty(_DISABLED_KEY, Boolean.valueOf(isDisabled));
558 }
559
560
561
562
563
564 public boolean isDisabled()
565 {
566 Boolean disabled = (Boolean) _facesBean.getProperty(_DISABLED_KEY);
567
568 return (disabled != null) ? disabled.booleanValue() : false;
569 }
570
571 private static Date _getDateValue(
572 Object value) throws IllegalArgumentException
573 {
574 if (value instanceof Date)
575 {
576 return ( (Date)value );
577 }
578
579 throw new IllegalArgumentException(_LOG.getMessage(
580 "VALUE_IS_NOT_DATE_TYPE"));
581 }
582
583 private FacesMessage _getNotInRangeMessage(
584 FacesContext context,
585 UIComponent component,
586 Object value,
587 Object min,
588 Object max)
589 {
590 Converter converter = _getConverter(context, component);
591
592 Object cValue = _getConvertedValue(context, component, converter, value);
593 Object cMin = _getConvertedValue(context, component, converter, min);
594 Object cMax = _getConvertedValue(context, component, converter, max);
595
596 Object msg = _getRawNotInRangeMessageDetail();
597 Object label = ValidatorUtils.getComponentLabel(component);
598
599 Object[] params = {label, cValue, cMin, cMax};
600
601 return MessageFactory.getMessage(context, NOT_IN_RANGE_MESSAGE_ID,
602 msg, params, component);
603 }
604
605
606
607 private Object _getRawNotInRangeMessageDetail()
608 {
609 return _facesBean.getRawProperty(_NOT_IN_RANGE_MESSAGE_DETAIL_KEY);
610 }
611
612
613 private FacesMessage _getMaximumMessage(
614 FacesContext context,
615 UIComponent component,
616 Object value,
617 Object max)
618 {
619 Converter converter = _getConverter(context, component);
620
621 Object cValue = _getConvertedValue(context, component, converter, value);
622 Object cMax = _getConvertedValue(context, component, converter, max);
623
624 Object msg = _getRawMaximumMessageDetail();
625 Object label = ValidatorUtils.getComponentLabel(component);
626
627 Object[] params = {label, cValue, cMax};
628
629 return MessageFactory.getMessage(context,
630 MAXIMUM_MESSAGE_ID,
631 msg,
632 params,
633 component);
634 }
635
636 private Object _getRawMaximumMessageDetail()
637 {
638 return _facesBean.getRawProperty(_MAXIMUM_MESSAGE_DETAIL_KEY);
639 }
640
641 private FacesMessage _getMinimumMessage(
642 FacesContext context,
643 UIComponent component,
644 Object value,
645 Object min)
646 {
647 Converter converter = _getConverter(context, component);
648
649 Object cValue = _getConvertedValue(context, component, converter, value);
650 Object cMin = _getConvertedValue(context, component, converter, min);
651
652
653 Object msg = _getRawMinimumMessageDetail();
654 Object label = ValidatorUtils.getComponentLabel(component);
655
656 Object[] params = {label, cValue, cMin};
657
658 return MessageFactory.getMessage(context, MINIMUM_MESSAGE_ID,
659 msg, params, component);
660 }
661
662 private Object _getRawMinimumMessageDetail()
663 {
664 return _facesBean.getRawProperty(_MINIMUM_MESSAGE_DETAIL_KEY);
665 }
666
667 private Converter _getConverter(
668 FacesContext context,
669 UIComponent component)
670 {
671 Converter converter = null;
672 if (component instanceof ValueHolder)
673 {
674 converter = ((ValueHolder) component).getConverter();
675 }
676
677 if (converter == null)
678 {
679
680
681
682 converter = context.getApplication().createConverter(
683 DateTimeConverter.CONVERTER_ID);
684 }
685
686 assert(converter != null);
687
688 return converter;
689 }
690
691
692 private Object _getConvertedValue(
693 FacesContext context,
694 UIComponent component,
695 Converter converter,
696 Object value)
697 {
698 return converter.getAsString(context, component, value);
699 }
700
701 private static final FacesBean.Type _TYPE = new FacesBean.Type();
702
703 private static final PropertyKey _MINIMUM_KEY =
704 _TYPE.registerKey("minimum", Date.class);
705
706 private static final PropertyKey _MAXIMUM_KEY =
707 _TYPE.registerKey("maximum", Date.class );
708
709 private static final PropertyKey _MAXIMUM_MESSAGE_DETAIL_KEY =
710 _TYPE.registerKey("messageDetailMaximum", String.class);
711
712 private static final PropertyKey _MINIMUM_MESSAGE_DETAIL_KEY =
713 _TYPE.registerKey("messageDetailMinimum", String.class);
714
715 private static final PropertyKey _NOT_IN_RANGE_MESSAGE_DETAIL_KEY =
716 _TYPE.registerKey("messageDetailNotInRange", String.class);
717
718 private static final PropertyKey _HINT_MAXIMUM_KEY =
719 _TYPE.registerKey("hintMaximum", String.class);
720
721 private static final PropertyKey _HINT_MINIMUM_KEY =
722 _TYPE.registerKey("hintMinimum", String.class);
723
724 private static final PropertyKey _HINT_NOT_IN_RANGE =
725 _TYPE.registerKey("hintNotInRange", String.class);
726
727
728 private static final PropertyKey _DISABLED_KEY =
729 _TYPE.registerKey("disabled", Boolean.class, Boolean.FALSE);
730
731 private FacesBean _facesBean = ValidatorUtils.getFacesBean(_TYPE);
732
733 private boolean _transientValue = false;
734
735 private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(
736 DateTimeRangeValidator.class);
737 }