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    }