1/*
2 * Copyright (c) 1999, 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 javax.xml.datatype.ptests;
25
26import static java.util.Calendar.HOUR;
27import static java.util.Calendar.MINUTE;
28import static java.util.Calendar.YEAR;
29import static org.testng.Assert.assertEquals;
30import static org.testng.Assert.assertTrue;
31
32import java.util.GregorianCalendar;
33import java.util.Locale;
34import java.util.TimeZone;
35
36import javax.xml.datatype.DatatypeConfigurationException;
37import javax.xml.datatype.DatatypeConstants;
38import javax.xml.datatype.DatatypeFactory;
39import javax.xml.datatype.Duration;
40import javax.xml.datatype.XMLGregorianCalendar;
41
42import org.testng.Assert;
43import org.testng.annotations.BeforeClass;
44import org.testng.annotations.DataProvider;
45import org.testng.annotations.Listeners;
46import org.testng.annotations.Test;
47
48/*
49 * @test
50 * @bug 5049592 5041845 5048932 5064587 5040542 5049531 5049528
51 * @library /javax/xml/jaxp/libs
52 * @run testng/othervm -DrunSecMngr=true javax.xml.datatype.ptests.XMLGregorianCalendarTest
53 * @run testng/othervm javax.xml.datatype.ptests.XMLGregorianCalendarTest
54 * @summary Class containing the test cases for XMLGregorianCalendar
55 */
56@Listeners({jaxp.library.BasePolicy.class})
57public class XMLGregorianCalendarTest {
58
59    private DatatypeFactory datatypeFactory;
60
61    @BeforeClass
62    public void setup() throws DatatypeConfigurationException {
63        datatypeFactory = DatatypeFactory.newInstance();
64    }
65
66    @DataProvider(name = "valid-milliseconds")
67    public Object[][] getValidMilliSeconds() {
68        return new Object[][] { { 0 }, { 1 }, { 2 }, { 16 }, { 1000 }   };
69    }
70
71    /*
72     * Test DatatypeFactory.newXMLGregorianCalendar(..) with milliseconds > 1.
73     *
74     * Bug # 5049592
75     *
76     */
77    @Test(dataProvider = "valid-milliseconds")
78    public void checkNewCalendar(int ms) {
79        // valid milliseconds
80        XMLGregorianCalendar calendar = datatypeFactory.newXMLGregorianCalendar(2004, // year
81                6, // month
82                2, // day
83                19, // hour
84                20, // minute
85                59, // second
86                ms, // milliseconds
87                840 // timezone
88                );
89        // expected success
90
91        assertEquals(calendar.getMillisecond(), ms);
92    }
93
94    /*
95     * Test DatatypeFactory.newXMLGregorianCalendarTime(..).
96     *
97     * Bug # 5049592
98     */
99    @Test(dataProvider = "valid-milliseconds")
100    public void checkNewTime(int ms) {
101        // valid milliseconds
102        XMLGregorianCalendar calendar2 = datatypeFactory.newXMLGregorianCalendarTime(19, // hour
103                20, // minute
104                59, // second
105                ms, // milliseconds
106                840 // timezone
107                );
108        // expected success
109
110        assertEquals(calendar2.getMillisecond(), ms);
111    }
112
113    @DataProvider(name = "invalid-milliseconds")
114    public Object[][] getInvalidMilliSeconds() {
115        return new Object[][] { { -1 }, { 1001 } };
116    }
117
118    /*
119     * Test DatatypeFactory.newXMLGregorianCalendar(..).
120     *
121     * Bug # 5049592 IllegalArgumentException is thrown if milliseconds < 0 or >
122     * 1001.
123     *
124     */
125    @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "invalid-milliseconds")
126    public void checkNewCalendarNeg(int milliseconds) {
127        // invalid milliseconds
128        datatypeFactory.newXMLGregorianCalendar(2004, // year
129                6, // month
130                2, // day
131                19, // hour
132                20, // minute
133                59, // second
134                milliseconds, // milliseconds
135                840 // timezone
136                );
137    }
138
139    /*
140     * Test DatatypeFactory.newXMLGregorianCalendarTime(..).
141     *
142     * Bug # 5049592 IllegalArgumentException is thrown if milliseconds < 0 or >
143     * 1001.
144     *
145     */
146    @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "invalid-milliseconds")
147    public void checkNewTimeNeg(int milliseconds) {
148        // invalid milliseconds
149        datatypeFactory.newXMLGregorianCalendarTime(19, // hour
150                20, // minute
151                59, // second
152                milliseconds, // milliseconds
153                840 // timezone
154                );
155    }
156
157    @DataProvider(name = "data-for-add")
158    public Object[][] getDataForAdd() {
159        return new Object[][] {
160                //calendar1, calendar2, duration
161                { "1999-12-31T00:00:00Z", "2000-01-01T00:00:00Z", "P1D" },
162                { "2000-12-31T00:00:00Z", "2001-01-01T00:00:00Z", "P1D" },
163                { "1998-12-31T00:00:00Z", "1999-01-01T00:00:00Z", "P1D" },
164                { "2001-12-31T00:00:00Z", "2002-01-01T00:00:00Z", "P1D" },
165                { "2003-04-11T00:00:00Z", "2003-04-12T00:00:00Z", "P1D" },
166                { "2003-04-11T00:00:00Z", "2003-04-14T00:00:00Z", "P3D" },
167                { "2003-04-30T00:00:00Z", "2003-05-01T00:00:00Z", "P1D" },
168                { "2003-02-28T00:00:00Z", "2003-03-01T00:00:00Z", "P1D" },
169                { "2000-02-29T00:00:00Z", "2000-03-01T00:00:00Z", "P1D" },
170                { "2000-02-28T00:00:00Z", "2000-02-29T00:00:00Z", "P1D" },
171                { "1998-01-11T00:00:00Z", "1998-04-11T00:00:00Z", "P90D" },
172                { "1999-05-11T00:00:00Z", "2002-05-11T00:00:00Z", "P1096D" }};
173    }
174
175    /*
176     * Test XMLGregorianCalendar.add(Duration).
177     *
178     */
179    @Test(dataProvider = "data-for-add")
180    public void checkAddDays(String cal1, String cal2, String dur) {
181
182        XMLGregorianCalendar calendar1 = datatypeFactory.newXMLGregorianCalendar(cal1);
183        XMLGregorianCalendar calendar2 = datatypeFactory.newXMLGregorianCalendar(cal2);
184
185        Duration duration = datatypeFactory.newDuration(dur);
186
187        XMLGregorianCalendar calendar1Clone = (XMLGregorianCalendar)calendar1.clone();
188
189        calendar1Clone.add(duration);
190        assertEquals(calendar1Clone, calendar2);
191
192        calendar2.add(duration.negate());
193        assertEquals(calendar2, calendar1);
194
195    }
196
197    @DataProvider(name = "gMonth")
198    public Object[][] getGMonth() {
199        return new Object[][] {
200                { "2000-02" },
201                { "2000-03" },
202                { "2018-02" }};
203    }
204    /*
205     * Test XMLGregorianCalendar#isValid(). for gMonth
206     *
207     * Bug # 5041845
208     *
209     */
210    @Test(dataProvider = "gMonth")
211    public void checkIsValid(String month) {
212
213        XMLGregorianCalendar gMonth = datatypeFactory.newXMLGregorianCalendar(month);
214        gMonth.setYear(null);
215        Assert.assertTrue(gMonth.isValid(), gMonth.toString() + " should isValid");
216
217    }
218
219    @DataProvider(name = "lexical01")
220    public Object[][] getLexicalRepresentForNormalize01() {
221        return new Object[][] { { "2000-01-16T12:00:00Z" }, { "2000-01-16T12:00:00" } };
222    }
223
224    /*
225     * Test XMLGregorianCalendar#normalize(...).
226     *
227     * Bug # 5048932 XMLGregorianCalendar.normalize works
228     *
229     */
230    @Test(dataProvider = "lexical01")
231    public void checkNormalize01(String lexical) {
232        XMLGregorianCalendar lhs = datatypeFactory.newXMLGregorianCalendar(lexical);
233        lhs.normalize();
234    }
235
236    @DataProvider(name = "lexical02")
237    public Object[][] getLexicalRepresentForNormalize02() {
238        return new Object[][] { { "2000-01-16T00:00:00.01Z" }, { "2000-01-16T00:00:00.01" }, { "13:20:00" } };
239    }
240
241    /*
242     * Test XMLGregorianCalendar#normalize(...).
243     *
244     * Bug # 5064587 XMLGregorianCalendar.normalize shall not change timezone
245     *
246     */
247    @Test(dataProvider = "lexical02")
248    public void checkNormalize02(String lexical) {
249        XMLGregorianCalendar orig = datatypeFactory.newXMLGregorianCalendar(lexical);
250        XMLGregorianCalendar normalized = datatypeFactory.newXMLGregorianCalendar(lexical).normalize();
251
252        assertEquals(normalized.getTimezone(), orig.getTimezone());
253        assertEquals(normalized.getMillisecond(), orig.getMillisecond());
254    }
255
256    /*
257     * Test XMLGregorianCalendar#toGregorianCalendar( TimeZone timezone, Locale
258     * aLocale, XMLGregorianCalendar defaults)
259     *
260     * Bug # 5040542 the defaults XMLGregorianCalendar parameter shall take
261     * effect
262     *
263     */
264    @Test
265    public void checkToGregorianCalendar01() {
266
267        XMLGregorianCalendar time_16_17_18 = datatypeFactory.newXMLGregorianCalendar("16:17:18");
268        XMLGregorianCalendar date_2001_02_03 = datatypeFactory.newXMLGregorianCalendar("2001-02-03");
269        GregorianCalendar calendar = date_2001_02_03.toGregorianCalendar(null, null, time_16_17_18);
270
271        int year = calendar.get(YEAR);
272        int minute = calendar.get(MINUTE);
273
274        assertTrue((year == 2001 && minute == 17), " expecting year == 2001, minute == 17" + ", result is year == " + year + ", minute == " + minute);
275
276
277        calendar = time_16_17_18.toGregorianCalendar(null, null, date_2001_02_03);
278
279        year = calendar.get(YEAR);
280        minute = calendar.get(MINUTE);
281
282        assertTrue((year == 2001 && minute == 17), " expecting year == 2001, minute == 17" + ", result is year == " + year + ", minute == " + minute);
283
284
285        date_2001_02_03.setMinute(3);
286        date_2001_02_03.setYear(null);
287
288        XMLGregorianCalendar date_time = datatypeFactory.newXMLGregorianCalendar("2003-04-11T02:13:01Z");
289
290        calendar = date_2001_02_03.toGregorianCalendar(null, null, date_time);
291
292        year = calendar.get(YEAR);
293        minute = calendar.get(MINUTE);
294        int hour = calendar.get(HOUR);
295
296        assertTrue((year == 2003 && hour == 2 && minute == 3), " expecting year == 2003, hour == 2, minute == 3" + ", result is year == " + year + ", hour == " + hour + ", minute == " + minute);
297
298
299    }
300
301    /*
302     * Test XMLGregorianCalendar#toGregorianCalendar( TimeZone timezone, Locale
303     * aLocale, XMLGregorianCalendar defaults) with the 'defaults' parameter
304     * being null.
305     *
306     * Bug # 5049531 XMLGregorianCalendar.toGregorianCalendar(..) can accept
307     * 'defaults' is null
308     *
309     */
310    @Test
311    public void checkToGregorianCalendar02() {
312
313        XMLGregorianCalendar calendar = datatypeFactory.newXMLGregorianCalendar("2004-05-19T12:00:00+06:00");
314        calendar.toGregorianCalendar(TimeZone.getDefault(), Locale.getDefault(), null);
315    }
316
317    @DataProvider(name = "calendar")
318    public Object[][] getXMLGregorianCalendarData() {
319        return new Object[][] {
320                // year, month, day, hour, minute, second
321                { 1970, 1, 1, 0, 0, 0 }, // DATETIME
322                { 1970, 1, 1, undef, undef, undef }, // DATE
323                { undef, undef, undef, 1, 0, 0 }, // TIME
324                { 1970, 1, undef, undef, undef, undef }, // GYEARMONTH
325                { undef, 1, 1, undef, undef, undef }, // GMONTHDAY
326                { 1970, undef, undef, undef, undef, undef }, // GYEAR
327                { undef, 1, undef, undef, undef, undef }, // GMONTH
328                { undef, undef, 1, undef, undef, undef } // GDAY
329        };
330    }
331
332    /*
333     * Test XMLGregorianCalendar#toString()
334     *
335     * Bug # 5049528
336     *
337     */
338    @Test(dataProvider = "calendar")
339    public void checkToStringPos(final int year, final int month, final int day, final int hour, final int minute, final int second) {
340        XMLGregorianCalendar calendar = datatypeFactory.newXMLGregorianCalendar(year, month, day, hour, minute, second, undef, undef);
341        calendar.toString();
342    }
343
344    /*
345     * Negative Test XMLGregorianCalendar#toString()
346     *
347     * Bug # 5049528 XMLGregorianCalendar.toString throws IllegalStateException
348     * if all parameters are undef
349     *
350     */
351    @Test(expectedExceptions = IllegalStateException.class)
352    public void checkToStringNeg() {
353        XMLGregorianCalendar calendar = datatypeFactory.newXMLGregorianCalendar(undef, undef, undef, undef, undef, undef, undef, undef);
354        // expected to fail
355        calendar.toString();
356    }
357
358    private final int undef = DatatypeConstants.FIELD_UNDEFINED;
359
360}
361