? gnu/xml/validation/relaxng Index: gnu/xml/validation/datatype/BooleanType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/BooleanType.java,v retrieving revision 1.1 diff -u -r1.1 BooleanType.java --- gnu/xml/validation/datatype/BooleanType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/BooleanType.java 15 Feb 2006 14:34:48 -0000 @@ -82,5 +82,10 @@ throw new DatatypeException("invalid boolean value"); } + public Object createValue(String literal, ValidationContext context) { + return ("1".equals(literal) || "true".equals(literal)) ? Boolean.TRUE : + Boolean.FALSE; + } + } Index: gnu/xml/validation/datatype/ByteType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/ByteType.java,v retrieving revision 1.1 diff -u -r1.1 ByteType.java --- gnu/xml/validation/datatype/ByteType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/ByteType.java 15 Feb 2006 14:34:48 -0000 @@ -118,5 +118,16 @@ } } + public Object createValue(String literal, ValidationContext context) { + try + { + return new Byte(literal); + } + catch (NumberFormatException e) + { + return null; + } + } + } Index: gnu/xml/validation/datatype/DateTimeType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/DateTimeType.java,v retrieving revision 1.1 diff -u -r1.1 DateTimeType.java --- gnu/xml/validation/datatype/DateTimeType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/DateTimeType.java 15 Feb 2006 14:34:48 -0000 @@ -37,6 +37,9 @@ package gnu.xml.validation.datatype; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.TimeZone; import javax.xml.XMLConstants; import javax.xml.namespace.QName; import org.relaxng.datatype.DatatypeException; @@ -211,5 +214,122 @@ } } + public Object createValue(String value, ValidationContext context) { + int len = value.length(); + int state = 0; + int start = 0; + Calendar cal = new GregorianCalendar(); + try + { + for (int i = 0; i < len; i++) + { + char c = value.charAt(i); + if (c == '-' && i == 0) + { + start++; + continue; + } + if (c >= 0x30 && c <= 0x39) + continue; + switch (state) + { + case 0: // year + if (c == '-') + { + cal.set(Calendar.YEAR, + Integer.parseInt(value.substring(0, i))); + state = 1; + start = i + 1; + continue; + } + break; + case 1: // month + if (c == '-') + { + cal.set(Calendar.MONTH, + Integer.parseInt(value.substring(start, i))); + state = 2; + start = i + 1; + continue; + } + break; + case 2: // day + if (c == 'T') + { + cal.set(Calendar.DATE, + Integer.parseInt(value.substring(start, i))); + state = 3; + start = i + 1; + continue; + } + break; + case 3: // hour + if (c == ':') + { + cal.set(Calendar.HOUR, + Integer.parseInt(value.substring(start, i))); + state = 4; + start = i + 1; + continue; + } + break; + case 4: // minute + if (c == ':') + { + cal.set(Calendar.MINUTE, + Integer.parseInt(value.substring(start, i))); + state = 5; + start = i + 1; + continue; + } + break; + case 5: // second + if (c == ' ') + { + float second = Float.parseFloat(value.substring(start, i)); + // TODO adjust non-integer values + cal.set(Calendar.SECOND, (int) second); + state = 7; + start = i + 1; + continue; + } + break; + } + } + // end of input + if (len - start > 0 && state == 7) + { + // Timezone + String timezone = value.substring(len - start); + int i = timezone.indexOf(':'); + if (i == -1) + { + if ("Z".equals(timezone)) + timezone = "UTC"; + TimeZone tz = TimeZone.getTimeZone(timezone); + if (tz == null) + return null; + cal.set(Calendar.ZONE_OFFSET, tz.getRawOffset()); + } + else + { + String tzh = timezone.substring(0, i); + String tzm = timezone.substring(i + 1); + int offset = Integer.parseInt(tzh) * 360000; + if (offset < 0) + offset -= Integer.parseInt(tzm) * 60000; + else + offset += Integer.parseInt(tzm) * 60000; + cal.set(Calendar.ZONE_OFFSET, offset); + } + } + return cal.getTime(); + } + catch (NumberFormatException e) + { + return null; + } + } + } Index: gnu/xml/validation/datatype/DateType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/DateType.java,v retrieving revision 1.1 diff -u -r1.1 DateType.java --- gnu/xml/validation/datatype/DateType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/DateType.java 15 Feb 2006 14:34:48 -0000 @@ -37,6 +37,9 @@ package gnu.xml.validation.datatype; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.TimeZone; import javax.xml.XMLConstants; import javax.xml.namespace.QName; import org.relaxng.datatype.DatatypeException; @@ -126,5 +129,94 @@ } } + public Object createValue(String value, ValidationContext context) { + int len = value.length(); + int state = 0; + int start = 0; + Calendar cal = new GregorianCalendar(); + cal.set(Calendar.HOUR, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + try + { + for (int i = 0; i < len; i++) + { + char c = value.charAt(i); + if (c == '-' && i == 0) + { + start++; + continue; + } + if (c >= 0x30 && c <= 0x39) + continue; + switch (state) + { + case 0: // year + if (c == '-') + { + cal.set(Calendar.YEAR, + Integer.parseInt(value.substring(0, i))); + state = 1; + start = i + 1; + continue; + } + break; + case 1: // month + if (c == '-') + { + cal.set(Calendar.MONTH, + Integer.parseInt(value.substring(start, i))); + state = 2; + start = i + 1; + continue; + } + break; + case 2: // day + if (c == 'T') + { + cal.set(Calendar.DATE, + Integer.parseInt(value.substring(start, i))); + state = 7; + start = i + 1; + continue; + } + break; + } + } + // end of input + if (len - start > 0 && state == 7) + { + // Timezone + String timezone = value.substring(len - start); + int i = timezone.indexOf(':'); + if (i == -1) + { + if ("Z".equals(timezone)) + timezone = "UTC"; + TimeZone tz = TimeZone.getTimeZone(timezone); + if (tz == null) + return null; + cal.set(Calendar.ZONE_OFFSET, tz.getRawOffset()); + } + else + { + String tzh = timezone.substring(0, i); + String tzm = timezone.substring(i + 1); + int offset = Integer.parseInt(tzh) * 360000; + if (offset < 0) + offset -= Integer.parseInt(tzm) * 60000; + else + offset += Integer.parseInt(tzm) * 60000; + cal.set(Calendar.ZONE_OFFSET, offset); + } + } + return cal.getTime(); + } + catch (NumberFormatException e) + { + return null; + } + } + } Index: gnu/xml/validation/datatype/DecimalType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/DecimalType.java,v retrieving revision 1.1 diff -u -r1.1 DecimalType.java --- gnu/xml/validation/datatype/DecimalType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/DecimalType.java 15 Feb 2006 14:34:48 -0000 @@ -37,6 +37,7 @@ package gnu.xml.validation.datatype; +import java.math.BigDecimal; import java.util.Collections; import java.util.Set; import javax.xml.XMLConstants; @@ -105,5 +106,16 @@ } } + public Object createValue(String literal, ValidationContext context) { + try + { + return new BigDecimal(literal); + } + catch (NumberFormatException e) + { + return null; + } + } + } Index: gnu/xml/validation/datatype/DoubleType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/DoubleType.java,v retrieving revision 1.1 diff -u -r1.1 DoubleType.java --- gnu/xml/validation/datatype/DoubleType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/DoubleType.java 15 Feb 2006 14:34:48 -0000 @@ -97,5 +97,16 @@ } } + public Object createValue(String literal, ValidationContext context) { + try + { + return new Double(literal); + } + catch (NumberFormatException e) + { + return null; + } + } + } Index: gnu/xml/validation/datatype/DurationType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/DurationType.java,v retrieving revision 1.1 diff -u -r1.1 DurationType.java --- gnu/xml/validation/datatype/DurationType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/DurationType.java 15 Feb 2006 14:34:48 -0000 @@ -51,6 +51,61 @@ extends AtomicSimpleType { + static class Duration + implements Comparable + { + int years; + int months; + int days; + int minutes; + float seconds; + + public int hashCode() + { + int hc = years; + hc = hc * 31 + months; + hc = hc * 31 + days; + hc = hc * 31 + minutes; + hc = hc * 31 + new Float(seconds).hashCode(); + return hc; + } + + public boolean equals(Object other) + { + if (other instanceof Duration) + { + Duration duration = (Duration) other; + return duration.years ==years && + duration.months == months && + duration.days == days && + duration.minutes == minutes && + duration.seconds == seconds; + } + return false; + } + + public int compareTo(Object other) + { + if (other instanceof Duration) + { + Duration duration = (Duration) other; + if (duration.years != years) + return years - duration.years; + if (duration.months != months) + return months - duration.months; + if (duration.days != days) + return days - duration.days; + if (duration.minutes != minutes) + return minutes = duration.minutes; + if (duration.seconds == seconds) + return 0; + return (seconds < duration.seconds) ? -1 : 1; + } + return 0; + } + + } + static final int[] CONSTRAINING_FACETS = { Facet.PATTERN, Facet.ENUMERATION, @@ -116,5 +171,69 @@ } } + public Object createValue(String value, ValidationContext context) { + boolean negative = false; + int days = 0, months = 0, years = 0; + int minutes = 0; + float seconds = 0.0f; + int len = value.length(); + char expect = 'P'; + boolean seenT = false; + int start = 0; + for (int i = 0; i < len; i++) + { + char c = value.charAt(i); + if (c == '-' && expect == 'P') + { + negative = true; + continue; + } + if (c == expect) + { + if (c == 'P') + expect = 'Y'; + else if (c == 'Y') + { + expect = 'M'; + years = Integer.parseInt(value.substring(start, i)); + } + else if (c == 'M' && !seenT) + expect = 'D'; + else if (c == 'D') + expect = 'T'; + else if (c == 'T') + { + expect = 'H'; + seenT = true; + } + else if (c == 'H') + expect = 'M'; + else if (c == 'M' && seenT) + expect = 'S'; + else if (c == 'S') + { + if (i + 1 != len) + return null; + } + start = i + 1; + continue; + } + if (c >= 0x30 && c <= 0x39 && expect != 'P' && expect != 'T') + continue; + return null; + } + if (negative) + { + days = days * -1; + minutes = minutes * -1; + seconds = seconds * -1.0f; + } + Duration duration = new Duration(); + duration.days = days; + duration.minutes = minutes; + duration.seconds = seconds; + return duration; + } + } Index: gnu/xml/validation/datatype/FloatType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/FloatType.java,v retrieving revision 1.1 diff -u -r1.1 FloatType.java --- gnu/xml/validation/datatype/FloatType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/FloatType.java 15 Feb 2006 14:34:48 -0000 @@ -97,5 +97,16 @@ } } + public Object createValue(String literal, ValidationContext context) { + try + { + return new Float(literal); + } + catch (NumberFormatException e) + { + return null; + } + } + } Index: gnu/xml/validation/datatype/GDayType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/GDayType.java,v retrieving revision 1.1 diff -u -r1.1 GDayType.java --- gnu/xml/validation/datatype/GDayType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/GDayType.java 15 Feb 2006 14:34:48 -0000 @@ -51,6 +51,38 @@ extends AtomicSimpleType { + static class GDay + implements Comparable + { + + int day; + + public int hashCode() + { + return day; + } + + public boolean equals(Object other) + { + if (other instanceof GDay) + return ((GDay) other).day == day; + return false; + } + + public int compareTo(Object other) + { + if (other instanceof GDay) + { + GDay gd = (GDay) other; + if (gd.day == day) + return 0; + return (day < gd.day) ? -1 : 1; + } + return 0; + } + + } + static final int[] CONSTRAINING_FACETS = { Facet.PATTERN, Facet.ENUMERATION, @@ -126,5 +158,18 @@ } } + public Object createValue(String literal, ValidationContext context) { + try + { + GDay ret = new GDay(); + ret.day = Integer.parseInt(literal.substring(3)); + return ret; + } + catch (Exception e) + { + return null; + } + } + } Index: gnu/xml/validation/datatype/GMonthDayType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/GMonthDayType.java,v retrieving revision 1.1 diff -u -r1.1 GMonthDayType.java --- gnu/xml/validation/datatype/GMonthDayType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/GMonthDayType.java 15 Feb 2006 14:34:48 -0000 @@ -51,6 +51,46 @@ extends AtomicSimpleType { + static class GMonthDay + implements Comparable + { + + int month; + int day; + + public int hashCode() + { + return month * 31 + day; + } + + public boolean equals(Object other) + { + if (other instanceof GMonthDay) + { + GMonthDay gmd = (GMonthDay) other; + return gmd.month == month && gmd.day == day; + } + return false; + } + + public int compareTo(Object other) + { + if (other instanceof GMonthDay) + { + GMonthDay gmd = (GMonthDay) other; + if (gmd.month == month) + { + if (gmd.day == day) + return 0; + return (day < gmd.day) ? -1 : 1; + } + return (month < gmd.month) ? -1 : 1; + } + return 0; + } + + } + static final int[] CONSTRAINING_FACETS = { Facet.PATTERN, Facet.ENUMERATION, @@ -126,5 +166,19 @@ } } + public Object createValue(String literal, ValidationContext context) { + try + { + GMonthDay ret = new GMonthDay(); + ret.month = Integer.parseInt(literal.substring(2, 5)); + ret.day = Integer.parseInt(literal.substring(6)); + return ret; + } + catch (Exception e) + { + return null; + } + } + } Index: gnu/xml/validation/datatype/GMonthType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/GMonthType.java,v retrieving revision 1.1 diff -u -r1.1 GMonthType.java --- gnu/xml/validation/datatype/GMonthType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/GMonthType.java 15 Feb 2006 14:34:48 -0000 @@ -51,6 +51,38 @@ extends AtomicSimpleType { + static class GMonth + implements Comparable + { + + int month; + + public int hashCode() + { + return month; + } + + public boolean equals(Object other) + { + if (other instanceof GMonth) + return ((GMonth) other).month == month; + return false; + } + + public int compareTo(Object other) + { + if (other instanceof GMonth) + { + GMonth gm = (GMonth) other; + if (gm.month == month) + return 0; + return (month < gm.month) ? -1 : 1; + } + return 0; + } + + } + static final int[] CONSTRAINING_FACETS = { Facet.PATTERN, Facet.ENUMERATION, @@ -115,5 +147,18 @@ } } + public Object createValue(String literal, ValidationContext context) { + try + { + GMonth ret = new GMonth(); + ret.month = Integer.parseInt(literal.substring(2)); + return ret; + } + catch (Exception e) + { + return null; + } + } + } Index: gnu/xml/validation/datatype/GYearMonthType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/GYearMonthType.java,v retrieving revision 1.1 diff -u -r1.1 GYearMonthType.java --- gnu/xml/validation/datatype/GYearMonthType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/GYearMonthType.java 15 Feb 2006 14:34:48 -0000 @@ -51,6 +51,46 @@ extends AtomicSimpleType { + static class GYearMonth + implements Comparable + { + + int year; + int month; + + public int hashCode() + { + return year * 31 + month; + } + + public boolean equals(Object other) + { + if (other instanceof GYearMonth) + { + GYearMonth gmy = (GYearMonth) other; + return gmy.year == year && gmy.month == month; + } + return false; + } + + public int compareTo(Object other) + { + if (other instanceof GYearMonth) + { + GYearMonth gmy = (GYearMonth) other; + if (gmy.year == year) + { + if (gmy.month == month) + return 0; + return (month < gmy.month) ? -1 : 1; + } + return (year < gmy.year) ? -1 : 1; + } + return 0; + } + + } + static final int[] CONSTRAINING_FACETS = { Facet.PATTERN, Facet.ENUMERATION, @@ -116,5 +156,22 @@ } } + public Object createValue(String literal, ValidationContext context) { + try + { + int offset = 5; + if (literal.charAt(0) == '-') + offset++; + GYearMonth ret = new GYearMonth(); + ret.year = Integer.parseInt(literal.substring(0, offset)); + ret.month = Integer.parseInt(literal.substring(offset + 1)); + return ret; + } + catch (Exception e) + { + return null; + } + } + } Index: gnu/xml/validation/datatype/GYearType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/GYearType.java,v retrieving revision 1.1 diff -u -r1.1 GYearType.java --- gnu/xml/validation/datatype/GYearType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/GYearType.java 15 Feb 2006 14:34:48 -0000 @@ -51,6 +51,38 @@ extends AtomicSimpleType { + static class GYear + implements Comparable + { + + int year; + + public int hashCode() + { + return year; + } + + public boolean equals(Object other) + { + if (other instanceof GYear) + return ((GYear) other).year == year; + return false; + } + + public int compareTo(Object other) + { + if (other instanceof GYear) + { + GYear gy = (GYear) other; + if (gy.year == year) + return 0; + return (year < gy.year) ? -1 : 1; + } + return 0; + } + + } + static final int[] CONSTRAINING_FACETS = { Facet.PATTERN, Facet.ENUMERATION, @@ -103,5 +135,18 @@ } } + public Object createValue(String literal, ValidationContext context) { + try + { + GYear ret = new GYear(); + ret.year = Integer.parseInt(literal); + return ret; + } + catch (Exception e) + { + return null; + } + } + } Index: gnu/xml/validation/datatype/IntType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/IntType.java,v retrieving revision 1.1 diff -u -r1.1 IntType.java --- gnu/xml/validation/datatype/IntType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/IntType.java 15 Feb 2006 14:34:48 -0000 @@ -118,5 +118,16 @@ } } + public Object createValue(String literal, ValidationContext context) { + try + { + return new Integer(literal); + } + catch (NumberFormatException e) + { + return null; + } + } + } Index: gnu/xml/validation/datatype/IntegerType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/IntegerType.java,v retrieving revision 1.1 diff -u -r1.1 IntegerType.java --- gnu/xml/validation/datatype/IntegerType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/IntegerType.java 15 Feb 2006 14:34:48 -0000 @@ -37,6 +37,7 @@ package gnu.xml.validation.datatype; +import java.math.BigInteger; import javax.xml.XMLConstants; import javax.xml.namespace.QName; import org.relaxng.datatype.DatatypeException; @@ -94,5 +95,16 @@ } } + public Object createValue(String literal, ValidationContext context) { + try + { + return new BigInteger(literal); + } + catch (NumberFormatException e) + { + return null; + } + } + } Index: gnu/xml/validation/datatype/LongType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/LongType.java,v retrieving revision 1.1 diff -u -r1.1 LongType.java --- gnu/xml/validation/datatype/LongType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/LongType.java 15 Feb 2006 14:34:48 -0000 @@ -118,5 +118,16 @@ } } + public Object createValue(String literal, ValidationContext context) { + try + { + return new Long(literal); + } + catch (NumberFormatException e) + { + return null; + } + } + } Index: gnu/xml/validation/datatype/MaxExclusiveFacet.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/MaxExclusiveFacet.java,v retrieving revision 1.1 diff -u -r1.1 MaxExclusiveFacet.java --- gnu/xml/validation/datatype/MaxExclusiveFacet.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/MaxExclusiveFacet.java 15 Feb 2006 14:34:48 -0000 @@ -37,6 +37,10 @@ package gnu.xml.validation.datatype; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Date; + /** * The maxExclusive facet. * @@ -46,11 +50,11 @@ extends Facet { - public final int value; // FIXME should be a value from the value space of the base definition + public final Object value; // date or number public final boolean fixed; - public MaxExclusiveFacet(int value, boolean fixed, Annotation annotation) + public MaxExclusiveFacet(Object value, boolean fixed, Annotation annotation) { super(MAX_EXCLUSIVE, annotation); this.value = value; @@ -59,13 +63,48 @@ public int hashCode() { - return value; + return value.hashCode(); } public boolean equals(Object other) { return (other instanceof MaxExclusiveFacet && - ((MaxExclusiveFacet) other).value == value); + ((MaxExclusiveFacet) other).value.equals(value)); + } + + boolean matches(Object test) + { + if (value instanceof Date) + { + Date dvalue = (Date) value; + if (!(test instanceof Date)) + return false; + return ((Date) test).before(dvalue); + } + else if (value instanceof BigInteger) + { + BigInteger ivalue = (BigInteger) value; + if (!(test instanceof BigInteger)) + return false; + return ((BigInteger) test).compareTo(ivalue) < 0; + } + else if (value instanceof BigDecimal) + { + BigDecimal dvalue = (BigDecimal) value; + if (!(test instanceof BigDecimal)) + return false; + return ((BigDecimal) test).compareTo(dvalue) < 0; + } + else if (value instanceof Comparable) + { + if (!(test.getClass().equals(value.getClass()))) + return false; + return ((Comparable) test).compareTo(value) < 0; + } + Number nvalue = (Number) value; + if (!(test instanceof Number)) + return false; + return ((Number) test).doubleValue() < nvalue.doubleValue(); } } Index: gnu/xml/validation/datatype/MaxInclusiveFacet.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/MaxInclusiveFacet.java,v retrieving revision 1.1 diff -u -r1.1 MaxInclusiveFacet.java --- gnu/xml/validation/datatype/MaxInclusiveFacet.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/MaxInclusiveFacet.java 15 Feb 2006 14:34:48 -0000 @@ -37,6 +37,10 @@ package gnu.xml.validation.datatype; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Date; + /** * The maxInclusive facet. * @@ -46,11 +50,11 @@ extends Facet { - public final int value; + public final Object value; public final boolean fixed; - public MaxInclusiveFacet(int value, boolean fixed, Annotation annotation) + public MaxInclusiveFacet(Object value, boolean fixed, Annotation annotation) { super(MAX_INCLUSIVE, annotation); this.value = value; @@ -59,13 +63,49 @@ public int hashCode() { - return value; + return value.hashCode(); } public boolean equals(Object other) { return (other instanceof MaxInclusiveFacet && - ((MaxInclusiveFacet) other).value == value); + ((MaxInclusiveFacet) other).value.equals(value)); + } + + boolean matches(Object test) + { + if (value instanceof Date) + { + Date dvalue = (Date) value; + if (!(test instanceof Date)) + return false; + Date dtest = (Date) test; + return dtest.equals(dvalue) || dtest.before(dvalue); + } + else if (value instanceof BigInteger) + { + BigInteger ivalue = (BigInteger) value; + if (!(test instanceof BigInteger)) + return false; + return ((BigInteger) test).compareTo(ivalue) <= 0; + } + else if (value instanceof BigDecimal) + { + BigDecimal dvalue = (BigDecimal) value; + if (!(test instanceof BigDecimal)) + return false; + return ((BigDecimal) test).compareTo(dvalue) <= 0; + } + else if (value instanceof Comparable) + { + if (!(test.getClass().equals(value.getClass()))) + return false; + return ((Comparable) test).compareTo(value) <= 0; + } + Number nvalue = (Number) value; + if (!(test instanceof Number)) + return false; + return ((Number) test).doubleValue() <= nvalue.doubleValue(); } } Index: gnu/xml/validation/datatype/MinExclusiveFacet.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/MinExclusiveFacet.java,v retrieving revision 1.1 diff -u -r1.1 MinExclusiveFacet.java --- gnu/xml/validation/datatype/MinExclusiveFacet.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/MinExclusiveFacet.java 15 Feb 2006 14:34:48 -0000 @@ -37,6 +37,10 @@ package gnu.xml.validation.datatype; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Date; + /** * The minExclusive facet. * @@ -46,11 +50,11 @@ extends Facet { - public final int value; + public final Object value; public final boolean fixed; - public MinExclusiveFacet(int value, boolean fixed, Annotation annotation) + public MinExclusiveFacet(Object value, boolean fixed, Annotation annotation) { super(MIN_EXCLUSIVE, annotation); this.value = value; @@ -59,13 +63,48 @@ public int hashCode() { - return value; + return value.hashCode(); } public boolean equals(Object other) { return (other instanceof MinExclusiveFacet && - ((MinExclusiveFacet) other).value == value); + ((MinExclusiveFacet) other).value.equals(value)); + } + + boolean matches(Object test) + { + if (value instanceof Date) + { + Date dvalue = (Date) value; + if (!(test instanceof Date)) + return false; + return ((Date) test).after(dvalue); + } + else if (value instanceof BigInteger) + { + BigInteger ivalue = (BigInteger) value; + if (!(test instanceof BigInteger)) + return false; + return ((BigInteger) test).compareTo(ivalue) > 0; + } + else if (value instanceof BigDecimal) + { + BigDecimal dvalue = (BigDecimal) value; + if (!(test instanceof BigDecimal)) + return false; + return ((BigDecimal) test).compareTo(dvalue) > 0; + } + else if (value instanceof Comparable) + { + if (!(test.getClass().equals(value.getClass()))) + return false; + return ((Comparable) test).compareTo(value) > 0; + } + Number nvalue = (Number) value; + if (!(test instanceof Number)) + return false; + return ((Number) test).doubleValue() > nvalue.doubleValue(); } } Index: gnu/xml/validation/datatype/MinInclusiveFacet.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/MinInclusiveFacet.java,v retrieving revision 1.1 diff -u -r1.1 MinInclusiveFacet.java --- gnu/xml/validation/datatype/MinInclusiveFacet.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/MinInclusiveFacet.java 15 Feb 2006 14:34:48 -0000 @@ -37,6 +37,10 @@ package gnu.xml.validation.datatype; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Date; + /** * The minInclusive facet. * @@ -46,11 +50,11 @@ extends Facet { - public final int value; + public final Object value; public final boolean fixed; - public MinInclusiveFacet(int value, boolean fixed, Annotation annotation) + public MinInclusiveFacet(Object value, boolean fixed, Annotation annotation) { super(MIN_INCLUSIVE, annotation); this.value = value; @@ -59,13 +63,49 @@ public int hashCode() { - return value; + return value.hashCode(); } public boolean equals(Object other) { return (other instanceof MinInclusiveFacet && - ((MinInclusiveFacet) other).value == value); + ((MinInclusiveFacet) other).value.equals(value)); + } + + boolean matches(Object test) + { + if (value instanceof Date) + { + Date dvalue = (Date) value; + if (!(test instanceof Date)) + return false; + Date dtest = (Date) test; + return dtest.equals(dvalue) || dtest.after(dvalue); + } + else if (value instanceof BigInteger) + { + BigInteger ivalue = (BigInteger) value; + if (!(test instanceof BigInteger)) + return false; + return ((BigInteger) test).compareTo(ivalue) >= 0; + } + else if (value instanceof BigDecimal) + { + BigDecimal dvalue = (BigDecimal) value; + if (!(test instanceof BigDecimal)) + return false; + return ((BigDecimal) test).compareTo(dvalue) >= 0; + } + else if (value instanceof Comparable) + { + if (!(test.getClass().equals(value.getClass()))) + return false; + return ((Comparable) test).compareTo(value) >= 0; + } + Number nvalue = (Number) value; + if (!(test instanceof Number)) + return false; + return ((Number) test).doubleValue() >= nvalue.doubleValue(); } } Index: gnu/xml/validation/datatype/NegativeIntegerType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/NegativeIntegerType.java,v retrieving revision 1.1 diff -u -r1.1 NegativeIntegerType.java --- gnu/xml/validation/datatype/NegativeIntegerType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/NegativeIntegerType.java 15 Feb 2006 14:34:48 -0000 @@ -37,6 +37,7 @@ package gnu.xml.validation.datatype; +import java.math.BigInteger; import javax.xml.XMLConstants; import javax.xml.namespace.QName; import org.relaxng.datatype.DatatypeException; @@ -95,5 +96,16 @@ } } + public Object createValue(String literal, ValidationContext context) { + try + { + return new BigInteger(literal); + } + catch (NumberFormatException e) + { + return null; + } + } + } Index: gnu/xml/validation/datatype/NonNegativeIntegerType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/NonNegativeIntegerType.java,v retrieving revision 1.1 diff -u -r1.1 NonNegativeIntegerType.java --- gnu/xml/validation/datatype/NonNegativeIntegerType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/NonNegativeIntegerType.java 15 Feb 2006 14:34:48 -0000 @@ -37,6 +37,7 @@ package gnu.xml.validation.datatype; +import java.math.BigInteger; import javax.xml.XMLConstants; import javax.xml.namespace.QName; import org.relaxng.datatype.DatatypeException; @@ -105,5 +106,16 @@ } } + public Object createValue(String literal, ValidationContext context) { + try + { + return new BigInteger(literal); + } + catch (NumberFormatException e) + { + return null; + } + } + } Index: gnu/xml/validation/datatype/NonPositiveIntegerType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/NonPositiveIntegerType.java,v retrieving revision 1.1 diff -u -r1.1 NonPositiveIntegerType.java --- gnu/xml/validation/datatype/NonPositiveIntegerType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/NonPositiveIntegerType.java 15 Feb 2006 14:34:48 -0000 @@ -37,6 +37,7 @@ package gnu.xml.validation.datatype; +import java.math.BigInteger; import javax.xml.XMLConstants; import javax.xml.namespace.QName; import org.relaxng.datatype.DatatypeException; @@ -105,5 +106,16 @@ } } + public Object createValue(String literal, ValidationContext context) { + try + { + return new BigInteger(literal); + } + catch (NumberFormatException e) + { + return null; + } + } + } Index: gnu/xml/validation/datatype/PositiveIntegerType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/PositiveIntegerType.java,v retrieving revision 1.1 diff -u -r1.1 PositiveIntegerType.java --- gnu/xml/validation/datatype/PositiveIntegerType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/PositiveIntegerType.java 15 Feb 2006 14:34:48 -0000 @@ -37,6 +37,7 @@ package gnu.xml.validation.datatype; +import java.math.BigInteger; import javax.xml.XMLConstants; import javax.xml.namespace.QName; import org.relaxng.datatype.DatatypeException; @@ -95,5 +96,16 @@ } } + public Object createValue(String literal, ValidationContext context) { + try + { + return new BigInteger(literal); + } + catch (NumberFormatException e) + { + return null; + } + } + } Index: gnu/xml/validation/datatype/ShortType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/ShortType.java,v retrieving revision 1.1 diff -u -r1.1 ShortType.java --- gnu/xml/validation/datatype/ShortType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/ShortType.java 15 Feb 2006 14:34:48 -0000 @@ -118,5 +118,16 @@ } } + public Object createValue(String literal, ValidationContext context) { + try + { + return new Short(literal); + } + catch (NumberFormatException e) + { + return null; + } + } + } Index: gnu/xml/validation/datatype/SimpleType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/SimpleType.java,v retrieving revision 1.1 diff -u -r1.1 SimpleType.java --- gnu/xml/validation/datatype/SimpleType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/SimpleType.java 15 Feb 2006 14:34:48 -0000 @@ -139,8 +139,9 @@ public void checkValid(String value, ValidationContext context) throws DatatypeException { - if (facets != null) + if (facets != null && !facets.isEmpty()) { + Object parsedValue = createValue(value, context); for (Iterator i = facets.iterator(); i.hasNext(); ) { Facet facet = (Facet) i.next(); @@ -174,10 +175,24 @@ // TODO break; case Facet.MAX_INCLUSIVE: + MaxInclusiveFacet xif = (MaxInclusiveFacet) facet; + if (!xif.matches(parsedValue)) + throw new DatatypeException("beyond upper bound"); + break; case Facet.MAX_EXCLUSIVE: + MaxExclusiveFacet xef = (MaxExclusiveFacet) facet; + if (!xef.matches(parsedValue)) + throw new DatatypeException("beyond upper bound"); + break; case Facet.MIN_EXCLUSIVE: + MinExclusiveFacet nef = (MinExclusiveFacet) facet; + if (!nef.matches(parsedValue)) + throw new DatatypeException("beyond lower bound"); + break; case Facet.MIN_INCLUSIVE: - // TODO + MinInclusiveFacet nif = (MinInclusiveFacet) facet; + if (!nif.matches(parsedValue)) + throw new DatatypeException("beyond lower bound"); break; case Facet.TOTAL_DIGITS: TotalDigitsFacet tdf = (TotalDigitsFacet) facet; @@ -216,19 +231,16 @@ throw new UnsupportedOperationException(); } - // TODO createValue public Object createValue(String literal, ValidationContext context) { - throw new UnsupportedOperationException(); + return literal; } - // TODO sameValue public boolean sameValue(Object value1, Object value2) { - throw new UnsupportedOperationException(); + return value1.equals(value2); } - // TODO valueHashCode public int valueHashCode(Object value) { - throw new UnsupportedOperationException(); + return value.hashCode(); } public int getIdType() Index: gnu/xml/validation/datatype/TimeType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/TimeType.java,v retrieving revision 1.1 diff -u -r1.1 TimeType.java --- gnu/xml/validation/datatype/TimeType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/TimeType.java 15 Feb 2006 14:34:48 -0000 @@ -37,6 +37,7 @@ package gnu.xml.validation.datatype; +import java.util.TimeZone; import javax.xml.XMLConstants; import javax.xml.namespace.QName; import org.relaxng.datatype.DatatypeException; @@ -51,6 +52,43 @@ extends AtomicSimpleType { + static class Time + implements Comparable + { + int minutes; + float seconds; + + public int hashCode() + { + return minutes * 31 + new Float(seconds).hashCode(); + } + + public boolean equals(Object other) + { + if (other instanceof Time) + { + Time time = (Time) other; + return time.minutes == minutes && time.seconds == seconds; + } + return false; + } + + public int compareTo(Object other) + { + if (other instanceof Time) + { + Time time = (Time) other; + if (time.minutes != minutes) + return minutes - time.minutes; + if (time.seconds == seconds) + return 0; + return (seconds < time.seconds) ? -1 : 1; + } + return 0; + } + + } + static final int[] CONSTRAINING_FACETS = { Facet.PATTERN, Facet.ENUMERATION, @@ -180,5 +218,86 @@ } } + public Object createValue(String value, ValidationContext context) { + int len = value.length(); + int state = 3; + int start = 0; + Time time = new Time(); + try + { + for (int i = 0; i < len; i++) + { + char c = value.charAt(i); + if (c >= 0x30 && c <= 0x39) + continue; + switch (state) + { + case 3: // hour + if (c == ':') + { + time.minutes = + Integer.parseInt(value.substring(start, i)) * 60; + state = 4; + start = i + 1; + continue; + } + break; + case 4: // minute + if (c == ':') + { + time.minutes += + Integer.parseInt(value.substring(start, i)); + state = 5; + start = i + 1; + continue; + } + break; + case 5: // second + if (c == ' ') + { + time.seconds = + Float.parseFloat(value.substring(start, i)); + state = 7; + start = i + 1; + continue; + } + break; + } + } + // end of input + if (len - start > 0 && state == 7) + { + // Timezone + String timezone = value.substring(len - start); + int i = timezone.indexOf(':'); + if (i == -1) + { + if ("Z".equals(timezone)) + timezone = "UTC"; + TimeZone tz = TimeZone.getTimeZone(timezone); + if (tz == null) + return null; + time.minutes += tz.getRawOffset(); + } + else + { + String tzh = timezone.substring(0, i); + String tzm = timezone.substring(i + 1); + int offset = Integer.parseInt(tzh) * 60; + if (offset < 0) + offset -= Integer.parseInt(tzm); + else + offset += Integer.parseInt(tzm); + time.minutes += offset; + } + } + return time; + } + catch (NumberFormatException e) + { + return null; + } + } + } Index: gnu/xml/validation/datatype/TypeBuilder.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/TypeBuilder.java,v retrieving revision 1.1 diff -u -r1.1 TypeBuilder.java --- gnu/xml/validation/datatype/TypeBuilder.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/TypeBuilder.java 15 Feb 2006 14:34:48 -0000 @@ -80,13 +80,13 @@ else if ("whiteSpace".equals(name)) type.facets.add(parseWhiteSpaceFacet(value)); else if ("maxInclusive".equals(name)) - type.facets.add(parseMaxInclusiveFacet(value)); + type.facets.add(parseMaxInclusiveFacet(value, context)); else if ("maxExclusive".equals(name)) - type.facets.add(parseMaxExclusiveFacet(value)); + type.facets.add(parseMaxExclusiveFacet(value, context)); else if ("minExclusive".equals(name)) - type.facets.add(parseMinExclusiveFacet(value)); + type.facets.add(parseMinExclusiveFacet(value, context)); else if ("minInclusive".equals(name)) - type.facets.add(parseMinInclusiveFacet(value)); + type.facets.add(parseMinInclusiveFacet(value, context)); else if ("totalDigits".equals(name)) type.facets.add(parseTotalDigitsFacet(value)); else if ("fractionDigits".equals(name)) @@ -171,7 +171,8 @@ throw new DatatypeException("argument must be preserve, replace, or collapse"); } - MaxInclusiveFacet parseMaxInclusiveFacet(String value) + MaxInclusiveFacet parseMaxInclusiveFacet(String value, + ValidationContext context) throws DatatypeException { int si = value.indexOf(' '); @@ -183,10 +184,11 @@ fixed = true; value = value.substring(0, si); } - return new MaxInclusiveFacet(Integer.parseInt(value), fixed, null); + return new MaxInclusiveFacet(type.createValue(value, context), fixed, null); } - MaxExclusiveFacet parseMaxExclusiveFacet(String value) + MaxExclusiveFacet parseMaxExclusiveFacet(String value, + ValidationContext context) throws DatatypeException { int si = value.indexOf(' '); @@ -198,10 +200,11 @@ fixed = true; value = value.substring(0, si); } - return new MaxExclusiveFacet(Integer.parseInt(value), fixed, null); + return new MaxExclusiveFacet(type.createValue(value, context), fixed, null); } - MinExclusiveFacet parseMinExclusiveFacet(String value) + MinExclusiveFacet parseMinExclusiveFacet(String value, + ValidationContext context) throws DatatypeException { int si = value.indexOf(' '); @@ -213,10 +216,11 @@ fixed = true; value = value.substring(0, si); } - return new MinExclusiveFacet(Integer.parseInt(value), fixed, null); + return new MinExclusiveFacet(type.createValue(value, context), fixed, null); } - MinInclusiveFacet parseMinInclusiveFacet(String value) + MinInclusiveFacet parseMinInclusiveFacet(String value, + ValidationContext context) throws DatatypeException { int si = value.indexOf(' '); @@ -228,7 +232,7 @@ fixed = true; value = value.substring(0, si); } - return new MinInclusiveFacet(Integer.parseInt(value), fixed, null); + return new MinInclusiveFacet(type.createValue(value, context), fixed, null); } TotalDigitsFacet parseTotalDigitsFacet(String value) Index: gnu/xml/validation/datatype/UnsignedByteType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/UnsignedByteType.java,v retrieving revision 1.1 diff -u -r1.1 UnsignedByteType.java --- gnu/xml/validation/datatype/UnsignedByteType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/UnsignedByteType.java 15 Feb 2006 14:34:48 -0000 @@ -106,5 +106,16 @@ } } + public Object createValue(String literal, ValidationContext context) { + try + { + return new Byte(literal); + } + catch (NumberFormatException e) + { + return null; + } + } + } Index: gnu/xml/validation/datatype/UnsignedIntType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/UnsignedIntType.java,v retrieving revision 1.1 diff -u -r1.1 UnsignedIntType.java --- gnu/xml/validation/datatype/UnsignedIntType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/UnsignedIntType.java 15 Feb 2006 14:34:48 -0000 @@ -106,5 +106,16 @@ } } + public Object createValue(String literal, ValidationContext context) { + try + { + return new Integer(literal); + } + catch (NumberFormatException e) + { + return null; + } + } + } Index: gnu/xml/validation/datatype/UnsignedLongType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/UnsignedLongType.java,v retrieving revision 1.1 diff -u -r1.1 UnsignedLongType.java --- gnu/xml/validation/datatype/UnsignedLongType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/UnsignedLongType.java 15 Feb 2006 14:34:48 -0000 @@ -106,5 +106,16 @@ } } + public Object createValue(String literal, ValidationContext context) { + try + { + return new Long(literal); + } + catch (NumberFormatException e) + { + return null; + } + } + } Index: gnu/xml/validation/datatype/UnsignedShortType.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/xml/validation/datatype/UnsignedShortType.java,v retrieving revision 1.1 diff -u -r1.1 UnsignedShortType.java --- gnu/xml/validation/datatype/UnsignedShortType.java 13 Feb 2006 19:27:24 -0000 1.1 +++ gnu/xml/validation/datatype/UnsignedShortType.java 15 Feb 2006 14:34:48 -0000 @@ -107,5 +107,16 @@ } } + public Object createValue(String literal, ValidationContext context) { + try + { + return new Short(literal); + } + catch (NumberFormatException e) + { + return null; + } + } + }