View Javadoc
1   /*******************************************************************************
2    * Portions created by Sebastian Thomschke are copyright (c) 2005-2011 Sebastian
3    * Thomschke.
4    *
5    * All Rights Reserved. This program and the accompanying materials
6    * are made available under the terms of the Eclipse Public License v1.0
7    * which accompanies this distribution, and is available at
8    * http://www.eclipse.org/legal/epl-v10.html
9    *
10   * Contributors:
11   *     Sebastian Thomschke - initial implementation.
12   *******************************************************************************/
13  package net.sf.oval.constraint;
14  
15  import static net.sf.oval.Validator.*;
16  
17  import java.math.BigDecimal;
18  import java.math.BigInteger;
19  import java.util.Map;
20  
21  import net.sf.oval.ConstraintTarget;
22  import net.sf.oval.Validator;
23  import net.sf.oval.configuration.annotation.AbstractAnnotationCheck;
24  import net.sf.oval.context.OValContext;
25  import net.sf.oval.internal.Log;
26  
27  /**
28   * @author Sebastian Thomschke
29   */
30  public class DigitsCheck extends AbstractAnnotationCheck<Digits>
31  {
32  	private static final Log LOG = Log.getLog(DigitsCheck.class);
33  
34  	private static final long serialVersionUID = 1L;
35  
36  	private int maxFraction = Integer.MAX_VALUE;
37  	private int maxInteger = Integer.MAX_VALUE;
38  	private int minFraction = 0;
39  	private int minInteger = 0;
40  
41  	/**
42  	 * {@inheritDoc}
43  	 */
44  	@Override
45  	public void configure(final Digits constraintAnnotation)
46  	{
47  		super.configure(constraintAnnotation);
48  		setMinInteger(constraintAnnotation.minInteger());
49  		setMaxInteger(constraintAnnotation.maxInteger());
50  		setMinFraction(constraintAnnotation.minFraction());
51  		setMaxFraction(constraintAnnotation.maxFraction());
52  	}
53  
54  	/**
55  	 * {@inheritDoc}
56  	 */
57  	@Override
58  	protected Map<String, String> createMessageVariables()
59  	{
60  		final Map<String, String> messageVariables = getCollectionFactory().createMap(2);
61  		messageVariables.put("maxInteger", Integer.toString(maxInteger));
62  		messageVariables.put("minInteger", Integer.toString(minInteger));
63  		messageVariables.put("maxFraction", Integer.toString(maxFraction));
64  		messageVariables.put("minFraction", Integer.toString(minFraction));
65  		return messageVariables;
66  	}
67  
68  	/**
69  	 * {@inheritDoc}
70  	 */
71  	@Override
72  	protected ConstraintTarget[] getAppliesToDefault()
73  	{
74  		return new ConstraintTarget[]{ConstraintTarget.VALUES};
75  	}
76  
77  	/**
78  	 * @return the maxFraction
79  	 */
80  	public int getMaxFraction()
81  	{
82  		return maxFraction;
83  	}
84  
85  	/**
86  	 * @return the maxInteger
87  	 */
88  	public int getMaxInteger()
89  	{
90  		return maxInteger;
91  	}
92  
93  	/**
94  	 * @return the minFraction
95  	 */
96  	public int getMinFraction()
97  	{
98  		return minFraction;
99  	}
100 
101 	/**
102 	 * @return the minInteger
103 	 */
104 	public int getMinInteger()
105 	{
106 		return minInteger;
107 	}
108 
109 	/**
110 	 * {@inheritDoc}
111 	 */
112 	public boolean isSatisfied(final Object validatedObject, final Object valueToValidate, final OValContext context,
113 			final Validator validator)
114 	{
115 		if (valueToValidate == null) return true;
116 
117 		final int fractLen, intLen;
118 		if (valueToValidate instanceof Integer)
119 		{
120 			final int value = (Integer) valueToValidate;
121 			intLen = value == 0 ? 1 : (int) Math.log10(value) + 1;
122 			fractLen = 0;
123 		}
124 		else if (valueToValidate instanceof Long)
125 		{
126 			final long value = (Long) valueToValidate;
127 			intLen = value == 0 ? 1 : (int) Math.log10(value) + 1;
128 			fractLen = 0;
129 		}
130 		else if (valueToValidate instanceof Short)
131 		{
132 			final short value = (Short) valueToValidate;
133 			intLen = value == 0 ? 1 : (int) Math.log10(value) + 1;
134 			fractLen = 0;
135 		}
136 		else if (valueToValidate instanceof Byte)
137 		{
138 			final byte value = (Byte) valueToValidate;
139 			intLen = value == 0 ? 1 : (int) Math.log10(value) + 1;
140 			fractLen = 0;
141 		}
142 		else if (valueToValidate instanceof BigInteger)
143 		{
144 			final long value = ((BigInteger) valueToValidate).longValue();
145 			intLen = value == 0 ? 1 : (int) Math.log10(value) + 1;
146 			fractLen = 0;
147 		}
148 		else
149 		{
150 			BigDecimal value = null;
151 			if (valueToValidate instanceof BigDecimal)
152 			{
153 				value = (BigDecimal) valueToValidate;
154 			}
155 			else
156 			{
157 				try
158 				{
159 					value = new BigDecimal(valueToValidate.toString());
160 				}
161 				catch (final NumberFormatException ex)
162 				{
163 					LOG.debug("Failed to parse numeric value: " + valueToValidate, ex);
164 					return false;
165 				}
166 			}
167 			final int valueScale = value.scale();
168 			final long longValue = value.longValue();
169 			intLen = longValue == 0 ? 1 : (int) Math.log10(longValue) + 1;
170 			fractLen = valueScale > 0 ? valueScale : 0;
171 		}
172 
173 		return intLen <= maxInteger && intLen >= minInteger && fractLen <= maxFraction && fractLen >= minFraction;
174 	}
175 
176 	/**
177 	 * @param maxFraction the maxFraction to set
178 	 */
179 	public void setMaxFraction(final int maxFraction)
180 	{
181 		this.maxFraction = maxFraction;
182 		requireMessageVariablesRecreation();
183 	}
184 
185 	/**
186 	 * @param maxInteger the maxInteger to set
187 	 */
188 	public void setMaxInteger(final int maxInteger)
189 	{
190 		this.maxInteger = maxInteger;
191 		requireMessageVariablesRecreation();
192 	}
193 
194 	/**
195 	 * @param minFraction the minFraction to set
196 	 */
197 	public void setMinFraction(final int minFraction)
198 	{
199 		this.minFraction = minFraction;
200 		requireMessageVariablesRecreation();
201 	}
202 
203 	/**
204 	 * @param minInteger the minInteger to set
205 	 */
206 	public void setMinInteger(final int minInteger)
207 	{
208 		this.minInteger = minInteger;
209 		requireMessageVariablesRecreation();
210 	}
211 }