001    package com.thaiopensource.datatype.xsd;
002    
003    import org.relaxng.datatype.ValidationContext;
004    
005    class DoubleDatatype extends DatatypeBase implements OrderRelation {
006    
007      boolean lexicallyAllows(String str) {
008        if (str.equals("INF") || str.equals("-INF") || str.equals("NaN"))
009          return true;
010        int len = str.length();
011        boolean hadSign = false;
012        boolean hadDecimalPoint = false;
013        boolean hadDigit = false;
014        boolean hadE = false;
015        for (int i = 0; i < len; i++) {
016          switch (str.charAt(i)) {
017          case '+':
018          case '-':
019            if (hadDigit || hadDecimalPoint || hadSign)
020              return false;
021            hadSign = true;
022            break;
023          case '0':
024          case '1':
025          case '2':
026          case '3':
027          case '4':
028          case '5':
029          case '6':
030          case '7':
031          case '8':
032          case '9':
033            hadDigit = true;
034            break;
035          case 'e':
036          case 'E':
037            if (hadE || !hadDigit)
038              return false;
039            hadDigit = false;
040            hadE = true;
041            hadSign = false;
042            hadDecimalPoint = false;
043            break;
044          case '.':
045            if (hadDecimalPoint || hadE)
046              return false;
047            hadDecimalPoint = true;
048            break;
049          default:
050            return false;
051          }
052        }
053        return hadDigit;
054      }
055    
056      Object getValue(String str, ValidationContext vc) {
057        if (str.equals("INF"))
058          return new Double(Double.POSITIVE_INFINITY);
059        if (str.equals("-INF"))
060          return new Double(Double.NEGATIVE_INFINITY);
061        if (str.equals("NaN"))
062          return new Double(Double.NaN);
063        return new Double(str);
064      }
065    
066      OrderRelation getOrderRelation() {
067        return this;
068      }
069    
070      public boolean isLessThan(Object obj1, Object obj2) {
071        return ((Double)obj1).doubleValue() < ((Double)obj2).doubleValue();
072      }
073    
074      public boolean sameValue(Object value1, Object value2) {
075        double d1 = ((Double)value1).doubleValue();
076        double d2 = ((Double)value2).doubleValue();
077        // NaN = NaN
078        return d1 == d2 || (d1 != d1 && d2 != d2);
079      }
080    }