001 package com.thaiopensource.datatype.xsd;
002
003 import java.math.BigDecimal;
004
005 import org.relaxng.datatype.ValidationContext;
006
007 class DecimalDatatype extends DatatypeBase implements OrderRelation {
008
009 boolean lexicallyAllows(String str) {
010 int len = str.length();
011 if (len == 0)
012 return false;
013 int i = 0;
014 switch (str.charAt(i)) {
015 case '+':
016 case '-':
017 if (++i == len)
018 return false;
019 }
020 boolean hadDecimalPoint = false;
021 if (str.charAt(i) == '.') {
022 hadDecimalPoint = true;
023 if (++i == len)
024 return false;
025 }
026 do {
027 switch (str.charAt(i)) {
028 case '0':
029 case '1':
030 case '2':
031 case '3':
032 case '4':
033 case '5':
034 case '6':
035 case '7':
036 case '8':
037 case '9':
038 break;
039 case '.':
040 if (hadDecimalPoint)
041 return false;
042 hadDecimalPoint = true;
043 break;
044 default:
045 return false;
046 }
047 } while (++i < len);
048 return true;
049 }
050
051 Object getValue(String str, ValidationContext vc) {
052 if (str.charAt(0) == '+')
053 str = str.substring(1); // JDK 1.1 doesn't handle leading +
054 return new BigDecimal(str);
055 }
056
057 OrderRelation getOrderRelation() {
058 return this;
059 }
060
061 public boolean isLessThan(Object obj1, Object obj2) {
062 return ((BigDecimal)obj1).compareTo((BigDecimal)obj2) < 0;
063 }
064
065 /**
066 * BigDecimal.equals considers objects distinct if they have the
067 * different scales but the same mathematical value. Similarly
068 * for hashCode.
069 */
070
071 public boolean sameValue(Object value1, Object value2) {
072 return ((BigDecimal)value1).compareTo((BigDecimal)value2) == 0;
073 }
074
075 public int valueHashCode(Object value) {
076 return ((BigDecimal)value).toBigInteger().hashCode();
077 }
078
079 }