You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by mu...@apache.org on 2023/10/23 17:14:31 UTC

[xalan-java] branch xalan-j_xslt3.0 updated: committing improvements to, use of xml schema data type xs:time within xpath expressions, along with few relevant working new test cases.

This is an automated email from the ASF dual-hosted git repository.

mukulg pushed a commit to branch xalan-j_xslt3.0
in repository https://gitbox.apache.org/repos/asf/xalan-java.git


The following commit(s) were added to refs/heads/xalan-j_xslt3.0 by this push:
     new bb7061ca committing improvements to, use of xml schema data type xs:time within xpath expressions, along with few relevant working new test cases.
     new 3c623636 Merge pull request #109 from mukulga/xalan-j_xslt3.0_mukul
bb7061ca is described below

commit bb7061ca4071e7db0c369f5fbae6cd68c19b4c4d
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Mon Oct 23 22:37:26 2023 +0530

    committing improvements to, use of xml schema data type xs:time within xpath expressions, along with few relevant working new test cases.
---
 .../apache/xalan/templates/ElemForEachGroup.java   |   4 +-
 .../apache/xpath/functions/FuncCurrentTime.java    |  13 +-
 src/org/apache/xpath/objects/XObject.java          |  15 +-
 src/org/apache/xpath/operations/Minus.java         |  10 ++
 src/org/apache/xpath/operations/Plus.java          |  10 ++
 src/org/apache/xpath/xs/types/XSDateTime.java      |   4 +-
 src/org/apache/xpath/xs/types/XSTime.java          | 188 ++++++++++++++++++++-
 .../apache/xalan/util/XslTransformTestsUtil.java   |   1 +
 .../xalan/xpath3/XsTimeWithArithmeticTests.java    |  93 ++++++++++
 tests/org/apache/xalan/xslt3/Xsl3TestSuite1.java   |   4 +-
 tests/xs_time_with_arithmetic/gold/test1.out       |   7 +
 tests/xs_time_with_arithmetic/gold/test2.out       |   9 +
 tests/xs_time_with_arithmetic/gold/test3.out       |   5 +
 tests/xs_time_with_arithmetic/gold/test4.out       |   4 +
 tests/xs_time_with_arithmetic/test1.xsl            |  52 ++++++
 tests/xs_time_with_arithmetic/test1_a.xml          |   5 +
 tests/xs_time_with_arithmetic/test2.xsl            |  56 ++++++
 tests/xs_time_with_arithmetic/test3.xsl            |  46 +++++
 tests/xs_time_with_arithmetic/test4.xsl            |  45 +++++
 19 files changed, 553 insertions(+), 18 deletions(-)

diff --git a/src/org/apache/xalan/templates/ElemForEachGroup.java b/src/org/apache/xalan/templates/ElemForEachGroup.java
index 4d552cd3..243dea1b 100644
--- a/src/org/apache/xalan/templates/ElemForEachGroup.java
+++ b/src/org/apache/xalan/templates/ElemForEachGroup.java
@@ -53,6 +53,7 @@ import org.apache.xpath.xs.types.XSDate;
 import org.apache.xpath.xs.types.XSDateTime;
 import org.apache.xpath.xs.types.XSNumericType;
 import org.apache.xpath.xs.types.XSString;
+import org.apache.xpath.xs.types.XSTime;
 
 /**
  * Implementation of the XSLT 3.0 xsl:for-each-group instruction.
@@ -826,7 +827,8 @@ public class ElemForEachGroup extends ElemTemplateElement
       else if (xpathEvalResult instanceof XSBoolean) {
           xpathRawResult = Boolean.valueOf(((XSBoolean)xpathEvalResult).value());
       }
-      else if ((xpathEvalResult instanceof XSDate) || (xpathEvalResult instanceof XSDateTime)) {
+      else if ((xpathEvalResult instanceof XSDate) || (xpathEvalResult instanceof XSDateTime) || 
+    		                                          (xpathEvalResult instanceof XSTime)) {
           xpathRawResult = xpathEvalResult;
       }
       else {
diff --git a/src/org/apache/xpath/functions/FuncCurrentTime.java b/src/org/apache/xpath/functions/FuncCurrentTime.java
index 776b4195..ceedfd01 100644
--- a/src/org/apache/xpath/functions/FuncCurrentTime.java
+++ b/src/org/apache/xpath/functions/FuncCurrentTime.java
@@ -22,8 +22,6 @@ package org.apache.xpath.functions;
 
 import java.util.Vector;
 
-import javax.xml.transform.SourceLocator;
-
 import org.apache.xalan.res.XSLMessages;
 import org.apache.xpath.XPathContext;
 import org.apache.xpath.objects.XObject;
@@ -52,13 +50,12 @@ public class FuncCurrentTime extends Function {
    *
    * @throws javax.xml.transform.TransformerException
    */
-  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException {
-
-    SourceLocator srcLocator = xctxt.getSAXLocator();
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException {    
     
-    XSTime currentTime = new XSTime(xctxt.getCurrentDateTime(), xctxt.getTimezone());
-
-    return (XObject)currentTime;
+    XSTime xsCurrentTime = new XSTime(xctxt.getCurrentDateTime(), xctxt.getTimezone());
+    xsCurrentTime.setPopulatedFromFnCurrentTime(true);
+    
+    return xsCurrentTime;
   }
 
   /**
diff --git a/src/org/apache/xpath/objects/XObject.java b/src/org/apache/xpath/objects/XObject.java
index e23050ed..5170fa90 100644
--- a/src/org/apache/xpath/objects/XObject.java
+++ b/src/org/apache/xpath/objects/XObject.java
@@ -45,6 +45,7 @@ import org.apache.xpath.xs.types.XSInt;
 import org.apache.xpath.xs.types.XSInteger;
 import org.apache.xpath.xs.types.XSLong;
 import org.apache.xpath.xs.types.XSString;
+import org.apache.xpath.xs.types.XSTime;
 import org.w3c.dom.DocumentFragment;
 import org.w3c.dom.NodeList;
 import org.w3c.dom.traversal.NodeIterator;
@@ -656,6 +657,9 @@ public class XObject extends Expression implements Serializable, Cloneable
        else if ((this instanceof XSDateTime) && (obj2 instanceof XSDateTime)) {
            return ((XSDateTime)this).lt((XSDateTime)obj2);    
        }
+       else if ((this instanceof XSTime) && (obj2 instanceof XSTime)) {
+           return ((XSTime)this).lt((XSTime)obj2);    
+       }
        else if ((this instanceof XNumber) && (obj2 instanceof XNumber)) {
            return ((XNumber)this).num() < ((XNumber)obj2).num(); 
        }
@@ -782,6 +786,9 @@ public class XObject extends Expression implements Serializable, Cloneable
        else if ((this instanceof XSDateTime) && (obj2 instanceof XSDateTime)) {
            return ((XSDateTime)this).gt((XSDateTime)obj2);    
        }
+       else if ((this instanceof XSTime) && (obj2 instanceof XSTime)) {
+           return ((XSTime)this).gt((XSTime)obj2);    
+       }
        else if ((this instanceof XString) && (obj2 instanceof XString)) {          
           String lStr = (((XString)this)).str();
           String rStr = (((XString)obj2)).str();
@@ -966,6 +973,9 @@ public class XObject extends Expression implements Serializable, Cloneable
     else if ((this instanceof XSDateTime) && (obj2 instanceof XSDateTime)) {
         return ((XSDateTime)this).equals((XSDateTime)obj2);    
     }
+    else if ((this instanceof XSTime) && (obj2 instanceof XSTime)) {
+        return ((XSTime)this).equals((XSTime)obj2);    
+    }
     else if ((this instanceof XSInteger) && (obj2 instanceof XNumber)) {
        double lDouble = ((XSInteger)this).doubleValue();
        double rDouble = ((XNumber)obj2).num();
@@ -1029,10 +1039,13 @@ public class XObject extends Expression implements Serializable, Cloneable
     }
     else if ((this instanceof XSDate) && (obj2 instanceof XSDate)) {
         return ((XSDate)this).equals((XSDate)obj2);    
-    }
+    }    
     else if ((this instanceof XSDateTime) && (obj2 instanceof XSDateTime)) {
         return ((XSDateTime)this).equals((XSDateTime)obj2);    
     }
+    else if ((this instanceof XSTime) && (obj2 instanceof XSTime)) {
+        return ((XSTime)this).equals((XSTime)obj2);    
+    }
     else if ((this instanceof XSString) && (obj2 instanceof XSString)) {
         return ((XSString)this).equals((XSString)obj2);    
     }
diff --git a/src/org/apache/xpath/operations/Minus.java b/src/org/apache/xpath/operations/Minus.java
index 432d2eed..5c334aa8 100644
--- a/src/org/apache/xpath/operations/Minus.java
+++ b/src/org/apache/xpath/operations/Minus.java
@@ -29,6 +29,7 @@ import org.apache.xpath.objects.XObject;
 import org.apache.xpath.xs.types.XSDate;
 import org.apache.xpath.xs.types.XSDateTime;
 import org.apache.xpath.xs.types.XSNumericType;
+import org.apache.xpath.xs.types.XSTime;
 import org.apache.xpath.xs.types.XSYearMonthDuration;
 
 /**
@@ -256,6 +257,9 @@ public class Minus extends Operation
       else if (left instanceof XSDateTime) {
           result = ((XSDateTime)left).subtract(right);  
       }
+      else if (left instanceof XSTime) {
+          result = ((XSTime)left).subtract(right);  
+      }
       else if ((left instanceof ResultSequence) && (right instanceof ResultSequence)) {
           ResultSequence rsLeft = (ResultSequence)left;          
           if (rsLeft.size() > 1) {
@@ -280,6 +284,9 @@ public class Minus extends Operation
           else if (lArg instanceof XSDateTime) {
               result = ((XSDateTime)lArg).subtract(rArg); 
           }
+          else if (lArg instanceof XSTime) {
+              result = ((XSTime)lArg).subtract(rArg); 
+          }
           else {
               java.lang.String lStr = XslTransformEvaluationHelper.getStrVal(lArg);
               double lDouble = (Double.valueOf(lStr)).doubleValue();
@@ -305,6 +312,9 @@ public class Minus extends Operation
           else if (lArg instanceof XSDateTime) {
               result = ((XSDateTime)lArg).subtract(right); 
           }
+          else if (lArg instanceof XSTime) {
+              result = ((XSTime)lArg).subtract(right); 
+          }
       }
       else {          
           try {
diff --git a/src/org/apache/xpath/operations/Plus.java b/src/org/apache/xpath/operations/Plus.java
index 9093c9bb..637f9387 100644
--- a/src/org/apache/xpath/operations/Plus.java
+++ b/src/org/apache/xpath/operations/Plus.java
@@ -29,6 +29,7 @@ import org.apache.xpath.objects.XObject;
 import org.apache.xpath.xs.types.XSDate;
 import org.apache.xpath.xs.types.XSDateTime;
 import org.apache.xpath.xs.types.XSNumericType;
+import org.apache.xpath.xs.types.XSTime;
 import org.apache.xpath.xs.types.XSUntyped;
 import org.apache.xpath.xs.types.XSUntypedAtomic;
 import org.apache.xpath.xs.types.XSYearMonthDuration;
@@ -289,6 +290,9 @@ public class Plus extends Operation
       else if (left instanceof XSDateTime) {
           result = ((XSDateTime)left).add(right);  
       }
+      else if (left instanceof XSTime) {
+          result = ((XSTime)left).add(right);  
+      }
       else if ((left instanceof ResultSequence) && (right instanceof ResultSequence)) {
           ResultSequence rsLeft = (ResultSequence)left;          
           if (rsLeft.size() > 1) {
@@ -313,6 +317,9 @@ public class Plus extends Operation
           else if (lArg instanceof XSDateTime) {
              result = ((XSDateTime)lArg).add(rArg); 
           }
+          else if (lArg instanceof XSTime) {
+             result = ((XSTime)lArg).add(rArg); 
+          }
           else {
              java.lang.String lStr = XslTransformEvaluationHelper.getStrVal(rsLeft.item(0));
              double lDouble = (Double.valueOf(lStr)).doubleValue();
@@ -338,6 +345,9 @@ public class Plus extends Operation
           else if (lArg instanceof XSDateTime) {
               result = ((XSDateTime)lArg).add(right); 
           }
+          else if (lArg instanceof XSTime) {
+              result = ((XSTime)lArg).add(right); 
+          }
       }
       else {
           try {
diff --git a/src/org/apache/xpath/xs/types/XSDateTime.java b/src/org/apache/xpath/xs/types/XSDateTime.java
index 625817bd..f902deb3 100644
--- a/src/org/apache/xpath/xs/types/XSDateTime.java
+++ b/src/org/apache/xpath/xs/types/XSDateTime.java
@@ -715,7 +715,7 @@ public class XSDateTime extends XSCalendarType {
     }
     
     /**
-     * Determine whether, this XSDateTime object is less that, the 
+     * Determine whether, this XSDateTime object is less than, the 
      * XSDateTime object provided as an argument to this method. 
      */
     public boolean lt(XSDateTime xsDateTime) {
@@ -760,7 +760,7 @@ public class XSDateTime extends XSCalendarType {
     }
     
     /**
-     * Determine whether, this XSDateTime object is greater that, the 
+     * Determine whether, this XSDateTime object is greater than, the 
      * XSDateTime object provided as an argument to this method. 
      */
     public boolean gt(XSDateTime xsDateTime) {
diff --git a/src/org/apache/xpath/xs/types/XSTime.java b/src/org/apache/xpath/xs/types/XSTime.java
index 7c508f9d..06484c6c 100644
--- a/src/org/apache/xpath/xs/types/XSTime.java
+++ b/src/org/apache/xpath/xs/types/XSTime.java
@@ -23,6 +23,7 @@ import java.util.TimeZone;
 import javax.xml.transform.TransformerException;
 
 import org.apache.xpath.objects.ResultSequence;
+import org.apache.xpath.objects.XObject;
 
 /**
  * An XML Schema data type representation, of the xs:time datatype.
@@ -43,6 +44,12 @@ public class XSTime extends XSCalendarType {
     
     private XSDuration _tz;
     
+    /**
+     * The value of this class field, stores the fact that whether this
+     * XSTime object is constructed via XPath function call fn:current-time().
+     */
+    private boolean isPopulatedFromFnCurrentTime = false;
+    
     /**
      * Class constructor.
      * 
@@ -133,10 +140,14 @@ public class XSTime extends XSCalendarType {
      * 
      * @return    Calendar representation of the time stored
      */
-    public Calendar calendar() {
+    public Calendar getCalendar() {
         return _calendar;
     }
     
+    public XSDuration getTimezone() {
+        return _tz;
+    }
+    
     /**
      * Get the hour value stored as an integer within this
      * XSTime object.
@@ -179,7 +190,7 @@ public class XSTime extends XSCalendarType {
      * @return true    if there is a timezone associated with this XSTime object.
      *                 false otherwise.
      */
-    public boolean isXsTimeObjectTimezoned() {
+    public boolean isTimetimezoned() {
         return _timezoned;
     }
 
@@ -187,7 +198,7 @@ public class XSTime extends XSCalendarType {
     public String stringValue() {
         String returnVal = "";
         
-        Calendar calendarVal = calendar();
+        Calendar calendarVal = getCalendar();
         returnVal += XSDateTime.padInt(calendarVal.get(Calendar.HOUR_OF_DAY), 2);
         
         returnVal += ":";
@@ -210,7 +221,7 @@ public class XSTime extends XSCalendarType {
             }
         }
 
-        if (isXsTimeObjectTimezoned()) {
+        if (isTimetimezoned()) {
             int hrs = _tz.hours();
             int min = _tz.minutes();
             double secs = _tz.seconds();
@@ -236,11 +247,178 @@ public class XSTime extends XSCalendarType {
          return returnVal;
     }
     
+    /**
+     * Determine whether, two XSTime objects are equal.
+     */
+    public boolean equals(XSTime xsTime) {
+        boolean isXsTimeEqual = false;
+        
+        int hour1 = hour();
+        int mins1 = minute();
+        double secs1 = second();
+        
+        int hour2 = xsTime.hour();
+        int mins2 = xsTime.minute();
+        double secs2 = xsTime.second();
+        XSDuration tz1 = getTimezone();
+        XSDuration tz2 = xsTime.getTimezone();
+        
+        isXsTimeEqual = ((hour1 == hour2) && (mins1 == mins2) && (secs1 == secs2)) && 
+                                                            isTimezoneEqual(tz1, tz2, isPopulatedFromFnCurrentTime, 
+                                                                            xsTime.isPopulatedFromFnCurrentTime());
+        
+        return isXsTimeEqual;
+    }
+    
+    @Override
+    public boolean equals(Object obj) {
+       boolean isTimeEqual = false;
+        
+       if (obj instanceof XSTime) {
+    	   isTimeEqual = this.equals((XSTime)obj);  
+       }
+       
+       return isTimeEqual;
+    }
+    
+    @Override
+    public int hashCode() {       
+       String strVal = stringValue();       
+       
+       return strVal.hashCode();
+    }
+    
+    /**
+     * Determine whether, this XSTime object is less than, the XSTime 
+     * object provided as an argument to this method. 
+     */
+    public boolean lt(XSTime xsTime) {
+       boolean isTimeBefore = false;
+       
+       int hour1 = hour();
+       int mins1 = minute();
+       double secs1 = second();
+       
+       int hour2 = xsTime.hour();
+       int mins2 = xsTime.minute();
+       double secs2 = xsTime.second();
+       
+       if (hour1 < hour2) {
+    	  isTimeBefore = true; 
+       }
+       else if (hour1 == hour2) {
+          if (mins1 < mins2) {
+        	 isTimeBefore = true;  
+          }
+          else if (mins1 == mins2) {
+             if (secs1 < secs2) {
+            	isTimeBefore = true;  
+             }
+          }
+       }
+    
+       return isTimeBefore;
+    }
+    
+    /**
+     * Determine whether, this XSTime object is greater than, the 
+     * XSTime object provided as an argument to this method. 
+     */
+    public boolean gt(XSTime xsTime) {
+    	boolean isTimeAfter = false;
+        
+        int hour1 = hour();
+        int mins1 = minute();
+        double secs1 = second();
+        
+        int hour2 = xsTime.hour();
+        int mins2 = xsTime.minute();
+        double secs2 = xsTime.second();
+        
+        if (hour1 > hour2) {
+        	isTimeAfter = true; 
+        }
+        else if (hour1 == hour2) {
+           if (mins1 > mins2) {
+        	   isTimeAfter = true;  
+           }
+           else if (mins1 == mins2) {
+              if (secs1 > secs2) {
+            	  isTimeAfter = true;  
+              }
+           }
+        }
+     
+        return isTimeAfter;
+    }
+    
+    /**
+     * Implementation of addition operation between this XSTime value, and a
+     * supplied value (as per XPath 3.1 spec, xs:dayTimeDuration is the only 
+     * permissible data type value, that may be added to an xs:Time value).
+     */
+    public XObject add(XObject xObject) throws TransformerException {
+         XObject result = null;
+         
+         if (!(xObject instanceof XSDayTimeDuration)) {
+            throw new TransformerException("XPTY0004 : The value of type xs:dayTimeDuration is the only "
+            		                                                                      + "one that may be added to an xs:Time value.");
+         }
+         
+         XSDayTimeDuration argVal = (XSDayTimeDuration)xObject;
+         double argValSecs = argVal.value();
+         Calendar cal1 = (Calendar)((getCalendar()).clone());
+         cal1.setTimeInMillis(cal1.getTimeInMillis() + ((((long)argValSecs * 1000))));
+         result = new XSTime(cal1, getTimezone());
+         
+         return result;
+    }
+     
+    /**
+     * Implementation of subtraction operation between this XSTime value, and a
+     * supplied value (as per XPath 3.1 spec, xs:time and xs:dayTimeDuration are
+     * the only permissible data type values, that may be subtracted from an 
+     * xs:time value).
+     */
+     public XObject subtract(XObject xObject) throws TransformerException {
+          XObject result = null;
+          
+          if (!((xObject instanceof XSTime) || (xObject instanceof XSDayTimeDuration))) {
+             throw new TransformerException("XPTY0004 : The values of types xs:time and xs:dayTimeDuration "
+             		                                                     + "are only ones that may be subtracted "
+             		                                                     + "from an xs:time value.");
+          }
+          
+          if (xObject instanceof XSTime) {
+             Calendar cal1 = getCalendar();
+             Calendar cal2 = ((XSTime)xObject).getCalendar();
+             long diffDurationMilliSecs = cal1.getTimeInMillis() - cal2.getTimeInMillis();
+             result = new XSDayTimeDuration(diffDurationMilliSecs / 1000);
+          }          
+          else if (xObject instanceof XSDayTimeDuration) {
+             XSDayTimeDuration argVal = (XSDayTimeDuration)xObject;
+             double argValSecs = argVal.value();
+             Calendar cal1 = (Calendar)((getCalendar()).clone());
+             cal1.setTimeInMillis(cal1.getTimeInMillis() + ((((long)argValSecs * 1000)) * -1));
+             result = new XSTime(cal1, getTimezone());
+          }
+          
+          return result;
+    }
+    
     public int getType() {
         return CLASS_XS_TIME;
     }
     
-    /**
+    public boolean isPopulatedFromFnCurrentTime() {
+		return isPopulatedFromFnCurrentTime;
+	}
+
+	public void setPopulatedFromFnCurrentTime(boolean isPopulatedFromFnCurrentTime) {
+		this.isPopulatedFromFnCurrentTime = isPopulatedFromFnCurrentTime;
+	}
+
+	/**
      * Do a data type cast, of an XSAnyType argument passed to this method, to
      * an XSTime object.
      */
diff --git a/tests/org/apache/xalan/util/XslTransformTestsUtil.java b/tests/org/apache/xalan/util/XslTransformTestsUtil.java
index 366ac7d4..967bfdfa 100644
--- a/tests/org/apache/xalan/util/XslTransformTestsUtil.java
+++ b/tests/org/apache/xalan/util/XslTransformTestsUtil.java
@@ -42,6 +42,7 @@ import junit.framework.Assert;
  * A class providing, common services to this JUnit test suite.
  * 
  * @author Mukul Gandhi <mu...@apache.org>
+ * @author Vladimir Sitnikov <si...@gmail.com>
  * 
  * @xsl.usage advanced
  */
diff --git a/tests/org/apache/xalan/xpath3/XsTimeWithArithmeticTests.java b/tests/org/apache/xalan/xpath3/XsTimeWithArithmeticTests.java
new file mode 100644
index 00000000..7fbd3790
--- /dev/null
+++ b/tests/org/apache/xalan/xpath3/XsTimeWithArithmeticTests.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.xalan.xpath3;
+
+import org.apache.xalan.util.XslTransformTestsUtil;
+import org.apache.xalan.xslt3.XSLConstants;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * XPath 3.1 test cases, to test use of XML Schema data 
+ * type xs:time within XPath expressions.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class XsTimeWithArithmeticTests extends XslTransformTestsUtil {        
+    
+    private static final String XSL_TRANSFORM_INPUT_DIRPATH = XSLConstants.XSL_TRANSFORM_INPUT_DIRPATH_PREFIX 
+    		                                                                                               + "xs_time_with_arithmetic/";
+    
+    private static final String XSL_TRANSFORM_GOLD_DIRPATH = XSLConstants.XSL_TRANSFORM_GOLD_DIRPATH_PREFIX 
+    		                                                                                               + "xs_time_with_arithmetic/gold/";
+
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        // no op
+    }
+
+    @AfterClass
+    public static void tearDownAfterClass() throws Exception {        
+        xmlDocumentBuilderFactory = null;
+        xmlDocumentBuilder = null;
+        xslTransformerFactory = null;
+    }
+
+    @Test
+    public void xsTimeTest1() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test1.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xsTimeTest2() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test2.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xsTimeTest3() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test3.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test3.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test3.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xsTimeTest4() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test4.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test4.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+
+}
diff --git a/tests/org/apache/xalan/xslt3/Xsl3TestSuite1.java b/tests/org/apache/xalan/xslt3/Xsl3TestSuite1.java
index e36678a3..27517705 100644
--- a/tests/org/apache/xalan/xslt3/Xsl3TestSuite1.java
+++ b/tests/org/apache/xalan/xslt3/Xsl3TestSuite1.java
@@ -26,6 +26,7 @@ import org.apache.xalan.xpath3.ValueComparisonTests;
 import org.apache.xalan.xpath3.XsConstructorFunctionTests;
 import org.apache.xalan.xpath3.XsDateTimeArithmeticTests;
 import org.apache.xalan.xpath3.XsDateTimeTests;
+import org.apache.xalan.xpath3.XsTimeWithArithmeticTests;
 import org.junit.runner.RunWith;
 import org.junit.runners.Suite;
 import org.junit.runners.Suite.SuiteClasses;
@@ -42,7 +43,8 @@ import org.junit.runners.Suite.SuiteClasses;
                 XslFunctionTests.class, HigherOrderFunctionTests.class, XsDateTimeTests.class,
                 ValueComparisonTests.class, InlineFunctionItemExprTests.class, 
                 FnForEachTests.class, XsConstructorFunctionTests.class,
-                FnAbsTests.class, StringTests.class, XsDateTimeArithmeticTests.class })
+                FnAbsTests.class, StringTests.class, XsDateTimeArithmeticTests.class,
+                XsTimeWithArithmeticTests.class })
 public class Xsl3TestSuite1 {
 
 }
diff --git a/tests/xs_time_with_arithmetic/gold/test1.out b/tests/xs_time_with_arithmetic/gold/test1.out
new file mode 100644
index 00000000..24b3f7fa
--- /dev/null
+++ b/tests/xs_time_with_arithmetic/gold/test1.out
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>true</one>
+  <two>false</two>
+  <three>false</three>
+  <four>true</four>
+  <five>false</five>
+</result>
diff --git a/tests/xs_time_with_arithmetic/gold/test2.out b/tests/xs_time_with_arithmetic/gold/test2.out
new file mode 100644
index 00000000..30d700cc
--- /dev/null
+++ b/tests/xs_time_with_arithmetic/gold/test2.out
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>15:00:00</one>
+  <two>11:30:00</two>
+  <three>13:00:00</three>
+  <snip/>
+  <four>05:00:00</four>
+  <five>08:30:00</five>
+  <six>07:00:00</six>
+</result>
diff --git a/tests/xs_time_with_arithmetic/gold/test3.out b/tests/xs_time_with_arithmetic/gold/test3.out
new file mode 100644
index 00000000..6bafe71d
--- /dev/null
+++ b/tests/xs_time_with_arithmetic/gold/test3.out
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>PT7H</one>
+  <two>PT2H</two>
+  <three>-PT3H</three>
+</result>
diff --git a/tests/xs_time_with_arithmetic/gold/test4.out b/tests/xs_time_with_arithmetic/gold/test4.out
new file mode 100644
index 00000000..9f48f813
--- /dev/null
+++ b/tests/xs_time_with_arithmetic/gold/test4.out
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>15:00:00</one>
+  <two>11:30:00</two>
+</result>
diff --git a/tests/xs_time_with_arithmetic/test1.xsl b/tests/xs_time_with_arithmetic/test1.xsl
new file mode 100644
index 00000000..f11fa7ba
--- /dev/null
+++ b/tests/xs_time_with_arithmetic/test1.xsl
@@ -0,0 +1,52 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                exclude-result-prefixes="xs"
+                version="3.0">
+                
+  <!-- Author: mukulg@apache.org -->
+  
+  <!-- An XSLT stylesheet test case, to test use of XML Schema 
+       data type xs:time within XPath expressions.
+  -->                
+                
+  <xsl:output method="xml" indent="yes"/>
+
+  <xsl:template match="/">     
+     <result>
+        <one>
+           <xsl:value-of select="xs:time('10:00:00') eq xs:time('10:00:00')"/>
+        </one>
+        <two>
+           <xsl:value-of select="xs:time('10:00:00') eq xs:time('10:30:00')"/>
+        </two>
+        <three>
+           <xsl:value-of select="xs:time('10:00:00') lt xs:time('10:00:00')"/>
+        </three>
+        <four>
+           <xsl:value-of select="xs:time('10:00:00') lt xs:time('10:30:00')"/>
+        </four>
+        <five>
+           <xsl:value-of select="xs:time('10:00:00') gt xs:time('10:30:00')"/>
+        </five>
+     </result>
+  </xsl:template>
+  
+  <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the  "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+  -->
+     
+</xsl:stylesheet>                
\ No newline at end of file
diff --git a/tests/xs_time_with_arithmetic/test1_a.xml b/tests/xs_time_with_arithmetic/test1_a.xml
new file mode 100644
index 00000000..b2c5b6a7
--- /dev/null
+++ b/tests/xs_time_with_arithmetic/test1_a.xml
@@ -0,0 +1,5 @@
+<info>
+  <time1>10:00:00</time1>  
+  <duration1>PT5H</duration1>
+  <duration2>PT1H30M</duration2>
+</info>
\ No newline at end of file
diff --git a/tests/xs_time_with_arithmetic/test2.xsl b/tests/xs_time_with_arithmetic/test2.xsl
new file mode 100644
index 00000000..9d2c2c4a
--- /dev/null
+++ b/tests/xs_time_with_arithmetic/test2.xsl
@@ -0,0 +1,56 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                exclude-result-prefixes="xs"
+                version="3.0">
+                
+  <!-- Author: mukulg@apache.org -->
+  
+  <!-- An XSLT stylesheet test case, to test use of XML Schema 
+       data type xs:time within XPath expressions.
+  -->                
+                
+  <xsl:output method="xml" indent="yes"/>
+
+  <xsl:template match="/">     
+     <result>
+        <one>
+           <xsl:value-of select="xs:time('10:00:00') + xs:dayTimeDuration('PT5H')"/>
+        </one>      
+        <two>
+           <xsl:value-of select="xs:time('10:00:00') + xs:dayTimeDuration('PT1H30M')"/>
+        </two>
+        <three>
+           <xsl:value-of select="xs:time('10:00:00') + xs:dayTimeDuration('P1DT3H')"/>
+        </three>
+        <snip/>
+        <four>
+           <xsl:value-of select="xs:time('10:00:00') - xs:dayTimeDuration('PT5H')"/>
+        </four>      
+        <five>
+           <xsl:value-of select="xs:time('10:00:00') - xs:dayTimeDuration('PT1H30M')"/>
+        </five>
+        <six>
+           <xsl:value-of select="xs:time('10:00:00') - xs:dayTimeDuration('P1DT3H')"/>
+        </six>
+     </result>
+  </xsl:template>
+  
+  <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the  "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+  -->
+     
+</xsl:stylesheet>                
\ No newline at end of file
diff --git a/tests/xs_time_with_arithmetic/test3.xsl b/tests/xs_time_with_arithmetic/test3.xsl
new file mode 100644
index 00000000..9b05e4e4
--- /dev/null
+++ b/tests/xs_time_with_arithmetic/test3.xsl
@@ -0,0 +1,46 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                exclude-result-prefixes="xs"
+                version="3.0">
+                
+  <!-- Author: mukulg@apache.org -->
+  
+  <!-- An XSLT stylesheet test case, to test use of XML Schema 
+       data type xs:time within XPath expressions.
+  -->                
+                
+  <xsl:output method="xml" indent="yes"/>
+
+  <xsl:template match="/">     
+     <result>
+        <one>
+           <xsl:value-of select="xs:time('17:00:00') - xs:time('10:00:00')"/>
+        </one>      
+        <two>
+           <xsl:value-of select="xs:time('17:00:00') - xs:time('15:00:00')"/>
+        </two>
+        <three>
+           <xsl:value-of select="xs:time('10:00:00') - xs:time('13:00:00')"/>
+        </three>
+     </result>
+  </xsl:template>
+  
+  <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the  "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+  -->
+     
+</xsl:stylesheet>                
\ No newline at end of file
diff --git a/tests/xs_time_with_arithmetic/test4.xsl b/tests/xs_time_with_arithmetic/test4.xsl
new file mode 100644
index 00000000..dbcdb525
--- /dev/null
+++ b/tests/xs_time_with_arithmetic/test4.xsl
@@ -0,0 +1,45 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                exclude-result-prefixes="xs"
+                version="3.0">
+                
+  <!-- Author: mukulg@apache.org -->
+  
+  <!-- use with test1_a.xml -->
+  
+  <!-- An XSLT stylesheet test case, to test use of XML Schema 
+       data type xs:time within XPath expressions.
+  -->              
+                
+  <xsl:output method="xml" indent="yes"/>
+
+  <xsl:template match="/info">     
+     <result>
+        <one>
+           <xsl:value-of select="xs:time(time1) + xs:dayTimeDuration(duration1)"/>
+        </one>      
+        <two>
+           <xsl:value-of select="xs:time(time1) + xs:dayTimeDuration(duration2)"/>
+        </two>
+     </result>
+  </xsl:template>
+  
+  <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the  "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+  -->
+     
+</xsl:stylesheet>                
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xalan.apache.org
For additional commands, e-mail: commits-help@xalan.apache.org