1 /*
   2  * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package datatype;
  25 
  26 import java.math.BigDecimal;
  27 import java.math.BigInteger;
  28 
  29 import javax.xml.datatype.DatatypeConfigurationException;
  30 import javax.xml.datatype.DatatypeConstants;
  31 import javax.xml.datatype.DatatypeFactory;
  32 import javax.xml.datatype.Duration;
  33 import javax.xml.datatype.XMLGregorianCalendar;
  34 import javax.xml.namespace.QName;
  35 
  36 import org.testng.Assert;
  37 import org.testng.annotations.Listeners;
  38 import org.testng.annotations.Test;
  39 
  40 /*
  41  * @summary Test DatatypeFactory.
  42  */
  43 @Listeners({jaxp.library.BasePolicy.class})
  44 public class DatatypeFactoryTest {
  45 
  46     private static final boolean DEBUG = false;
  47 
  48     private static final String TEST_VALUE_FAIL = "*FAIL*";
  49 
  50     private static final String FIELD_UNDEFINED = "FIELD_UNDEFINED";
  51 
  52     static int parseInt(String value) {
  53         return FIELD_UNDEFINED.equals(value) ? DatatypeConstants.FIELD_UNDEFINED : Integer.parseInt(value);
  54     }
  55 
  56     static BigDecimal parseBigDecimal(String value) {
  57         return FIELD_UNDEFINED.equals(value) ? null : new BigDecimal(value);
  58     }
  59 
  60     static BigInteger parseBigInteger(String value) {
  61         return FIELD_UNDEFINED.equals(value) ? null : new BigInteger(value);
  62     }
  63 
  64     @Test
  65     public final void testNewDurationMilliseconds() {
  66 
  67         /*
  68          * to generate millisecond values
  69          * final TimeZone GMT = TimeZone.getTimeZone("GMT"); GregorianCalendar
  70          * gregorianCalendar = new GregorianCalendar(GMT);
  71          * gregorianCalendar.setTimeInMillis(0);
  72          * gregorianCalendar.add(Calendar.HOUR_OF_DAY, 1);
  73          * gregorianCalendar.add(Calendar.MINUTE, 1);
  74          * System.err.println("1 hour, 1 minute = " +
  75          * gregorianCalendar.getTimeInMillis() + " milliseconds");
  76          */
  77 
  78         /**
  79          * Millisecond test values to test.
  80          */
  81         final long[] TEST_VALUES_MILLISECONDS = { 0L, // 0
  82                 1L, // 1 millisecond
  83                 -1L, 1000L, // 1 second
  84                 -1000L, 1001L, // 1 second, 1 millisecond
  85                 -1001L, 60000L, // 1 minute
  86                 -60000L, 61000L, // 1 minute, 1 second
  87                 -61000L, 3600000L, // 1 hour
  88                 -3600000L, 3660000L, // 1 hour, 1 minute
  89                 -3660000L, 86400000L, // 1 day
  90                 -86400000L, 90000000L, // 1 day, 1 hour
  91                 -90000000L, 2678400000L, // 1 month
  92                 -2678400000L, 2764800000L, // 1 month, 1 day
  93                 -2764800000L, 31536000000L, // 1 year
  94                 -31536000000L, 34214400000L, // 1 year, 1 month
  95                 -34214400000L };
  96 
  97         /**
  98          * Millisecond test value results of test.
  99          */
 100         final String[] TEST_VALUES_MILLISECONDS_RESULTS = { "P0Y0M0DT0H0M0.000S", // 0
 101                 "P0Y0M0DT0H0M0.001S", // 1 millisecond
 102                 "-P0Y0M0DT0H0M0.001S", "P0Y0M0DT0H0M1.000S", // 1 second
 103                 "-P0Y0M0DT0H0M1.000S", "P0Y0M0DT0H0M1.001S", // 1 second, 1
 104                                                              // millisecond
 105                 "-P0Y0M0DT0H0M1.001S", "P0Y0M0DT0H1M0.000S", // 1 minute
 106                 "-P0Y0M0DT0H1M0.000S", "P0Y0M0DT0H1M1.000S", // 1 minute, 1
 107                                                              // second
 108                 "-P0Y0M0DT0H1M1.000S", "P0Y0M0DT1H0M0.000S", // 1 hour
 109                 "-P0Y0M0DT1H0M0.000S", "P0Y0M0DT1H1M0.000S", // 1 hour, 1 minute
 110                 "-P0Y0M0DT1H1M0.000S", "P0Y0M1DT0H0M0.000S", // 1 day
 111                 "-P0Y0M1DT0H0M0.000S", "P0Y0M1DT1H0M0.000S", // 1 day, 1 hour
 112                 "-P0Y0M1DT1H0M0.000S", "P0Y1M0DT0H0M0.000S", // 1 month
 113                 "-P0Y1M0DT0H0M0.000S", "P0Y1M1DT0H0M0.000S", // 1 month, 1 day
 114                 "-P0Y1M1DT0H0M0.000S", "P1Y0M0DT0H0M0.000S", // 1 year
 115                 "-P1Y0M0DT0H0M0.000S", "P1Y1M0DT0H0M0.000S", // 1 year, 1 month
 116                 "-P1Y1M0DT0H0M0.000S" };
 117 
 118         DatatypeFactory datatypeFactory = null;
 119         try {
 120             datatypeFactory = DatatypeFactory.newInstance();
 121         } catch (DatatypeConfigurationException datatypeConfigurationException) {
 122             Assert.fail(datatypeConfigurationException.toString());
 123         }
 124 
 125         if (DEBUG) {
 126             System.err.println("DatatypeFactory created: " + datatypeFactory.toString());
 127         }
 128 
 129         // test each value
 130         for (int onTestValue = 0; onTestValue < TEST_VALUES_MILLISECONDS.length; onTestValue++) {
 131 
 132             if (DEBUG) {
 133                 System.err.println("testing value: \"" + TEST_VALUES_MILLISECONDS[onTestValue] + "\", expecting: \""
 134                         + TEST_VALUES_MILLISECONDS_RESULTS[onTestValue] + "\"");
 135             }
 136 
 137             try {
 138                 Duration duration = datatypeFactory.newDuration(TEST_VALUES_MILLISECONDS[onTestValue]);
 139 
 140                 if (DEBUG) {
 141                     System.err.println("Duration created: \"" + duration.toString() + "\"");
 142                 }
 143 
 144                 // was this expected to fail?
 145                 if (TEST_VALUES_MILLISECONDS_RESULTS[onTestValue].equals(TEST_VALUE_FAIL)) {
 146                     Assert.fail("the value \"" + TEST_VALUES_MILLISECONDS[onTestValue] + "\" is invalid yet it created the Duration \"" + duration.toString()
 147                             + "\"");
 148                 }
 149 
 150                 // right XMLSchemaType?
 151                 QName xmlSchemaType = duration.getXMLSchemaType();
 152                 if (!xmlSchemaType.equals(DatatypeConstants.DURATION)) {
 153                     Assert.fail("Duration created with XMLSchemaType of\"" + xmlSchemaType + "\" was expected to be \"" + DatatypeConstants.DURATION
 154                             + "\" and has the value \"" + duration.toString() + "\"");
 155                 }
 156 
 157                 // does it have the right value?
 158                 if (!TEST_VALUES_MILLISECONDS_RESULTS[onTestValue].equals(duration.toString())) {
 159                     Assert.fail("Duration created with \"" + TEST_VALUES_MILLISECONDS[onTestValue] + "\" was expected to be \""
 160                             + TEST_VALUES_MILLISECONDS_RESULTS[onTestValue] + "\" and has the value \"" + duration.toString() + "\"");
 161                 }
 162 
 163                 // Duration created with correct value
 164             } catch (Exception exception) {
 165 
 166                 if (DEBUG) {
 167                     System.err.println("Exception in creating duration: \"" + exception.toString() + "\"");
 168                 }
 169 
 170                 // was this expected to succed?
 171                 if (!TEST_VALUES_MILLISECONDS_RESULTS[onTestValue].equals(TEST_VALUE_FAIL)) {
 172                     Assert.fail("the value \"" + TEST_VALUES_MILLISECONDS[onTestValue] + "\" is valid yet it failed with \"" + exception.toString() + "\"");
 173                 }
 174                 // expected failure
 175             }
 176         }
 177     }
 178 
 179     /**
 180      * Test {@link DatatypeFactory.newDurationYearMonth(String
 181      * lexicalRepresentation)}.
 182      */
 183     @Test
 184     public final void testNewDurationYearMonthLexicalRepresentation() {
 185 
 186         /**
 187          * Lexical test values to test.
 188          */
 189         final String[] TEST_VALUES_LEXICAL = { null, TEST_VALUE_FAIL, "", TEST_VALUE_FAIL, "-", TEST_VALUE_FAIL, "P", TEST_VALUE_FAIL, "-P", TEST_VALUE_FAIL,
 190                 "P1D", TEST_VALUE_FAIL, "P1Y1M1D", TEST_VALUE_FAIL, "P1M", "P1M", "-P1M", "-P1M", "P1Y", "P1Y", "-P1Y", "-P1Y", "P1Y1M", "P1Y1M", "-P1Y1M",
 191                 "-P1Y1M" };
 192 
 193         DatatypeFactory datatypeFactory = null;
 194         try {
 195             datatypeFactory = DatatypeFactory.newInstance();
 196         } catch (DatatypeConfigurationException datatypeConfigurationException) {
 197             Assert.fail(datatypeConfigurationException.toString());
 198         }
 199 
 200         if (DEBUG) {
 201             System.err.println("DatatypeFactory created: " + datatypeFactory.toString());
 202         }
 203 
 204         // test each value
 205         for (int onTestValue = 0; onTestValue < TEST_VALUES_LEXICAL.length; onTestValue = onTestValue + 2) {
 206 
 207             if (DEBUG) {
 208                 System.err.println("testing value: \"" + TEST_VALUES_LEXICAL[onTestValue] + "\", expecting: \"" + TEST_VALUES_LEXICAL[onTestValue + 1] + "\"");
 209             }
 210 
 211             try {
 212                 Duration duration = datatypeFactory.newDurationYearMonth(TEST_VALUES_LEXICAL[onTestValue]);
 213 
 214                 if (DEBUG) {
 215                     System.err.println("Duration created: \"" + duration.toString() + "\"");
 216                 }
 217 
 218                 // was this expected to fail?
 219                 if (TEST_VALUES_LEXICAL[onTestValue + 1].equals(TEST_VALUE_FAIL)) {
 220                     Assert.fail("the value \"" + TEST_VALUES_LEXICAL[onTestValue] + "\" is invalid yet it created the Duration \"" + duration.toString() + "\"");
 221                 }
 222 
 223                 // right XMLSchemaType?
 224                 // TODO: enable test, it should pass, it fails with Exception(s)
 225                 // for now due to a bug
 226                 try {
 227                     QName xmlSchemaType = duration.getXMLSchemaType();
 228                     if (!xmlSchemaType.equals(DatatypeConstants.DURATION_YEARMONTH)) {
 229                         Assert.fail("Duration created with XMLSchemaType of\"" + xmlSchemaType + "\" was expected to be \""
 230                                 + DatatypeConstants.DURATION_YEARMONTH + "\" and has the value \"" + duration.toString() + "\"");
 231                     }
 232                 } catch (IllegalStateException illegalStateException) {
 233                     // TODO; this test really should pass
 234                     System.err.println("Please fix this bug that is being ignored, for now: " + illegalStateException.getMessage());
 235                 }
 236 
 237                 // does it have the right value?
 238                 if (!TEST_VALUES_LEXICAL[onTestValue + 1].equals(duration.toString())) {
 239                     Assert.fail("Duration created with \"" + TEST_VALUES_LEXICAL[onTestValue] + "\" was expected to be \""
 240                             + TEST_VALUES_LEXICAL[onTestValue + 1] + "\" and has the value \"" + duration.toString() + "\"");
 241                 }
 242 
 243                 // Duration created with correct value
 244             } catch (Exception exception) {
 245 
 246                 if (DEBUG) {
 247                     System.err.println("Exception in creating duration: \"" + exception.toString() + "\"");
 248                 }
 249 
 250                 // was this expected to succed?
 251                 if (!TEST_VALUES_LEXICAL[onTestValue + 1].equals(TEST_VALUE_FAIL)) {
 252                     Assert.fail("the value \"" + TEST_VALUES_LEXICAL[onTestValue] + "\" is valid yet it failed with \"" + exception.toString() + "\"");
 253                 }
 254                 // expected failure
 255             }
 256         }
 257     }
 258 
 259     /**
 260      * Test {@link DatatypeFactory.newDurationYearMonth(long milliseconds)}.
 261      *
 262      */
 263     @Test
 264     public final void testNewDurationYearMonthMilliseconds() {
 265 
 266         /**
 267          * Millisecond test values to test.
 268          */
 269         final long[] TEST_VALUES_MILLISECONDS = { 0L, 1L, -1L, 2678400000L, // 31
 270                                                                             // days,
 271                                                                             // e.g.
 272                                                                             // 1
 273                                                                             // month
 274                 -2678400000L, 5270400000L, // 61 days, e.g. 2 months
 275                 -5270400000L, 31622400000L, // 366 days, e.g. 1 year
 276                 -31622400000L, 34300800000L, // 397 days, e.g. 1 year, 1 month
 277                 -34300800000L };
 278 
 279         /**
 280          * Millisecond test value results of test.
 281          */
 282         final String[] TEST_VALUES_MILLISECONDS_RESULTS = { "P0Y0M", "P0Y0M", "P0Y0M", "P0Y1M", "-P0Y1M", "P0Y2M", "-P0Y2M", "P1Y0M", "-P1Y0M", "P1Y1M",
 283                 "-P1Y1M" };
 284 
 285         DatatypeFactory datatypeFactory = null;
 286         try {
 287             datatypeFactory = DatatypeFactory.newInstance();
 288         } catch (DatatypeConfigurationException datatypeConfigurationException) {
 289             Assert.fail(datatypeConfigurationException.toString());
 290         }
 291 
 292         if (DEBUG) {
 293             System.err.println("DatatypeFactory created: " + datatypeFactory.toString());
 294         }
 295 
 296         // test each value
 297         for (int onTestValue = 0; onTestValue < TEST_VALUES_MILLISECONDS.length; onTestValue++) {
 298 
 299             if (DEBUG) {
 300                 System.err.println("testing value: \"" + TEST_VALUES_MILLISECONDS[onTestValue] + "\", expecting: \""
 301                         + TEST_VALUES_MILLISECONDS_RESULTS[onTestValue] + "\"");
 302             }
 303 
 304             try {
 305                 Duration duration = datatypeFactory.newDurationYearMonth(TEST_VALUES_MILLISECONDS[onTestValue]);
 306 
 307                 if (DEBUG) {
 308                     System.err.println("Duration created: \"" + duration.toString() + "\"");
 309                 }
 310 
 311                 // was this expected to fail?
 312                 if (TEST_VALUES_MILLISECONDS_RESULTS[onTestValue].equals(TEST_VALUE_FAIL)) {
 313                     Assert.fail("the value \"" + TEST_VALUES_MILLISECONDS[onTestValue] + "\" is invalid yet it created the Duration \"" + duration.toString()
 314                             + "\"");
 315                 }
 316 
 317                 // right XMLSchemaType?
 318                 QName xmlSchemaType = duration.getXMLSchemaType();
 319                 if (!xmlSchemaType.equals(DatatypeConstants.DURATION_YEARMONTH)) {
 320                     Assert.fail("Duration created with XMLSchemaType of\"" + xmlSchemaType + "\" was expected to be \"" + DatatypeConstants.DURATION_YEARMONTH
 321                             + "\" and has the value \"" + duration.toString() + "\"");
 322                 }
 323 
 324                 // does it have the right value?
 325                 if (!TEST_VALUES_MILLISECONDS_RESULTS[onTestValue].equals(duration.toString())) {
 326                     Assert.fail("Duration created with \"" + TEST_VALUES_MILLISECONDS[onTestValue] + "\" was expected to be \""
 327                             + TEST_VALUES_MILLISECONDS_RESULTS[onTestValue] + "\" and has the value \"" + duration.toString() + "\"");
 328                 }
 329 
 330                 // only YEAR & MONTH should have values
 331                 int days = duration.getDays();
 332                 int hours = duration.getHours();
 333                 int minutes = duration.getMinutes();
 334                 if (days != 0 || hours != 0 || minutes != 0) {
 335                     Assert.fail("xdt:yearMonthDuration created without discarding remaining milliseconds: " + " days = " + days + ", hours = " + hours
 336                             + ", minutess = " + minutes);
 337                 }
 338 
 339                 // Duration created with correct values
 340             } catch (Exception exception) {
 341 
 342                 if (DEBUG) {
 343                     System.err.println("Exception in creating duration: \"" + exception.toString() + "\"");
 344                 }
 345 
 346                 // was this expected to succed?
 347                 if (!TEST_VALUES_MILLISECONDS_RESULTS[onTestValue].equals(TEST_VALUE_FAIL)) {
 348                     Assert.fail("the value \"" + TEST_VALUES_MILLISECONDS[onTestValue] + "\" is valid yet it failed with \"" + exception.toString() + "\"");
 349                 }
 350                 // expected failure
 351             }
 352         }
 353     }
 354 
 355     /**
 356      * Test {@link DatatypeFactory.newDurationDayTime(long milliseconds)}.
 357      */
 358     @Test
 359     public final void testNewDurationDayTime() {
 360 
 361         /**
 362          * Millisecond test values to test.
 363          */
 364         final long[] TEST_VALUES_MILLISECONDS = { 0L, 1L, -1L, 2678400000L, // 31
 365                                                                             // days,
 366                                                                             // e.g.
 367                                                                             // 1
 368                                                                             // month
 369                 -2678400000L, 5270400000L, // 61 days, e.g. 2 months
 370                 -5270400000L, 31622400000L, // 366 days, e.g. 1 year
 371                 -31622400000L, 34300800000L, // 397 days, e.g. 1 year, 1 month
 372                 -34300800000L };
 373 
 374         /**
 375          * Millisecond test value results of test.
 376          */
 377         final String[] TEST_VALUES_MILLISECONDS_RESULTS = { "P0Y0M0DT0H0M0.000S", "P0Y0M0DT0H0M0.001S", "-P0Y0M0DT0H0M0.001S", "P0Y1M", "-P0Y1M", "P0Y2M",
 378                 "-P0Y2M", "P1Y0M", "-P1Y0M", "P1Y1M", "-P1Y1M" };
 379 
 380         DatatypeFactory datatypeFactory = null;
 381         try {
 382             datatypeFactory = DatatypeFactory.newInstance();
 383         } catch (DatatypeConfigurationException datatypeConfigurationException) {
 384             Assert.fail(datatypeConfigurationException.toString());
 385         }
 386 
 387         if (DEBUG) {
 388             System.err.println("DatatypeFactory created: " + datatypeFactory.toString());
 389         }
 390 
 391         // test each value
 392         for (int onTestValue = 0; onTestValue < TEST_VALUES_MILLISECONDS.length; onTestValue++) {
 393 
 394             if (DEBUG) {
 395                 System.err.println("testing value: \"" + TEST_VALUES_MILLISECONDS[onTestValue] + "\", expecting: \""
 396                         + TEST_VALUES_MILLISECONDS_RESULTS[onTestValue] + "\"");
 397             }
 398 
 399             try {
 400                 Duration duration = datatypeFactory.newDurationDayTime(TEST_VALUES_MILLISECONDS[onTestValue]);
 401 
 402                 if (DEBUG) {
 403                     System.err.println("Duration created: \"" + duration.toString() + "\"");
 404                 }
 405 
 406                 // was this expected to fail?
 407                 if (TEST_VALUES_MILLISECONDS_RESULTS[onTestValue].equals(TEST_VALUE_FAIL)) {
 408                     Assert.fail("the value \"" + TEST_VALUES_MILLISECONDS[onTestValue] + "\" is invalid yet it created the Duration \"" + duration.toString()
 409                             + "\"");
 410                 }
 411 
 412                 // does it have the right value?
 413                 if (!TEST_VALUES_MILLISECONDS_RESULTS[onTestValue].equals(duration.toString())) {
 414                     // TODO: this is bug that should be fixed
 415                     if (false) {
 416                         Assert.fail("Duration created with \"" + TEST_VALUES_MILLISECONDS[onTestValue] + "\" was expected to be \""
 417                                 + TEST_VALUES_MILLISECONDS_RESULTS[onTestValue] + "\" and has the value \"" + duration.toString() + "\"");
 418                     } else {
 419                         System.err.println("Please fix this bug: " + "Duration created with \"" + TEST_VALUES_MILLISECONDS[onTestValue]
 420                                 + "\" was expected to be \"" + TEST_VALUES_MILLISECONDS_RESULTS[onTestValue] + "\" and has the value \"" + duration.toString()
 421                                 + "\"");
 422                     }
 423                 }
 424 
 425                 // only day, hour, minute, and second should have values
 426                 QName xmlSchemaType = duration.getXMLSchemaType();
 427                 int years = duration.getYears();
 428                 int months = duration.getMonths();
 429 
 430                 if (!xmlSchemaType.equals(DatatypeConstants.DURATION_DAYTIME) || years != 0 || months != 0) {
 431                     // TODO: this is bug that should be fixed
 432                     if (false) {
 433                         Assert.fail("xdt:dayTimeDuration created without discarding remaining milliseconds: " + " XMLSchemaType = " + xmlSchemaType
 434                                 + ", years = " + years + ", months = " + months);
 435                     } else {
 436                         System.err.println("Please fix this bug: " + "xdt:dayTimeDuration created without discarding remaining milliseconds: "
 437                                 + " XMLSchemaType = " + xmlSchemaType + ", years = " + years + ", months = " + months);
 438                     }
 439                 }
 440 
 441                 // Duration created with correct values
 442             } catch (Exception exception) {
 443 
 444                 if (DEBUG) {
 445                     System.err.println("Exception in creating duration: \"" + exception.toString() + "\"");
 446                 }
 447 
 448                 // was this expected to succed?
 449                 if (!TEST_VALUES_MILLISECONDS_RESULTS[onTestValue].equals(TEST_VALUE_FAIL)) {
 450                     Assert.fail("the value \"" + TEST_VALUES_MILLISECONDS[onTestValue] + "\" is valid yet it failed with \"" + exception.toString() + "\"");
 451                 }
 452                 // expected failure
 453             }
 454         }
 455     }
 456 
 457     /**
 458      * Test {@link DatatypeFactory.newXMLGregorianCalendar(String
 459      * lexicalRepresentation)}.
 460      */
 461     @Test
 462     public final void testNewXMLGregorianCalendarLexicalRepresentation() {
 463 
 464         /**
 465          * Lexical test values to test.
 466          */
 467         final String[] TEST_VALUES_LEXICAL = { null, TEST_VALUE_FAIL, "", TEST_VALUE_FAIL, "---01", "---01", // gDay
 468                 "---01Z", "---01Z", // gDay, UTC
 469                 "---01-08:00", "---01-08:00", // gDay, PDT
 470                 "--01--", TEST_VALUE_FAIL, // gMonth pre errata, --MM--(z?)
 471                 "--01", "--01", // gMonth
 472                 "--01Z", "--01Z", // gMonth, UTC
 473                 "--01-08:00", "--01-08:00", // gMonth, PDT
 474                 "--01-01", "--01-01", // gMonthDay
 475                 "--01-01Z", "--01-01Z", // gMonthDay, UTC
 476                 "--01-01-08:00", "--01-01-08:00" // gMonthDay, PDT
 477         };
 478 
 479         // get a DatatypeFactory
 480         DatatypeFactory datatypeFactory = null;
 481         try {
 482             datatypeFactory = DatatypeFactory.newInstance();
 483         } catch (DatatypeConfigurationException datatypeConfigurationException) {
 484             Assert.fail(datatypeConfigurationException.toString());
 485         }
 486 
 487         if (DEBUG) {
 488             System.err.println("DatatypeFactory created: " + datatypeFactory.toString());
 489         }
 490 
 491         // test each value
 492         for (int onTestValue = 0; onTestValue < TEST_VALUES_LEXICAL.length; onTestValue = onTestValue + 2) {
 493 
 494             if (DEBUG) {
 495                 System.err.println("testing value: \"" + TEST_VALUES_LEXICAL[onTestValue] + "\", expecting: \"" + TEST_VALUES_LEXICAL[onTestValue + 1] + "\"");
 496             }
 497 
 498             try {
 499                 XMLGregorianCalendar xmlGregorianCalendar = datatypeFactory.newXMLGregorianCalendar(TEST_VALUES_LEXICAL[onTestValue]);
 500 
 501                 if (DEBUG) {
 502                     System.err.println("XMLGregorianCalendar created: \"" + xmlGregorianCalendar.toString() + "\"");
 503                 }
 504 
 505                 // was this expected to fail?
 506                 if (TEST_VALUES_LEXICAL[onTestValue + 1].equals(TEST_VALUE_FAIL)) {
 507                     Assert.fail("the value \"" + TEST_VALUES_LEXICAL[onTestValue] + "\" is invalid yet it created the XMLGregorianCalendar \""
 508                             + xmlGregorianCalendar.toString() + "\"");
 509                 }
 510 
 511                 // does it have the right value?
 512                 if (!TEST_VALUES_LEXICAL[onTestValue + 1].equals(xmlGregorianCalendar.toString())) {
 513                     Assert.fail("XMLGregorianCalendar created with \"" + TEST_VALUES_LEXICAL[onTestValue] + "\" was expected to be \""
 514                             + TEST_VALUES_LEXICAL[onTestValue + 1] + "\" and has the value \"" + xmlGregorianCalendar.toString() + "\"");
 515                 }
 516 
 517                 // XMLGregorianCalendar created with correct value
 518             } catch (Exception exception) {
 519 
 520                 if (DEBUG) {
 521                     System.err.println("Exception in creating XMLGregorianCalendar: \"" + exception.toString() + "\"");
 522                 }
 523 
 524                 // was this expected to succed?
 525                 if (!TEST_VALUES_LEXICAL[onTestValue + 1].equals(TEST_VALUE_FAIL)) {
 526                     Assert.fail("the value \"" + TEST_VALUES_LEXICAL[onTestValue] + "\" is valid yet it failed with \"" + exception.toString() + "\"");
 527                 }
 528                 // expected failure
 529             }
 530         }
 531     }
 532 
 533     /**
 534      * Test {@link DatatypeFactory.newXMLGregorianCalendar( BigInteger year, int
 535      * month, int day, int hour, int minute, int second, BigDecimal
 536      * fractionalSecond, int timezone)} and
 537      * DatatypeFactory.newXMLGregorianCalendar( int year, int month, int day,
 538      * int hour, int minute, int second, int fractionalSecond, int timezone)} .
 539      */
 540     @Test
 541     public final void testNewXMLGregorianCalendarYearMonthDayHourMinuteSecondFractionalSecondTimezone() {
 542 
 543         final String[][] invalidDates = {
 544                 { "1970", "-1", "1", "0", "0", "0", "0", "0" },
 545                 { "1970", "0", "1", "0", "0", "0", "0", "0" },
 546                 { "1970", "13", "1", "0", "0", "0", "0", "0" },
 547                 { "1970", "1", "-1", "0", "0", "0", "0", "0" },
 548                 { "1970", "1", "0", "0", "0", "0", "0", "0" },
 549                 { "1970", "1", "32", "0", "0", "0", "0", "0" },
 550                 { "1970", "1", "1", "-1", "0", "0", "0", "0" },
 551                 // valid per Schema Errata:
 552                 // http://www.w3.org/2001/05/xmlschema-errata#e2-45
 553                 // {"1970", "1", "1", "24", "0", "0", "0", "0" }
 554                 // put in a repeat value to preserve offsets & TCK tests
 555                 { "1970", "1", "1", "0", "-1", "0", "0", "0" }, { "1970", "1", "1", "0", "-1", "0", "0", "0" }, { "1970", "1", "1", "0", "60", "0", "0", "0" },
 556                 { "1970", "1", "1", "0", "0", "-1", "0", "0" }, { "1970", "1", "1", "0", "0", "61", "0", "0" },
 557                 { "1970", "1", "1", "0", "0", "0", "-0.000001", "0" }, { "1970", "1", "1", "0", "0", "0", "1.0001", "0" },
 558                 { "1970", "1", "1", "0", "0", "0", "0", "841" }, { "1970", "1", "1", "0", "0", "0", "0", "-841" }, };
 559 
 560         // get a DatatypeFactory
 561         DatatypeFactory datatypeFactory = null;
 562         try {
 563             datatypeFactory = DatatypeFactory.newInstance();
 564         } catch (DatatypeConfigurationException datatypeConfigurationException) {
 565             Assert.fail(datatypeConfigurationException.toString());
 566         }
 567 
 568         if (DEBUG) {
 569             System.err.println("DatatypeFactory created: " + datatypeFactory.toString());
 570         }
 571 
 572         // test values, expect failure
 573         for (int valueIndex = 0; valueIndex < invalidDates.length; ++valueIndex) {
 574 
 575             try {
 576 
 577                 if (DEBUG) {
 578                     System.err.println("testing DatatypeFactory.newXMLGregorianCalendar(" + invalidDates[valueIndex][0] + ", " + invalidDates[valueIndex][1]
 579                             + ", " + invalidDates[valueIndex][2] + ", " + invalidDates[valueIndex][3] + ", " + invalidDates[valueIndex][4] + ", "
 580                             + invalidDates[valueIndex][5] + ", " + invalidDates[valueIndex][6] + ", " + invalidDates[valueIndex][7] + ")");
 581                 }
 582 
 583                 XMLGregorianCalendar xmlGregorianCalendar = datatypeFactory.newXMLGregorianCalendar(parseBigInteger(invalidDates[valueIndex][0]),
 584                         parseInt(invalidDates[valueIndex][1]), parseInt(invalidDates[valueIndex][2]), parseInt(invalidDates[valueIndex][3]),
 585                         parseInt(invalidDates[valueIndex][4]), parseInt(invalidDates[valueIndex][5]), parseBigDecimal(invalidDates[valueIndex][6]),
 586                         parseInt(invalidDates[valueIndex][7]));
 587 
 588                 if (DEBUG) {
 589                     System.err.println("created XMLGregorianCalendar: " + xmlGregorianCalendar.toString());
 590                 }
 591 
 592                 // unexpected success, should have failed
 593                 Assert.fail("expected IllegalArgumentException " + "for DatatypeFactory.newXMLGregorianCalendar(" + invalidDates[valueIndex][0] + ", "
 594                         + invalidDates[valueIndex][1] + ", " + invalidDates[valueIndex][2] + ", " + invalidDates[valueIndex][3] + ", "
 595                         + invalidDates[valueIndex][4] + ", " + invalidDates[valueIndex][5] + ", " + invalidDates[valueIndex][6] + ", "
 596                         + invalidDates[valueIndex][7] + ").  " + "Instead, XMLGregorianCalendar: \"" + xmlGregorianCalendar.toString() + "\" was created.");
 597             } catch (IllegalArgumentException illegalArgumentException) {
 598                 // expected failure
 599                 if (DEBUG) {
 600                     System.err.println("Exception creating XMLGregorianCalendar: " + illegalArgumentException.toString());
 601                 }
 602             }
 603         }
 604 
 605         // test with all ints
 606         int[] testIndex = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, };
 607         for (int i = 0; i < testIndex.length; ++i) {
 608             int valueIndex = testIndex[i];
 609             try {
 610                 if (DEBUG) {
 611                     System.err.println("testing DatatypeFactory.newXMLGregorianCalendar(" + invalidDates[valueIndex][0] + ", " + invalidDates[valueIndex][1]
 612                             + ", " + invalidDates[valueIndex][2] + ", " + invalidDates[valueIndex][3] + ", " + invalidDates[valueIndex][4] + ", "
 613                             + invalidDates[valueIndex][5] + ", " + invalidDates[valueIndex][6] + ", " + invalidDates[valueIndex][7] + ")");
 614                 }
 615 
 616                 XMLGregorianCalendar xmlGregorianCalendar = datatypeFactory.newXMLGregorianCalendar(parseInt(invalidDates[valueIndex][0]),
 617                         parseInt(invalidDates[valueIndex][1]), parseInt(invalidDates[valueIndex][2]), parseInt(invalidDates[valueIndex][3]),
 618                         parseInt(invalidDates[valueIndex][4]), parseInt(invalidDates[valueIndex][5]), parseInt(invalidDates[valueIndex][6]),
 619                         parseInt(invalidDates[valueIndex][7]));
 620 
 621                 if (DEBUG) {
 622                     System.err.println("created XMLGregorianCalendar: " + xmlGregorianCalendar.toString());
 623                 }
 624 
 625                 // unexpected success, should have failed
 626                 Assert.fail("expected IllegalArgumentException " + "for DatatypeFactory.newXMLGregorianCalendar(" + invalidDates[valueIndex][0] + ", "
 627                         + invalidDates[valueIndex][1] + ", " + invalidDates[valueIndex][2] + ", " + invalidDates[valueIndex][3] + ", "
 628                         + invalidDates[valueIndex][4] + ", " + invalidDates[valueIndex][5] + ", " + invalidDates[valueIndex][6] + ", "
 629                         + invalidDates[valueIndex][7] + ").  " + "Instead, XMLGregorianCalendar: \"" + xmlGregorianCalendar.toString() + "\" was created.");
 630             } catch (IllegalArgumentException illegalArgumentException) {
 631                 // expected failure
 632                 if (DEBUG) {
 633                     System.err.println("Exception creating XMLGregorianCalendar: " + illegalArgumentException.toString());
 634                 }
 635             }
 636         }
 637     }
 638 }