jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/AbstractDateTimeDV.java

Print this page

        

*** 50,87 **** * @version $Id: AbstractDateTimeDV.java,v 1.7 2010-11-01 04:39:46 joehw Exp $ */ public abstract class AbstractDateTimeDV extends TypeValidator { //debugging ! private static final boolean DEBUG=false; ! //define shared variables for date/time - - //define constants to be used in assigning default values for //all date/time excluding duration ! protected final static int YEAR=2000; ! protected final static int MONTH=01; protected final static int DAY = 01; - protected static final DatatypeFactory datatypeFactory = new DatatypeFactoryImpl(); ! public short getAllowedFacets(){ ! return ( XSSimpleTypeDecl.FACET_PATTERN | XSSimpleTypeDecl.FACET_WHITESPACE | XSSimpleTypeDecl.FACET_ENUMERATION |XSSimpleTypeDecl.FACET_MAXINCLUSIVE |XSSimpleTypeDecl.FACET_MININCLUSIVE | XSSimpleTypeDecl.FACET_MAXEXCLUSIVE | XSSimpleTypeDecl.FACET_MINEXCLUSIVE ); }//getAllowedFacets() - // distinguishes between identity and equality for date/time values // ie: two values representing the same "moment in time" but with different // remembered timezones are now equal but not identical. ! public boolean isIdentical (Object value1, Object value2) { if (!(value1 instanceof DateTimeData) || !(value2 instanceof DateTimeData)) { return false; } ! DateTimeData v1 = (DateTimeData)value1; ! DateTimeData v2 = (DateTimeData)value2; // original timezones must be the same in addition to date/time values // being 'equal' if ((v1.timezoneHr == v2.timezoneHr) && (v1.timezoneMin == v2.timezoneMin)) { return v1.equals(v2); --- 50,84 ---- * @version $Id: AbstractDateTimeDV.java,v 1.7 2010-11-01 04:39:46 joehw Exp $ */ public abstract class AbstractDateTimeDV extends TypeValidator { //debugging ! private static final boolean DEBUG = false; //define shared variables for date/time //define constants to be used in assigning default values for //all date/time excluding duration ! protected final static int YEAR = 2000; ! protected final static int MONTH = 01; protected final static int DAY = 01; protected static final DatatypeFactory datatypeFactory = new DatatypeFactoryImpl(); ! @Override ! public short getAllowedFacets() { ! return (XSSimpleTypeDecl.FACET_PATTERN | XSSimpleTypeDecl.FACET_WHITESPACE | XSSimpleTypeDecl.FACET_ENUMERATION | XSSimpleTypeDecl.FACET_MAXINCLUSIVE | XSSimpleTypeDecl.FACET_MININCLUSIVE | XSSimpleTypeDecl.FACET_MAXEXCLUSIVE | XSSimpleTypeDecl.FACET_MINEXCLUSIVE); }//getAllowedFacets() // distinguishes between identity and equality for date/time values // ie: two values representing the same "moment in time" but with different // remembered timezones are now equal but not identical. ! @Override ! public boolean isIdentical(Object value1, Object value2) { if (!(value1 instanceof DateTimeData) || !(value2 instanceof DateTimeData)) { return false; } ! DateTimeData v1 = (DateTimeData) value1; ! DateTimeData v2 = (DateTimeData) value2; // original timezones must be the same in addition to date/time values // being 'equal' if ((v1.timezoneHr == v2.timezoneHr) && (v1.timezoneMin == v2.timezoneMin)) { return v1.equals(v2);
*** 89,106 **** return false; }//isIdentical() // the parameters are in compiled form (from getActualValue) ! public int compare (Object value1, Object value2) { ! return compareDates(((DateTimeData)value1), ! ((DateTimeData)value2), true); }//compare() /** ! * Compare algorithm described in dateDime (3.2.7). ! * Duration datatype overwrites this method * * @param date1 normalized date representation of the first value * @param date2 normalized date representation of the second value * @param strict * @return less, greater, less_equal, greater_equal, equal --- 86,104 ---- return false; }//isIdentical() // the parameters are in compiled form (from getActualValue) ! @Override ! public int compare(Object value1, Object value2) { ! return compareDates(((DateTimeData) value1), ! ((DateTimeData) value2), true); }//compare() /** ! * Compare algorithm described in dateDime (3.2.7). Duration datatype ! * overwrites this method * * @param date1 normalized date representation of the first value * @param date2 normalized date representation of the second value * @param strict * @return less, greater, less_equal, greater_equal, equal
*** 111,227 **** } short c1, c2; DateTimeData tempDate = new DateTimeData(null, this); ! if ( date1.utc=='Z' ) { //compare date1<=date1<=(date2 with time zone -14) // cloneDate(date2, tempDate); //clones date1 value to global temporary storage: fTempDate ! tempDate.timezoneHr=14; tempDate.timezoneMin = 0; ! tempDate.utc='+'; normalize(tempDate); c1 = compareOrder(date1, tempDate); ! if (c1 == LESS_THAN) return c1; //compare date1>=(date2 with time zone +14) // cloneDate(date2, tempDate); //clones date1 value to global temporary storage: tempDate tempDate.timezoneHr = -14; tempDate.timezoneMin = 0; ! tempDate.utc='-'; normalize(tempDate); c2 = compareOrder(date1, tempDate); ! if (c2 == GREATER_THAN) return c2; return INDETERMINATE; ! } ! else if ( date2.utc=='Z' ) { //compare (date1 with time zone -14)<=date2 // cloneDate(date1, tempDate); //clones date1 value to global temporary storage: tempDate tempDate.timezoneHr = -14; tempDate.timezoneMin = 0; ! tempDate.utc='-'; if (DEBUG) { System.out.println("tempDate=" + dateToString(tempDate)); } normalize(tempDate); c1 = compareOrder(tempDate, date2); if (DEBUG) { System.out.println("date=" + dateToString(date2)); System.out.println("tempDate=" + dateToString(tempDate)); } ! if (c1 == LESS_THAN) return c1; //compare (date1 with time zone +14)<=date2 // cloneDate(date1, tempDate); //clones date1 value to global temporary storage: tempDate tempDate.timezoneHr = 14; tempDate.timezoneMin = 0; ! tempDate.utc='+'; normalize(tempDate); c2 = compareOrder(tempDate, date2); if (DEBUG) { System.out.println("tempDate=" + dateToString(tempDate)); } ! if (c2 == GREATER_THAN) return c2; return INDETERMINATE; } return INDETERMINATE; } /** ! * Given normalized values, determines order-relation ! * between give date/time objects. * * @param date1 date/time object * @param date2 date/time object ! * @return 0 if date1 and date2 are equal, a value less than 0 if date1 is less than date2, a value greater than 0 if date1 is greater than date2 */ protected short compareOrder(DateTimeData date1, DateTimeData date2) { ! if(date1.position < 1) { ! if (date1.year < date2.year) return -1; ! if (date1.year > date2.year) return 1; } ! if(date1.position < 2) { ! if (date1.month < date2.month) return -1; ! if (date1.month > date2.month) return 1; } ! if (date1.day < date2.day) return -1; ! if (date1.day > date2.day) return 1; ! if (date1.hour < date2.hour) return -1; ! if (date1.hour > date2.hour) return 1; ! if (date1.minute < date2.minute) return -1; ! if (date1.minute > date2.minute) return 1; ! if (date1.second < date2.second) return -1; ! if (date1.second > date2.second) return 1; ! if (date1.utc < date2.utc) return -1; ! if (date1.utc > date2.utc) return 1; return 0; } /** * Parses time hh:mm:ss.sss and time zone if any --- 109,243 ---- } short c1, c2; DateTimeData tempDate = new DateTimeData(null, this); ! if (date1.utc == 'Z') { //compare date1<=date1<=(date2 with time zone -14) // cloneDate(date2, tempDate); //clones date1 value to global temporary storage: fTempDate ! tempDate.timezoneHr = 14; tempDate.timezoneMin = 0; ! tempDate.utc = '+'; normalize(tempDate); c1 = compareOrder(date1, tempDate); ! if (c1 == LESS_THAN) { return c1; + } //compare date1>=(date2 with time zone +14) // cloneDate(date2, tempDate); //clones date1 value to global temporary storage: tempDate tempDate.timezoneHr = -14; tempDate.timezoneMin = 0; ! tempDate.utc = '-'; normalize(tempDate); c2 = compareOrder(date1, tempDate); ! if (c2 == GREATER_THAN) { return c2; + } return INDETERMINATE; ! } else if (date2.utc == 'Z') { //compare (date1 with time zone -14)<=date2 // cloneDate(date1, tempDate); //clones date1 value to global temporary storage: tempDate tempDate.timezoneHr = -14; tempDate.timezoneMin = 0; ! tempDate.utc = '-'; if (DEBUG) { System.out.println("tempDate=" + dateToString(tempDate)); } normalize(tempDate); c1 = compareOrder(tempDate, date2); if (DEBUG) { System.out.println("date=" + dateToString(date2)); System.out.println("tempDate=" + dateToString(tempDate)); } ! if (c1 == LESS_THAN) { return c1; + } //compare (date1 with time zone +14)<=date2 // cloneDate(date1, tempDate); //clones date1 value to global temporary storage: tempDate tempDate.timezoneHr = 14; tempDate.timezoneMin = 0; ! tempDate.utc = '+'; normalize(tempDate); c2 = compareOrder(tempDate, date2); if (DEBUG) { System.out.println("tempDate=" + dateToString(tempDate)); } ! if (c2 == GREATER_THAN) { return c2; + } return INDETERMINATE; } return INDETERMINATE; } /** ! * Given normalized values, determines order-relation between give date/time ! * objects. * * @param date1 date/time object * @param date2 date/time object ! * @return 0 if date1 and date2 are equal, a value less than 0 if date1 is ! * less than date2, a value greater than 0 if date1 is greater than date2 */ protected short compareOrder(DateTimeData date1, DateTimeData date2) { ! if (date1.position < 1) { ! if (date1.year < date2.year) { return -1; ! } ! if (date1.year > date2.year) { return 1; } ! } ! if (date1.position < 2) { ! if (date1.month < date2.month) { return -1; ! } ! if (date1.month > date2.month) { return 1; } ! } ! if (date1.day < date2.day) { return -1; ! } ! if (date1.day > date2.day) { return 1; ! } ! if (date1.hour < date2.hour) { return -1; ! } ! if (date1.hour > date2.hour) { return 1; ! } ! if (date1.minute < date2.minute) { return -1; ! } ! if (date1.minute > date2.minute) { return 1; ! } ! if (date1.second < date2.second) { return -1; ! } ! if (date1.second > date2.second) { return 1; ! } ! if (date1.utc < date2.utc) { return -1; ! } ! if (date1.utc > date2.utc) { return 1; + } return 0; } /** * Parses time hh:mm:ss.sss and time zone if any
*** 229,257 **** * @param start * @param end * @param data * @exception RuntimeException */ ! protected void getTime (String buffer, int start, int end, DateTimeData data) throws RuntimeException{ ! int stop = start+2; //get hours (hh) ! data.hour=parseInt(buffer, start,stop); //get minutes (mm) ! if (buffer.charAt(stop++)!=':') { ! throw new RuntimeException("Error in parsing time zone" ); } start = stop; ! stop = stop+2; ! data.minute=parseInt(buffer, start,stop); //get seconds (ss) ! if (buffer.charAt(stop++)!=':') { ! throw new RuntimeException("Error in parsing time zone" ); } //find UTC sign if any int sign = findUTCSign(buffer, start, end); --- 245,273 ---- * @param start * @param end * @param data * @exception RuntimeException */ ! protected void getTime(String buffer, int start, int end, DateTimeData data) throws RuntimeException { ! int stop = start + 2; //get hours (hh) ! data.hour = parseInt(buffer, start, stop); //get minutes (mm) ! if (buffer.charAt(stop++) != ':') { ! throw new RuntimeException("Error in parsing time zone"); } start = stop; ! stop = stop + 2; ! data.minute = parseInt(buffer, start, stop); //get seconds (ss) ! if (buffer.charAt(stop++) != ':') { ! throw new RuntimeException("Error in parsing time zone"); } //find UTC sign if any int sign = findUTCSign(buffer, start, end);
*** 273,291 **** * @param start start position * @param end end position * @param date * @exception RuntimeException */ ! protected int getDate (String buffer, int start, int end, DateTimeData date) throws RuntimeException{ start = getYearMonth(buffer, start, end, date); ! if (buffer.charAt(start++) !='-') { throw new RuntimeException("CCYY-MM must be followed by '-' sign"); } int stop = start + 2; ! date.day=parseInt(buffer, start, stop); return stop; } /** * Parses date CCYY-MM --- 289,307 ---- * @param start start position * @param end end position * @param date * @exception RuntimeException */ ! protected int getDate(String buffer, int start, int end, DateTimeData date) throws RuntimeException { start = getYearMonth(buffer, start, end, date); ! if (buffer.charAt(start++) != '-') { throw new RuntimeException("CCYY-MM must be followed by '-' sign"); } int stop = start + 2; ! date.day = parseInt(buffer, start, stop); return stop; } /** * Parses date CCYY-MM
*** 294,347 **** * @param start start position * @param end end position * @param date * @exception RuntimeException */ ! protected int getYearMonth (String buffer, int start, int end, DateTimeData date) throws RuntimeException{ ! if ( buffer.charAt(0)=='-' ) { // REVISIT: date starts with preceding '-' sign // do we have to do anything with it? // start++; } int i = indexOf(buffer, start, end, '-'); ! if ( i==-1 ) throw new RuntimeException("Year separator is missing or misplaced"); ! int length = i-start; ! if (length<4) { ! throw new RuntimeException("Year must have 'CCYY' format"); } ! else if (length > 4 && buffer.charAt(start)=='0'){ throw new RuntimeException("Leading zeros are required if the year value would otherwise have fewer than four digits; otherwise they are forbidden"); } ! date.year= parseIntYear(buffer, i); ! if (buffer.charAt(i)!='-') { throw new RuntimeException("CCYY must be followed by '-' sign"); } start = ++i; ! i = start +2; ! date.month=parseInt(buffer, start, i); return i; //fStart points right after the MONTH } /** ! * Shared code from Date and YearMonth datatypes. ! * Finds if time zone sign is present * * @param end * @param date * @exception RuntimeException */ ! protected void parseTimeZone (String buffer, int start, int end, DateTimeData date) throws RuntimeException{ //fStart points right after the date ! if ( start < end ) { if (!isNextCharUTCSign(buffer, start, end)) { ! throw new RuntimeException ("Error in month parsing"); ! } ! else { getTimeZone(buffer, date, start, end); } } } --- 310,363 ---- * @param start start position * @param end end position * @param date * @exception RuntimeException */ ! protected int getYearMonth(String buffer, int start, int end, DateTimeData date) throws RuntimeException { ! if (buffer.charAt(0) == '-') { // REVISIT: date starts with preceding '-' sign // do we have to do anything with it? // start++; } int i = indexOf(buffer, start, end, '-'); ! if (i == -1) { ! throw new RuntimeException("Year separator is missing or misplaced"); } ! int length = i - start; ! if (length < 4) { ! throw new RuntimeException("Year must have 'CCYY' format"); ! } else if (length > 4 && buffer.charAt(start) == '0') { throw new RuntimeException("Leading zeros are required if the year value would otherwise have fewer than four digits; otherwise they are forbidden"); } ! date.year = parseIntYear(buffer, i); ! if (buffer.charAt(i) != '-') { throw new RuntimeException("CCYY must be followed by '-' sign"); } start = ++i; ! i = start + 2; ! date.month = parseInt(buffer, start, i); return i; //fStart points right after the MONTH } /** ! * Shared code from Date and YearMonth datatypes. Finds if time zone sign is ! * present * * @param end * @param date * @exception RuntimeException */ ! protected void parseTimeZone(String buffer, int start, int end, DateTimeData date) throws RuntimeException { //fStart points right after the date ! if (start < end) { if (!isNextCharUTCSign(buffer, start, end)) { ! throw new RuntimeException("Error in month parsing"); ! } else { getTimeZone(buffer, date, start, end); } } }
*** 350,392 **** * * @param data * @param sign * @exception RuntimeException */ ! protected void getTimeZone (String buffer, DateTimeData data, int sign, int end) throws RuntimeException{ ! data.utc=buffer.charAt(sign); ! if ( buffer.charAt(sign) == 'Z' ) { ! if (end>(++sign)) { throw new RuntimeException("Error in parsing time zone"); } return; } ! if ( sign<=(end-6) ) { ! int negate = buffer.charAt(sign) == '-'?-1:1; //parse hr ! int stop = ++sign+2; ! data.timezoneHr = negate*parseInt(buffer, sign, stop); ! if (buffer.charAt(stop++)!=':') { ! throw new RuntimeException("Error in parsing time zone" ); } //parse min ! data.timezoneMin = negate*parseInt(buffer, stop, stop+2); ! if ( stop+2!=end ) { throw new RuntimeException("Error in parsing time zone"); } ! if(data.timezoneHr != 0 || data.timezoneMin != 0) data.normalized = false; } ! else { throw new RuntimeException("Error in parsing time zone"); } ! if ( DEBUG ) { ! System.out.println("time[hh]="+data.timezoneHr + " time[mm]=" +data.timezoneMin); } } /** * Computes index of given char within StringBuffer --- 366,408 ---- * * @param data * @param sign * @exception RuntimeException */ ! protected void getTimeZone(String buffer, DateTimeData data, int sign, int end) throws RuntimeException { ! data.utc = buffer.charAt(sign); ! if (buffer.charAt(sign) == 'Z') { ! if (end > (++sign)) { throw new RuntimeException("Error in parsing time zone"); } return; } ! if (sign <= (end - 6)) { ! int negate = buffer.charAt(sign) == '-' ? -1 : 1; //parse hr ! int stop = ++sign + 2; ! data.timezoneHr = negate * parseInt(buffer, sign, stop); ! if (buffer.charAt(stop++) != ':') { ! throw new RuntimeException("Error in parsing time zone"); } //parse min ! data.timezoneMin = negate * parseInt(buffer, stop, stop + 2); ! if (stop + 2 != end) { throw new RuntimeException("Error in parsing time zone"); } ! if (data.timezoneHr != 0 || data.timezoneMin != 0) { data.normalized = false; } ! } else { throw new RuntimeException("Error in parsing time zone"); } ! if (DEBUG) { ! System.out.println("time[hh]=" + data.timezoneHr + " time[mm]=" + data.timezoneMin); } } /** * Computes index of given char within StringBuffer
*** 394,508 **** * @param start * @param end * @param ch character to look for in StringBuffer * @return index of ch within StringBuffer */ ! protected int indexOf (String buffer, int start, int end, char ch) { ! for ( int i=start;i<end;i++ ) { ! if ( buffer.charAt(i) == ch ) { return i; } } return -1; } /** ! * Validates given date/time object accoring to W3C PR Schema ! * [D.1 ISO 8601 Conventions] * * @param data */ ! protected void validateDateTime (DateTimeData data) { //REVISIT: should we throw an exception for not valid dates // or reporting an error message should be sufficient? /** * XML Schema 1.1 - RQ-123: Allow year 0000 in date related types. */ ! if (!Constants.SCHEMA_1_1_SUPPORT && data.year==0 ) { throw new RuntimeException("The year \"0000\" is an illegal year value"); } ! if ( data.month<1 || data.month>12 ) { throw new RuntimeException("The month must have values 1 to 12"); } //validate days ! if ( data.day>maxDayInMonthFor(data.year, data.month) || data.day<1 ) { throw new RuntimeException("The day must have values 1 to 31"); } //validate hours ! if ( data.hour>23 || data.hour<0 ) { if (data.hour == 24 && data.minute == 0 && data.second == 0) { data.hour = 0; if (++data.day > maxDayInMonthFor(data.year, data.month)) { data.day = 1; if (++data.month > 12) { data.month = 1; if (Constants.SCHEMA_1_1_SUPPORT) { ++data.year; ! } ! else if (++data.year == 0) { data.year = 1; } } } ! } ! else { throw new RuntimeException("Hour must have values 0-23, unless 24:00:00"); } } //validate ! if ( data.minute>59 || data.minute<0 ) { throw new RuntimeException("Minute must have values 0-59"); } //validate ! if ( data.second>=60 || data.second<0 ) { throw new RuntimeException("Second must have values 0-59"); } //validate ! if ( data.timezoneHr>14 || data.timezoneHr<-14 ) { throw new RuntimeException("Time zone should have range -14:00 to +14:00"); ! } ! else { ! if((data.timezoneHr == 14 || data.timezoneHr == -14) && data.timezoneMin != 0) throw new RuntimeException("Time zone should have range -14:00 to +14:00"); ! else if(data.timezoneMin > 59 || data.timezoneMin < -59) throw new RuntimeException("Minute must have values 0-59"); } } /** * Return index of UTC char: 'Z', '+', '-' * * @param start * @param end * @return index of the UTC character that was found */ ! protected int findUTCSign (String buffer, int start, int end) { int c; ! for ( int i=start;i<end;i++ ) { ! c=buffer.charAt(i); ! if ( c == 'Z' || c=='+' || c=='-' ) { return i; } } return -1; } /** ! * Returns <code>true</code> if the character at start is 'Z', '+' or '-'. */ protected final boolean isNextCharUTCSign(String buffer, int start, int end) { if (start < end) { char c = buffer.charAt(start); return (c == 'Z' || c == '+' || c == '-'); --- 410,523 ---- * @param start * @param end * @param ch character to look for in StringBuffer * @return index of ch within StringBuffer */ ! protected int indexOf(String buffer, int start, int end, char ch) { ! for (int i = start; i < end; i++) { ! if (buffer.charAt(i) == ch) { return i; } } return -1; } /** ! * Validates given date/time object accoring to W3C PR Schema [D.1 ISO 8601 ! * Conventions] * * @param data */ ! protected void validateDateTime(DateTimeData data) { //REVISIT: should we throw an exception for not valid dates // or reporting an error message should be sufficient? /** * XML Schema 1.1 - RQ-123: Allow year 0000 in date related types. */ ! if (!Constants.SCHEMA_1_1_SUPPORT && data.year == 0) { throw new RuntimeException("The year \"0000\" is an illegal year value"); } ! if (data.month < 1 || data.month > 12) { throw new RuntimeException("The month must have values 1 to 12"); } //validate days ! if (data.day > maxDayInMonthFor(data.year, data.month) || data.day < 1) { throw new RuntimeException("The day must have values 1 to 31"); } //validate hours ! if (data.hour > 23 || data.hour < 0) { if (data.hour == 24 && data.minute == 0 && data.second == 0) { data.hour = 0; if (++data.day > maxDayInMonthFor(data.year, data.month)) { data.day = 1; if (++data.month > 12) { data.month = 1; if (Constants.SCHEMA_1_1_SUPPORT) { ++data.year; ! } else if (++data.year == 0) { data.year = 1; } } } ! } else { throw new RuntimeException("Hour must have values 0-23, unless 24:00:00"); } } //validate ! if (data.minute > 59 || data.minute < 0) { throw new RuntimeException("Minute must have values 0-59"); } //validate ! if (data.second >= 60 || data.second < 0) { throw new RuntimeException("Second must have values 0-59"); } //validate ! if (data.timezoneHr > 14 || data.timezoneHr < -14) { throw new RuntimeException("Time zone should have range -14:00 to +14:00"); ! } else { ! if ((data.timezoneHr == 14 || data.timezoneHr == -14) && data.timezoneMin != 0) { throw new RuntimeException("Time zone should have range -14:00 to +14:00"); ! } else if (data.timezoneMin > 59 || data.timezoneMin < -59) { throw new RuntimeException("Minute must have values 0-59"); } + } } /** * Return index of UTC char: 'Z', '+', '-' * * @param start * @param end * @return index of the UTC character that was found */ ! protected int findUTCSign(String buffer, int start, int end) { int c; ! for (int i = start; i < end; i++) { ! c = buffer.charAt(i); ! if (c == 'Z' || c == '+' || c == '-') { return i; } } return -1; } /** ! * Returns ! * <code>true</code> if the character at start is 'Z', '+' or '-'. */ protected final boolean isNextCharUTCSign(String buffer, int start, int end) { if (start < end) { char c = buffer.charAt(start); return (c == 'Z' || c == '+' || c == '-');
*** 516,587 **** * @param buffer string to parse * @param start start position * @param end end position * @return return integer representation of characters */ ! protected int parseInt (String buffer, int start, int end) ! throws NumberFormatException{ //REVISIT: more testing on this parsing needs to be done. ! int radix=10; int result = 0; ! int digit=0; int limit = -Integer.MAX_VALUE; int multmin = limit / radix; int i = start; do { digit = getDigit(buffer.charAt(i)); ! if ( digit < 0 ) throw new NumberFormatException("'" + buffer + "' has wrong format"); ! if ( result < multmin ) throw new NumberFormatException("'" + buffer + "' has wrong format"); result *= radix; ! if ( result < limit + digit ) throw new NumberFormatException("'" + buffer + "' has wrong format"); result -= digit; ! }while ( ++i < end ); return -result; } // parse Year differently to support negative value. ! protected int parseIntYear (String buffer, int end){ ! int radix=10; int result = 0; boolean negative = false; ! int i=0; int limit; int multmin; ! int digit=0; ! if (buffer.charAt(0) == '-'){ negative = true; limit = Integer.MIN_VALUE; i++; ! } ! else{ limit = -Integer.MAX_VALUE; } multmin = limit / radix; ! while (i < end) ! { digit = getDigit(buffer.charAt(i++)); ! if (digit < 0) throw new NumberFormatException("'" + buffer + "' has wrong format"); ! if (result < multmin) throw new NumberFormatException("'" + buffer + "' has wrong format"); result *= radix; ! if (result < limit + digit) throw new NumberFormatException("'" + buffer + "' has wrong format"); result -= digit; } ! if (negative) ! { ! if (i > 1) return result; ! else throw new NumberFormatException("'" + buffer + "' has wrong format"); } return -result; } /** ! * If timezone present - normalize dateTime [E Adding durations to dateTimes] * * @param date CCYY-MM-DDThh:mm:ss+03 */ protected void normalize(DateTimeData date) { --- 531,615 ---- * @param buffer string to parse * @param start start position * @param end end position * @return return integer representation of characters */ ! protected int parseInt(String buffer, int start, int end) ! throws NumberFormatException { //REVISIT: more testing on this parsing needs to be done. ! int radix = 10; int result = 0; ! int digit = 0; int limit = -Integer.MAX_VALUE; int multmin = limit / radix; int i = start; do { digit = getDigit(buffer.charAt(i)); ! if (digit < 0) { ! throw new NumberFormatException("'" + buffer + "' has wrong format"); ! } ! if (result < multmin) { ! throw new NumberFormatException("'" + buffer + "' has wrong format"); ! } result *= radix; ! if (result < limit + digit) { ! throw new NumberFormatException("'" + buffer + "' has wrong format"); ! } result -= digit; ! } while (++i < end); return -result; } // parse Year differently to support negative value. ! protected int parseIntYear(String buffer, int end) { ! int radix = 10; int result = 0; boolean negative = false; ! int i = 0; int limit; int multmin; ! int digit = 0; ! if (buffer.charAt(0) == '-') { negative = true; limit = Integer.MIN_VALUE; i++; ! } else { limit = -Integer.MAX_VALUE; } multmin = limit / radix; ! while (i < end) { digit = getDigit(buffer.charAt(i++)); ! if (digit < 0) { ! throw new NumberFormatException("'" + buffer + "' has wrong format"); ! } ! if (result < multmin) { ! throw new NumberFormatException("'" + buffer + "' has wrong format"); ! } result *= radix; ! if (result < limit + digit) { ! throw new NumberFormatException("'" + buffer + "' has wrong format"); ! } result -= digit; } ! if (negative) { ! if (i > 1) { ! return result; ! } else { ! throw new NumberFormatException("'" + buffer + "' has wrong format"); ! } } return -result; } /** ! * If timezone present - normalize dateTime [E Adding durations to ! * dateTimes] * * @param date CCYY-MM-DDThh:mm:ss+03 */ protected void normalize(DateTimeData date) {
*** 590,645 **** // //add minutes (from time zone) int negate = -1; ! if ( DEBUG ) { ! System.out.println("==>date.minute"+date.minute); ! System.out.println("==>date.timezoneMin" +date.timezoneMin); } int temp = date.minute + negate * date.timezoneMin; ! int carry = fQuotient (temp, 60); ! date.minute= mod(temp, 60, carry); ! if ( DEBUG ) { System.out.println("==>carry: " + carry); } //add hours temp = date.hour + negate * date.timezoneHr + carry; carry = fQuotient(temp, 24); ! date.hour=mod(temp, 24, carry); ! if ( DEBUG ) { ! System.out.println("==>date.hour"+date.hour); System.out.println("==>carry: " + carry); } ! date.day=date.day+carry; ! while ( true ) { ! temp=maxDayInMonthFor(date.year, date.month); ! if (date.day<1) { ! date.day = date.day + maxDayInMonthFor(date.year, date.month-1); ! carry=-1; ! } ! else if ( date.day>temp ) { ! date.day=date.day-temp; ! carry=1; ! } ! else { break; } ! temp=date.month+carry; ! date.month=modulo(temp, 1, 13); ! date.year=date.year+fQuotient(temp, 1, 13); ! if(date.year == 0 && !Constants.SCHEMA_1_1_SUPPORT) { ! date.year = (date.timezoneHr < 0 || date.timezoneMin < 0)?1:-1; } } ! date.utc='Z'; } - /** * @param date */ protected void saveUnnormalized(DateTimeData date) { date.unNormYear = date.year; --- 618,670 ---- // //add minutes (from time zone) int negate = -1; ! if (DEBUG) { ! System.out.println("==>date.minute" + date.minute); ! System.out.println("==>date.timezoneMin" + date.timezoneMin); } int temp = date.minute + negate * date.timezoneMin; ! int carry = fQuotient(temp, 60); ! date.minute = mod(temp, 60, carry); ! if (DEBUG) { System.out.println("==>carry: " + carry); } //add hours temp = date.hour + negate * date.timezoneHr + carry; carry = fQuotient(temp, 24); ! date.hour = mod(temp, 24, carry); ! if (DEBUG) { ! System.out.println("==>date.hour" + date.hour); System.out.println("==>carry: " + carry); } ! date.day = date.day + carry; ! while (true) { ! temp = maxDayInMonthFor(date.year, date.month); ! if (date.day < 1) { ! date.day = date.day + maxDayInMonthFor(date.year, date.month - 1); ! carry = -1; ! } else if (date.day > temp) { ! date.day = date.day - temp; ! carry = 1; ! } else { break; } ! temp = date.month + carry; ! date.month = modulo(temp, 1, 13); ! date.year = date.year + fQuotient(temp, 1, 13); ! if (date.year == 0 && !Constants.SCHEMA_1_1_SUPPORT) { ! date.year = (date.timezoneHr < 0 || date.timezoneMin < 0) ? 1 : -1; } } ! date.utc = 'Z'; } /** * @param date */ protected void saveUnnormalized(DateTimeData date) { date.unNormYear = date.year;
*** 666,743 **** data.timezoneHr = 0; data.timezoneMin = 0; } /** ! * Given {year,month} computes maximum ! * number of days for given month * * @param year * @param month * @return integer containg the number of days in a given month */ protected int maxDayInMonthFor(int year, int month) { //validate days ! if ( month==4 || month==6 || month==9 || month==11 ) { return 30; ! } ! else if ( month==2 ) { ! if ( isLeapYear(year) ) { return 29; ! } ! else { return 28; } ! } ! else { return 31; } } private boolean isLeapYear(int year) { //REVISIT: should we take care about Julian calendar? ! return((year%4 == 0) && ((year%100 != 0) || (year%400 == 0))); } // // help function described in W3C PR Schema [E Adding durations to dateTimes] // ! protected int mod (int a, int b, int quotient) { //modulo(a, b) = a - fQuotient(a,b)*b ! return (a - quotient*b) ; } // // help function described in W3C PR Schema [E Adding durations to dateTimes] // ! protected int fQuotient (int a, int b) { //fQuotient(a, b) = the greatest integer less than or equal to a/b ! return (int)Math.floor((float)a/b); } // // help function described in W3C PR Schema [E Adding durations to dateTimes] // ! protected int modulo (int temp, int low, int high) { //modulo(a - low, high - low) + low int a = temp - low; int b = high - low; ! return (mod (a, b, fQuotient(a, b)) + low) ; } // // help function described in W3C PR Schema [E Adding durations to dateTimes] // ! protected int fQuotient (int temp, int low, int high) { //fQuotient(a - low, high - low) return fQuotient(temp - low, high - low); } - protected String dateToString(DateTimeData date) { StringBuffer message = new StringBuffer(25); append(message, date.year, 4); message.append('-'); append(message, date.month, 2); --- 691,763 ---- data.timezoneHr = 0; data.timezoneMin = 0; } /** ! * Given {year,month} computes maximum number of days for given month * * @param year * @param month * @return integer containg the number of days in a given month */ protected int maxDayInMonthFor(int year, int month) { //validate days ! if (month == 4 || month == 6 || month == 9 || month == 11) { return 30; ! } else if (month == 2) { ! if (isLeapYear(year)) { return 29; ! } else { return 28; } ! } else { return 31; } } private boolean isLeapYear(int year) { //REVISIT: should we take care about Julian calendar? ! return ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0))); } // // help function described in W3C PR Schema [E Adding durations to dateTimes] // ! protected int mod(int a, int b, int quotient) { //modulo(a, b) = a - fQuotient(a,b)*b ! return (a - quotient * b); } // // help function described in W3C PR Schema [E Adding durations to dateTimes] // ! protected int fQuotient(int a, int b) { //fQuotient(a, b) = the greatest integer less than or equal to a/b ! return (int) Math.floor((float) a / b); } // // help function described in W3C PR Schema [E Adding durations to dateTimes] // ! protected int modulo(int temp, int low, int high) { //modulo(a - low, high - low) + low int a = temp - low; int b = high - low; ! return (mod(a, b, fQuotient(a, b)) + low); } // // help function described in W3C PR Schema [E Adding durations to dateTimes] // ! protected int fQuotient(int temp, int low, int high) { //fQuotient(a - low, high - low) return fQuotient(temp - low, high - low); } protected String dateToString(DateTimeData date) { StringBuffer message = new StringBuffer(25); append(message, date.year, 4); message.append('-'); append(message, date.month, 2);
*** 747,757 **** append(message, date.hour, 2); message.append(':'); append(message, date.minute, 2); message.append(':'); append(message, date.second); ! append(message, (char)date.utc, 0); return message.toString(); } protected final void append(StringBuffer message, int value, int nch) { if (value == Integer.MIN_VALUE) { --- 767,777 ---- append(message, date.hour, 2); message.append(':'); append(message, date.minute, 2); message.append(':'); append(message, date.second); ! append(message, (char) date.utc, 0); return message.toString(); } protected final void append(StringBuffer message, int value, int nch) { if (value == Integer.MIN_VALUE) {
*** 761,786 **** if (value < 0) { message.append('-'); value = -value; } if (nch == 4) { ! if (value < 10) message.append("000"); ! else if (value < 100) message.append("00"); ! else if (value < 1000) message.append('0'); - message.append(value); } ! else if (nch == 2) { ! if (value < 10) message.append('0'); message.append(value); } - else { - if (value != 0) - message.append((char)value); } } protected final void append(StringBuffer message, double value) { if (value < 0) { --- 781,807 ---- if (value < 0) { message.append('-'); value = -value; } if (nch == 4) { ! if (value < 10) { message.append("000"); ! } else if (value < 100) { message.append("00"); ! } else if (value < 1000) { message.append('0'); } ! message.append(value); ! } else if (nch == 2) { ! if (value < 10) { message.append('0'); + } message.append(value); + } else { + if (value != 0) { + message.append((char) value); } } } protected final void append(StringBuffer message, double value) { if (value < 0) {
*** 795,806 **** protected final void append2(StringBuffer message, double value) { final int intValue = (int) value; if (value == intValue) { message.append(intValue); ! } ! else { append3(message, value); } } private void append3(StringBuffer message, double value) { --- 816,826 ---- protected final void append2(StringBuffer message, double value) { final int intValue = (int) value; if (value == intValue) { message.append(intValue); ! } else { append3(message, value); } } private void append3(StringBuffer message, double value) {
*** 813,825 **** int exp; if (value < 1) { // Need to convert from scientific notation of the form // n.nnn...E-N (N >= 4) to a normal decimal value. try { ! exp = parseInt(d, eIndex+2, d.length()); ! } ! // This should never happen. // It's only possible if String.valueOf(double) is broken. catch (Exception e) { message.append(d); return; } --- 833,844 ---- int exp; if (value < 1) { // Need to convert from scientific notation of the form // n.nnn...E-N (N >= 4) to a normal decimal value. try { ! exp = parseInt(d, eIndex + 2, d.length()); ! } // This should never happen. // It's only possible if String.valueOf(double) is broken. catch (Exception e) { message.append(d); return; }
*** 841,858 **** char c = d.charAt(i); if (c != '.') { message.append(c); } } ! } ! else { // Need to convert from scientific notation of the form // n.nnn...EN (N >= 7) to a normal decimal value. try { ! exp = parseInt(d, eIndex+1, d.length()); ! } ! // This should never happen. // It's only possible if String.valueOf(double) is broken. catch (Exception e) { message.append(d); return; } --- 860,875 ---- char c = d.charAt(i); if (c != '.') { message.append(c); } } ! } else { // Need to convert from scientific notation of the form // n.nnn...EN (N >= 7) to a normal decimal value. try { ! exp = parseInt(d, eIndex + 1, d.length()); ! } // This should never happen. // It's only possible if String.valueOf(double) is broken. catch (Exception e) { message.append(d); return; }
*** 876,905 **** protected double parseSecond(String buffer, int start, int end) throws NumberFormatException { int dot = -1; for (int i = start; i < end; i++) { char ch = buffer.charAt(i); ! if (ch == '.') dot = i; ! else if (ch > '9' || ch < '0') throw new NumberFormatException("'" + buffer + "' has wrong format"); } if (dot == -1) { ! if (start+2 != end) throw new NumberFormatException("'" + buffer + "' has wrong format"); } ! else if (start+2 != dot || dot+1 == end) { throw new NumberFormatException("'" + buffer + "' has wrong format"); } return Double.parseDouble(buffer.substring(start, end)); } // //Private help functions // ! ! private void cloneDate (DateTimeData finalValue, DateTimeData tempDate) { tempDate.year = finalValue.year; tempDate.month = finalValue.month; tempDate.day = finalValue.day; tempDate.hour = finalValue.hour; tempDate.minute = finalValue.minute; --- 893,922 ---- protected double parseSecond(String buffer, int start, int end) throws NumberFormatException { int dot = -1; for (int i = start; i < end; i++) { char ch = buffer.charAt(i); ! if (ch == '.') { dot = i; ! } else if (ch > '9' || ch < '0') { throw new NumberFormatException("'" + buffer + "' has wrong format"); } + } if (dot == -1) { ! if (start + 2 != end) { throw new NumberFormatException("'" + buffer + "' has wrong format"); } ! } else if (start + 2 != dot || dot + 1 == end) { throw new NumberFormatException("'" + buffer + "' has wrong format"); } return Double.parseDouble(buffer.substring(start, end)); } // //Private help functions // ! private void cloneDate(DateTimeData finalValue, DateTimeData tempDate) { tempDate.year = finalValue.year; tempDate.month = finalValue.month; tempDate.day = finalValue.day; tempDate.hour = finalValue.hour; tempDate.minute = finalValue.minute;
*** 911,945 **** /** * Represents date time data */ static final class DateTimeData implements XSDateTime { int year, month, day, hour, minute, utc; double second; int timezoneHr, timezoneMin; private String originalValue; boolean normalized = true; - int unNormYear; int unNormMonth; int unNormDay; int unNormHour; int unNormMinute; double unNormSecond; - // used for comparisons - to decide the 'interesting' portions of // a date/time based data type. int position; // a pointer to the type that was used go generate this data // note that this is not the actual simple type, but one of the // statically created XXXDV objects, so this won't cause any GC problem. final AbstractDateTimeDV type; ! private String canonical; public DateTimeData(String originalValue, AbstractDateTimeDV type) { this.originalValue = originalValue; this.type = type; } public DateTimeData(int year, int month, int day, int hour, int minute, double second, int utc, String originalValue, boolean normalized, AbstractDateTimeDV type) { this.year = year; this.month = month; this.day = day; --- 928,963 ---- /** * Represents date time data */ static final class DateTimeData implements XSDateTime { + int year, month, day, hour, minute, utc; double second; int timezoneHr, timezoneMin; private String originalValue; boolean normalized = true; int unNormYear; int unNormMonth; int unNormDay; int unNormHour; int unNormMinute; double unNormSecond; // used for comparisons - to decide the 'interesting' portions of // a date/time based data type. int position; // a pointer to the type that was used go generate this data // note that this is not the actual simple type, but one of the // statically created XXXDV objects, so this won't cause any GC problem. final AbstractDateTimeDV type; ! private volatile String canonical; ! public DateTimeData(String originalValue, AbstractDateTimeDV type) { this.originalValue = originalValue; this.type = type; } + public DateTimeData(int year, int month, int day, int hour, int minute, double second, int utc, String originalValue, boolean normalized, AbstractDateTimeDV type) { this.year = year; this.month = month; this.day = day;
*** 948,1060 **** this.second = second; this.utc = utc; this.type = type; this.originalValue = originalValue; } public boolean equals(Object obj) { ! if (!(obj instanceof DateTimeData)) return false; - return type.compareDates(this, (DateTimeData)obj, true)==0; } ! public synchronized String toString() { if (canonical == null) { canonical = type.dateToString(this); } return canonical; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#getYear() */ public int getYears() { ! if(type instanceof DurationDV) return 0; ! return normalized?year:unNormYear; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#getMonth() */ public int getMonths() { ! if(type instanceof DurationDV) { ! return year*12 + month; } ! return normalized?month:unNormMonth; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#getDay() */ public int getDays() { ! if(type instanceof DurationDV) return 0; ! return normalized?day:unNormDay; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#getHour() */ public int getHours() { ! if(type instanceof DurationDV) return 0; ! return normalized?hour:unNormHour; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#getMinutes() */ public int getMinutes() { ! if(type instanceof DurationDV) return 0; ! return normalized?minute:unNormMinute; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#getSeconds() */ public double getSeconds() { ! if(type instanceof DurationDV) { ! return day*24*60*60 + hour*60*60 + minute*60 + second; } ! return normalized?second:unNormSecond; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#hasTimeZone() */ public boolean hasTimeZone() { return utc != 0; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#getTimeZoneHours() */ public int getTimeZoneHours() { return timezoneHr; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#getTimeZoneMinutes() */ public int getTimeZoneMinutes() { return timezoneMin; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#getLexicalValue() */ public String getLexicalValue() { return originalValue; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#normalize() */ public XSDateTime normalize() { ! if(!normalized) { ! DateTimeData dt = (DateTimeData)this.clone(); dt.normalized = true; return dt; } return this; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#isNormalized() */ public boolean isNormalized() { return normalized; } public Object clone() { DateTimeData dt = new DateTimeData(this.year, this.month, this.day, this.hour, this.minute, this.second, this.utc, this.originalValue, this.normalized, this.type); dt.canonical = this.canonical; dt.position = position; --- 966,1126 ---- this.second = second; this.utc = utc; this.type = type; this.originalValue = originalValue; } + + @Override public boolean equals(Object obj) { ! if (!(obj instanceof DateTimeData)) { return false; } ! return type.compareDates(this, (DateTimeData) obj, true) == 0; ! } ! ! // If two DateTimeData are equals - then they should have the same ! // hashcode. This means we need to convert the date to UTC before ! // we return its hashcode. ! // The DateTimeData is unfortunately mutable - so we cannot ! // cache the result of the conversion... ! // ! @Override ! public int hashCode() { ! final DateTimeData tempDate = new DateTimeData(null, type); ! type.cloneDate(this, tempDate); ! type.normalize(tempDate); ! return type.dateToString(tempDate).hashCode(); ! } ! ! @Override ! public String toString() { if (canonical == null) { canonical = type.dateToString(this); } return canonical; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#getYear() */ + + @Override public int getYears() { ! if (type instanceof DurationDV) { return 0; ! } ! return normalized ? year : unNormYear; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#getMonth() */ + + @Override public int getMonths() { ! if (type instanceof DurationDV) { ! return year * 12 + month; } ! return normalized ? month : unNormMonth; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#getDay() */ + + @Override public int getDays() { ! if (type instanceof DurationDV) { return 0; ! } ! return normalized ? day : unNormDay; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#getHour() */ + + @Override public int getHours() { ! if (type instanceof DurationDV) { return 0; ! } ! return normalized ? hour : unNormHour; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#getMinutes() */ + + @Override public int getMinutes() { ! if (type instanceof DurationDV) { return 0; ! } ! return normalized ? minute : unNormMinute; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#getSeconds() */ + + @Override public double getSeconds() { ! if (type instanceof DurationDV) { ! return day * 24 * 60 * 60 + hour * 60 * 60 + minute * 60 + second; } ! return normalized ? second : unNormSecond; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#hasTimeZone() */ + + @Override public boolean hasTimeZone() { return utc != 0; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#getTimeZoneHours() */ + + @Override public int getTimeZoneHours() { return timezoneHr; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#getTimeZoneMinutes() */ + + @Override public int getTimeZoneMinutes() { return timezoneMin; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#getLexicalValue() */ + + @Override public String getLexicalValue() { return originalValue; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#normalize() */ + + @Override public XSDateTime normalize() { ! if (!normalized) { ! DateTimeData dt = (DateTimeData) this.clone(); dt.normalized = true; return dt; } return this; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#isNormalized() */ + + @Override public boolean isNormalized() { return normalized; } + @Override public Object clone() { DateTimeData dt = new DateTimeData(this.year, this.month, this.day, this.hour, this.minute, this.second, this.utc, this.originalValue, this.normalized, this.type); dt.canonical = this.canonical; dt.position = position;
*** 1070,1085 **** --- 1136,1154 ---- } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#getXMLGregorianCalendar() */ + @Override public XMLGregorianCalendar getXMLGregorianCalendar() { return type.getXMLGregorianCalendar(this); } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#getDuration() */ + + @Override public Duration getDuration() { return type.getDuration(this); } }