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