View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package javax.faces.validator;
20  
21  import javax.faces.component.PartialStateHolder;
22  import javax.faces.component.UIComponent;
23  import javax.faces.context.FacesContext;
24  
25  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFJspProperty;
26  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
27  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFValidator;
28  
29  /**
30   * Creates a validator and associateds it with the nearest parent
31   * UIComponent.  When invoked, the validator ensures that values are
32   * valid doubles that lie within the minimum and maximum values specified.
33   * 
34   * Commonly associated with a h:inputText entity.
35   * 
36   * Unless otherwise specified, all attributes accept static values or EL expressions.
37   * 
38   * see Javadoc of <a href="http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/index.html">JSF Specification</a>
39   */
40  @JSFValidator(
41      name="f:validateDoubleRange",
42      bodyContent="empty",
43      tagClass="org.apache.myfaces.taglib.core.ValidateDoubleRangeTag")
44  @JSFJspProperty(
45      name="binding", 
46      returnType = "javax.faces.validator.DoubleRangeValidator",
47      longDesc = "A ValueExpression that evaluates to a DoubleRangeValidator.")
48  public class DoubleRangeValidator
49          implements Validator, PartialStateHolder
50  {
51      // FIELDS
52      public static final String VALIDATOR_ID       = "javax.faces.DoubleRange";
53      public static final String MAXIMUM_MESSAGE_ID = "javax.faces.validator.DoubleRangeValidator.MAXIMUM";
54      public static final String MINIMUM_MESSAGE_ID = "javax.faces.validator.DoubleRangeValidator.MINIMUM";
55      public static final String TYPE_MESSAGE_ID    = "javax.faces.validator.DoubleRangeValidator.TYPE";
56      public static final String NOT_IN_RANGE_MESSAGE_ID = "javax.faces.validator.DoubleRangeValidator.NOT_IN_RANGE";
57      
58      private Double _minimum = null;
59      private Double _maximum = null;
60      private boolean _transient = false;
61  
62      // CONSTRUCTORS
63      public DoubleRangeValidator()
64      {
65      }
66  
67      public DoubleRangeValidator(double maximum)
68      {
69          _maximum = new Double(maximum);
70      }
71  
72      public DoubleRangeValidator(double maximum,
73                                  double minimum)
74      {
75          _maximum = new Double(maximum);
76          _minimum = new Double(minimum);
77      }
78  
79      // VALIDATE
80      public void validate(FacesContext facesContext,
81                           UIComponent uiComponent,
82                           Object value)
83              throws ValidatorException
84      {
85          if (facesContext == null)
86          {
87              throw new NullPointerException("facesContext");
88          }
89          if (uiComponent == null)
90          {
91              throw new NullPointerException("uiComponent");
92          }
93  
94          if (value == null)
95          {
96              return;
97          }
98  
99          double dvalue = parseDoubleValue(facesContext, uiComponent,value);
100         if (_minimum != null && _maximum != null)
101         {
102             if (dvalue < _minimum.doubleValue() ||
103                 dvalue > _maximum.doubleValue())
104             {
105                 Object[] args = {_minimum, _maximum,_MessageUtils.getLabel(facesContext, uiComponent)};
106                 throw new ValidatorException(_MessageUtils.getErrorMessage(facesContext, NOT_IN_RANGE_MESSAGE_ID,
107                                                                            args));
108             }
109         }
110         else if (_minimum != null)
111         {
112             if (dvalue < _minimum.doubleValue())
113             {
114                 Object[] args = {_minimum,_MessageUtils.getLabel(facesContext, uiComponent)};
115                 throw new ValidatorException(_MessageUtils.getErrorMessage(facesContext, MINIMUM_MESSAGE_ID, args));
116             }
117         }
118         else if (_maximum != null)
119         {
120             if (dvalue > _maximum.doubleValue())
121             {
122                 Object[] args = {_maximum,_MessageUtils.getLabel(facesContext, uiComponent)};
123                 throw new ValidatorException(_MessageUtils.getErrorMessage(facesContext, MAXIMUM_MESSAGE_ID, args));
124             }
125         }
126     }
127 
128     private double parseDoubleValue(FacesContext facesContext, UIComponent uiComponent, Object value)
129         throws ValidatorException
130     {
131         if (value instanceof Number)
132         {
133             return ((Number)value).doubleValue();
134         }
135         
136         try
137         {
138             return Double.parseDouble(value.toString());
139         }
140         catch (NumberFormatException e)
141         {
142             Object[] args = {_MessageUtils.getLabel(facesContext, uiComponent)};
143             throw new ValidatorException(_MessageUtils.getErrorMessage(facesContext, TYPE_MESSAGE_ID, args));
144         }
145     }
146 
147 
148     // GETTER & SETTER
149     
150     /** 
151      * The largest value that should be considered valid.
152      * 
153      */
154     @JSFProperty(deferredValueType="java.lang.Double")
155     public double getMaximum()
156     {
157         return _maximum != null ? _maximum.doubleValue() : Double.MAX_VALUE;
158     }
159 
160     public void setMaximum(double maximum)
161     {
162         _maximum = new Double(maximum);
163         clearInitialState();
164     }
165 
166     /**
167      * The smallest value that should be considered valid.
168      *  
169      */
170     @JSFProperty(deferredValueType="java.lang.Double")
171     public double getMinimum()
172     {
173         return _minimum != null ? _minimum.doubleValue() : Double.MIN_VALUE;
174     }
175 
176     public void setMinimum(double minimum)
177     {
178         _minimum = new Double(minimum);
179         clearInitialState();
180     }
181 
182 
183     // RESTORE/SAVE STATE
184     public Object saveState(FacesContext context)
185     {
186         if (!initialStateMarked())
187         {
188             Object values[] = new Object[2];
189             values[0] = _maximum;
190             values[1] = _minimum;
191             return values;
192         }
193         return null;
194     }
195 
196     public void restoreState(FacesContext context,
197                              Object state)
198     {
199         if (state != null)
200         {
201             Object values[] = (Object[])state;
202             _maximum = (Double)values[0];
203             _minimum = (Double)values[1];
204         }
205     }
206 
207     public boolean isTransient()
208     {
209         return _transient;
210     }
211 
212     public void setTransient(boolean transientValue)
213     {
214         _transient = transientValue;
215     }
216 
217     // MISC
218     @Override
219     public boolean equals(Object o)
220     {
221         if (this == o)
222         {
223             return true;
224         }
225         if (!(o instanceof DoubleRangeValidator))
226         {
227             return false;
228         }
229 
230         DoubleRangeValidator doubleRangeValidator = (DoubleRangeValidator)o;
231 
232         if (_maximum != null ? !_maximum.equals(doubleRangeValidator._maximum) : doubleRangeValidator._maximum != null)
233         {
234             return false;
235         }
236         if (_minimum != null ? !_minimum.equals(doubleRangeValidator._minimum) : doubleRangeValidator._minimum != null)
237         {
238             return false;
239         }
240 
241         return true;
242     }
243 
244 
245 
246     private boolean _initialStateMarked = false;
247 
248     public void clearInitialState()
249     {
250         _initialStateMarked = false;
251     }
252 
253     public boolean initialStateMarked()
254     {
255         return _initialStateMarked;
256     }
257 
258     public void markInitialState()
259     {
260         _initialStateMarked = true;
261     }
262     
263     @JSFProperty(faceletsOnly=true)
264     @SuppressWarnings("unused")
265     private Boolean isDisabled()
266     {
267         return null;
268     }
269     
270     @JSFProperty(faceletsOnly=true)
271     @SuppressWarnings("unused")
272     private String getFor()
273     {
274         return null;
275     }
276 
277     @Override
278     public int hashCode()
279     {
280         int result = _minimum != null ? _minimum.hashCode() : 0;
281         result = 31 * result + (_maximum != null ? _maximum.hashCode() : 0);
282         return result;
283     }
284 }