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 }