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