| 1 16 17 package org.apache.xerces.jaxp.datatype; 18 19 import java.io.Serializable ; 20 import java.math.BigDecimal ; 21 import java.math.BigInteger ; 22 import java.util.Calendar ; 23 import java.util.Date ; 24 import java.util.GregorianCalendar ; 25 import java.util.Locale ; 26 import java.util.TimeZone ; 27 28 import javax.xml.datatype.DatatypeConstants ; 29 import javax.xml.datatype.Duration ; 30 import javax.xml.datatype.XMLGregorianCalendar ; 31 import javax.xml.namespace.QName ; 32 33 import org.apache.xerces.util.DatatypeMessageFormatter; 34 35 178 179 class XMLGregorianCalendarImpl 180 extends XMLGregorianCalendar  181 implements Serializable , Cloneable { 182 183 184 private BigInteger orig_eon; 185 private int orig_year = DatatypeConstants.FIELD_UNDEFINED; 186 private int orig_month = DatatypeConstants.FIELD_UNDEFINED; 187 private int orig_day = DatatypeConstants.FIELD_UNDEFINED; 188 private int orig_hour = DatatypeConstants.FIELD_UNDEFINED; 189 private int orig_minute = DatatypeConstants.FIELD_UNDEFINED; 190 private int orig_second = DatatypeConstants.FIELD_UNDEFINED; 191 private BigDecimal orig_fracSeconds; 192 private int orig_timezone = DatatypeConstants.FIELD_UNDEFINED; 193 194 197 private BigInteger eon = null; 198 199 202 private int year = DatatypeConstants.FIELD_UNDEFINED; 203 204 207 private int month = DatatypeConstants.FIELD_UNDEFINED; 208 209 212 private int day = DatatypeConstants.FIELD_UNDEFINED; 213 214 217 private int timezone = DatatypeConstants.FIELD_UNDEFINED; 218 219 222 private int hour = DatatypeConstants.FIELD_UNDEFINED; 223 224 227 private int minute = DatatypeConstants.FIELD_UNDEFINED; 228 229 232 private int second = DatatypeConstants.FIELD_UNDEFINED ; 233 234 237 private BigDecimal fractionalSecond = null; 238 239 242 private static final BigInteger BILLION = new BigInteger ("1000000000"); 243 244 248 private static final Date PURE_GREGORIAN_CHANGE = 249 new Date (Long.MIN_VALUE); 250 251 254 private static final int YEAR = 0; 255 256 259 private static final int MONTH = 1; 260 261 264 private static final int DAY = 2; 265 266 269 private static final int HOUR = 3; 270 271 274 private static final int MINUTE = 4; 275 276 279 private static final int SECOND = 5; 280 281 284 private static final int MILLISECOND = 6; 285 286 289 private static final int TIMEZONE = 7; 290 291 294 private static final int MIN_FIELD_VALUE[] = { 295 Integer.MIN_VALUE, DatatypeConstants.JANUARY, 298 1, 0, 0, 0, 0, -14 * 60 }; 305 306 309 private static final int MAX_FIELD_VALUE[] = { 310 Integer.MAX_VALUE, DatatypeConstants.DECEMBER, 313 31, 23, 59, 60, 999, 14 * 60 }; 320 321 324 private static final String FIELD_NAME[] = { 325 "Year", 326 "Month", 327 "Day", 328 "Hour", 329 "Minute", 330 "Second", 331 "Millisecond", 332 "Timezone" 333 }; 334 335 341 private static final long serialVersionUID = 1L; 342 343 355 public static final XMLGregorianCalendar LEAP_YEAR_DEFAULT = 356 createDateTime( 357 400, DatatypeConstants.JANUARY, 1, 0, 0, 0, DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED ); 366 367 369 386 protected XMLGregorianCalendarImpl(String lexicalRepresentation) 387 throws IllegalArgumentException { 388 389 String format = null; 391 String lexRep = lexicalRepresentation; 392 final int NOT_FOUND = -1; 393 int lexRepLength = lexRep.length(); 394 395 396 if (lexRep.indexOf('T') != NOT_FOUND) { 400 format = "%Y-%M-%DT%h:%m:%s" + "%z"; 402 } else if (lexRepLength >= 3 && lexRep.charAt(2) == ':') { 403 format = "%h:%m:%s" +"%z"; 405 } else if (lexRep.startsWith("--")) { 406 if (lexRepLength >= 3 && lexRep.charAt(2) == '-') { 408 format = "---%D" + "%z"; 411 } else if (lexRepLength == 4 || (lexRepLength >= 6 && (lexRep.charAt(4) == '+' || (lexRep.charAt(4) == '-' && (lexRep.charAt(5) == '-' || lexRepLength == 10))))) { 412 format = "--%M--%z"; 415 Parser p = new Parser(format, lexRep); 416 try { 417 p.parse(); 418 if (!isValid()) { 420 throw new IllegalArgumentException ( 421 DatatypeMessageFormatter.formatMessage(null,"InvalidXGCRepresentation", new Object []{lexicalRepresentation}) 422 ); 424 } 425 save(); 426 return; 427 } 428 catch(IllegalArgumentException e) { 429 format = "--%M%z"; 430 } 431 } else { 432 format = "--%M-%D" + "%z"; 434 } 435 } else { 436 int countSeparator = 0; 438 439 441 442 int timezoneOffset = lexRep.indexOf(':'); 443 if (timezoneOffset != NOT_FOUND) { 444 445 lexRepLength -= 6; 450 } 451 452 for (int i=1; i < lexRepLength; i++) { 453 if (lexRep.charAt(i) == '-') { 454 countSeparator++; 455 } 456 } 457 if (countSeparator == 0) { 458 format = "%Y" + "%z"; 460 } else if (countSeparator == 1) { 461 format = "%Y-%M" + "%z"; 463 } else { 464 format = "%Y-%M-%D" + "%z"; 467 } 468 } 469 Parser p = new Parser(format, lexRep); 470 p.parse(); 471 472 if (!isValid()) { 474 throw new IllegalArgumentException ( 475 DatatypeMessageFormatter.formatMessage(null,"InvalidXGCRepresentation", new Object []{lexicalRepresentation}) 476 ); 478 } 479 save(); 480 } 481 482 485 private void save() { 486 orig_eon = eon; 487 orig_year = year; 488 orig_month = month; 489 orig_day = day; 490 orig_hour = hour; 491 orig_minute = minute; 492 orig_second = second; 493 orig_fracSeconds = fractionalSecond; 494 orig_timezone = timezone; 495 } 496 497 501 public XMLGregorianCalendarImpl() { 502 503 } 505 506 523 protected XMLGregorianCalendarImpl( 524 BigInteger year, 525 int month, 526 int day, 527 int hour, 528 int minute, 529 int second, 530 BigDecimal fractionalSecond, 531 int timezone) { 532 533 setYear(year); 534 setMonth(month); 535 setDay(day); 536 setTime(hour, minute, second, fractionalSecond); 537 setTimezone(timezone); 538 539 if (!isValid()) { 541 542 throw new IllegalArgumentException ( 543 DatatypeMessageFormatter.formatMessage(null, 544 "InvalidXGCValue-fractional", 545 new Object [] { year, new Integer (month), new Integer (day), 546 new Integer (hour), new Integer (minute), new Integer (second), 547 fractionalSecond, new Integer (timezone)}) 548 ); 549 550 572 573 } 574 575 save(); 576 577 } 578 579 596 private XMLGregorianCalendarImpl( 597 int year, 598 int month, 599 int day, 600 int hour, 601 int minute, 602 int second, 603 int millisecond, 604 int timezone) { 605 606 setYear(year); 607 setMonth(month); 608 setDay(day); 609 setTime(hour, minute, second); 610 setTimezone(timezone); 611 setMillisecond(millisecond); 612 613 if (!isValid()) { 614 615 throw new IllegalArgumentException ( 616 DatatypeMessageFormatter.formatMessage(null, 617 "InvalidXGCValue-milli", 618 new Object [] { new Integer (year), new Integer (month), new Integer (day), 619 new Integer (hour), new Integer (minute), new Integer (second), 620 new Integer (millisecond), new Integer (timezone)}) 621 ); 622 635 636 } 637 save(); 638 } 639 640 697 public XMLGregorianCalendarImpl(GregorianCalendar cal) { 698 699 int year = cal.get(Calendar.YEAR); 700 if (cal.get(Calendar.ERA) == GregorianCalendar.BC) { 701 year = -year; 702 } 703 this.setYear(year); 704 705 this.setMonth(cal.get(Calendar.MONTH) + 1); 708 this.setDay(cal.get(Calendar.DAY_OF_MONTH)); 709 this.setTime( 710 cal.get(Calendar.HOUR_OF_DAY), 711 cal.get(Calendar.MINUTE), 712 cal.get(Calendar.SECOND), 713 cal.get(Calendar.MILLISECOND)); 714 715 int offsetInMinutes = (cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET)) / (60 * 1000); 717 this.setTimezone(offsetInMinutes); 718 save(); 719 } 720 721 723 744 public static XMLGregorianCalendar createDateTime( 745 BigInteger year, 746 int month, 747 int day, 748 int hours, 749 int minutes, 750 int seconds, 751 BigDecimal fractionalSecond, 752 int timezone) { 753 754 return new XMLGregorianCalendarImpl( 755 year, 756 month, 757 day, 758 hours, 759 minutes, 760 seconds, 761 fractionalSecond, 762 timezone); 763 } 764 765 782 public static XMLGregorianCalendar createDateTime( 783 int year, 784 int month, 785 int day, 786 int hour, 787 int minute, 788 int second) { 789 790 return new XMLGregorianCalendarImpl( 791 year, 792 month, 793 day, 794 hour, 795 minute, 796 second, 797 DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED ); 800 } 801 802 822 public static XMLGregorianCalendar createDateTime( 823 int year, 824 int month, 825 int day, 826 int hours, 827 int minutes, 828 int seconds, 829 int milliseconds, 830 int timezone) { 831 832 return new XMLGregorianCalendarImpl( 833 year, 834 month, 835 day, 836 hours, 837 minutes, 838 seconds, 839 milliseconds, 840 timezone); 841 } 842 843 863 public static XMLGregorianCalendar createDate( 864 int year, 865 int month, 866 int day, 867 int timezone) { 868 869 return new XMLGregorianCalendarImpl( 870 year, 871 month, 872 day, 873 DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED, timezone); 878 } 879 880 895 public static XMLGregorianCalendar createTime( 896 int hours, 897 int minutes, 898 int seconds, 899 int timezone) { 900 901 return new XMLGregorianCalendarImpl( 902 DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED, hours, 906 minutes, 907 seconds, 908 DatatypeConstants.FIELD_UNDEFINED, timezone); 910 } 911 912 929 public static XMLGregorianCalendar createTime( |