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
24package datatype;
25
26import java.math.BigDecimal;
27import java.math.BigInteger;
28
29import javax.xml.datatype.DatatypeConfigurationException;
30import javax.xml.datatype.DatatypeConstants;
31import javax.xml.datatype.DatatypeFactory;
32import javax.xml.datatype.Duration;
33import javax.xml.datatype.XMLGregorianCalendar;
34import javax.xml.namespace.QName;
35
36import org.testng.Assert;
37import org.testng.annotations.Listeners;
38import 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})
48public 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}
643