jaxp/src/com/sun/org/apache/xerces/internal/jaxp/datatype/XMLGregorianCalendarImpl.java
Print this page
@@ -23,10 +23,12 @@
* questions.
*/
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;
import java.util.TimeZone;
import java.util.Calendar;
@@ -193,10 +195,21 @@
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;
+
/**
* <p>Eon of this <code>XMLGregorianCalendar</code>.</p>
*/
private BigInteger eon = null;
@@ -239,15 +252,20 @@
* <p>Fractional second of this <code>XMLGregorianCalendar</code>.</p>
*/
private BigDecimal fractionalSecond = null;
/**
- * <p>Constant to represent a billion.</p>
+ * <p>BigInteger constant; representing a billion.</p>
*/
- private static final BigInteger BILLION = new BigInteger("1000000000");
+ private static final BigInteger BILLION_B = new BigInteger("1000000000");
/**
+ * <p>int constant; representing a billion.</p>
+ */
+ private static final int BILLION_I = 1000000000;
+
+ /**
* <p>Obtain a pure Gregorian Calendar by calling
* GregorianCalendar.setChange(PURE_GREGORIAN_CHANGE). </p>
*/
private static final Date PURE_GREGORIAN_CHANGE =
new Date(Long.MIN_VALUE);
@@ -439,13 +457,30 @@
throw new IllegalArgumentException(
DatatypeMessageFormatter.formatMessage(null, "InvalidXGCRepresentation", new Object[]{lexicalRepresentation})
//"\"" + 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;
+ }
+
+ /**
* <p>Create an instance with all date/time datatype fields set to
* {@link DatatypeConstants#FIELD_UNDEFINED} or null respectively.</p>
*/
public XMLGregorianCalendarImpl() {
@@ -519,10 +554,11 @@
);
*/
}
+ save();
}
/**
* <p>Private constructor of value spaces that a
* <code>java.util.GregorianCalendar</code> instance would need to convert to an
@@ -553,11 +589,15 @@
setYear(year);
setMonth(month);
setDay(day);
setTime(hour, minute, second);
setTimezone(timezone);
- setMillisecond(millisecond);
+ BigDecimal realMilliseconds = null;
+ if (millisecond != DatatypeConstants.FIELD_UNDEFINED) {
+ realMilliseconds = BigDecimal.valueOf(millisecond, 3);
+ }
+ setFractionalSecond(realMilliseconds);
if (!isValid()) {
throw new IllegalArgumentException(
DatatypeMessageFormatter.formatMessage(null,
@@ -579,10 +619,12 @@
+ ", is not a valid representation of an XML Gregorian Calendar value."
);
*/
}
+
+ save();
}
/**
* <p>Convert a <code>java.util.GregorianCalendar</code> to XML Schema 1.0
* representation.</p>
@@ -659,10 +701,11 @@
cal.get(Calendar.MILLISECOND));
// 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
/**
@@ -1162,11 +1205,11 @@
public void setYear(BigInteger year) {
if (year == null) {
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));
}
}
@@ -1185,16 +1228,17 @@
*/
public void setYear(int year) {
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));
}
}
@@ -1686,10 +1730,13 @@
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof XMLGregorianCalendar)) {
return false;
}
+ if (obj == this) {
+ return true;
+ }
return compare((XMLGregorianCalendar) obj) == DatatypeConstants.EQUAL;
}
/**
* <p>Returns a hash code consistent with the definition of the equals method.</p>
@@ -1948,56 +1995,41 @@
// 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.
- //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;
-
+ // 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(year!=DatatypeConstants.FIELD_UNDEFINED)
- maxDays = maximumDayInMonthFor(year,getMonth());
- } else {
- BigInteger years = getEonAndYear();
- if (years != null) {
- maxDays = maximumDayInMonthFor(getEonAndYear(), DatatypeConstants.FEBRUARY);
+ if (day > maximumDayInMonthFor(year, month)) {
+ return false;
}
}
- if (getDay() > maxDays) {
+ else if (day > maximumDayInMonthFor(getEonAndYear(), month)) {
return false;
}
}
+ // 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) {
+ if (hour == 24 && (minute != 0 || second != 0 ||
+ (fractionalSecond != null && fractionalSecond.compareTo(DECIMAL_ZERO) != 0))) {
return false;
- } else if (getSecond() != 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
// be allowed in next version and treated as 1 B.C.E.
- if (eon == null) {
- // optimize check.
- if (year == 0) {
+ if (eon == null && year == 0) {
return false;
}
- } else {
- BigInteger yearField = getEonAndYear();
- if (yearField != null) {
- int result = compareField(yearField, BigInteger.ZERO);
- if (result == DatatypeConstants.EQUAL) {
- return false;
- }
- }
- }
return true;
}
/**
* <p>Add <code>duration</code> to this instance.<\p>
@@ -2211,11 +2243,11 @@
intTemp = getMonth() + monthCarry;
int endMonth = (intTemp - 1) % (13 - 1);
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;
}
setMonth(endMonth);
@@ -2257,44 +2289,46 @@
private static final BigInteger HUNDRED = BigInteger.valueOf(100);
private static final BigInteger FOUR_HUNDRED = BigInteger.valueOf(400);
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.
+ 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) &&
year.mod(FOUR).equals(BigInteger.ZERO))) {
// is a leap year.
return 29;
} else {
- return daysInMonth[month];
+ return DaysInMonth.table[month];
}
}
}
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))) {
// is a leap year.
return 29;
} else {
- return daysInMonth[DatatypeConstants.FEBRUARY];
+ return DaysInMonth.table[DatatypeConstants.FEBRUARY];
}
}
}
/**
@@ -2402,15 +2436,21 @@
result = new GregorianCalendar(tz, locale);
result.clear();
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
if (month != DatatypeConstants.FIELD_UNDEFINED) {
// Calendar.MONTH is zero based while XMLGregorianCalendar month field is not.
result.set(Calendar.MONTH, month - 1);
@@ -2541,30 +2581,45 @@
result = new GregorianCalendar(tz, aLocale);
result.clear();
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());
}
+ }
+ }
+ }
// only set month if it is set
if (month != DatatypeConstants.FIELD_UNDEFINED) {
// Calendar.MONTH is zero based while XMLGregorianCalendar month field is not.
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);
}
}
@@ -2572,11 +2627,11 @@
// only set day if it is set
if (day != DatatypeConstants.FIELD_UNDEFINED) {
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);
}
}
@@ -2594,11 +2649,11 @@
// only set minute if it is set
if (minute != DatatypeConstants.FIELD_UNDEFINED) {
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);
}
}
@@ -2605,11 +2660,11 @@
// only set second if it is set
if (second != DatatypeConstants.FIELD_UNDEFINED) {
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);
}
}
@@ -2616,11 +2671,11 @@
// only set millisend if it is set
if (fractionalSecond != null) {
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());
}
}
@@ -2669,10 +2724,13 @@
StringBuffer customTimezoneId = new StringBuffer(8);
customTimezoneId.append("GMT");
customTimezoneId.append(sign);
customTimezoneId.append(hour);
if (minutes != 0) {
+ if (minutes < 10) {
+ customTimezoneId.append('0');
+ }
customTimezoneId.append(minutes);
}
result = TimeZone.getTimeZone(customTimezoneId.toString());
}
return result;
@@ -2716,11 +2774,11 @@
fractionalSecond = null;
} else {
if(millisecond<0 || 999<millisecond)
if(millisecond!=DatatypeConstants.FIELD_UNDEFINED)
invalidFieldValue(MILLISECOND, millisecond);
- fractionalSecond = new BigDecimal((long) millisecond).movePointLeft(3);
+ fractionalSecond = BigDecimal.valueOf(millisecond, 3);
}
}
public void setFractionalSecond(BigDecimal fractional) {
if (fractional != null) {
@@ -2768,11 +2826,11 @@
}
// seen meta character. we don't do error check against the format
switch (format.charAt(fidx++)) {
case 'Y' : // year
- parseAndSetYear(4);
+ parseYear();
break;
case 'M' : // month
setMonth(parseInt(2, 2));
break;
@@ -2849,11 +2907,11 @@
throws IllegalArgumentException {
int n = 0;
char ch;
int vstart = vidx;
- while (isDigit(ch=peek()) && (vidx - vstart) <= maxDigits) {
+ while (isDigit(ch=peek()) && (vidx - vstart) < maxDigits) {
vidx++;
n = n*10 + ch-'0';
}
if ((vidx - vstart) < minDigits) {
// we are expecting more digits
@@ -2861,44 +2919,36 @@
}
return n;
}
- private void parseAndSetYear(int minDigits)
+ private void parseYear()
throws IllegalArgumentException {
int vstart = vidx;
- int n = 0;
- boolean neg = false;
+ int sign = 0;
// skip leading negative, if it exists
if (peek() == '-') {
vidx++;
- neg = true;
+ sign = 1;
}
- while(true) {
- char ch = peek();
- if(!isDigit(ch))
- break;
+ while (isDigit(peek())) {
vidx++;
- n = n*10 + ch-'0';
}
-
- if ((vidx - vstart) < minDigits) {
+ final int digits = vidx - vstart - sign;
+ if (digits < 4) {
// we are expecting more digits
throw new IllegalArgumentException(value); //,vidx);
}
-
- if(vidx-vstart<7) {
- // definitely int only. I don't know the exact # of digits that can be in int,
- // but as long as we can catch (0-9999) range, that should be enough.
- if(neg) n = -n;
- year = n;
- eon = null;
- } else {
- setYear(new BigInteger(value.substring(vstart, vidx)));
+ final String yearString = value.substring(vstart, vidx);
+ if (digits < 10) {
+ setYear(Integer.parseInt(yearString));
}
+ else {
+ setYear(new BigInteger(yearString));
}
+ }
private BigDecimal parseBigDecimal()
throws IllegalArgumentException {
int vstart = vidx;
@@ -2920,155 +2970,128 @@
/**
* Prints this object according to the format specification.
*
* <p>
- * I wrote a custom format method for a particular format string to
- * see if it improves the performance, but it didn't. So this interpreting
- * approach isn't too bad.
- *
- * <p>
* 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(fidx<flen) {
char fch = format.charAt(fidx++);
if(fch!='%') {// not a meta char
- buf[bufPtr++] = fch;
+ buf.append(fch);
continue;
}
switch(format.charAt(fidx++)) {
case 'Y':
- if(eon==null) {
- // optimized path
- int y = getYear();
- if(y<0) {
- buf[bufPtr++] = '-';
- y = -y;
+ if (eon == null) {
+ int absYear = year;
+ if (absYear < 0) {
+ buf.append('-');
+ absYear = -year;
}
- bufPtr = print4Number(buf,bufPtr,y);
- } else {
- String s = getEonAndYear().toString();
- // reallocate the buffer now so that it has enough space
- char[] n = new char[buf.length+s.length()];
- System.arraycopy(buf,0,n,0,bufPtr);
- buf = n;
- for(int i=s.length();i<4;i++)
- buf[bufPtr++] = '0';
- s.getChars(0,s.length(),buf,bufPtr);
- bufPtr += s.length();
+ printNumber(buf, absYear, 4);
}
+ else {
+ printNumber(buf, getEonAndYear(), 4);
+ }
break;
case 'M':
- bufPtr = print2Number(buf,bufPtr,getMonth());
+ printNumber(buf,getMonth(),2);
break;
case 'D':
- bufPtr = print2Number(buf,bufPtr,getDay());
+ printNumber(buf,getDay(),2);
break;
case 'h':
- bufPtr = print2Number(buf,bufPtr,getHour());
+ printNumber(buf,getHour(),2);
break;
case 'm':
- bufPtr = print2Number(buf,bufPtr,getMinute());
+ printNumber(buf,getMinute(),2);
break;
case 's':
- bufPtr = print2Number(buf,bufPtr,getSecond());
+ printNumber(buf,getSecond(),2);
if (getFractionalSecond() != null) {
- // Note: toPlainString() isn't available before Java 1.5
- String frac = getFractionalSecond().toString();
-
- int pos = frac.indexOf("E-");
- if (pos >= 0) {
- String zeros = frac.substring(pos+2);
- frac = frac.substring(0,pos);
- pos = frac.indexOf(".");
- if (pos >= 0) {
- frac = frac.substring(0,pos) + frac.substring(pos+1);
- }
- int count = Integer.parseInt(zeros);
- if (count < 40) {
- frac = "00000000000000000000000000000000000000000".substring(0,count-1) + frac;
- } else {
- // do it the hard way
- while (count > 1) {
- frac = "0" + frac;
- count--;
- }
- }
- frac = "0." + frac;
- }
-
- // reallocate the buffer now so that it has enough space
- char[] n = new char[buf.length+frac.length()];
- System.arraycopy(buf,0,n,0,bufPtr);
- buf = n;
+ //Xerces uses a custom method toString instead of
+ //toPlainString() since it needs to support JDKs older than 1.5
+ String frac = getFractionalSecond().toPlainString();
//skip leading zero.
- frac.getChars(1, frac.length(), buf, bufPtr);
- bufPtr += frac.length()-1;
+ buf.append(frac.substring(1, frac.length()));
}
break;
case 'z':
int offset = getTimezone();
if (offset == 0) {
- buf[bufPtr++] = 'Z';
- } else
- if (offset != DatatypeConstants.FIELD_UNDEFINED) {
+ buf.append('Z');
+ }
+ else if (offset != DatatypeConstants.FIELD_UNDEFINED) {
if (offset < 0) {
- buf[bufPtr++] = '-';
+ buf.append('-');
offset *= -1;
- } else {
- buf[bufPtr++] = '+';
}
- bufPtr = print2Number(buf, bufPtr, offset / 60);
- buf[bufPtr++] = ':';
- bufPtr = print2Number(buf, bufPtr, offset % 60);
+ else {
+ buf.append('+');
}
+ printNumber(buf,offset/60,2);
+ buf.append(':');
+ printNumber(buf,offset%60,2);
+ }
break;
default:
throw new InternalError(); // impossible
}
}
- return new String(buf,0,bufPtr);
+ return buf.toString();
}
/**
- * Prints an int as two digits into the buffer.
+ * Prints an integer as a String.
*
+ * @param out
+ * The formatted string will be appended into this buffer.
* @param number
- * Number to be printed. Must be positive.
+ * The integer to be printed.
+ * @param nDigits
+ * The field will be printed by using at least this
+ * number of digits. For example, 5 will be printed as "0005"
+ * if nDigits==4.
*/
- private int print2Number( char[] out, int bufptr, int number ) {
- out[bufptr++] = (char) ('0'+(number/10));
- out[bufptr++] = (char) ('0'+(number%10));
- return bufptr;
+ private void printNumber( StringBuilder out, int number, int nDigits ) {
+ String s = String.valueOf(number);
+ for (int i = s.length(); i < nDigits; i++) {
+ out.append('0');
}
+ out.append(s);
+ }
/**
- * Prints an int as four digits into the buffer.
+ * Prints an BigInteger as a String.
*
+ * @param out
+ * The formatted string will be appended into this buffer.
* @param number
- * Number to be printed. Must be positive.
+ * The integer to be printed.
+ * @param nDigits
+ * The field will be printed by using at least this
+ * number of digits. For example, 5 will be printed as "0005"
+ * if nDigits==4.
*/
- private int print4Number( char[] out, int bufptr, int number ) {
- out[bufptr+3] = (char) ('0'+(number%10));
- number /= 10;
- out[bufptr+2] = (char) ('0'+(number%10));
- number /= 10;
- out[bufptr+1] = (char) ('0'+(number%10));
- number /= 10;
- out[bufptr ] = (char) ('0'+(number%10));
- return bufptr+4;
+ private void printNumber( StringBuilder out, BigInteger number, int nDigits) {
+ String s = number.toString();
+ for (int i=s.length(); i < nDigits; i++) {
+ out.append('0');
}
+ out.append(s);
+ }
/**
* Compute <code>value*signum</code> where value==null is treated as
* value==0.
* @return non-null {@link BigInteger}.
@@ -3083,8 +3106,28 @@
/** <p><code>reset()</code> is designed to allow the reuse of existing
* <code>XMLGregorianCalendar</code>s thus saving resources associated
* with the creation of new <code>XMLGregorianCalendar</code>s.</p>
*/
public void reset() {
- //PENDING : Implementation of reset method
+ eon = orig_eon;
+ year = orig_year;
+ month = orig_month;
+ day = orig_day;
+ hour = orig_hour;
+ minute = orig_minute;
+ second = orig_second;
+ fractionalSecond = orig_fracSeconds;
+ timezone = orig_timezone;
}
+
+ /** Deserialize Calendar. */
+ private void readObject(ObjectInputStream ois)
+ throws ClassNotFoundException, IOException {
+
+ // perform default deseralization
+ ois.defaultReadObject();
+
+ // initialize orig_* fields
+ save();
+
+ } // readObject(ObjectInputStream)
}