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 javax.xml.datatype.DatatypeConstants.DAYS;
  27 import static javax.xml.datatype.DatatypeConstants.HOURS;
  28 import static javax.xml.datatype.DatatypeConstants.MINUTES;
  29 import static javax.xml.datatype.DatatypeConstants.MONTHS;
  30 import static javax.xml.datatype.DatatypeConstants.SECONDS;
  31 import static javax.xml.datatype.DatatypeConstants.YEARS;
  32 import static org.testng.Assert.assertEquals;
  33 import static org.testng.Assert.assertFalse;
  34 import static org.testng.Assert.assertTrue;
  35 
  36 import java.math.BigDecimal;
  37 import java.math.BigInteger;
  38 import java.util.Calendar;
  39 import java.util.function.Function;
  40 
  41 import javax.xml.datatype.DatatypeConfigurationException;
  42 import javax.xml.datatype.DatatypeConstants;
  43 import javax.xml.datatype.DatatypeFactory;
  44 import javax.xml.datatype.Duration;
  45 import javax.xml.namespace.QName;
  46 
  47 import org.testng.Assert;
  48 import org.testng.annotations.BeforeClass;
  49 import org.testng.annotations.DataProvider;
  50 import org.testng.annotations.Listeners;
  51 import org.testng.annotations.Test;
  52 
  53 /*
  54  * @summary Class containing the test cases for Duration.
  55  */
  56 @Listeners({jaxp.library.BasePolicy.class})
  57 public class DurationTest {
  58 
  59     private DatatypeFactory datatypeFactory;
  60 
  61     /*
  62      * Setup.
  63      */
  64     @BeforeClass
  65     public void setup() throws DatatypeConfigurationException {
  66         datatypeFactory = DatatypeFactory.newInstance();
  67     }
  68 
  69     @DataProvider(name = "legal-number-duration")
  70     public Object[][] getLegalNumberDuration() {
  71         return new Object[][] {
  72                 // is positive, year, month, day, hour, minute, second
  73                 { true, 1, 1, 1, 1, 1, 1 },
  74                 { false, 1, 1, 1, 1, 1, 1 },
  75                 { true, 1, 0, 0, 0, 0, 0 },
  76                 { false, 1, 0, 0, 0, 0, 0 }
  77         };
  78     }
  79 
  80     /*
  81      * Test for constructor Duration(boolean isPositive,int years,int months,
  82      * int days,int hours,int minutes,int seconds).
  83      */
  84     @Test(dataProvider = "legal-number-duration")
  85     public void checkNumberDurationPos(boolean isPositive, int years, int months, int days, int hours, int minutes, int seconds) {
  86         datatypeFactory.newDuration(isPositive, years, months, days, hours, minutes, seconds);
  87     }
  88 
  89     @DataProvider(name = "illegal-number-duration")
  90     public Object[][] getIllegalNumberDuration() {
  91         return new Object[][] {
  92                 // is positive, year, month, day, hour, minute, second
  93                 { true, 1, 1, -1, 1, 1, 1 },
  94                 { false, 1, 1, -1, 1, 1, 1 },
  95                 { true, undef, undef, undef, undef, undef, undef },
  96                 { false, undef, undef, undef, undef, undef, undef }
  97         };
  98     }
  99 
 100     /*
 101      * Test for constructor Duration(boolean isPositive,int years,int months,
 102      * int days,int hours,int minutes,int seconds), if any of the fields is
 103      * negative should throw IllegalArgumentException.
 104      */
 105     @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "illegal-number-duration")
 106     public void checkDurationNumberNeg(boolean isPositive, int years, int months, int days, int hours, int minutes, int seconds) {
 107         datatypeFactory.newDuration(isPositive, years, months, days, hours, minutes, seconds);
 108     }
 109 
 110     @DataProvider(name = "legal-bigint-duration")
 111     public Object[][] getLegalBigIntegerDuration() {
 112         return new Object[][] {
 113                 // is positive, year, month, day, hour, minute, second
 114                 { true, zero, zero, zero, zero, zero, new BigDecimal(zero) },
 115                 { false, zero, zero, zero, zero, zero, new BigDecimal(zero) },
 116                 { true, one, one, one, one, one, new BigDecimal(one) },
 117                 { false, one, one, one, one, one, new BigDecimal(one) },
 118                 { true, null, null, null, null, null, new BigDecimal(one) },
 119                 { false, null, null, null, null, null, new BigDecimal(one) } };
 120     }
 121 
 122     /*
 123      * Test for constructor Duration(boolean isPositive,BigInteger
 124      * years,BigInteger months, BigInteger days,BigInteger hours,BigInteger
 125      * minutes,BigDecimal seconds).
 126      */
 127     @Test(dataProvider = "legal-bigint-duration")
 128     public void checkBigIntegerDurationPos(boolean isPositive, BigInteger years, BigInteger months, BigInteger days, BigInteger hours, BigInteger minutes,
 129             BigDecimal seconds) {
 130         datatypeFactory.newDuration(isPositive, years, months, days, hours, minutes, seconds);
 131     }
 132 
 133     @DataProvider(name = "illegal-bigint-duration")
 134     public Object[][] getIllegalBigIntegerDuration() {
 135         return new Object[][] {
 136                 // is positive, year, month, day, hour, minute, second
 137                 { true, null, null, null, null, null, null },
 138                 { false, null, null, null, null, null, null }
 139         };
 140     }
 141 
 142     /*
 143      * Test for constructor Duration(boolean isPositive,BigInteger
 144      * years,BigInteger months, BigInteger days,BigInteger hours,BigInteger
 145      * minutes,BigDecimal seconds), if all the fields are null should throw
 146      * IllegalArgumentException.
 147      */
 148     @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "illegal-bigint-duration")
 149     public void checkBigIntegerDurationNeg(boolean isPositive, BigInteger years, BigInteger months, BigInteger days, BigInteger hours, BigInteger minutes,
 150             BigDecimal seconds) {
 151         datatypeFactory.newDuration(isPositive, years, months, days, hours, minutes, seconds);
 152     }
 153 
 154     @DataProvider(name = "legal-millisec-duration")
 155     public Object[][] getLegalMilliSecondDuration() {
 156         return new Object[][] { { 1000000 }, { 0 }, { Long.MAX_VALUE }, { Long.MIN_VALUE }
 157 
 158         };
 159     }
 160 
 161     /*
 162      * Test for constructor Duration(long durationInMilliSeconds)
 163      */
 164     @Test(dataProvider = "legal-millisec-duration")
 165     public void checkMilliSecondDuration(long millisec) {
 166         datatypeFactory.newDuration(millisec);
 167     }
 168 
 169     @DataProvider(name = "legal-lexical-duration")
 170     public Object[][] getLegalLexicalDuration() {
 171         return new Object[][] { { "P1Y1M1DT1H1M1S" }, { "-P1Y1M1DT1H1M1S" } };
 172     }
 173 
 174     /*
 175      * Test for constructor Duration(java.lang.String lexicalRepresentation)
 176      */
 177     @Test(dataProvider = "legal-lexical-duration")
 178     public void checkLexicalDurationPos(String lexRepresentation) {
 179         datatypeFactory.newDuration(lexRepresentation);
 180     }
 181 
 182     @DataProvider(name = "illegal-lexical-duration")
 183     public Object[][] getIllegalLexicalDuration() {
 184         return new Object[][] {
 185                 { null },
 186                 { "P1Y1M1DT1H1M1S " },
 187                 { " P1Y1M1DT1H1M1S" },
 188                 { "X1Y1M1DT1H1M1S" },
 189                 { "" },
 190                 { "P1Y2MT" } // The designator 'T' shall be absent if all of the time items are absent in "PnYnMnDTnHnMnS"
 191         };
 192     }
 193 
 194     /*
 195      * Test for constructor Duration(java.lang.String lexicalRepresentation),
 196      * null should throw NullPointerException, invalid lex should throw
 197      * IllegalArgumentException
 198      */
 199     @Test(expectedExceptions = { NullPointerException.class, IllegalArgumentException.class }, dataProvider = "illegal-lexical-duration")
 200     public void checkLexicalDurationNeg(String lexRepresentation) {
 201         datatypeFactory.newDuration(lexRepresentation);
 202     }
 203 
 204     @DataProvider(name = "equal-duration")
 205     public Object[][] getEqualDurations() {
 206         return new Object[][] { { "P1Y1M1DT1H1M1S", "P1Y1M1DT1H1M1S" } };
 207     }
 208 
 209     /*
 210      * Test for compare() both durations valid and equal.
 211      */
 212     @Test(dataProvider = "equal-duration")
 213     public void checkDurationEqual(String lexRepresentation1, String lexRepresentation2) {
 214         Duration duration1 = datatypeFactory.newDuration(lexRepresentation1);
 215         Duration duration2 = datatypeFactory.newDuration(lexRepresentation2);
 216         assertTrue(duration1.equals(duration2));
 217     }
 218 
 219     @DataProvider(name = "greater-duration")
 220     public Object[][] getGreaterDuration() {
 221         return new Object[][] {
 222                 { "P1Y1M1DT1H1M2S", "P1Y1M1DT1H1M1S" },
 223                 { "P1Y1M1DT1H1M1S", "-P1Y1M1DT1H1M2S" },
 224                 { "P1Y1M1DT1H1M2S", "-P1Y1M1DT1H1M1S" },
 225                 { "-P1Y1M1DT1H1M1S", "-P1Y1M1DT1H1M2S" }, };
 226     }
 227 
 228     /*
 229      * Test for compare() both durations valid and lhs > rhs.
 230      */
 231     @Test(dataProvider = "greater-duration")
 232     public void checkDurationCompare(String lexRepresentation1, String lexRepresentation2) {
 233         Duration duration1 = datatypeFactory.newDuration(lexRepresentation1);
 234         Duration duration2 = datatypeFactory.newDuration(lexRepresentation2);
 235         assertTrue(duration1.compare(duration2) == DatatypeConstants.GREATER);
 236     }
 237 
 238     @DataProvider(name = "not-equal-duration")
 239     public Object[][] getNotEqualDurations() {
 240         return new Object[][] {
 241                 { "P1Y1M1DT1H1M1S", "-P1Y1M1DT1H1M1S" },
 242                 { "P2Y1M1DT1H1M1S", "P1Y1M1DT1H1M1S" } };
 243     }
 244 
 245     /*
 246      * Test for equals() both durations valid and lhs not equals rhs.
 247      */
 248     @Test(dataProvider = "not-equal-duration")
 249     public void checkDurationNotEqual(String lexRepresentation1, String lexRepresentation2) {
 250         Duration duration1 = datatypeFactory.newDuration(lexRepresentation1);
 251         Duration duration2 = datatypeFactory.newDuration(lexRepresentation2);
 252         Assert.assertNotEquals(duration1, duration2);
 253     }
 254 
 255     @DataProvider(name = "duration-sign")
 256     public Object[][] getDurationAndSign() {
 257         return new Object[][] {
 258                 { "P0Y0M0DT0H0M0S", 0 },
 259                 { "P1Y0M0DT0H0M0S", 1 },
 260                 { "-P1Y0M0DT0H0M0S", -1 } };
 261     }
 262 
 263     /*
 264      * Test for Duration.getSign().
 265      */
 266     @Test(dataProvider = "duration-sign")
 267     public void checkDurationSign(String lexRepresentation, int sign) {
 268         Duration duration = datatypeFactory.newDuration(lexRepresentation);
 269         assertEquals(duration.getSign(), sign);
 270     }
 271 
 272     /*
 273      * Test for Duration.negate().
 274      */
 275     @Test
 276     public void checkDurationNegate() {
 277         Duration durationPos = datatypeFactory.newDuration("P1Y0M0DT0H0M0S");
 278         Duration durationNeg = datatypeFactory.newDuration("-P1Y0M0DT0H0M0S");
 279 
 280         assertEquals(durationPos.negate(), durationNeg);
 281         assertEquals(durationNeg.negate(), durationPos);
 282         assertEquals(durationPos.negate().negate(), durationPos);
 283 
 284     }
 285 
 286     /*
 287      * Test for Duration.isShorterThan(Duration) and
 288      * Duration.isLongerThan(Duration).
 289      */
 290     @Test
 291     public void checkDurationShorterLonger() {
 292         Duration shorter = datatypeFactory.newDuration("P1Y1M1DT1H1M1S");
 293         Duration longer = datatypeFactory.newDuration("P2Y1M1DT1H1M1S");
 294 
 295         assertTrue(shorter.isShorterThan(longer));
 296         assertFalse(longer.isShorterThan(shorter));
 297         assertFalse(shorter.isShorterThan(shorter));
 298 
 299         assertTrue(longer.isLongerThan(shorter));
 300         assertFalse(shorter.isLongerThan(longer));
 301         assertFalse(shorter.isLongerThan(shorter));
 302     }
 303 
 304     /*
 305      * Test for Duration.isSet().
 306      */
 307     @Test
 308     public void checkDurationIsSet() {
 309         Duration duration1 = datatypeFactory.newDuration(true, 1, 1, 1, 1, 1, 1);
 310         Duration duration2 = datatypeFactory.newDuration(true, 0, 0, 0, 0, 0, 0);
 311 
 312         assertTrue(duration1.isSet(YEARS));
 313         assertTrue(duration1.isSet(MONTHS));
 314         assertTrue(duration1.isSet(DAYS));
 315         assertTrue(duration1.isSet(HOURS));
 316         assertTrue(duration1.isSet(MINUTES));
 317         assertTrue(duration1.isSet(SECONDS));
 318 
 319         assertTrue(duration2.isSet(YEARS));
 320         assertTrue(duration2.isSet(MONTHS));
 321         assertTrue(duration2.isSet(DAYS));
 322         assertTrue(duration2.isSet(HOURS));
 323         assertTrue(duration2.isSet(MINUTES));
 324         assertTrue(duration2.isSet(SECONDS));
 325 
 326         Duration duration66 = datatypeFactory.newDuration(true, null, null, zero, null, null, null);
 327         assertFalse(duration66.isSet(YEARS));
 328         assertFalse(duration66.isSet(MONTHS));
 329         assertFalse(duration66.isSet(HOURS));
 330         assertFalse(duration66.isSet(MINUTES));
 331         assertFalse(duration66.isSet(SECONDS));
 332 
 333         Duration duration3 = datatypeFactory.newDuration("P1D");
 334         assertFalse(duration3.isSet(YEARS));
 335         assertFalse(duration3.isSet(MONTHS));
 336         assertFalse(duration3.isSet(HOURS));
 337         assertFalse(duration3.isSet(MINUTES));
 338         assertFalse(duration3.isSet(SECONDS));
 339     }
 340 
 341     /*
 342      * Test Duration.isSet(Field) throws NPE if the field parameter is null.
 343      */
 344     @Test(expectedExceptions = NullPointerException.class)
 345     public void checkDurationIsSetNeg() {
 346         Duration duration = datatypeFactory.newDuration(true, 0, 0, 0, 0, 0, 0);
 347         duration.isSet(null);
 348     }
 349 
 350     /*
 351      * Test for -getField(DatatypeConstants.Field) DatatypeConstants.Field is
 352      * null - throws NPE.
 353      */
 354     @Test(expectedExceptions = NullPointerException.class)
 355     public void checkDurationGetFieldNeg() {
 356         Duration duration67 = datatypeFactory.newDuration("P1Y1M1DT1H1M1S");
 357         duration67.getField(null);
 358     }
 359 
 360     @DataProvider(name = "duration-fields")
 361     public Object[][] getDurationAndFields() {
 362         return new Object[][] {
 363                 { "P1Y1M1DT1H1M1S", one, one, one, one, one, new BigDecimal(one) },
 364                 { "PT1M", null, null, null, null, one, null },
 365                 { "P1M", null, one, null, null, null, null } };
 366     }
 367 
 368     /*
 369      * Test for Duration.getField(DatatypeConstants.Field).
 370      */
 371     @Test(dataProvider = "duration-fields")
 372     public void checkDurationGetField(String lexRepresentation, BigInteger years, BigInteger months, BigInteger days, BigInteger hours, BigInteger minutes,
 373             BigDecimal seconds) {
 374         Duration duration = datatypeFactory.newDuration(lexRepresentation);
 375 
 376         assertEquals(duration.getField(YEARS), years);
 377         assertEquals(duration.getField(MONTHS), months);
 378         assertEquals(duration.getField(DAYS), days);
 379         assertEquals(duration.getField(HOURS), hours);
 380         assertEquals(duration.getField(MINUTES), minutes);
 381         assertEquals(duration.getField(SECONDS), seconds);
 382     }
 383 
 384     @DataProvider(name = "number-string")
 385     public Object[][] getNumberAndString() {
 386         return new Object[][] {
 387                 // is positive, year, month, day, hour, minute, second, lexical
 388                 { true, 1, 1, 1, 1, 1, 1, "P1Y1M1DT1H1M1S" },
 389                 { false, 1, 1, 1, 1, 1, 1, "-P1Y1M1DT1H1M1S" },
 390                 { true, 0, 0, 0, 0, 0, 0, "P0Y0M0DT0H0M0S" },
 391                 { false, 0, 0, 0, 0, 0, 0, "P0Y0M0DT0H0M0S" }
 392         };
 393     }
 394 
 395     /*
 396      * Test for - toString().
 397      */
 398     @Test(dataProvider = "number-string")
 399     public void checkDurationToString(boolean isPositive, int years, int months, int days, int hours, int minutes, int seconds, String lexical) {
 400         Duration duration = datatypeFactory.newDuration(isPositive,  years,  months,  days,  hours,  minutes,  seconds);
 401         assertEquals(duration.toString(), lexical);
 402 
 403         assertEquals(datatypeFactory.newDuration(duration.toString()), duration);
 404     }
 405 
 406     @DataProvider(name = "duration-field")
 407     public Object[][] getDurationAndField() {
 408         Function<Duration, Integer> getyears = duration -> duration.getYears();
 409         Function<Duration, Integer> getmonths = duration -> duration.getMonths();
 410         Function<Duration, Integer> getdays = duration -> duration.getDays();
 411         Function<Duration, Integer> gethours = duration -> duration.getHours();
 412         Function<Duration, Integer> getminutes = duration -> duration.getMinutes();
 413         Function<Duration, Integer> getseconds = duration -> duration.getSeconds();
 414         return new Object[][] {
 415                 { "P1Y1M1DT1H1M1S", getyears, 1 },
 416                 { "P1M1DT1H1M1S", getyears, 0 },
 417                 { "P1Y1M1DT1H1M1S", getmonths, 1 },
 418                 { "P1Y1DT1H1M1S", getmonths, 0 },
 419                 { "P1Y1M1DT1H1M1S", getdays, 1 },
 420                 { "P1Y1MT1H1M1S", getdays, 0 },
 421                 { "P1Y1M1DT1H1M1S", gethours, 1 },
 422                 { "P1Y1M1DT1M1S", gethours, 0 },
 423                 { "P1Y1M1DT1H1M1S", getminutes, 1 },
 424                 { "P1Y1M1DT1H1S", getminutes, 0 },
 425                 { "P1Y1M1DT1H1M1S", getseconds, 1 },
 426                 { "P1Y1M1DT1H1M", getseconds, 0 },
 427                 { "P1Y1M1DT1H1M100000000S", getseconds, 100000000 }, };
 428     }
 429 
 430     /*
 431      * Test for Duration.getYears(), getMonths(), etc.
 432      */
 433     @Test(dataProvider = "duration-field")
 434     public void checkDurationGetOneField(String lexRepresentation, Function<Duration, Integer> getter, int value) {
 435         Duration duration = datatypeFactory.newDuration(lexRepresentation);
 436         assertEquals(getter.apply(duration).intValue(), value);
 437     }
 438 
 439     /*
 440      * Test for - getField(SECONDS)
 441      */
 442     @Test
 443     public void checkDurationGetSecondsField() {
 444         Duration duration85 = datatypeFactory.newDuration("P1Y1M1DT1H1M100000000S");
 445         assertEquals((duration85.getField(SECONDS)).intValue(), 100000000);
 446     }
 447 
 448     /*
 449      * getTimeInMillis(java.util.Calendar startInstant) returns milliseconds
 450      * between startInstant and startInstant plus this Duration.
 451      */
 452     @Test
 453     public void checkDurationGetTimeInMillis() {
 454         Duration duration86 = datatypeFactory.newDuration("PT1M1S");
 455         Calendar calendar86 = Calendar.getInstance();
 456         assertEquals(duration86.getTimeInMillis(calendar86), 61000);
 457     }
 458 
 459     /*
 460      * getTimeInMillis(java.util.Calendar startInstant) returns milliseconds
 461      * between startInstant and startInstant plus this Duration throws NPE if
 462      * startInstant parameter is null.
 463      */
 464     @Test(expectedExceptions = NullPointerException.class)
 465     public void checkDurationGetTimeInMillisNeg() {
 466         Duration duration87 = datatypeFactory.newDuration("PT1M1S");
 467         Calendar calendar87 = null;
 468         duration87.getTimeInMillis(calendar87);
 469     }
 470 
 471     @DataProvider(name = "duration-for-hash")
 472     public Object[][] getDurationsForHash() {
 473         return new Object[][] {
 474                 { "P1Y1M1DT1H1M1S", "P1Y1M1DT1H1M1S" },
 475                 { "P1D", "PT24H" },
 476                 { "PT1H", "PT60M" },
 477                 { "PT1M", "PT60S" },
 478                 { "P1Y", "P12M" } };
 479     }
 480 
 481     /*
 482      * Test for Duration.hashcode(). hashcode() should return same value for
 483      * some equal durations.
 484      */
 485     @Test(dataProvider = "duration-for-hash")
 486     public void checkDurationHashCode(String lexRepresentation1, String lexRepresentation2) {
 487         Duration duration1 = datatypeFactory.newDuration(lexRepresentation1);
 488         Duration duration2 = datatypeFactory.newDuration(lexRepresentation2);
 489         int hash1 = duration1.hashCode();
 490         int hash2 = duration2.hashCode();
 491         assertTrue(hash1 == hash2, " generated hash1 : " + hash1 + " generated hash2 : " + hash2);
 492     }
 493 
 494     @DataProvider(name = "duration-for-add")
 495     public Object[][] getDurationsForAdd() {
 496         return new Object[][] {
 497                 // initVal, addVal, resultVal
 498                 { "P1Y1M1DT1H1M1S", "P1Y1M1DT1H1M1S", "P2Y2M2DT2H2M2S" },
 499                 { "P1Y1M1DT1H1M1S", "-P1Y1M1DT1H1M1S", "P0Y0M0DT0H0M0S" },
 500                 { "-P1Y1M1DT1H1M1S", "-P1Y1M1DT1H1M1S", "-P2Y2M2DT2H2M2S" }, };
 501     }
 502 
 503     /*
 504      * Test for add(Duration rhs).
 505      */
 506     @Test(dataProvider = "duration-for-add")
 507     public void checkDurationAdd(String initVal, String addVal, String result) {
 508         Duration durationInit = datatypeFactory.newDuration(initVal);
 509         Duration durationAdd = datatypeFactory.newDuration(addVal);
 510         Duration durationResult = datatypeFactory.newDuration(result);
 511 
 512         assertEquals(durationInit.add(durationAdd), durationResult);
 513     }
 514 
 515     @DataProvider(name = "duration-for-addneg")
 516     public Object[][] getDurationsForAddNeg() {
 517         return new Object[][] {
 518                 // initVal, addVal
 519                 { "P1Y1M1DT1H1M1S", null },
 520                 { "P1Y", "-P1D" },
 521                 { "-P1Y", "P1D" }, };
 522     }
 523 
 524     /*
 525      * Test for add(Duration rhs) 'rhs' is null , should throw NPE. "1 year" +
 526      * "-1 day" or "-1 year" + "1 day" should throw IllegalStateException
 527      */
 528     @Test(expectedExceptions = { NullPointerException.class, IllegalStateException.class }, dataProvider = "duration-for-addneg")
 529     public void checkDurationAddNeg(String initVal, String addVal) {
 530         Duration durationInit = datatypeFactory.newDuration(initVal);
 531         Duration durationAdd = addVal == null ? null : datatypeFactory.newDuration(addVal);
 532 
 533         durationInit.add(durationAdd);
 534     }
 535 
 536     /*
 537      * Test Duration#compare(Duration duration) with large durations.
 538      *
 539      * Bug # 4972785 UnsupportedOperationException is expected
 540      *
 541      */
 542     @Test(expectedExceptions = UnsupportedOperationException.class)
 543     public void checkDurationCompareLarge() {
 544         String duration1Lex = "P100000000000000000000D";
 545         String duration2Lex = "PT2400000000000000000000H";
 546 
 547         Duration duration1 = datatypeFactory.newDuration(duration1Lex);
 548         Duration duration2 = datatypeFactory.newDuration(duration2Lex);
 549         duration1.compare(duration2);
 550 
 551     }
 552 
 553     /*
 554      * Test Duration#getXMLSchemaType().
 555      *
 556      * Bug # 5049544 Duration.getXMLSchemaType shall return the correct result
 557      *
 558      */
 559     @Test
 560     public void checkDurationGetXMLSchemaType() {
 561         // DURATION
 562         Duration duration = datatypeFactory.newDuration("P1Y1M1DT1H1M1S");
 563         QName duration_xmlSchemaType = duration.getXMLSchemaType();
 564         assertEquals(duration_xmlSchemaType, DatatypeConstants.DURATION, "Expected DatatypeConstants.DURATION, returned " + duration_xmlSchemaType.toString());
 565 
 566         // DURATION_DAYTIME
 567         Duration duration_dayTime = datatypeFactory.newDuration("P1DT1H1M1S");
 568         QName duration_dayTime_xmlSchemaType = duration_dayTime.getXMLSchemaType();
 569         assertEquals(duration_dayTime_xmlSchemaType, DatatypeConstants.DURATION_DAYTIME, "Expected DatatypeConstants.DURATION_DAYTIME, returned "
 570                 + duration_dayTime_xmlSchemaType.toString());
 571 
 572         // DURATION_YEARMONTH
 573         Duration duration_yearMonth = datatypeFactory.newDuration("P1Y1M");
 574         QName duration_yearMonth_xmlSchemaType = duration_yearMonth.getXMLSchemaType();
 575         assertEquals(duration_yearMonth_xmlSchemaType, DatatypeConstants.DURATION_YEARMONTH, "Expected DatatypeConstants.DURATION_YEARMONTH, returned "
 576                 + duration_yearMonth_xmlSchemaType.toString());
 577 
 578     }
 579 
 580 
 581     private final int undef = DatatypeConstants.FIELD_UNDEFINED;
 582     private final BigInteger zero = BigInteger.ZERO;
 583     private final BigInteger one = BigInteger.ONE;
 584 
 585 }