001 /******************************************************************************* 002 * Portions created by Sebastian Thomschke are copyright (c) 2005-2011 Sebastian 003 * Thomschke. 004 * 005 * All Rights Reserved. This program and the accompanying materials 006 * are made available under the terms of the Eclipse Public License v1.0 007 * which accompanies this distribution, and is available at 008 * http://www.eclipse.org/legal/epl-v10.html 009 * 010 * Contributors: 011 * Sebastian Thomschke - initial implementation. 012 *******************************************************************************/ 013 package net.sf.oval.constraint; 014 015 import static net.sf.oval.Validator.*; 016 017 import java.math.BigDecimal; 018 import java.math.BigInteger; 019 import java.util.Map; 020 021 import net.sf.oval.ConstraintTarget; 022 import net.sf.oval.Validator; 023 import net.sf.oval.configuration.annotation.AbstractAnnotationCheck; 024 import net.sf.oval.context.OValContext; 025 import net.sf.oval.internal.Log; 026 027 /** 028 * @author Sebastian Thomschke 029 */ 030 public class DigitsCheck extends AbstractAnnotationCheck<Digits> 031 { 032 private static final Log LOG = Log.getLog(DigitsCheck.class); 033 034 private static final long serialVersionUID = 1L; 035 036 private int maxFraction = Integer.MAX_VALUE; 037 private int maxInteger = Integer.MAX_VALUE; 038 private int minFraction = 0; 039 private int minInteger = 0; 040 041 /** 042 * {@inheritDoc} 043 */ 044 @Override 045 public void configure(final Digits constraintAnnotation) 046 { 047 super.configure(constraintAnnotation); 048 setMinInteger(constraintAnnotation.minInteger()); 049 setMaxInteger(constraintAnnotation.maxInteger()); 050 setMinFraction(constraintAnnotation.minFraction()); 051 setMaxFraction(constraintAnnotation.maxFraction()); 052 } 053 054 /** 055 * {@inheritDoc} 056 */ 057 @Override 058 protected Map<String, String> createMessageVariables() 059 { 060 final Map<String, String> messageVariables = getCollectionFactory().createMap(2); 061 messageVariables.put("maxInteger", Integer.toString(maxInteger)); 062 messageVariables.put("minInteger", Integer.toString(minInteger)); 063 messageVariables.put("maxFraction", Integer.toString(maxFraction)); 064 messageVariables.put("minFraction", Integer.toString(minFraction)); 065 return messageVariables; 066 } 067 068 /** 069 * {@inheritDoc} 070 */ 071 @Override 072 protected ConstraintTarget[] getAppliesToDefault() 073 { 074 return new ConstraintTarget[]{ConstraintTarget.VALUES}; 075 } 076 077 /** 078 * @return the maxFraction 079 */ 080 public int getMaxFraction() 081 { 082 return maxFraction; 083 } 084 085 /** 086 * @return the maxInteger 087 */ 088 public int getMaxInteger() 089 { 090 return maxInteger; 091 } 092 093 /** 094 * @return the minFraction 095 */ 096 public int getMinFraction() 097 { 098 return minFraction; 099 } 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 value = (BigDecimal) valueToValidate; 153 else 154 try 155 { 156 value = new BigDecimal(valueToValidate.toString()); 157 } 158 catch (final NumberFormatException ex) 159 { 160 LOG.debug("Failed to parse numeric value: " + valueToValidate, ex); 161 return false; 162 } 163 final int valueScale = value.scale(); 164 final long longValue = value.longValue(); 165 intLen = longValue == 0 ? 1 : (int) Math.log10(longValue) + 1; 166 fractLen = valueScale > 0 ? valueScale : 0; 167 } 168 169 return intLen <= maxInteger && intLen >= minInteger && fractLen <= maxFraction && fractLen >= minFraction; 170 } 171 172 /** 173 * @param maxFraction the maxFraction to set 174 */ 175 public void setMaxFraction(final int maxFraction) 176 { 177 this.maxFraction = maxFraction; 178 } 179 180 /** 181 * @param maxInteger the maxInteger to set 182 */ 183 public void setMaxInteger(final int maxInteger) 184 { 185 this.maxInteger = maxInteger; 186 } 187 188 /** 189 * @param minFraction the minFraction to set 190 */ 191 public void setMinFraction(final int minFraction) 192 { 193 this.minFraction = minFraction; 194 } 195 196 /** 197 * @param minInteger the minInteger to set 198 */ 199 public void setMinInteger(final int minInteger) 200 { 201 this.minInteger = minInteger; 202 } 203 }