1 57 58 package org.enhydra.apache.xerces.validators.datatype; 59 60 import java.math.BigDecimal ; 61 import java.util.Hashtable ; 62 import java.util.Vector ; 63 64 import org.enhydra.apache.xerces.validators.schema.SchemaSymbols; 65 66 76 77 public class DecimalDatatypeValidator extends AbstractNumericValidator { 78 79 protected int fTotalDigits; 80 protected int fFractionDigits; 81 82 public DecimalDatatypeValidator () throws InvalidDatatypeFacetException { 83 this( null, null, false ); } 85 86 public DecimalDatatypeValidator ( DatatypeValidator base, Hashtable facets, 87 boolean derivedByList ) throws InvalidDatatypeFacetException { 88 super (base, facets, derivedByList); 89 } 90 91 public int compare( String value1, String value2) { 92 try { 93 BigDecimal d1 = new BigDecimal (stripPlusIfPresent(value1)); 94 BigDecimal d2 = new BigDecimal (stripPlusIfPresent(value2)); 95 return d1.compareTo(d2); 96 } 97 catch ( NumberFormatException e ) { 98 return -1; 100 } 101 catch ( Exception e){ 102 return -1; 103 } 104 } 105 106 protected void inheritAdditionalFacets() { 107 108 if ( (( ((DecimalDatatypeValidator)fBaseValidator).fFacetsDefined & DatatypeValidator.FACET_TOTALDIGITS) != 0) && 110 !((fFacetsDefined & DatatypeValidator.FACET_TOTALDIGITS) != 0) ) { 111 fFacetsDefined |= FACET_TOTALDIGITS; 112 fTotalDigits = ((DecimalDatatypeValidator)fBaseValidator).fTotalDigits; 113 } 114 if ( (( ((DecimalDatatypeValidator)fBaseValidator).fFacetsDefined & DatatypeValidator.FACET_FRACTIONDIGITS) != 0) 116 && !((fFacetsDefined & DatatypeValidator.FACET_FRACTIONDIGITS) != 0) ) { 117 fFacetsDefined |= FACET_FRACTIONDIGITS; 118 fFractionDigits = ((DecimalDatatypeValidator)fBaseValidator).fFractionDigits; 119 } 120 } 121 122 protected void checkFacetConstraints() throws InvalidDatatypeFacetException{ 123 if ( ((fFacetsDefined & DatatypeValidator.FACET_FRACTIONDIGITS) != 0) && 125 ((fFacetsDefined & DatatypeValidator.FACET_TOTALDIGITS) != 0) ) { 126 if ( fFractionDigits > fTotalDigits ) 127 throw new InvalidDatatypeFacetException( "fractionDigits value ='" + this.fFractionDigits + "'must be <= totalDigits value ='" + 128 this.fTotalDigits + "'. " ); 129 } 130 } 131 132 protected void checkBaseFacetConstraints() throws InvalidDatatypeFacetException{ 133 134 if ( ((fFacetsDefined & DatatypeValidator.FACET_TOTALDIGITS) != 0) ) { 136 if ( (( ((DecimalDatatypeValidator)fBaseValidator).fFacetsDefined & DatatypeValidator.FACET_TOTALDIGITS) != 0)){ 137 if ((((DecimalDatatypeValidator)fBaseValidator).fFlags & DatatypeValidator.FACET_TOTALDIGITS) != 0 && 138 fTotalDigits != ((DecimalDatatypeValidator)fBaseValidator).fTotalDigits){ 139 throw new InvalidDatatypeFacetException("totalDigits value = '" + fTotalDigits + 140 "' must be equal to base.totalDigits value = '" + 141 ((DecimalDatatypeValidator)fBaseValidator).fTotalDigits + 142 "' with attribute {fixed} = true" ); 143 } 144 if (fTotalDigits > ((DecimalDatatypeValidator)fBaseValidator).fTotalDigits ){ 145 throw new InvalidDatatypeFacetException( "totalDigits value ='" + fTotalDigits + "' must be <= base.totalDigits value ='" + 146 ((DecimalDatatypeValidator)fBaseValidator).fTotalDigits + "'." ); 147 } 148 } 149 } 150 if ( ((fFacetsDefined & DatatypeValidator.FACET_FRACTIONDIGITS) != 0) ) { 152 if ( (( ((DecimalDatatypeValidator)fBaseValidator).fFacetsDefined & DatatypeValidator.FACET_FRACTIONDIGITS) != 0)){ 153 if ((((DecimalDatatypeValidator)fBaseValidator).fFlags & DatatypeValidator.FACET_FRACTIONDIGITS) != 0 && 154 fFractionDigits != ((DecimalDatatypeValidator)fBaseValidator).fFractionDigits){ 155 throw new InvalidDatatypeFacetException("fractionDigits value = '" + fFractionDigits + 156 "' must be equal to base.fractionDigits value = '" + 157 ((DecimalDatatypeValidator)fBaseValidator).fFractionDigits + 158 "' with attribute {fixed} = true" ); 159 } 160 } 161 } 162 } 163 164 protected void assignAdditionalFacets(String key, Hashtable facets ) throws InvalidDatatypeFacetException{ 165 166 String value = null; 167 try { 168 if ( key.equals(SchemaSymbols.ELT_TOTALDIGITS) ) { 169 value = ((String ) facets.get(key )); 170 fFacetsDefined |= DatatypeValidator.FACET_TOTALDIGITS; 171 fTotalDigits = Integer.parseInt(value ); 172 if ( fTotalDigits <= 0 ) 174 throw new InvalidDatatypeFacetException("totalDigits value '"+fTotalDigits+"' must be a positiveInteger."); 175 } 176 else if ( key.equals(SchemaSymbols.ELT_FRACTIONDIGITS) ) { 177 value = ((String ) facets.get(key )); 178 fFacetsDefined |= DatatypeValidator.FACET_FRACTIONDIGITS; 179 fFractionDigits = Integer.parseInt( value ); 180 if ( fFractionDigits < 0 ) 182 throw new InvalidDatatypeFacetException("fractionDigits value '"+fFractionDigits+"' must be a positiveInteger."); 183 } 184 else { 185 throw new InvalidDatatypeFacetException( getErrorString( DatatypeMessageProvider.ILLEGAL_DECIMAL_FACET, 186 DatatypeMessageProvider.MSG_NONE, new Object [] { value, key})); 187 } 188 } 189 catch ( Exception ex ) { 190 throw new InvalidDatatypeFacetException( getErrorString( DatatypeMessageProvider.ILLEGAL_FACET_VALUE, 191 DatatypeMessageProvider.MSG_NONE, new Object [] { value, key})); 192 } 193 } 194 195 protected int compareValues (Object value1, Object value2) { 196 return((BigDecimal )value1).compareTo((BigDecimal )value2); 197 } 198 199 protected void setMaxInclusive (String value) { 200 fMaxInclusive = new BigDecimal (stripPlusIfPresent(value)); 201 } 202 protected void setMinInclusive (String value) { 203 fMinInclusive = new BigDecimal (stripPlusIfPresent(value)); 204 205 } 206 protected void setMaxExclusive (String value) { 207 fMaxExclusive = new BigDecimal (stripPlusIfPresent(value)); 208 209 } 210 protected void setMinExclusive (String value) { 211 fMinExclusive = new BigDecimal (stripPlusIfPresent(value)); 212 213 } 214 protected void setEnumeration (Vector enumeration) throws InvalidDatatypeValueException{ 215 if ( enumeration != null ) { 216 fEnumeration = new BigDecimal [enumeration.size()]; 217 Object baseEnum=null; 218 try { 219 220 for ( int i = 0; i < enumeration.size(); i++ ) { 221 fEnumeration[i] = new BigDecimal ( stripPlusIfPresent(((String ) enumeration.elementAt(i))));; 222 ((DecimalDatatypeValidator)fBaseValidator).validate((String )enumeration.elementAt(i), null); 223 } 224 } 225 catch ( Exception e ) { 226 throw new InvalidDatatypeValueException(e.getMessage()); 227 } 228 } 229 } 230 231 232 protected String getMaxInclusive (boolean isBase) { 233 return(isBase)?(((DecimalDatatypeValidator)fBaseValidator).fMaxInclusive.toString()) 234 :((BigDecimal )fMaxInclusive).toString(); 235 } 236 protected String getMinInclusive (boolean isBase) { 237 return(isBase)?(((DecimalDatatypeValidator)fBaseValidator).fMinInclusive.toString()) 238 :((BigDecimal )fMinInclusive).toString(); 239 } 240 protected String getMaxExclusive (boolean isBase) { 241 return(isBase)?(((DecimalDatatypeValidator)fBaseValidator).fMaxExclusive.toString()) 242 :((BigDecimal )fMaxExclusive).toString(); 243 } 244 protected String getMinExclusive (boolean isBase) { 245 return(isBase)?(((DecimalDatatypeValidator)fBaseValidator).fMinExclusive.toString()) 246 :((BigDecimal )fMinExclusive).toString(); 247 } 248 249 250 251 protected void checkContent(String content, Object state, Vector enumeration, boolean asBase) 252 throws InvalidDatatypeValueException { 253 if ( this.fBaseValidator != null ) { 255 ((DecimalDatatypeValidator)fBaseValidator).checkContent(content, state, enumeration, true); 257 } 258 259 if ( (fFacetsDefined & DatatypeValidator.FACET_PATTERN ) != 0 ) { 261 if ( fRegex == null || fRegex.matches( content) == false ) 262 throw new InvalidDatatypeValueException("Value'"+content+ 263 "' does not match regular expression facet " + fRegex.getPattern() ); 264 } 265 266 if ( asBase ) 269 return; 270 271 BigDecimal d = null; try { 273 d = new BigDecimal ( stripPlusIfPresent( content)); 274 } 275 catch ( Exception nfe ) { 276 throw new InvalidDatatypeValueException( getErrorString(DatatypeMessageProvider.NOT_DECIMAL, 277 DatatypeMessageProvider.MSG_NONE, 278 new Object [] { "'" + content +"'"})); 279 } 280 281 if ( enumeration != null ) { int size= enumeration.size(); 283 BigDecimal [] enumDecimal = new BigDecimal [size]; 284 int i = 0; 285 try { 286 for ( ; i < size; i++ ) 287 enumDecimal[i] = new BigDecimal ( stripPlusIfPresent(((String ) enumeration.elementAt(i)))); 288 } 289 catch ( NumberFormatException nfe ) { 290 throw new InvalidDatatypeValueException( getErrorString(DatatypeMessageProvider.INVALID_ENUM_VALUE, 291 DatatypeMessageProvider.MSG_NONE, 292 new Object [] { enumeration.elementAt(i)})); 293 } 294 enumCheck(d, enumDecimal); 295 } 296 297 if ( (fFacetsDefined & DatatypeValidator.FACET_FRACTIONDIGITS)!=0 ) { 298 if ( d.scale() > fFractionDigits ) 299 throw new InvalidDatatypeValueException( 300 getErrorString(DatatypeMessageProvider.FRACTION_EXCEEDED, 301 DatatypeMessageProvider.MSG_NONE, 302 new Object [] { "'" + content + "'" + " with fractionDigits = '"+ d.scale() +"'" 303 , "'" + fFractionDigits + "'"})); 304 } 305 if ( (fFacetsDefined & DatatypeValidator.FACET_TOTALDIGITS)!=0 ) { 306 int totalDigits = d.movePointRight(d.scale()).toString().length() - 307 ((d.signum() < 0) ? 1 : 0); if ( totalDigits > fTotalDigits ) 309 throw new InvalidDatatypeValueException( 310 getErrorString(DatatypeMessageProvider.TOTALDIGITS_EXCEEDED, 311 DatatypeMessageProvider.MSG_NONE, 312 new Object [] { "'" + content + "'" + " with totalDigits = '"+ totalDigits +"'" 313 , "'" + fTotalDigits + "'"} )); 314 } 315 boundsCheck(d); 316 if ( fEnumeration != null ) 317 enumCheck(d, (BigDecimal []) fEnumeration); 318 319 return; 320 321 } 322 323 338 static private String stripPlusIfPresent( String value ) { 339 String strippedPlus = value; 340 341 if ( value.length() >= 2 && value.charAt(0) == '+' && value.charAt(1) != '-' ) { 342 strippedPlus = value.substring(1); 343 } 344 return strippedPlus; 345 } 346 347 private void enumCheck(BigDecimal v, BigDecimal [] enumer) throws InvalidDatatypeValueException { 348 for ( int i = 0; i < enumer.length; i++ ) { 349 if ( v.equals(enumer[i] ) ) { 350 return; 351 } 352 } 353 throw new InvalidDatatypeValueException( 354 getErrorString(DatatypeMessageProvider.NOT_ENUM_VALUE, 355 DatatypeMessageProvider.MSG_NONE, 356 new Object [] { v})); 357 } 358 359 } 360 | Popular Tags |