1 57 58 package org.enhydra.apache.xerces.validators.datatype; 59 60 import java.util.Hashtable ; 61 62 68 69 public class DurationDatatypeValidator extends DateTimeValidator { 70 71 private final static int[][] DATETIMES= { 78 {1696, 9, 1, 0, 0, 0, 0, 'Z'}, 79 {1697, 2, 1, 0, 0, 0, 0, 'Z'}, 80 {1903, 3, 1, 0, 0, 0, 0, 'Z'}, 81 {1903, 7, 1, 0, 0, 0, 0, 'Z'}}; 82 83 private int[][] fDuration = null; 84 85 86 public DurationDatatypeValidator() throws InvalidDatatypeFacetException{ 87 super(); 88 } 89 public DurationDatatypeValidator ( DatatypeValidator base, Hashtable facets, 90 boolean derivedByList ) throws InvalidDatatypeFacetException { 91 92 super(base, facets, derivedByList); 93 } 94 95 96 104 protected int[] parse(String str, int[] date) throws SchemaDateTimeException{ 105 106 resetBuffer(str); 108 109 if ( date== null ) { 111 date=new int[TOTAL_SIZE]; 112 } 113 resetDateObj(date); 114 115 116 char c=fBuffer.charAt(fStart++); 117 if ( c!='P' && c!='-' ) { 118 throw new SchemaDateTimeException(); 119 } 120 else { 121 date[utc]=(c=='-')?'-':0; 122 if ( c=='-' && fBuffer.charAt(fStart++)!='P' ) { 123 throw new SchemaDateTimeException(); 124 } 125 } 126 127 int negate = 1; 128 if ( date[utc]=='-' ) { 130 negate = -1; 131 132 } 133 boolean designator = false; 135 136 int endDate = indexOf (fStart, fEnd, 'T'); 137 if ( endDate == -1 ) { 138 endDate = fEnd; 139 } 140 int end = indexOf (fStart, endDate, 'Y'); 142 if ( end!=-1 ) { 143 date[CY]=negate * parseInt(fStart,end); 145 fStart = end+1; 146 designator = true; 147 } 148 149 end = indexOf (fStart, endDate, 'M'); 150 if ( end!=-1 ) { 151 date[M]=negate * parseInt(fStart,end); 153 fStart = end+1; 154 designator = true; 155 } 156 157 end = indexOf (fStart, endDate, 'D'); 158 if ( end!=-1 ) { 159 date[D]=negate * parseInt(fStart,end); 161 fStart = end+1; 162 designator = true; 163 } 164 165 if ( fEnd == endDate && fStart!=fEnd ) { 166 throw new SchemaDateTimeException(); 167 } 168 if ( fEnd !=endDate ) { 169 170 174 end = indexOf (++fStart, fEnd, 'H'); 175 if ( end!=-1 ) { 176 date[h]=negate * parseInt(fStart,end); 178 fStart=end+1; 179 designator = true; 180 } 181 182 end = indexOf (fStart, fEnd, 'M'); 183 if ( end!=-1 ) { 184 date[m]=negate * parseInt(fStart,end); 186 fStart=end+1; 187 designator = true; 188 } 189 190 end = indexOf (fStart, fEnd, 'S'); 191 if ( end!=-1 ) { 192 int mlsec = indexOf (fStart, end, '.'); 194 if ( mlsec >0 ) { 195 date[s] = negate * parseInt (fStart, mlsec); 196 date[ms] = negate * parseInt (mlsec+1, end); 197 } 198 else { 199 date[s]=negate * parseInt(fStart,end); 200 } 201 fStart=end+1; 202 designator = true; 203 } 204 if ( fStart != fEnd || fBuffer.charAt(--fStart)=='T' ) { 207 throw new SchemaDateTimeException(); 208 } 209 } 210 211 if ( !designator ) { 212 throw new SchemaDateTimeException(); 213 } 214 215 return date; 216 } 217 218 219 228 protected short compareDates(int[] date1, int[] date2, boolean strict) { 229 230 234 short resultA, resultB= INDETERMINATE; 236 237 resultA = compareOrder (date1, date2); 239 if ( resultA == EQUAL ) { 240 return EQUAL; 241 } 242 if ( fDuration == null ) { 243 fDuration = new int[2][TOTAL_SIZE]; 244 } 245 int[] tempA = addDuration (date1, 0, fDuration[0]); 247 int[] tempB = addDuration (date2, 0, fDuration[1]); 248 resultA = compareOrder(tempA, tempB); 249 if ( resultA == INDETERMINATE ) { 250 return INDETERMINATE; 251 } 252 253 tempA = addDuration(date1, 1, fDuration[0]); 254 tempB = addDuration(date2, 1, fDuration[1]); 255 resultB = compareOrder(tempA, tempB); 256 resultA = compareResults(resultA, resultB, strict); 257 if (resultA == INDETERMINATE) { 258 return INDETERMINATE; 259 } 260 261 tempA = addDuration(date1, 2, fDuration[0]); 262 tempB = addDuration(date2, 2, fDuration[1]); 263 resultB = compareOrder(tempA, tempB); 264 resultA = compareResults(resultA, resultB, strict); 265 if (resultA == INDETERMINATE) { 266 return INDETERMINATE; 267 } 268 269 tempA = addDuration(date1, 3, fDuration[0]); 270 tempB = addDuration(date2, 3, fDuration[1]); 271 resultB = compareOrder(tempA, tempB); 272 resultA = compareResults(resultA, resultB, strict); 273 274 return resultA; 275 } 276 277 private short compareResults(short resultA, short resultB, boolean strict){ 278 279 if ( resultB == INDETERMINATE ) { 280 return INDETERMINATE; 281 } 282 else if ( resultA!=resultB && strict ) { 283 return INDETERMINATE; 284 } 285 else if ( resultA!=resultB && !strict ) { 286 if ( resultA!=EQUAL && resultB!=EQUAL ) { 287 return INDETERMINATE; 288 } 289 else { 290 return (resultA!=EQUAL)?resultA:resultB; 291 } 292 } 293 return resultA; 294 } 295 296 private int[] addDuration(int[] date, int index, int[] duration) { 297 298 302 resetDateObj(duration); 303 int temp = DATETIMES[index][M] + date[M]; 305 duration[M] = modulo (temp, 1, 13); 306 int carry = fQuotient (temp, 1, 13); 307 308 duration[CY]=DATETIMES[index][CY] + date[CY] + carry; 310 311 temp = DATETIMES[index][s] + date[s]; 313 carry = fQuotient (temp, 60); 314 duration[s] = mod(temp, 60, carry); 315 316 temp = DATETIMES[index][m] +date[m] + carry; 318 carry = fQuotient (temp, 60); 319 duration[m]= mod(temp, 60, carry); 320 321 temp = DATETIMES[index][h] + date[h] + carry; 323 carry = fQuotient(temp, 24); 324 duration[h] = mod(temp, 24, carry); 325 326 327 duration[D]=DATETIMES[index][D] + date[D] + carry; 328 329 while ( true ) { 330 331 temp=maxDayInMonthFor(duration[CY], duration[M]); 332 if ( duration[D] < 1 ) { duration[D] = duration[D] + maxDayInMonthFor(duration[CY], duration[M]-1); 334 carry=-1; 335 } 336 else if ( duration[D] > temp ) { 337 duration[D] = duration[D] - temp; 338 carry=1; 339 } 340 else { 341 break; 342 } 343 temp = duration[M]+carry; 344 duration[M] = modulo(temp, 1, 13); 345 duration[CY] = duration[CY]+fQuotient(temp, 1, 13); 346 } 347 348 duration[utc]='Z'; 349 return duration; 350 } 351 352 protected String dateToString(int[] date) { 353 message.setLength(0); 354 int negate = 1; 355 if ( date[CY]<0 ) { 356 message.append('-'); 357 negate=-1; 358 } 359 message.append('P'); 360 message.append(negate * date[CY]); 361 message.append('Y'); 362 message.append(negate * date[M]); 363 message.append('M'); 364 message.append(negate * date[D]); 365 message.append('D'); 366 message.append('T'); 367 message.append(negate * date[h]); 368 message.append('H'); 369 message.append(negate * date[m]); 370 message.append('M'); 371 message.append(negate * date[s]); 372 message.append('.'); 373 message.append(negate * date[ms]); 374 message.append('S'); 375 376 return message.toString(); 377 } 378 } 379 380 381 | Popular Tags |