1 16 17 package org.apache.xerces.impl.dv.xs; 18 19 import java.math.BigDecimal ; 20 import java.math.BigInteger ; 21 22 import javax.xml.datatype.DatatypeConstants ; 23 import javax.xml.datatype.Duration ; 24 25 import org.apache.xerces.impl.dv.InvalidDatatypeValueException; 26 import org.apache.xerces.impl.dv.ValidationContext; 27 28 37 public class DurationDV extends AbstractDateTimeDV { 38 39 public static final int DURATION_TYPE = 0; 40 public static final int YEARMONTHDURATION_TYPE = 1; 41 public static final int DAYTIMEDURATION_TYPE = 2; 42 private final static DateTimeData[] DATETIMES= { 49 new DateTimeData(1696, 9, 1, 0, 0, 0, 'Z', null, true, null), 50 new DateTimeData(1697, 2, 1, 0, 0, 0, 'Z', null, true, null), 51 new DateTimeData(1903, 3, 1, 0, 0, 0, 'Z', null, true, null), 52 new DateTimeData(1903, 7, 1, 0, 0, 0, 'Z', null, true, null)}; 53 54 public Object getActualValue(String content, ValidationContext context) throws InvalidDatatypeValueException{ 55 try{ 56 return parse(content, DURATION_TYPE); 57 } catch (Exception ex) { 58 throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object []{content, "duration"}); 59 } 60 } 61 62 70 protected DateTimeData parse(String str, int durationType) throws SchemaDateTimeException{ 71 int len = str.length(); 72 DateTimeData date= new DateTimeData(str, this); 73 74 int start = 0; 75 char c=str.charAt(start++); 76 if ( c!='P' && c!='-' ) { 77 throw new SchemaDateTimeException(); 78 } 79 else { 80 date.utc=(c=='-')?'-':0; 81 if ( c=='-' && str.charAt(start++)!='P' ) { 82 throw new SchemaDateTimeException(); 83 } 84 } 85 86 int negate = 1; 87 if ( date.utc=='-' ) { 89 negate = -1; 90 91 } 92 boolean designator = false; 94 95 int endDate = indexOf (str, start, len, 'T'); 96 if ( endDate == -1 ) { 97 endDate = len; 98 } 99 else if (durationType == YEARMONTHDURATION_TYPE) { 100 throw new SchemaDateTimeException(); 101 } 102 103 int end = indexOf (str, start, endDate, 'Y'); 105 if ( end!=-1 ) { 106 107 if (durationType == DAYTIMEDURATION_TYPE) { 108 throw new SchemaDateTimeException(); 109 } 110 111 date.year=negate * parseInt(str,start,end); 113 start = end+1; 114 designator = true; 115 } 116 117 end = indexOf (str, start, endDate, 'M'); 118 if ( end!=-1 ) { 119 120 if (durationType == DAYTIMEDURATION_TYPE) { 121 throw new SchemaDateTimeException(); 122 } 123 124 date.month=negate * parseInt(str,start,end); 126 start = end+1; 127 designator = true; 128 } 129 130 end = indexOf (str, start, endDate, 'D'); 131 if ( end!=-1 ) { 132 133 if(durationType == YEARMONTHDURATION_TYPE) { 134 throw new SchemaDateTimeException(); 135 } 136 137 date.day=negate * parseInt(str,start,end); 139 start = end+1; 140 designator = true; 141 } 142 143 if ( len == endDate && start!=len ) { 144 throw new SchemaDateTimeException(); 145 } 146 if ( len !=endDate ) { 147 148 152 end = indexOf (str, ++start, len, 'H'); 153 if ( end!=-1 ) { 154 date.hour=negate * parseInt(str,start,end); 156 start=end+1; 157 designator = true; 158 } 159 160 end = indexOf (str, start, len, 'M'); 161 if ( end!=-1 ) { 162 date.minute=negate * parseInt(str,start,end); 164 start=end+1; 165 designator = true; 166 } 167 168 end = indexOf (str, start, len, 'S'); 169 if ( end!=-1 ) { 170 date.second = negate * parseSecond(str, start, end); 172 start=end+1; 173 designator = true; 174 } 175 if ( start != len || str.charAt(--start)=='T' ) { 178 throw new SchemaDateTimeException(); 179 } 180 } 181 182 if ( !designator ) { 183 throw new SchemaDateTimeException(); 184 } 185 186 return date; 187 } 188 189 203 protected short compareDates(DateTimeData date1, DateTimeData date2, boolean strict) { 204 205 209 short resultA, resultB= INDETERMINATE; 211 resultA = compareOrder (date1, date2); 213 if ( resultA == 0 ) { 214 return 0; 215 } 216 217 DateTimeData[] result = new DateTimeData[2]; 218 result[0] = new DateTimeData(null, this); 219 result[1] = new DateTimeData(null, this); 220 221 DateTimeData tempA = addDuration (date1, DATETIMES[0], result[0]); 223 DateTimeData tempB = addDuration (date2, DATETIMES[0], result[1]); 224 resultA = compareOrder(tempA, tempB); 225 if ( resultA == INDETERMINATE ) { 226 return INDETERMINATE; 227 } 228 229 tempA = addDuration(date1, DATETIMES[1], result[0]); 230 tempB = addDuration(date2, DATETIMES[1], result[1]); 231 resultB = compareOrder(tempA, tempB); 232 resultA = compareResults(resultA, resultB, strict); 233 if (resultA == INDETERMINATE) { 234 return INDETERMINATE; 235 } 236 237 tempA = addDuration(date1, DATETIMES[2], result[0]); 238 tempB = addDuration(date2, DATETIMES[2], result[1]); 239 resultB = compareOrder(tempA, tempB); 240 resultA = compareResults(resultA, resultB, strict); 241 if (resultA == INDETERMINATE) { 242 return INDETERMINATE; 243 } 244 245 tempA = addDuration(date1, DATETIMES[3], result[0]); 246 tempB = addDuration(date2, DATETIMES[3], result[1]); 247 resultB = compareOrder(tempA, tempB); 248 resultA = compareResults(resultA, resultB, strict); 249 250 return resultA; 251 } 252 253 private short compareResults(short resultA, short resultB, boolean strict){ 254 255 if ( resultB == INDETERMINATE ) { 256 return INDETERMINATE; 257 } 258 else if ( resultA!=resultB && strict ) { 259 return INDETERMINATE; 260 } 261 else if ( resultA!=resultB && !strict ) { 262 if ( resultA!=0 && resultB!=0 ) { 263 return INDETERMINATE; 264 } 265 else { 266 return (resultA!=0)?resultA:resultB; 267 } 268 } 269 return resultA; 270 } 271 272 private DateTimeData addDuration(DateTimeData date, DateTimeData addto, DateTimeData duration) { 273 274 278 resetDateObj(duration); 279 int temp = addto.month + date.month; 281 duration.month = modulo (temp, 1, 13); 282 int carry = fQuotient (temp, 1, 13); 283 284 duration.year=addto.year + date.year + carry; 286 287 double dtemp = addto.second + date.second; 289 carry = (int)Math.floor(dtemp/60); 290 duration.second = dtemp - carry*60; 291 292 temp = addto.minute +date.minute + carry; 294 carry = fQuotient (temp, 60); 295 duration.minute= mod(temp, 60, carry); 296 297 temp = addto.hour + date.hour + carry; 299 carry = fQuotient(temp, 24); 300 duration.hour = mod(temp, 24, carry); 301 302 303 duration.day=addto.day + date.day + carry; 304 305 while ( true ) { 306 307 temp=maxDayInMonthFor(duration.year, duration.month); 308 if ( duration.day < 1 ) { duration.day = duration.day + maxDayInMonthFor(duration.year, duration.month-1); 310 carry=-1; 311 } 312 else if ( duration.day > temp ) { 313 duration.day = duration.day - temp; 314 carry=1; 315 } 316 else { 317 break; 318 } 319 temp = duration.month+carry; 320 duration.month = modulo(temp, 1, 13); 321 duration.year = duration.year+fQuotient(temp, 1, 13); 322 } 323 324 duration.utc='Z'; 325 return duration; 326 } 327 328 protected double parseSecond(String buffer, int start, int end) 329 throws NumberFormatException { 330 int dot = -1; 331 for (int i = start; i < end; i++) { 332 char ch = buffer.charAt(i); 333 if (ch == '.') 334 dot = i; 335 else if (ch > '9' || ch < '0') 336 throw new NumberFormatException ("'" + buffer + "' has wrong format"); 337 } 338 if (dot+1 == end) { 339 throw new NumberFormatException ("'" + buffer + "' has wrong format"); 340 } 341 return Double.parseDouble(buffer.substring(start, end)); 342 } 343 344 protected String dateToString(DateTimeData date) { 345 StringBuffer message = new StringBuffer (30); 346 if ( date.year<0 || date.month<0 || date.day<0 347 || date.hour<0 || date.minute<0 || date.second<0) { 348 message.append('-'); 349 } 350 message.append('P'); 351 message.append((date.year < 0?-1:1) * date.year); 352 message.append('Y'); 353 message.append((date.month < 0?-1:1) * date.month); 354 message.append('M'); 355 message.append((date.day < 0?-1:1) * date.day); 356 message.append('D'); 357 message.append('T'); 358 message.append((date.hour < 0?-1:1) * date.hour); 359 message.append('H'); 360 message.append((date.minute < 0?-1:1) * date.minute); 361 message.append('M'); 362 message.append((date.second < 0?-1:1) * date.second); 363 message.append('S'); 364 365 return message.toString(); 366 } 367 368 protected Duration getDuration(DateTimeData date) { 369 int sign = 1; 370 if ( date.year<0 || date.month<0 || date.day<0 371 || date.hour<0 || date.minute<0 || date.second<0) { 372 sign = -1; 373 } 374 return factory.newDuration(sign == 1, 375 date.year != DatatypeConstants.FIELD_UNDEFINED?BigInteger.valueOf(sign*date.year):null, 376 date.month != DatatypeConstants.FIELD_UNDEFINED?BigInteger.valueOf(sign*date.month):null, 377 date.day != DatatypeConstants.FIELD_UNDEFINED?BigInteger.valueOf(sign*date.day):null, 378 date.hour != DatatypeConstants.FIELD_UNDEFINED?BigInteger.valueOf(sign*date.hour):null, 379 date.minute != DatatypeConstants.FIELD_UNDEFINED?BigInteger.valueOf(sign*date.minute):null, 380 date.second != DatatypeConstants.FIELD_UNDEFINED?new BigDecimal (String.valueOf(sign*date.second)):null); 381 } 382 } 383 | Popular Tags |