DurationDVpublic class DurationDV extends AbstractDateTimeDV Validator for <duration> datatype (W3C Schema Datatypes) |
Fields Summary |
---|
public static final int | DURATION_TYPE | public static final int | YEARMONTHDURATION_TYPE | public static final int | DAYTIMEDURATION_TYPE | private static final DateTimeData[] | DATETIMES |
Methods Summary |
---|
private DateTimeData | addDuration(DateTimeData date, DateTimeData addto, DateTimeData duration)
//REVISIT: some code could be shared between normalize() and this method,
// however is it worth moving it? The structures are different...
//
resetDateObj(duration);
//add months (may be modified additionaly below)
int temp = addto.month + date.month;
duration.month = modulo (temp, 1, 13);
int carry = fQuotient (temp, 1, 13);
//add years (may be modified additionaly below)
duration.year=addto.year + date.year + carry;
//add seconds
double dtemp = addto.second + date.second;
carry = (int)Math.floor(dtemp/60);
duration.second = dtemp - carry*60;
//add minutes
temp = addto.minute +date.minute + carry;
carry = fQuotient (temp, 60);
duration.minute= mod(temp, 60, carry);
//add hours
temp = addto.hour + date.hour + carry;
carry = fQuotient(temp, 24);
duration.hour = mod(temp, 24, carry);
duration.day=addto.day + date.day + carry;
while ( true ) {
temp=maxDayInMonthFor(duration.year, duration.month);
if ( duration.day < 1 ) { //original duration was negative
duration.day = duration.day + maxDayInMonthFor(duration.year, duration.month-1);
carry=-1;
}
else if ( duration.day > temp ) {
duration.day = duration.day - temp;
carry=1;
}
else {
break;
}
temp = duration.month+carry;
duration.month = modulo(temp, 1, 13);
duration.year = duration.year+fQuotient(temp, 1, 13);
}
duration.utc='Z";
return duration;
| protected short | compareDates(DateTimeData date1, DateTimeData date2, boolean strict)Compares 2 given durations. (refer to W3C Schema Datatypes "3.2.6 duration")
//REVISIT: this is unoptimazed vs of comparing 2 durations
// Algorithm is described in 3.2.6.2 W3C Schema Datatype specs
//
//add constA to both durations
short resultA, resultB= INDETERMINATE;
//try and see if the objects are equal
resultA = compareOrder (date1, date2);
if ( resultA == 0 ) {
return 0;
}
DateTimeData[] result = new DateTimeData[2];
result[0] = new DateTimeData(null, this);
result[1] = new DateTimeData(null, this);
//long comparison algorithm is required
DateTimeData tempA = addDuration (date1, DATETIMES[0], result[0]);
DateTimeData tempB = addDuration (date2, DATETIMES[0], result[1]);
resultA = compareOrder(tempA, tempB);
if ( resultA == INDETERMINATE ) {
return INDETERMINATE;
}
tempA = addDuration(date1, DATETIMES[1], result[0]);
tempB = addDuration(date2, DATETIMES[1], result[1]);
resultB = compareOrder(tempA, tempB);
resultA = compareResults(resultA, resultB, strict);
if (resultA == INDETERMINATE) {
return INDETERMINATE;
}
tempA = addDuration(date1, DATETIMES[2], result[0]);
tempB = addDuration(date2, DATETIMES[2], result[1]);
resultB = compareOrder(tempA, tempB);
resultA = compareResults(resultA, resultB, strict);
if (resultA == INDETERMINATE) {
return INDETERMINATE;
}
tempA = addDuration(date1, DATETIMES[3], result[0]);
tempB = addDuration(date2, DATETIMES[3], result[1]);
resultB = compareOrder(tempA, tempB);
resultA = compareResults(resultA, resultB, strict);
return resultA;
| private short | compareResults(short resultA, short resultB, boolean strict)
if ( resultB == INDETERMINATE ) {
return INDETERMINATE;
}
else if ( resultA!=resultB && strict ) {
return INDETERMINATE;
}
else if ( resultA!=resultB && !strict ) {
if ( resultA!=0 && resultB!=0 ) {
return INDETERMINATE;
}
else {
return (resultA!=0)?resultA:resultB;
}
}
return resultA;
| protected java.lang.String | dateToString(DateTimeData date)
StringBuffer message = new StringBuffer(30);
if ( date.year<0 || date.month<0 || date.day<0
|| date.hour<0 || date.minute<0 || date.second<0) {
message.append('-");
}
message.append('P");
message.append((date.year < 0?-1:1) * date.year);
message.append('Y");
message.append((date.month < 0?-1:1) * date.month);
message.append('M");
message.append((date.day < 0?-1:1) * date.day);
message.append('D");
message.append('T");
message.append((date.hour < 0?-1:1) * date.hour);
message.append('H");
message.append((date.minute < 0?-1:1) * date.minute);
message.append('M");
message.append((date.second < 0?-1:1) * date.second);
message.append('S");
return message.toString();
| public java.lang.Object | getActualValue(java.lang.String content, com.sun.org.apache.xerces.internal.impl.dv.ValidationContext context)
try{
return parse(content, DURATION_TYPE);
} catch (Exception ex) {
throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object[]{content, "duration"});
}
| protected javax.xml.datatype.Duration | getDuration(DateTimeData date)
int sign = 1;
if ( date.year<0 || date.month<0 || date.day<0
|| date.hour<0 || date.minute<0 || date.second<0) {
sign = -1;
}
return factory.newDuration(sign == 1,
date.year != DatatypeConstants.FIELD_UNDEFINED?BigInteger.valueOf(sign*date.year):null,
date.month != DatatypeConstants.FIELD_UNDEFINED?BigInteger.valueOf(sign*date.month):null,
date.day != DatatypeConstants.FIELD_UNDEFINED?BigInteger.valueOf(sign*date.day):null,
date.hour != DatatypeConstants.FIELD_UNDEFINED?BigInteger.valueOf(sign*date.hour):null,
date.minute != DatatypeConstants.FIELD_UNDEFINED?BigInteger.valueOf(sign*date.minute):null,
date.second != DatatypeConstants.FIELD_UNDEFINED?new BigDecimal(String.valueOf(sign*date.second)):null);
| protected DateTimeData | parse(java.lang.String str, int durationType)Parses, validates and computes normalized version of duration object
int len = str.length();
DateTimeData date= new DateTimeData(str, this);
int start = 0;
char c=str.charAt(start++);
if ( c!='P" && c!='-" ) {
throw new SchemaDateTimeException();
}
else {
date.utc=(c=='-")?'-":0;
if ( c=='-" && str.charAt(start++)!='P" ) {
throw new SchemaDateTimeException();
}
}
int negate = 1;
//negative duration
if ( date.utc=='-" ) {
negate = -1;
}
//at least one number and designator must be seen after P
boolean designator = false;
int endDate = indexOf (str, start, len, 'T");
if ( endDate == -1 ) {
endDate = len;
}
else if (durationType == YEARMONTHDURATION_TYPE) {
throw new SchemaDateTimeException();
}
//find 'Y'
int end = indexOf (str, start, endDate, 'Y");
if ( end!=-1 ) {
if (durationType == DAYTIMEDURATION_TYPE) {
throw new SchemaDateTimeException();
}
//scan year
date.year=negate * parseInt(str,start,end);
start = end+1;
designator = true;
}
end = indexOf (str, start, endDate, 'M");
if ( end!=-1 ) {
if (durationType == DAYTIMEDURATION_TYPE) {
throw new SchemaDateTimeException();
}
//scan month
date.month=negate * parseInt(str,start,end);
start = end+1;
designator = true;
}
end = indexOf (str, start, endDate, 'D");
if ( end!=-1 ) {
if(durationType == YEARMONTHDURATION_TYPE) {
throw new SchemaDateTimeException();
}
//scan day
date.day=negate * parseInt(str,start,end);
start = end+1;
designator = true;
}
if ( len == endDate && start!=len ) {
throw new SchemaDateTimeException();
}
if ( len !=endDate ) {
//scan hours, minutes, seconds
//REVISIT: can any item include a decimal fraction or only seconds?
//
end = indexOf (str, ++start, len, 'H");
if ( end!=-1 ) {
//scan hours
date.hour=negate * parseInt(str,start,end);
start=end+1;
designator = true;
}
end = indexOf (str, start, len, 'M");
if ( end!=-1 ) {
//scan min
date.minute=negate * parseInt(str,start,end);
start=end+1;
designator = true;
}
end = indexOf (str, start, len, 'S");
if ( end!=-1 ) {
//scan seconds
date.second = negate * parseSecond(str, start, end);
start=end+1;
designator = true;
}
// no additional data shouls appear after last item
// P1Y1M1DT is illigal value as well
if ( start != len || str.charAt(--start)=='T" ) {
throw new SchemaDateTimeException();
}
}
if ( !designator ) {
throw new SchemaDateTimeException();
}
return date;
| protected double | parseSecond(java.lang.String buffer, int start, int end)
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 == end) {
throw new NumberFormatException("'" + buffer + "' has wrong format");
}
return Double.parseDouble(buffer.substring(start, end));
|
|