1 11 12 package org.eclipse.core.internal.databinding.conversion; 13 14 import java.math.BigDecimal ; 15 import java.math.BigInteger ; 16 import java.text.ParsePosition ; 17 18 import org.eclipse.core.internal.databinding.BindingMessages; 19 20 import com.ibm.icu.text.NumberFormat; 21 22 27 public class StringToNumberParser { 28 private static final BigDecimal FLOAT_MAX_BIG_DECIMAL = new BigDecimal ( 29 Float.MAX_VALUE); 30 private static final BigDecimal FLOAT_MIN_BIG_DECIMAL = new BigDecimal ( 31 -Float.MAX_VALUE); 32 33 private static final BigDecimal DOUBLE_MAX_BIG_DECIMAL = new BigDecimal ( 34 Double.MAX_VALUE); 35 private static final BigDecimal DOUBLE_MIN_BIG_DECIMAL = new BigDecimal ( 36 -Double.MAX_VALUE); 37 38 44 public static ParseResult parse(Object value, NumberFormat numberFormat, 45 boolean primitive) { 46 if (!(value instanceof String )) { 47 throw new IllegalArgumentException ( 48 "Value to convert is not a String"); } 50 51 String source = (String ) value; 52 ParseResult result = new ParseResult(); 53 if (!primitive && source.trim().length() == 0) { 54 return result; 55 } 56 57 synchronized (numberFormat) { 58 ParsePosition position = new ParsePosition (0); 59 Number parseResult = null; 60 parseResult = numberFormat.parse(source, position); 61 62 if (position.getIndex() != source.length() 63 || position.getErrorIndex() > -1) { 64 65 result.position = position; 66 } else { 67 result.number = parseResult; 68 } 69 } 70 71 return result; 72 } 73 74 79 public static class ParseResult { 80 Number number; 81 ParsePosition position; 82 83 90 public Number getNumber() { 91 return number; 92 } 93 94 100 public ParsePosition getPosition() { 101 return position; 102 } 103 } 104 105 112 public static String createParseErrorMessage(String value, 113 ParsePosition position) { 114 int errorIndex = (position.getErrorIndex() > -1) ? position 115 .getErrorIndex() : position.getIndex(); 116 117 return BindingMessages.formatString("Validate_NumberParseError", new Object [] { value, new Integer (errorIndex + 1), 119 new Character (value.charAt(errorIndex)) }); 120 } 121 122 130 public static String createOutOfRangeMessage(Number minValue, 131 Number maxValue, NumberFormat numberFormat) { 132 String min = null; 133 String max = null; 134 135 synchronized (numberFormat) { 136 min = numberFormat.format(minValue); 137 max = numberFormat.format(maxValue); 138 } 139 140 return BindingMessages.formatString( 141 "Validate_NumberOutOfRangeError", new Object [] { min, max }); } 143 144 153 public static boolean inIntegerRange(Number number) { 154 return checkInteger(number, 31); 155 } 156 157 164 private static boolean checkInteger(Number number, int bitLength) { 165 BigInteger bigInteger = null; 166 167 if (number instanceof Integer || number instanceof Long ) { 168 bigInteger = BigInteger.valueOf(number.longValue()); 169 } else if (number instanceof Float || number instanceof Double ) { 170 double doubleValue = number.doubleValue(); 171 176 if (doubleValue == doubleValue 177 && doubleValue != Double.NEGATIVE_INFINITY 178 && doubleValue != Double.POSITIVE_INFINITY) { 179 bigInteger = new BigDecimal (doubleValue).toBigInteger(); 180 } else { 181 return false; 182 } 183 } else if (number instanceof BigInteger ) { 184 bigInteger = (BigInteger ) number; 185 } else if (number instanceof BigDecimal ) { 186 bigInteger = ((BigDecimal ) number).toBigInteger(); 187 } else { 188 194 bigInteger = new BigDecimal (number.doubleValue()).toBigInteger(); 195 } 196 197 if (bigInteger != null) { 198 return bigInteger.bitLength() <= bitLength; 199 } 200 201 throw new IllegalArgumentException ( 202 "Number of type [" + number.getClass().getName() + "] is not supported."); } 204 205 214 public static boolean inLongRange(Number number) { 215 return checkInteger(number, 63); 216 } 217 218 227 public static boolean inFloatRange(Number number) { 228 return checkDecimal(number, FLOAT_MIN_BIG_DECIMAL, FLOAT_MAX_BIG_DECIMAL); 229 } 230 231 private static boolean checkDecimal(Number number, BigDecimal min, BigDecimal max) { 232 BigDecimal bigDecimal = null; 233 if (number instanceof Integer || number instanceof Long ) { 234 bigDecimal = new BigDecimal (number.doubleValue()); 235 } else if (number instanceof Float || number instanceof Double ) { 236 double doubleValue = number.doubleValue(); 237 238 243 if (doubleValue == doubleValue 244 && doubleValue != Double.NEGATIVE_INFINITY 245 && doubleValue != Double.POSITIVE_INFINITY) { 246 bigDecimal = new BigDecimal (doubleValue); 247 } else { 248 return false; 249 } 250 } else if (number instanceof BigInteger ) { 251 bigDecimal = new BigDecimal ((BigInteger ) number); 252 } else if (number instanceof BigDecimal ) { 253 bigDecimal = (BigDecimal ) number; 254 } else { 255 261 bigDecimal = new BigDecimal (number.doubleValue()); 262 } 263 264 if (bigDecimal != null) { 265 return max.compareTo(bigDecimal) >= 0 266 && min.compareTo(bigDecimal) <= 0; 267 } 268 269 throw new IllegalArgumentException ( 270 "Number of type [" + number.getClass().getName() + "] is not supported."); } 272 273 282 public static boolean inDoubleRange(Number number) { 283 return checkDecimal(number, DOUBLE_MIN_BIG_DECIMAL, DOUBLE_MAX_BIG_DECIMAL); 284 } 285 286 293 public static boolean inShortRange(Number number) { 294 return checkInteger(number, 15); 295 } 296 297 304 public static boolean inByteRange(Number number) { 305 return checkInteger(number, 7); 306 } 307 } 308 | Popular Tags |