I made a couple of bug fixes and enhancements for the StringValidator (comments below). Even though it's not 100% clear in the spec, I assumed that the "length" facet means that the length is _required_. Please let me know if I submitted this incorrectly, or if I should refrain from the verbose comments in the header...
--- original_src\org\apache\xerces\validators\datatype\StringValidator.java Tue Feb 22 14:54:34 2000 +++ src\org\apache\xerces\validators\datatype\StringValidator.java Fri Feb 25 18:01:46 2000 @@ -68,6 +68,13 @@ * StringValidator validates that XML content is a W3C string type. * * @author Ted Leung + * @author Kito D. Mann, Virtua Communications Corp. + * - 2/25/00 + * - changed setFacets() to use the error framework when throwing an IllegalFacetException + * - added validation for MinLength, MaxLength, and Length + * - fixed problem with setFacets() using facetData before it was initialized + * (this caused setFacets() to fail unconditionally) + * - added check to prevent use of length and maxlength or minlength facets at the same time * @version */ @@ -78,6 +85,11 @@ StringValidator fBaseValidator = null; int fMaxLength = 0; boolean fIsMaxLength = false; + int fMinLength = 0; + boolean fIsMinLength = false; + int fLength = 0; + boolean fIsLength = false; + private DatatypeMessageProvider fMessageProvider = new DatatypeMessageProvider(); /** * validate that a string is a W3C string type @@ -108,6 +120,14 @@ if (fIsMaxLength && content.length() > fMaxLength) throw new InvalidDatatypeValueException("Value '"+content+"' with length '"+content.length()+"' exceeds maximum length of "+fMaxLength+"."); } + else if (key.equals(DatatypeValidator.MINLENGTH)) { + if (fIsMinLength && content.length() < fMinLength) + throw new InvalidDatatypeValueException("Value '"+content+"' with length '"+content.length()+"' is less than the minimum length of "+fMinLength+"."); + } + else if (key.equals(DatatypeValidator.LENGTH)) { + if (fIsLength && content.length() != fLength) + throw new InvalidDatatypeValueException("Value '"+content+"' with length '"+content.length()+"' is not equal to required length of "+fLength+"."); + } } } @@ -115,33 +135,62 @@ } public void setFacets(Hashtable facets) throws UnknownFacetException, IllegalFacetException, IllegalFacetValueException { - facetData = new Hashtable(); // reset old facets + for (Enumeration e = facets.keys(); e.hasMoreElements();) { String key = (String) e.nextElement(); - if (key.equals(DatatypeValidator.LENGTH)) { - } else if (key.equals(DatatypeValidator.MINLENGTH)) { - } else if (key.equals(DatatypeValidator.MAXLENGTH)) { - int vvv; - String value = (String)facetData.get(key); - try { + if (key.equals(DatatypeValidator.LENGTH) || + key.equals(DatatypeValidator.MINLENGTH) || + key.equals(DatatypeValidator.MAXLENGTH)) { + int vvv; + String value = (String)facets.get(key); + try { vvv = Integer.parseInt(value); - } catch(NumberFormatException nfe) { - throw new IllegalFacetValueException("maxLength value '"+value+"' is invalid."); + if (vvv < 0) throw new NumberFormatException(); + } catch(NumberFormatException nfe) { + if (value == null) + value = "'null'"; + throw new IllegalFacetValueException( + getErrorString(DatatypeMessageProvider.IllegalFacetValue, + DatatypeMessageProvider.MSG_NONE, + new Object [] { value, key } )); + } + + if (key.equals(DatatypeValidator.LENGTH)) + { + if (fIsMaxLength || fIsMinLength) + throw new IllegalFacetException("Length facet is not allowed when maxLength or minLength has been defined."); + fLength = vvv; + fIsLength = true; } - fMaxLength = vvv; - fIsMaxLength = true; - } else if (key.equals(DatatypeValidator.MAXINCLUSIVE)) { + else + if (key.equals(DatatypeValidator.MINLENGTH)) + { + if (fIsLength) + throw new IllegalFacetException("MinLength facet is not allowed when length has been defined."); + fMinLength = vvv; + fIsMinLength = true; + } + else + if (key.equals(DatatypeValidator.MAXLENGTH)) + { + if (fIsLength) + throw new IllegalFacetException("MaxLength facet is not allowed when length has been defined."); + fMaxLength = vvv; + fIsMaxLength = true; + } + } + else if (key.equals(DatatypeValidator.MAXINCLUSIVE)) { } else if (key.equals(DatatypeValidator.MAXEXCLUSIVE)) { } else if (key.equals(DatatypeValidator.MININCLUSIVE)) { } else if (key.equals(DatatypeValidator.MINEXCLUSIVE)) { } else if (key.equals(DatatypeValidator.PATTERN)) { } else if (key.equals(DatatypeValidator.ENUMERATION)) { - facetData.put(key,facets.get(key)); } else { - throw new IllegalFacetException(); + throw new IllegalFacetException("Invalid facet (" + key + ")"); } } - } + facetData = facets; + } public void setFacets(int facets[]) throws UnknownFacetException, IllegalFacetException, IllegalFacetValueException { } @@ -156,4 +205,12 @@ public void setLocale(Locale locale) { fLocale = locale; } + + private String getErrorString(int major, int minor, Object args[]) { + try { + return fMessageProvider.createMessage(fLocale, major, minor, args); + } catch (Exception e) { + return "Illegal Errorcode "+minor; + } + } } Kito D. Mann Virtua Communications Corp.