--- old/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/datatype/XMLGregorianCalendarImpl.java Tue Feb 18 09:40:14 2014 +++ new/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/datatype/XMLGregorianCalendarImpl.java Tue Feb 18 09:40:14 2014 @@ -25,6 +25,8 @@ package com.sun.org.apache.xerces.internal.jaxp.datatype; +import java.io.IOException; +import java.io.ObjectInputStream; import java.io.Serializable; import java.math.BigDecimal; import java.math.BigInteger; @@ -194,6 +196,17 @@ public class XMLGregorianCalendarImpl extends XMLGregorianCalendar implements Serializable, Cloneable { + + /** Backup values **/ + transient private BigInteger orig_eon; + transient private int orig_year = DatatypeConstants.FIELD_UNDEFINED; + transient private int orig_month = DatatypeConstants.FIELD_UNDEFINED; + transient private int orig_day = DatatypeConstants.FIELD_UNDEFINED; + transient private int orig_hour = DatatypeConstants.FIELD_UNDEFINED; + transient private int orig_minute = DatatypeConstants.FIELD_UNDEFINED; + transient private int orig_second = DatatypeConstants.FIELD_UNDEFINED; + transient private BigDecimal orig_fracSeconds; + transient private int orig_timezone = DatatypeConstants.FIELD_UNDEFINED; /** *
Eon of this XMLGregorianCalendar
.
Constant to represent a billion.
+ *BigInteger constant; representing a billion.
*/ - private static final BigInteger BILLION = new BigInteger("1000000000"); - + private static final BigInteger BILLION_B = new BigInteger("1000000000"); + /** + *int constant; representing a billion.
+ */ + private static final int BILLION_I = 1000000000; + + /** *Obtain a pure Gregorian Calendar by calling * GregorianCalendar.setChange(PURE_GREGORIAN_CHANGE).
*/ @@ -441,9 +459,26 @@ //"\"" + lexicalRepresentation + "\" is not a valid representation of an XML Gregorian Calendar value." ); } + + save(); } /** + * save original values + */ + private void save() { + orig_eon = eon; + orig_year = year; + orig_month = month; + orig_day = day; + orig_hour = hour; + orig_minute = minute; + orig_second = second; + orig_fracSeconds = fractionalSecond; + orig_timezone = timezone; + } + + /** *Create an instance with all date/time datatype fields set to * {@link DatatypeConstants#FIELD_UNDEFINED} or null respectively.
*/ @@ -479,14 +514,14 @@ BigDecimal fractionalSecond, int timezone) { - setYear(year); + setYear(year); setMonth(month); setDay(day); setTime(hour, minute, second, fractionalSecond); - setTimezone(timezone); + setTimezone(timezone); - // check for validity - if (!isValid()) { + // check for validity + if (!isValid()) { throw new IllegalArgumentException( DatatypeMessageFormatter.formatMessage(null, @@ -519,8 +554,9 @@ ); */ - } - + } + + save(); } /** @@ -547,17 +583,21 @@ int hour, int minute, int second, - int millisecond, + int millisecond, int timezone) { - setYear(year); + setYear(year); setMonth(month); setDay(day); setTime(hour, minute, second); - setTimezone(timezone); - setMillisecond(millisecond); + setTimezone(timezone); + BigDecimal realMilliseconds = null; + if (millisecond != DatatypeConstants.FIELD_UNDEFINED) { + realMilliseconds = BigDecimal.valueOf(millisecond, 3); + } + setFractionalSecond(realMilliseconds); - if (!isValid()) { + if (!isValid()) { throw new IllegalArgumentException( DatatypeMessageFormatter.formatMessage(null, @@ -580,7 +620,9 @@ ); */ - } + } + + save(); } /** @@ -661,6 +703,7 @@ // Calendar ZONE_OFFSET and DST_OFFSET fields are in milliseconds. int offsetInMinutes = (cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET)) / (60 * 1000); this.setTimezone(offsetInMinutes); + save(); } // Factories @@ -1164,7 +1207,7 @@ this.eon = null; this.year = DatatypeConstants.FIELD_UNDEFINED; } else { - BigInteger temp = year.remainder(BILLION); + BigInteger temp = year.remainder(BILLION_B); this.year = temp.intValue(); setEon(year.subtract(temp)); } @@ -1187,12 +1230,13 @@ if (year == DatatypeConstants.FIELD_UNDEFINED) { this.year = DatatypeConstants.FIELD_UNDEFINED; this.eon = null; - } else if (Math.abs(year) < BILLION.intValue()) { + } + else if (Math.abs(year) < BILLION_I) { this.year = year; this.eon = null; } else { BigInteger theYear = BigInteger.valueOf((long) year); - BigInteger remainder = theYear.remainder(BILLION); + BigInteger remainder = theYear.remainder(BILLION_B); this.year = remainder.intValue(); setEon(theYear.subtract(remainder)); } @@ -1684,10 +1728,13 @@ * @returntrue
when compare(this,(XMLGregorianCalendar)obj) == EQUAL.
.
*/
public boolean equals(Object obj) {
-
+
if (obj == null || !(obj instanceof XMLGregorianCalendar)) {
return false;
}
+ if (obj == this) {
+ return true;
+ }
return compare((XMLGregorianCalendar) obj) == DatatypeConstants.EQUAL;
}
@@ -1945,56 +1992,41 @@
* @return true if data values are valid.
*/
public boolean isValid() {
- // since setters do not allow for invalid values,
+ // since setters do not allow for invalid values,
// (except for exceptional case of year field of zero),
// no need to check for anything except for constraints
- // between fields.
+ // between fields.
- //check if days in month is valid. Can be dependent on leap year.
- if (getMonth() == DatatypeConstants.FEBRUARY) {
- // years could not be set
- int maxDays = 29;
-
- if (eon == null) {
- if(year!=DatatypeConstants.FIELD_UNDEFINED)
- maxDays = maximumDayInMonthFor(year,getMonth());
- } else {
- BigInteger years = getEonAndYear();
- if (years != null) {
- maxDays = maximumDayInMonthFor(getEonAndYear(), DatatypeConstants.FEBRUARY);
+ // check if days in month is valid. Can be dependent on leap year.
+ if (month != DatatypeConstants.FIELD_UNDEFINED && day != DatatypeConstants.FIELD_UNDEFINED) {
+ if (year != DatatypeConstants.FIELD_UNDEFINED) {
+ if (eon == null) {
+ if (day > maximumDayInMonthFor(year, month)) {
+ return false;
+ }
}
+ else if (day > maximumDayInMonthFor(getEonAndYear(), month)) {
+ return false;
+ }
}
- if (getDay() > maxDays) {
+ // Use 2000 as a default since it's a leap year.
+ else if (day > maximumDayInMonthFor(2000, month)) {
return false;
}
}
// http://www.w3.org/2001/05/xmlschema-errata#e2-45
- if (getHour() == 24) {
- if(getMinute() != 0) {
- return false;
- } else if (getSecond() != 0) {
- return false;
- }
+ if (hour == 24 && (minute != 0 || second != 0 ||
+ (fractionalSecond != null && fractionalSecond.compareTo(DECIMAL_ZERO) != 0))) {
+ return false;
}
// XML Schema 1.0 specification defines year value of zero as
// invalid. Allow this class to set year field to zero
- // since XML Schema 1.0 errata states that lexical zero will
+ // since XML Schema 1.0 errata states that lexical zero will
// be allowed in next version and treated as 1 B.C.E.
- if (eon == null) {
- // optimize check.
- if (year == 0) {
- return false;
- }
- } else {
- BigInteger yearField = getEonAndYear();
- if (yearField != null) {
- int result = compareField(yearField, BigInteger.ZERO);
- if (result == DatatypeConstants.EQUAL) {
- return false;
- }
- }
+ if (eon == null && year == 0) {
+ return false;
}
return true;
}
@@ -2213,7 +2245,7 @@
int quotient;
if (endMonth < 0) {
endMonth = (13 - 1) + endMonth + 1;
- quotient = new BigDecimal(intTemp - 1).divide(new BigDecimal(TWELVE), BigDecimal.ROUND_UP).intValue();
+ quotient = BigDecimal.valueOf(intTemp - 1).divide(new BigDecimal(TWELVE), BigDecimal.ROUND_UP).intValue();
} else {
quotient = (intTemp - 1) / (13 - 1);
endMonth += 1;
@@ -2259,18 +2291,20 @@
private static final BigInteger SIXTY = BigInteger.valueOf(60);
private static final BigInteger TWENTY_FOUR = BigInteger.valueOf(24);
private static final BigInteger TWELVE = BigInteger.valueOf(12);
- private static final BigDecimal DECIMAL_ZERO = new BigDecimal("0");
- private static final BigDecimal DECIMAL_ONE = new BigDecimal("1");
- private static final BigDecimal DECIMAL_SIXTY = new BigDecimal("60");
+ private static final BigDecimal DECIMAL_ZERO = BigDecimal.valueOf(0);
+ private static final BigDecimal DECIMAL_ONE = BigDecimal.valueOf(1);
+ private static final BigDecimal DECIMAL_SIXTY = BigDecimal.valueOf(60);
- private static int daysInMonth[] = { 0, // XML Schema months start at 1.
- 31, 28, 31, 30, 31, 30,
- 31, 31, 30, 31, 30, 31};
+ private static class DaysInMonth {
+ private static final int [] table = { 0, // XML Schema months start at 1.
+ 31, 28, 31, 30, 31, 30,
+ 31, 31, 30, 31, 30, 31};
+ }
private static int maximumDayInMonthFor(BigInteger year, int month) {
if (month != DatatypeConstants.FEBRUARY) {
- return daysInMonth[month];
+ return DaysInMonth.table[month];
} else {
if (year.mod(FOUR_HUNDRED).equals(BigInteger.ZERO) ||
(!year.mod(HUNDRED).equals(BigInteger.ZERO) &&
@@ -2278,7 +2312,7 @@
// is a leap year.
return 29;
} else {
- return daysInMonth[month];
+ return DaysInMonth.table[month];
}
}
}
@@ -2285,7 +2319,7 @@
private static int maximumDayInMonthFor(int year, int month) {
if (month != DatatypeConstants.FEBRUARY) {
- return daysInMonth[month];
+ return DaysInMonth.table[month];
} else {
if (((year % 400) == 0) ||
(((year % 100) != 0) && ((year % 4) == 0))) {
@@ -2292,7 +2326,7 @@
// is a leap year.
return 29;
} else {
- return daysInMonth[DatatypeConstants.FEBRUARY];
+ return DaysInMonth.table[DatatypeConstants.FEBRUARY];
}
}
}
@@ -2404,10 +2438,16 @@
result.setGregorianChange(PURE_GREGORIAN_CHANGE);
// if year( and eon) are undefined, leave default Calendar values
- BigInteger year = getEonAndYear();
- if (year != null) {
- result.set(Calendar.ERA, year.signum() == -1 ? GregorianCalendar.BC : GregorianCalendar.AD);
- result.set(Calendar.YEAR, year.abs().intValue());
+ if (year != DatatypeConstants.FIELD_UNDEFINED) {
+ if (eon == null) {
+ result.set(Calendar.ERA, year < 0 ? GregorianCalendar.BC : GregorianCalendar.AD);
+ result.set(Calendar.YEAR, Math.abs(year));
+ }
+ else {
+ BigInteger eonAndYear = getEonAndYear();
+ result.set(Calendar.ERA, eonAndYear.signum() == -1 ? GregorianCalendar.BC : GregorianCalendar.AD);
+ result.set(Calendar.YEAR, eonAndYear.abs().intValue());
+ }
}
// only set month if it is set
@@ -2543,16 +2583,31 @@
result.setGregorianChange(PURE_GREGORIAN_CHANGE);
// if year( and eon) are undefined, leave default Calendar values
- BigInteger year = getEonAndYear();
- if (year != null) {
- result.set(Calendar.ERA, year.signum() == -1 ? GregorianCalendar.BC : GregorianCalendar.AD);
- result.set(Calendar.YEAR, year.abs().intValue());
+ if (year != DatatypeConstants.FIELD_UNDEFINED) {
+ if (eon == null) {
+ result.set(Calendar.ERA, year < 0 ? GregorianCalendar.BC : GregorianCalendar.AD);
+ result.set(Calendar.YEAR, Math.abs(year));
+ }
+ else {
+ final BigInteger eonAndYear = getEonAndYear();
+ result.set(Calendar.ERA, eonAndYear.signum() == -1 ? GregorianCalendar.BC : GregorianCalendar.AD);
+ result.set(Calendar.YEAR, eonAndYear.abs().intValue());
+ }
} else {
// use default if set
- BigInteger defaultYear = (defaults != null) ? defaults.getEonAndYear() : null;
- if (defaultYear != null) {
- result.set(Calendar.ERA, defaultYear.signum() == -1 ? GregorianCalendar.BC : GregorianCalendar.AD);
- result.set(Calendar.YEAR, defaultYear.abs().intValue());
+ if (defaults != null) {
+ final int defaultYear = defaults.getYear();
+ if (defaultYear != DatatypeConstants.FIELD_UNDEFINED) {
+ if (defaults.getEon() == null) {
+ result.set(Calendar.ERA, defaultYear < 0 ? GregorianCalendar.BC : GregorianCalendar.AD);
+ result.set(Calendar.YEAR, Math.abs(defaultYear));
+ }
+ else {
+ final BigInteger defaultEonAndYear = defaults.getEonAndYear();
+ result.set(Calendar.ERA, defaultEonAndYear.signum() == -1 ? GregorianCalendar.BC : GregorianCalendar.AD);
+ result.set(Calendar.YEAR, defaultEonAndYear.abs().intValue());
+ }
+ }
}
}
@@ -2562,7 +2617,7 @@
result.set(Calendar.MONTH, month - 1);
} else {
// use default if set
- int defaultMonth = (defaults != null) ? defaults.getMonth() : DatatypeConstants.FIELD_UNDEFINED;
+ final int defaultMonth = (defaults != null) ? defaults.getMonth() : DatatypeConstants.FIELD_UNDEFINED;
if (defaultMonth != DatatypeConstants.FIELD_UNDEFINED) {
// Calendar.MONTH is zero based while XMLGregorianCalendar month field is not.
result.set(Calendar.MONTH, defaultMonth - 1);
@@ -2574,7 +2629,7 @@
result.set(Calendar.DAY_OF_MONTH, day);
} else {
// use default if set
- int defaultDay = (defaults != null) ? defaults.getDay() : DatatypeConstants.FIELD_UNDEFINED;
+ final int defaultDay = (defaults != null) ? defaults.getDay() : DatatypeConstants.FIELD_UNDEFINED;
if (defaultDay != DatatypeConstants.FIELD_UNDEFINED) {
result.set(Calendar.DAY_OF_MONTH, defaultDay);
}
@@ -2596,7 +2651,7 @@
result.set(Calendar.MINUTE, minute);
} else {
// use default if set
- int defaultMinute = (defaults != null) ? defaults.getMinute() : DatatypeConstants.FIELD_UNDEFINED;
+ final int defaultMinute = (defaults != null) ? defaults.getMinute() : DatatypeConstants.FIELD_UNDEFINED;
if (defaultMinute != DatatypeConstants.FIELD_UNDEFINED) {
result.set(Calendar.MINUTE, defaultMinute);
}
@@ -2607,7 +2662,7 @@
result.set(Calendar.SECOND, second);
} else {
// use default if set
- int defaultSecond = (defaults != null) ? defaults.getSecond() : DatatypeConstants.FIELD_UNDEFINED;
+ final int defaultSecond = (defaults != null) ? defaults.getSecond() : DatatypeConstants.FIELD_UNDEFINED;
if (defaultSecond != DatatypeConstants.FIELD_UNDEFINED) {
result.set(Calendar.SECOND, defaultSecond);
}
@@ -2618,7 +2673,7 @@
result.set(Calendar.MILLISECOND, getMillisecond());
} else {
// use default if set
- BigDecimal defaultFractionalSecond = (defaults != null) ? defaults.getFractionalSecond() : null;
+ final BigDecimal defaultFractionalSecond = (defaults != null) ? defaults.getFractionalSecond() : null;
if (defaultFractionalSecond != null) {
result.set(Calendar.MILLISECOND, defaults.getMillisecond());
}
@@ -2671,6 +2726,9 @@
customTimezoneId.append(sign);
customTimezoneId.append(hour);
if (minutes != 0) {
+ if (minutes < 10) {
+ customTimezoneId.append('0');
+ }
customTimezoneId.append(minutes);
}
result = TimeZone.getTimeZone(customTimezoneId.toString());
@@ -2718,7 +2776,7 @@
if(millisecond<0 || 999
* StringBuffer -> StringBuilder change had a very visible impact.
- * It almost cut the execution time to half, but unfortunately we can't use it
- * because we need to run on JDK 1.3
+ * It almost cut the execution time to half.
+ * Diff from Xerces:
+ * Xerces use StringBuffer due to the requirement to support
+ * JDKs older than JDK 1.5
*/
private String format( String format ) {
- char[] buf = new char[32];
- int bufPtr = 0;
-
+ StringBuilder buf = new StringBuilder();
int fidx=0,flen=format.length();
while(fidxXMLGregorianCalendar
s.