1 16 package org.apache.xerces.impl.dv.xs; 17 18 import org.apache.xerces.impl.dv.InvalidDatatypeValueException; 19 import org.apache.xerces.impl.dv.ValidationContext; 20 21 30 class PrecisionDecimalDV extends TypeValidator { 31 32 static class XPrecisionDecimal { 33 34 int sign = 1; 36 int totalDigits = 0; 38 int intDigits = 0; 40 int fracDigits = 0; 42 String ivalue = ""; 46 String fvalue = ""; 48 49 int pvalue = 0; 50 51 52 XPrecisionDecimal(String content) throws NumberFormatException { 53 if(content.equals("NaN")) { 54 ivalue = content; 55 sign = 0; 56 } 57 if(content.equals("+INF") || content.equals("INF") || content.equals("-INF")) { 58 ivalue = content.charAt(0) == '+' ? content.substring(1) : content; 59 return; 60 } 61 initD(content); 62 } 63 64 void initD(String content) throws NumberFormatException { 65 int len = content.length(); 66 if (len == 0) 67 throw new NumberFormatException (); 68 69 int intStart = 0, intEnd = 0, fracStart = 0, fracEnd = 0; 72 73 if (content.charAt(0) == '+') { 75 intStart = 1; 77 } 78 else if (content.charAt(0) == '-') { 79 intStart = 1; 80 sign = -1; 81 } 82 83 int actualIntStart = intStart; 85 while (actualIntStart < len && content.charAt(actualIntStart) == '0') { 86 actualIntStart++; 87 } 88 89 for (intEnd = actualIntStart; intEnd < len && TypeValidator.isDigit(content.charAt(intEnd)); intEnd++); 91 92 if (intEnd < len) { 94 if (content.charAt(intEnd) != '.' && content.charAt(intEnd) != 'E' && content.charAt(intEnd) != 'e') 96 throw new NumberFormatException (); 97 98 if(content.charAt(intEnd) == '.') { 99 fracStart = intEnd + 1; 101 102 for (fracEnd = fracStart; 105 fracEnd < len && TypeValidator.isDigit(content.charAt(fracEnd)); 106 fracEnd++); 107 } 108 else { 109 pvalue = Integer.parseInt(content.substring(intEnd + 1, len)); 110 } 111 } 112 113 if (intStart == intEnd && fracStart == fracEnd) 115 throw new NumberFormatException (); 116 117 121 122 for (int fracPos = fracStart; fracPos < fracEnd; fracPos++) { 124 if (!TypeValidator.isDigit(content.charAt(fracPos))) 125 throw new NumberFormatException (); 126 } 127 128 intDigits = intEnd - actualIntStart; 129 fracDigits = fracEnd - fracStart; 130 131 if (intDigits > 0) { 132 ivalue = content.substring(actualIntStart, intEnd); 133 } 134 135 if (fracDigits > 0) { 136 fvalue = content.substring(fracStart, fracEnd); 137 if(fracEnd < len) { 138 pvalue = Integer.parseInt(content.substring(fracEnd + 1, len)); 139 } 140 } 141 totalDigits = intDigits + fracDigits; 142 } 143 144 145 public boolean equals(Object val) { 146 if (val == this) 147 return true; 148 149 if (!(val instanceof XPrecisionDecimal)) 150 return false; 151 XPrecisionDecimal oval = (XPrecisionDecimal)val; 152 153 return this.compareTo(oval) == EQUAL; 154 } 155 156 159 private int compareFractionalPart(XPrecisionDecimal oval) { 160 if(fvalue.equals(oval.fvalue)) 161 return EQUAL; 162 163 StringBuffer temp1 = new StringBuffer (fvalue); 164 StringBuffer temp2 = new StringBuffer (oval.fvalue); 165 166 truncateTrailingZeros(temp1, temp2); 167 return temp1.toString().compareTo(temp2.toString()); 168 } 169 170 private void truncateTrailingZeros(StringBuffer fValue, StringBuffer otherFValue) { 171 for(int i = fValue.length() - 1;i >= 0; i--) 172 if(fValue.charAt(i) == '0') 173 fValue.deleteCharAt(i); 174 else 175 break; 176 177 for(int i = otherFValue.length() - 1;i >= 0; i--) 178 if(otherFValue.charAt(i) == '0') 179 otherFValue.deleteCharAt(i); 180 else 181 break; 182 } 183 184 public int compareTo(XPrecisionDecimal val) { 185 186 if(sign == 0) 188 return INDETERMINATE; 189 190 if(ivalue.equals("INF") || val.ivalue.equals("INF")) { 192 if(ivalue.equals(val.ivalue)) 193 return EQUAL; 194 else if(ivalue.equals("INF")) 195 return GREATER_THAN; 196 return LESS_THAN; 197 } 198 199 if(ivalue.equals("-INF") || val.ivalue.equals("-INF")) { 201 if(ivalue.equals(val.ivalue)) 202 return EQUAL; 203 else if(ivalue.equals("-INF")) 204 return LESS_THAN; 205 return GREATER_THAN; 206 } 207 208 if (sign != val.sign) 209 return sign > val.sign ? GREATER_THAN : LESS_THAN; 210 211 return sign * compare(val); 212 } 213 214 private int compare(XPrecisionDecimal val) { 217 218 if(pvalue != 0 || val.pvalue != 0) { 219 if(pvalue == val.pvalue) 220 return intComp(val); 221 else { 222 223 if(intDigits + pvalue != val.intDigits + val.pvalue) 224 return intDigits + pvalue > val.intDigits + val.pvalue ? GREATER_THAN : LESS_THAN; 225 226 if(pvalue > val.pvalue) { 228 int expDiff = pvalue - val.pvalue; 229 StringBuffer buffer = new StringBuffer (ivalue); 230 StringBuffer fbuffer = new StringBuffer (fvalue); 231 for(int i = 0;i < expDiff; i++) { 232 if(i < fracDigits) { 233 buffer.append(fvalue.charAt(i)); 234 fbuffer.deleteCharAt(i); 235 } 236 else 237 buffer.append('0'); 238 } 239 return compareDecimal(buffer.toString(), val.ivalue, fbuffer.toString(), val.fvalue); 240 } 241 else { 242 int expDiff = val.pvalue - pvalue; 243 StringBuffer buffer = new StringBuffer (val.ivalue); 244 StringBuffer fbuffer = new StringBuffer (val.fvalue); 245 for(int i = 0;i < expDiff; i++) { 246 if(i < val.fracDigits) { 247 buffer.append(val.fvalue.charAt(i)); 248 fbuffer.deleteCharAt(i); 249 } 250 else 251 buffer.append('0'); 252 } 253 return compareDecimal(ivalue, buffer.toString(), fvalue, fbuffer.toString()); 254 } 255 } 256 } 257 else { 258 return intComp(val); 259 } 260 } 261 262 266 private int intComp(XPrecisionDecimal val) { 267 if (intDigits != val.intDigits) 268 return intDigits > val.intDigits ? GREATER_THAN : LESS_THAN; 269 270 return compareDecimal(ivalue, val.ivalue, fvalue, val.fvalue); 271 } 272 273 277 private int compareDecimal(String iValue, String fValue, String otherIValue, String otherFValue) { 278 int ret = iValue.compareTo(otherIValue); 279 if (ret != 0) 280 return ret > 0 ? GREATER_THAN : LESS_THAN; 281 282 if(fValue.equals(otherFValue)) 283 return EQUAL; 284 285 StringBuffer temp1=new StringBuffer (fValue); 286 StringBuffer temp2=new StringBuffer (otherFValue); 287 288 truncateTrailingZeros(temp1, temp2); 289 ret = temp1.toString().compareTo(temp2.toString()); 290 return ret == 0 ? EQUAL : (ret > 0 ? GREATER_THAN : LESS_THAN); 291 } 292 293 private String canonical; 294 295 public synchronized String toString() { 296 if (canonical == null) { 297 makeCanonical(); 298 } 299 return canonical; 300 } 301 302 private void makeCanonical() { 303 canonical = "TBD by Working Group"; 305 } 306 307 311 public boolean isIdentical(XPrecisionDecimal decimal) { 312 if(ivalue.equals(decimal.ivalue) && (ivalue.equals("INF") || ivalue.equals("-INF") || ivalue.equals("NaN"))) 313 return true; 314 315 if(sign == decimal.sign && intDigits == decimal.intDigits && fracDigits == decimal.fracDigits && pvalue == decimal.pvalue 316 && ivalue.equals(decimal.ivalue) && fvalue.equals(decimal.fvalue)) 317 return true; 318 return false; 319 } 320 321 } 322 325 public short getAllowedFacets() { 326 return ( XSSimpleTypeDecl.FACET_PATTERN | XSSimpleTypeDecl.FACET_WHITESPACE | XSSimpleTypeDecl.FACET_ENUMERATION |XSSimpleTypeDecl.FACET_MAXINCLUSIVE |XSSimpleTypeDecl.FACET_MININCLUSIVE | XSSimpleTypeDecl.FACET_MAXEXCLUSIVE | XSSimpleTypeDecl.FACET_MINEXCLUSIVE | XSSimpleTypeDecl.FACET_TOTALDIGITS | XSSimpleTypeDecl.FACET_FRACTIONDIGITS); 327 } 328 329 332 public Object getActualValue(String content, ValidationContext context) 333 throws InvalidDatatypeValueException { 334 try { 335 return new XPrecisionDecimal(content); 336 } catch (NumberFormatException nfe) { 337 throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object []{content, "precisionDecimal"}); 338 } 339 } 340 341 public int compare(Object value1, Object value2) { 342 return ((XPrecisionDecimal)value1).compareTo((XPrecisionDecimal)value2); 343 } 344 345 public int getFractionDigits(Object value) { 346 return ((XPrecisionDecimal)value).fracDigits; 347 } 348 349 public int getTotalDigits(Object value) { 350 return ((XPrecisionDecimal)value).totalDigits; 351 } 352 353 public boolean isIdentical(Object value1, Object value2) { 354 if(!(value2 instanceof XPrecisionDecimal) || !(value1 instanceof XPrecisionDecimal)) 355 return false; 356 return ((XPrecisionDecimal)value1).isIdentical((XPrecisionDecimal)value2); 357 } 358 } 359 | Popular Tags |