001    package org.apache.fulcrum.intake.validator;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *   http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import java.text.NumberFormat;
023    import java.text.ParseException;
024    import java.util.Locale;
025    import java.util.Map;
026    
027    import org.apache.commons.lang.StringUtils;
028    import org.apache.fulcrum.intake.model.Field;
029    
030    /**
031     * Validates Doubles with the following constraints in addition to those
032     * listed in NumberValidator and DefaultValidator.
033     *
034     * <table>
035     * <tr><th>Name</th><th>Valid Values</th><th>Default Value</th></tr>
036     * <tr><td>minValue</td><td>greater than Double.MIN_VALUE</td>
037     * <td>&nbsp;</td></tr>
038     * <tr><td>maxValue</td><td>less than Double.MAX_VALUE</td>
039     * <td>&nbsp;</td></tr>
040     * <tr><td>invalidNumberMessage</td><td>Some text</td>
041     * <td>Entry was not a valid number</td></tr>
042     * </table>
043     *
044     * @author <a href="mailto:jmcnally@collab.net">John McNally</a>
045     * @author <a href="mailto:Colin.Chalmers@maxware.nl">Colin Chalmers</a>
046     * @author <a href="mailto:jh@byteaction.de">J&uuml;rgen Hoffmann</a>
047     * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
048     * @version $Id: DoubleValidator.java 812827 2009-09-09 08:46:27Z tv $
049     */
050    public class DoubleValidator
051            extends NumberValidator
052    {
053        /* Init the minValue to that for a Double */
054        private double minValue = Double.NEGATIVE_INFINITY;
055    
056        /* Init the maxValue to that for a Double */
057        private double maxValue = Double.POSITIVE_INFINITY;
058    
059        /**
060         * Constructor to use when initialising Object
061         *
062         * @param paramMap
063         * @throws InvalidMaskException
064         */
065        public DoubleValidator(Map paramMap)
066                throws InvalidMaskException
067        {
068            this();
069            init(paramMap);
070        }
071    
072        /**
073         * Default Constructor
074         */
075        public DoubleValidator()
076        {
077            invalidNumberMessage = "Entry was not a valid Double";
078        }
079    
080        /**
081         * Method to initialise Object
082         *
083         * @param paramMap
084         * @throws InvalidMaskException
085         */
086        public void init(Map paramMap)
087                throws InvalidMaskException
088        {
089            super.init(paramMap);
090    
091            Constraint constraint = (Constraint) paramMap.get(MIN_VALUE_RULE_NAME);
092            if (constraint != null)
093            {
094                String param = constraint.getValue();
095                minValue = Double.parseDouble(param);
096                minValueMessage = constraint.getMessage();
097            }
098    
099            constraint = (Constraint) paramMap.get(MAX_VALUE_RULE_NAME);
100            if (constraint != null)
101            {
102                String param = constraint.getValue();
103                maxValue = Double.parseDouble(param);
104                maxValueMessage = constraint.getMessage();
105            }
106        }
107    
108        /**
109         * Determine whether a field meets the criteria specified
110         * in the constraints defined for this validator
111         *
112         * @param field a <code>Field</code> to be tested
113         * @exception ValidationException containing an error message if the
114         * testValue did not pass the validation tests.
115         */
116        public void assertValidity(Field field)
117                throws ValidationException
118        {
119            Locale locale = field.getLocale();
120    
121            if (field.isMultiValued())
122            {
123                String[] stringValues = (String[])field.getTestValue();
124    
125                for (int i = 0; i < stringValues.length; i++)
126                {
127                    assertValidity(stringValues[i], locale);
128                }
129            }
130            else
131            {
132                assertValidity((String)field.getTestValue(), locale);
133            }
134        }
135    
136        /**
137         * Determine whether a testValue meets the criteria specified
138         * in the constraints defined for this validator
139         *
140         * @param testValue a <code>String</code> to be tested
141         * @param locale the Locale of the associated field
142         * @exception ValidationException containing an error message if the
143         * testValue did not pass the validation tests.
144         */
145        public void assertValidity(String testValue, Locale locale)
146                throws ValidationException
147        {
148            super.assertValidity(testValue);
149    
150            double d = 0.0D;
151    
152            if (required || StringUtils.isNotEmpty(testValue))
153            {
154                NumberFormat nf = NumberFormat.getInstance(locale);
155    
156                try
157                {
158                    d = nf.parse(testValue).doubleValue();
159                }
160                catch (ParseException e)
161                {
162                    errorMessage = invalidNumberMessage;
163                    throw new ValidationException(invalidNumberMessage);
164                }
165    
166                if (d < minValue)
167                {
168                    errorMessage = minValueMessage;
169                    throw new ValidationException(minValueMessage);
170                }
171    
172                if (d > maxValue)
173                {
174                    errorMessage = maxValueMessage;
175                    throw new ValidationException(maxValueMessage);
176                }
177            }
178        }
179    
180    
181        // ************************************************************
182        // **                Bean accessor methods                   **
183        // ************************************************************
184    
185        /**
186         * Get the value of minValue.
187         *
188         * @return value of minValue.
189         */
190        public double getMinValue()
191        {
192            return minValue;
193        }
194    
195        /**
196         * Set the value of minValue.
197         *
198         * @param value  Value to assign to minValue.
199         */
200        public void setMinValue(double value)
201        {
202            this.minValue = value;
203        }
204    
205        /**
206         * Get the value of maxValue.
207         *
208         * @return value of maxValue.
209         */
210        public double getMaxValue()
211        {
212            return maxValue;
213        }
214    
215        /**
216         * Set the value of maxValue.
217         *
218         * @param value  Value to assign to maxValue.
219         */
220        public void setMaxValue(double value)
221        {
222            this.maxValue = value;
223        }
224    }