jaxp/src/com/sun/org/apache/xerces/internal/jaxp/datatype/DurationImpl.java
Print this page
@@ -19,26 +19,24 @@
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.jaxp.datatype;
+import com.sun.org.apache.xerces.internal.util.DatatypeMessageFormatter;
import java.io.IOException;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
-
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.Duration;
import javax.xml.datatype.XMLGregorianCalendar;
-import com.sun.org.apache.xerces.internal.util.DatatypeMessageFormatter;
-
/**
* <p>Immutable representation of a time span as defined in
* the W3C XML Schema 1.0 specification.</p>
*
* <p>A Duration object represents a period of Gregorian time,
@@ -118,21 +116,10 @@
DatatypeConstants.HOURS,
DatatypeConstants.MINUTES,
DatatypeConstants.SECONDS
};
- /**
- * <p>Internal array of value Field ids.</p>
- */
- private static final int[] FIELD_IDS = {
- DatatypeConstants.YEARS.getId(),
- DatatypeConstants.MONTHS.getId(),
- DatatypeConstants.DAYS.getId(),
- DatatypeConstants.HOURS.getId(),
- DatatypeConstants.MINUTES.getId(),
- DatatypeConstants.SECONDS.getId()
- };
/**
* TimeZone for GMT.
*/
private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
@@ -141,10 +128,16 @@
* <p>BigDecimal value of 0.</p>
*/
private static final BigDecimal ZERO = BigDecimal.valueOf(0);
/**
+ * BigInteger value of Integer's max value.</p>
+ */
+ private static final BigInteger MaxIntAsBigInt =
+ BigInteger.valueOf((long) Integer.MAX_VALUE);
+
+ /**
* <p>Indicates the sign. -1, 0 or 1 if the duration is negative,
* zero, or positive.</p>
*/
protected int signum;
@@ -194,14 +187,14 @@
return signum;
}
/**
- * TODO: Javadoc
- * @param isPositive Sign.
+ * Determine the sign of the duration.
*
- * @return 1 if positive, else -1.
+ * @param isPositive Sign.
+ * @return 1 if positive, -1 negative, or 0 if all fields are zero.
*/
protected int calcSignum(boolean isPositive) {
if ((years == null || years.signum() == 0)
&& (months == null || months.signum() == 0)
&& (days == null || days.signum() == 0)
@@ -723,184 +716,46 @@
*
* @see #isShorterThan(Duration)
* @see #isLongerThan(Duration)
*/
public int compare(Duration rhs) {
-
- BigInteger maxintAsBigInteger = BigInteger.valueOf(Integer.MAX_VALUE);
-
- // check for fields that are too large in this Duration
- if (years != null && years.compareTo(maxintAsBigInteger) == 1) {
- throw new UnsupportedOperationException(
- DatatypeMessageFormatter.formatMessage(null, "TooLarge",
- new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.YEARS.toString(), years.toString()})
- //this.getClass().getName() + "#compare(Duration duration)"
- //+ " years too large to be supported by this implementation "
- //+ years.toString()
- );
+ /** check if any field in the Durations is too large for the operation
+ * that uses XMLGregorianCalendar for comparison
+ */
+ for (DatatypeConstants.Field field : FIELDS) {
+ checkMaxValue(getField(field), field);
+ checkMaxValue(rhs.getField(field), field);
}
- if (months != null && months.compareTo(maxintAsBigInteger) == 1) {
- throw new UnsupportedOperationException(
- DatatypeMessageFormatter.formatMessage(null, "TooLarge",
- new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.MONTHS.toString(), months.toString()})
- //this.getClass().getName() + "#compare(Duration duration)"
- //+ " months too large to be supported by this implementation "
- //+ months.toString()
- );
+ return compareDates(this, rhs);
}
- if (days != null && days.compareTo(maxintAsBigInteger) == 1) {
- throw new UnsupportedOperationException(
- DatatypeMessageFormatter.formatMessage(null, "TooLarge",
- new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.DAYS.toString(), days.toString()})
- //this.getClass().getName() + "#compare(Duration duration)"
- //+ " days too large to be supported by this implementation "
- //+ days.toString()
- );
+ /**
+ * Check if a field exceeds the maximum value
+ * @param field the value of a field
+ * @param fieldType type of the field, e.g. year, month, day, hour, minute or second.
+ */
+ private void checkMaxValue(Number field, DatatypeConstants.Field fieldType) {
+ BigInteger fieldValue = null;
+ if (fieldType != DatatypeConstants.SECONDS) {
+ fieldValue = (BigInteger) field;
+ } else {
+ BigDecimal rhsSecondsAsBigDecimal = (BigDecimal) field;
+ if ( rhsSecondsAsBigDecimal != null ) {
+ fieldValue = rhsSecondsAsBigDecimal.toBigInteger();
}
- if (hours != null && hours.compareTo(maxintAsBigInteger) == 1) {
- throw new UnsupportedOperationException(
- DatatypeMessageFormatter.formatMessage(null, "TooLarge",
- new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.HOURS.toString(), hours.toString()})
-
- //this.getClass().getName() + "#compare(Duration duration)"
- //+ " hours too large to be supported by this implementation "
- //+ hours.toString()
- );
}
- if (minutes != null && minutes.compareTo(maxintAsBigInteger) == 1) {
- throw new UnsupportedOperationException(
- DatatypeMessageFormatter.formatMessage(null, "TooLarge",
- new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.MINUTES.toString(), minutes.toString()})
- //this.getClass().getName() + "#compare(Duration duration)"
- //+ " minutes too large to be supported by this implementation "
- //+ minutes.toString()
- );
- }
- if (seconds != null && seconds.toBigInteger().compareTo(maxintAsBigInteger) == 1) {
+ if (fieldValue != null && fieldValue.compareTo(MaxIntAsBigInt) == 1) {
throw new UnsupportedOperationException(
DatatypeMessageFormatter.formatMessage(null, "TooLarge",
- new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.SECONDS.toString(), toString(seconds)})
-
- //this.getClass().getName() + "#compare(Duration duration)"
- //+ " seconds too large to be supported by this implementation "
- //+ seconds.toString()
+ new Object[]{this.getClass().getName() + "#compare(Duration duration)"
+ + fieldType, field.toString()})
);
}
-
- // check for fields that are too large in rhs Duration
- BigInteger rhsYears = (BigInteger) rhs.getField(DatatypeConstants.YEARS);
- if (rhsYears != null && rhsYears.compareTo(maxintAsBigInteger) == 1) {
- throw new UnsupportedOperationException(
- DatatypeMessageFormatter.formatMessage(null, "TooLarge",
- new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.YEARS.toString(), rhsYears.toString()})
-
- //this.getClass().getName() + "#compare(Duration duration)"
- //+ " years too large to be supported by this implementation "
- //+ rhsYears.toString()
- );
}
- BigInteger rhsMonths = (BigInteger) rhs.getField(DatatypeConstants.MONTHS);
- if (rhsMonths != null && rhsMonths.compareTo(maxintAsBigInteger) == 1) {
- throw new UnsupportedOperationException(
- DatatypeMessageFormatter.formatMessage(null, "TooLarge",
- new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.MONTHS.toString(), rhsMonths.toString()})
- //this.getClass().getName() + "#compare(Duration duration)"
- //+ " months too large to be supported by this implementation "
- //+ rhsMonths.toString()
- );
- }
- BigInteger rhsDays = (BigInteger) rhs.getField(DatatypeConstants.DAYS);
- if (rhsDays != null && rhsDays.compareTo(maxintAsBigInteger) == 1) {
- throw new UnsupportedOperationException(
- DatatypeMessageFormatter.formatMessage(null, "TooLarge",
- new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.DAYS.toString(), rhsDays.toString()})
-
- //this.getClass().getName() + "#compare(Duration duration)"
- //+ " days too large to be supported by this implementation "
- //+ rhsDays.toString()
- );
- }
- BigInteger rhsHours = (BigInteger) rhs.getField(DatatypeConstants.HOURS);
- if (rhsHours != null && rhsHours.compareTo(maxintAsBigInteger) == 1) {
- throw new UnsupportedOperationException(
- DatatypeMessageFormatter.formatMessage(null, "TooLarge",
- new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.HOURS.toString(), rhsHours.toString()})
-
- //this.getClass().getName() + "#compare(Duration duration)"
- //+ " hours too large to be supported by this implementation "
- //+ rhsHours.toString()
- );
- }
- BigInteger rhsMinutes = (BigInteger) rhs.getField(DatatypeConstants.MINUTES);
- if (rhsMinutes != null && rhsMinutes.compareTo(maxintAsBigInteger) == 1) {
- throw new UnsupportedOperationException(
- DatatypeMessageFormatter.formatMessage(null, "TooLarge",
- new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.MINUTES.toString(), rhsMinutes.toString()})
-
- //this.getClass().getName() + "#compare(Duration duration)"
- //+ " minutes too large to be supported by this implementation "
- //+ rhsMinutes.toString()
- );
- }
- BigDecimal rhsSecondsAsBigDecimal = (BigDecimal) rhs.getField(DatatypeConstants.SECONDS);
- BigInteger rhsSeconds = null;
- if ( rhsSecondsAsBigDecimal != null ) {
- rhsSeconds = rhsSecondsAsBigDecimal.toBigInteger();
- }
- if (rhsSeconds != null && rhsSeconds.compareTo(maxintAsBigInteger) == 1) {
- throw new UnsupportedOperationException(
- DatatypeMessageFormatter.formatMessage(null, "TooLarge",
- new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.SECONDS.toString(), rhsSeconds.toString()})
-
- //this.getClass().getName() + "#compare(Duration duration)"
- //+ " seconds too large to be supported by this implementation "
- //+ rhsSeconds.toString()
- );
- }
-
- // turn this Duration into a GregorianCalendar
- GregorianCalendar lhsCalendar = new GregorianCalendar(
- 1970,
- 1,
- 1,
- 0,
- 0,
- 0);
- lhsCalendar.add(GregorianCalendar.YEAR, getYears() * getSign());
- lhsCalendar.add(GregorianCalendar.MONTH, getMonths() * getSign());
- lhsCalendar.add(GregorianCalendar.DAY_OF_YEAR, getDays() * getSign());
- lhsCalendar.add(GregorianCalendar.HOUR_OF_DAY, getHours() * getSign());
- lhsCalendar.add(GregorianCalendar.MINUTE, getMinutes() * getSign());
- lhsCalendar.add(GregorianCalendar.SECOND, getSeconds() * getSign());
-
- // turn compare Duration into a GregorianCalendar
- GregorianCalendar rhsCalendar = new GregorianCalendar(
- 1970,
- 1,
- 1,
- 0,
- 0,
- 0);
- rhsCalendar.add(GregorianCalendar.YEAR, rhs.getYears() * rhs.getSign());
- rhsCalendar.add(GregorianCalendar.MONTH, rhs.getMonths() * rhs.getSign());
- rhsCalendar.add(GregorianCalendar.DAY_OF_YEAR, rhs.getDays() * rhs.getSign());
- rhsCalendar.add(GregorianCalendar.HOUR_OF_DAY, rhs.getHours() * rhs.getSign());
- rhsCalendar.add(GregorianCalendar.MINUTE, rhs.getMinutes() * rhs.getSign());
- rhsCalendar.add(GregorianCalendar.SECOND, rhs.getSeconds() * rhs.getSign());
-
-
- if (lhsCalendar.equals(rhsCalendar)) {
- return DatatypeConstants.EQUAL;
- }
-
- return compareDates(this, rhs);
- }
-
/**
* Compares 2 given durations. (refer to W3C Schema Datatypes "3.2.6 duration")
*
* @param duration1 Unnormalized duration
* @param duration2 Unnormalized duration