| /* |
| * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package datatype; |
| |
| import java.math.BigDecimal; |
| import java.math.BigInteger; |
| import java.util.Calendar; |
| import java.util.Date; |
| import java.util.GregorianCalendar; |
| import java.util.TimeZone; |
| |
| import javax.xml.datatype.DatatypeConfigurationException; |
| import javax.xml.datatype.DatatypeConstants; |
| import javax.xml.datatype.DatatypeFactory; |
| import javax.xml.datatype.Duration; |
| import javax.xml.namespace.QName; |
| |
| import org.testng.Assert; |
| import org.testng.AssertJUnit; |
| import org.testng.annotations.BeforeMethod; |
| import org.testng.annotations.Listeners; |
| import org.testng.annotations.Test; |
| |
| /* |
| * @test |
| * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest |
| * @run testng/othervm -DrunSecMngr=true datatype.DurationTest |
| * @run testng/othervm datatype.DurationTest |
| * @summary Test Duration. |
| */ |
| @Listeners({jaxp.library.BasePolicy.class}) |
| public class DurationTest { |
| |
| private final static boolean DEBUG = true; |
| |
| protected Duration duration = null; |
| |
| @BeforeMethod |
| public void setUp() { |
| try { |
| duration = DatatypeFactory.newInstance().newDuration(100); |
| } catch (DatatypeConfigurationException dce) { |
| dce.printStackTrace(); |
| Assert.fail("Failed to create instance of DatatypeFactory " + dce.getMessage()); |
| } |
| } |
| |
| @Test |
| public void testDurationSubtract() { |
| try { |
| Duration bigDur = DatatypeFactory.newInstance().newDuration(20000); |
| Duration smallDur = DatatypeFactory.newInstance().newDuration(10000); |
| if (smallDur.subtract(bigDur).getSign() != -1) { |
| Assert.fail("smallDur.subtract(bigDur).getSign() is not -1"); |
| } |
| if (bigDur.subtract(smallDur).getSign() != 1) { |
| Assert.fail("bigDur.subtract(smallDur).getSign() is not 1"); |
| } |
| if (smallDur.subtract(smallDur).getSign() != 0) { |
| Assert.fail("smallDur.subtract(smallDur).getSign() is not 0"); |
| } |
| } catch (DatatypeConfigurationException e) { |
| e.printStackTrace(); |
| } |
| } |
| |
| @Test |
| public void testDurationMultiply() { |
| int num = 5000; // millisends. 5 seconds |
| int factor = 2; |
| try { |
| Duration dur = DatatypeFactory.newInstance().newDuration(num); |
| if (dur.multiply(factor).getSeconds() != 10) { |
| Assert.fail("duration.multiply() return wrong value"); |
| } |
| // factor is 2*10^(-1) |
| if (dur.multiply(new BigDecimal(new BigInteger("2"), 1)).getSeconds() != 1) { |
| Assert.fail("duration.multiply() return wrong value"); |
| } |
| if (dur.subtract(DatatypeFactory.newInstance().newDuration(1000)).multiply(new BigDecimal(new BigInteger("2"), 1)).getSeconds() != 0) { |
| Assert.fail("duration.multiply() return wrong value"); |
| } |
| } catch (DatatypeConfigurationException e) { |
| e.printStackTrace(); |
| } |
| } |
| |
| @Test |
| public void testDurationAndCalendar1() { |
| int year = 1; |
| int month = 2; |
| int day = 3; |
| int hour = 4; |
| int min = 5; |
| int sec = 6; |
| String lexicalRepresentation = "P" + year + "Y" + month + "M" + day + "DT" + hour + "H" + min + "M" + sec + "S"; |
| try { |
| Duration dur = DatatypeFactory.newInstance().newDuration(lexicalRepresentation); |
| System.out.println(dur.toString()); |
| AssertJUnit.assertTrue("year should be 1", dur.getYears() == year); |
| AssertJUnit.assertTrue("month should be 2", dur.getMonths() == month); |
| AssertJUnit.assertTrue("day should be 3", dur.getDays() == day); |
| AssertJUnit.assertTrue("hour should be 4", dur.getHours() == hour); |
| AssertJUnit.assertTrue("minute should be 5", dur.getMinutes() == min); |
| AssertJUnit.assertTrue("second should be 6", dur.getSeconds() == sec); |
| } catch (DatatypeConfigurationException e) { |
| e.printStackTrace(); |
| } |
| } |
| |
| @Test |
| public void testDurationAndCalendar2() { |
| try { |
| AssertJUnit.assertTrue("10.00099S means 10 sec since it will be rounded to zero", DatatypeFactory.newInstance().newDuration("PT10.00099S") |
| .getTimeInMillis(new Date()) == 10000); |
| AssertJUnit.assertTrue("10.00099S means 10 sec since it will be rounded to zero", DatatypeFactory.newInstance().newDuration("-PT10.00099S") |
| .getTimeInMillis(new Date()) == -10000); |
| AssertJUnit.assertTrue("10.00099S means 10 sec since it will be rounded to zero", DatatypeFactory.newInstance().newDuration("PT10.00099S") |
| .getTimeInMillis(new GregorianCalendar()) == 10000); |
| AssertJUnit.assertTrue("10.00099S means 10 sec since it will be rounded to zero", DatatypeFactory.newInstance().newDuration("-PT10.00099S") |
| .getTimeInMillis(new GregorianCalendar()) == -10000); |
| } catch (DatatypeConfigurationException e) { |
| e.printStackTrace(); |
| } |
| } |
| |
| @Test |
| public void testDurationAndCalendar3() { |
| try { |
| Calendar cal = new GregorianCalendar(); |
| cal.set(Calendar.SECOND, 59); |
| DatatypeFactory.newInstance().newDuration(10000).addTo(cal); |
| AssertJUnit.assertTrue("sec will be 9", cal.get(Calendar.SECOND) == 9); |
| |
| Date date = new Date(); |
| date.setSeconds(59); |
| DatatypeFactory.newInstance().newDuration(10000).addTo(date); |
| AssertJUnit.assertTrue("sec will be 9", date.getSeconds() == 9); |
| } catch (DatatypeConfigurationException e) { |
| e.printStackTrace(); |
| } |
| } |
| |
| @Test |
| public void testEqualsWithDifferentObjectParam() { |
| |
| AssertJUnit.assertFalse("equals method should return false for any object other than Duration", duration.equals(new Integer(0))); |
| } |
| |
| @Test |
| public void testEqualsWithNullObjectParam() { |
| |
| AssertJUnit.assertFalse("equals method should return false for null parameter", duration.equals(null)); |
| } |
| |
| @Test |
| public void testEqualsWithEqualObjectParam() { |
| try { |
| AssertJUnit.assertTrue("equals method is expected to return true", duration.equals(DatatypeFactory.newInstance().newDuration(100))); |
| } catch (DatatypeConfigurationException dce) { |
| dce.printStackTrace(); |
| Assert.fail("Failed to create instance of DatatypeFactory " + dce.getMessage()); |
| } |
| } |
| |
| /** |
| * Inspired by CR 5077522 Duration.compare makes mistakes for some values. |
| */ |
| @Test |
| public void testCompareWithInderterminateRelation() { |
| |
| final String[][] partialOrder = { // partialOrder |
| { "P1Y", "<>", "P365D" }, { "P1Y", "<>", "P366D" }, { "P1M", "<>", "P28D" }, { "P1M", "<>", "P29D" }, { "P1M", "<>", "P30D" }, { "P1M", "<>", "P31D" }, |
| { "P5M", "<>", "P150D" }, { "P5M", "<>", "P151D" }, { "P5M", "<>", "P152D" }, { "P5M", "<>", "P153D" }, { "PT2419200S", "<>", "P1M" }, |
| { "PT2678400S", "<>", "P1M" }, { "PT31536000S", "<>", "P1Y" }, { "PT31622400S", "<>", "P1Y" }, { "PT525600M", "<>", "P1Y" }, |
| { "PT527040M", "<>", "P1Y" }, { "PT8760H", "<>", "P1Y" }, { "PT8784H", "<>", "P1Y" }, { "P365D", "<>", "P1Y" }, }; |
| |
| DatatypeFactory df = null; |
| try { |
| df = DatatypeFactory.newInstance(); |
| } catch (DatatypeConfigurationException ex) { |
| ex.printStackTrace(); |
| Assert.fail(ex.toString()); |
| } |
| |
| boolean compareErrors = false; |
| |
| for (int valueIndex = 0; valueIndex < partialOrder.length; ++valueIndex) { |
| Duration duration1 = df.newDuration(partialOrder[valueIndex][0]); |
| Duration duration2 = df.newDuration(partialOrder[valueIndex][2]); |
| int cmp = duration1.compare(duration2); |
| int expected = ">".equals(partialOrder[valueIndex][1]) ? DatatypeConstants.GREATER |
| : "<".equals(partialOrder[valueIndex][1]) ? DatatypeConstants.LESSER : "==".equals(partialOrder[valueIndex][1]) ? DatatypeConstants.EQUAL |
| : DatatypeConstants.INDETERMINATE; |
| |
| // just note any errors, do not fail until all cases have been |
| // tested |
| if (expected != cmp) { |
| compareErrors = true; |
| System.err.println("returned " + cmp2str(cmp) + " for durations \'" + duration1 + "\' and " + duration2 + "\', but expected " |
| + cmp2str(expected)); |
| } |
| } |
| |
| if (compareErrors) { |
| // TODO; fix bug, these tests should pass |
| if (false) { |
| Assert.fail("Errors in comparing indeterminate relations, see Stderr"); |
| } else { |
| System.err.println("Please fix this bug: " + "Errors in comparing indeterminate relations, see Stderr"); |
| } |
| } |
| } |
| |
| public static String cmp2str(int cmp) { |
| return cmp == DatatypeConstants.LESSER ? "LESSER" : cmp == DatatypeConstants.GREATER ? "GREATER" : cmp == DatatypeConstants.EQUAL ? "EQUAL" |
| : cmp == DatatypeConstants.INDETERMINATE ? "INDETERMINATE" : "UNDEFINED"; |
| } |
| |
| /** |
| * Inspired by CR 6238220 javax.xml.datatype.Duration has no clear |
| * description concerning return values range. |
| */ |
| @Test |
| public void testNormalizedReturnValues() throws Exception { |
| |
| final Object[] TEST_VALUES = { |
| // test 61 seconds -> 1 minute, 1 second |
| true, // isPositive, |
| BigInteger.ZERO, // years, |
| BigInteger.ZERO, // months |
| BigInteger.ZERO, // days |
| BigInteger.ZERO, // hours |
| BigInteger.ZERO, // minutes |
| new BigDecimal(61), // seconds |
| 61000L, // durationInMilliSeconds, |
| "P0Y0M0DT0H0M61S", // lexicalRepresentation |
| |
| // test - 61 seconds -> - 1 minute, 1 second |
| false, // isPositive, |
| BigInteger.ZERO, // years, |
| BigInteger.ZERO, // months |
| BigInteger.ZERO, // days |
| BigInteger.ZERO, // hours |
| BigInteger.ZERO, // minutes |
| new BigDecimal(61), // seconds |
| 61000L, // durationInMilliSeconds, |
| "-P0Y0M0DT0H0M61S", // lexicalRepresentation |
| }; |
| |
| final Object[] NORM_VALUES = { |
| // test 61 seconds -> 1 minute, 1 second |
| true, // normalized isPositive, |
| BigInteger.ZERO, // normalized years, |
| BigInteger.ZERO, // normalized months |
| BigInteger.ZERO, // normalized days |
| BigInteger.ZERO, // normalized hours |
| BigInteger.ONE, // normalized minutes |
| BigDecimal.ONE, // normalized seconds |
| 61000L, // normalized durationInMilliSeconds, |
| "P0Y0M0DT0H1M1.000S", // normalized lexicalRepresentation |
| |
| // test - 61 seconds -> - 1 minute, 1 second |
| false, // normalized isPositive, |
| BigInteger.ZERO, // normalized years, |
| BigInteger.ZERO, // normalized months |
| BigInteger.ZERO, // normalized days |
| BigInteger.ZERO, // normalized hours |
| BigInteger.ONE, // normalized minutes |
| BigDecimal.ONE, // normalized seconds |
| 61000L, // normalized durationInMilliSeconds, |
| "-P0Y0M0DT0H1M1.000S" // normalized lexicalRepresentation |
| }; |
| |
| for (int onValue = 0; onValue < TEST_VALUES.length; onValue += 9) { |
| newDurationTester(((Boolean) TEST_VALUES[onValue]).booleanValue(), // isPositive, |
| ((Boolean) NORM_VALUES[onValue]).booleanValue(), // normalized |
| // isPositive, |
| (BigInteger) TEST_VALUES[onValue + 1], // years, |
| (BigInteger) NORM_VALUES[onValue + 1], // normalized years, |
| (BigInteger) TEST_VALUES[onValue + 2], // months |
| (BigInteger) NORM_VALUES[onValue + 2], // normalized months |
| (BigInteger) TEST_VALUES[onValue + 3], // days |
| (BigInteger) NORM_VALUES[onValue + 3], // normalized days |
| (BigInteger) TEST_VALUES[onValue + 4], // hours |
| (BigInteger) NORM_VALUES[onValue + 4], // normalized hours |
| (BigInteger) TEST_VALUES[onValue + 5], // minutes |
| (BigInteger) NORM_VALUES[onValue + 5], // normalized minutes |
| (BigDecimal) TEST_VALUES[onValue + 6], // seconds |
| (BigDecimal) NORM_VALUES[onValue + 6], // normalized seconds |
| ((Long) TEST_VALUES[onValue + 7]).longValue(), // durationInMilliSeconds, |
| ((Long) NORM_VALUES[onValue + 7]).longValue(), // normalized |
| // durationInMilliSeconds, |
| (String) TEST_VALUES[onValue + 8], // lexicalRepresentation |
| (String) NORM_VALUES[onValue + 8]); // normalized |
| // lexicalRepresentation |
| |
| newDurationDayTimeTester(((Boolean) TEST_VALUES[onValue]).booleanValue(), // isPositive, |
| ((Boolean) NORM_VALUES[onValue]).booleanValue(), // normalized |
| // isPositive, |
| BigInteger.ZERO, // years, |
| BigInteger.ZERO, // normalized years, |
| BigInteger.ZERO, // months |
| BigInteger.ZERO, // normalized months |
| (BigInteger) TEST_VALUES[onValue + 3], // days |
| (BigInteger) NORM_VALUES[onValue + 3], // normalized days |
| (BigInteger) TEST_VALUES[onValue + 4], // hours |
| (BigInteger) NORM_VALUES[onValue + 4], // normalized hours |
| (BigInteger) TEST_VALUES[onValue + 5], // minutes |
| (BigInteger) NORM_VALUES[onValue + 5], // normalized minutes |
| (BigDecimal) TEST_VALUES[onValue + 6], // seconds |
| (BigDecimal) NORM_VALUES[onValue + 6], // normalized seconds |
| ((Long) TEST_VALUES[onValue + 7]).longValue(), // durationInMilliSeconds, |
| ((Long) NORM_VALUES[onValue + 7]).longValue(), // normalized |
| // durationInMilliSeconds, |
| (String) TEST_VALUES[onValue + 8], // lexicalRepresentation |
| (String) NORM_VALUES[onValue + 8]); // normalized |
| // lexicalRepresentation |
| } |
| } |
| |
| private void newDurationTester(boolean isPositive, boolean normalizedIsPositive, BigInteger years, BigInteger normalizedYears, BigInteger months, |
| BigInteger normalizedMonths, BigInteger days, BigInteger normalizedDays, BigInteger hours, BigInteger normalizedHours, BigInteger minutes, |
| BigInteger normalizedMinutes, BigDecimal seconds, BigDecimal normalizedSeconds, long durationInMilliSeconds, long normalizedDurationInMilliSeconds, |
| String lexicalRepresentation, String normalizedLexicalRepresentation) { |
| |
| DatatypeFactory datatypeFactory = null; |
| try { |
| datatypeFactory = DatatypeFactory.newInstance(); |
| } catch (DatatypeConfigurationException ex) { |
| ex.printStackTrace(); |
| Assert.fail(ex.toString()); |
| } |
| |
| // create 4 Durations using the 4 different constructors |
| |
| Duration durationBigInteger = datatypeFactory.newDuration(isPositive, years, months, days, hours, minutes, seconds); |
| durationAssertEquals(durationBigInteger, DatatypeConstants.DURATION, normalizedIsPositive, normalizedYears.intValue(), normalizedMonths.intValue(), |
| normalizedDays.intValue(), normalizedHours.intValue(), normalizedMinutes.intValue(), normalizedSeconds.intValue(), |
| normalizedDurationInMilliSeconds, normalizedLexicalRepresentation); |
| |
| Duration durationInt = datatypeFactory.newDuration(isPositive, years.intValue(), months.intValue(), days.intValue(), hours.intValue(), |
| minutes.intValue(), seconds.intValue()); |
| durationAssertEquals(durationInt, DatatypeConstants.DURATION, normalizedIsPositive, normalizedYears.intValue(), normalizedMonths.intValue(), |
| normalizedDays.intValue(), normalizedHours.intValue(), normalizedMinutes.intValue(), normalizedSeconds.intValue(), |
| normalizedDurationInMilliSeconds, normalizedLexicalRepresentation); |
| |
| Duration durationMilliseconds = datatypeFactory.newDuration(durationInMilliSeconds); |
| durationAssertEquals(durationMilliseconds, DatatypeConstants.DURATION, normalizedIsPositive, normalizedYears.intValue(), normalizedMonths.intValue(), |
| normalizedDays.intValue(), normalizedHours.intValue(), normalizedMinutes.intValue(), normalizedSeconds.intValue(), |
| normalizedDurationInMilliSeconds, normalizedLexicalRepresentation); |
| |
| Duration durationLexical = datatypeFactory.newDuration(lexicalRepresentation); |
| durationAssertEquals(durationLexical, DatatypeConstants.DURATION, normalizedIsPositive, normalizedYears.intValue(), normalizedMonths.intValue(), |
| normalizedDays.intValue(), normalizedHours.intValue(), normalizedMinutes.intValue(), normalizedSeconds.intValue(), |
| normalizedDurationInMilliSeconds, normalizedLexicalRepresentation); |
| } |
| |
| private void newDurationDayTimeTester(boolean isPositive, boolean normalizedIsPositive, BigInteger years, BigInteger normalizedYears, BigInteger months, |
| BigInteger normalizedMonths, BigInteger days, BigInteger normalizedDays, BigInteger hours, BigInteger normalizedHours, BigInteger minutes, |
| BigInteger normalizedMinutes, BigDecimal seconds, BigDecimal normalizedSeconds, long durationInMilliSeconds, long normalizedDurationInMilliSeconds, |
| String lexicalRepresentation, String normalizedLexicalRepresentation) { |
| |
| DatatypeFactory datatypeFactory = null; |
| try { |
| datatypeFactory = DatatypeFactory.newInstance(); |
| } catch (DatatypeConfigurationException ex) { |
| ex.printStackTrace(); |
| Assert.fail(ex.toString()); |
| } |
| |
| // create 4 dayTime Durations using the 4 different constructors |
| |
| Duration durationDayTimeBigInteger = datatypeFactory.newDurationDayTime(isPositive, days, hours, minutes, seconds.toBigInteger()); |
| durationAssertEquals(durationDayTimeBigInteger, DatatypeConstants.DURATION_DAYTIME, normalizedIsPositive, normalizedYears.intValue(), |
| normalizedMonths.intValue(), normalizedDays.intValue(), normalizedHours.intValue(), normalizedMinutes.intValue(), normalizedSeconds.intValue(), |
| normalizedDurationInMilliSeconds, normalizedLexicalRepresentation); |
| |
| /* |
| * Duration durationDayTimeInt = datatypeFactory.newDurationDayTime( |
| * isPositive, days.intValue(), hours.intValue(), minutes.intValue(), |
| * seconds.intValue()); Duration durationDayTimeMilliseconds = |
| * datatypeFactory.newDurationDayTime( durationInMilliSeconds); Duration |
| * durationDayTimeLexical = datatypeFactory.newDurationDayTime( |
| * lexicalRepresentation); |
| * Duration durationYearMonthBigInteger = |
| * datatypeFactory.newDurationYearMonth( isPositive, years, months); |
| * Duration durationYearMonthInt = datatypeFactory.newDurationYearMonth( |
| * isPositive, years.intValue(), months.intValue()); Duration |
| * durationYearMonthMilliseconds = datatypeFactory.newDurationYearMonth( |
| * durationInMilliSeconds); Duration durationYearMonthLexical = |
| * datatypeFactory.newDurationYearMonth( lexicalRepresentation) ; |
| */ |
| |
| } |
| |
| private void durationAssertEquals(Duration duration, QName xmlSchemaType, boolean isPositive, int years, int months, int days, int hours, int minutes, |
| int seconds, long milliseconds, String lexical) { |
| |
| final TimeZone GMT = TimeZone.getTimeZone("GMT"); |
| final GregorianCalendar EPOCH = new GregorianCalendar(GMT); |
| EPOCH.clear(); |
| |
| if (DEBUG) { |
| System.out.println("Testing Duration: " + duration.toString()); |
| } |
| |
| // sign |
| if (DEBUG) { |
| boolean actual = (duration.getSign() == 1) ? true : false; |
| System.out.println("sign:"); |
| System.out.println(" expected: \"" + isPositive + "\""); |
| System.out.println(" actual: \"" + actual + "\""); |
| } |
| |
| if (DEBUG) { |
| System.out.println("years:"); |
| System.out.println(" expected: \"" + years + "\""); |
| System.out.println(" actual: \"" + duration.getYears() + "\""); |
| } |
| |
| if (DEBUG) { |
| System.out.println("months:"); |
| System.out.println(" expected: \"" + months + "\""); |
| System.out.println(" actual: \"" + duration.getMonths() + "\""); |
| } |
| |
| if (DEBUG) { |
| System.out.println("days:"); |
| System.out.println(" expected: \"" + days + "\""); |
| System.out.println(" actual: \"" + duration.getDays() + "\""); |
| } |
| |
| if (DEBUG) { |
| System.out.println("hours:"); |
| System.out.println(" expected: \"" + hours + "\""); |
| System.out.println(" actual: \"" + duration.getHours() + "\""); |
| } |
| |
| if (DEBUG) { |
| System.out.println("minutes:"); |
| System.out.println(" expected: \"" + minutes + "\""); |
| System.out.println(" actual: \"" + duration.getMinutes() + "\""); |
| } |
| |
| if (DEBUG) { |
| System.out.println("seconds:"); |
| System.out.println(" expected: \"" + seconds + "\""); |
| System.out.println(" actual: \"" + duration.getSeconds() + "\""); |
| } |
| |
| if (DEBUG) { |
| System.out.println("milliseconds:"); |
| System.out.println(" expected: \"" + milliseconds + "\""); |
| System.out.println(" actual: \"" + duration.getTimeInMillis(EPOCH) + "\""); |
| } |
| |
| if (DEBUG) { |
| System.out.println("lexical:"); |
| System.out.println(" expected: \"" + lexical + "\""); |
| System.out.println(" actual: \"" + duration.toString() + "\""); |
| } |
| |
| } |
| } |