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/08/24 09:37:59 UTC

[xalan-java] branch xalan-j_xslt3.0 updated: implementing the xpath 3.1 function fn:unordered. improving the implementations of xpath 3.1 functions fn:insert-before, fn:subsequence. adding few new working test cases for function fn:sort.

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 f5f685b5 implementing the xpath 3.1 function fn:unordered. improving the implementations of xpath 3.1 functions fn:insert-before, fn:subsequence. adding few new working test cases for function fn:sort.
     new 14b0ead9 Merge pull request #59 from mukulga/xalan-j_xslt3.0_mukul
f5f685b5 is described below

commit f5f685b5eb920703544979c44914b451a42f15f8
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Thu Aug 24 15:03:18 2023 +0530

    implementing the xpath 3.1 function fn:unordered. improving the implementations of xpath 3.1 functions fn:insert-before, fn:subsequence. adding few new working test cases for function fn:sort.
---
 src/org/apache/xpath/compiler/FunctionTable.java   |  9 ++-
 src/org/apache/xpath/compiler/Keywords.java        |  3 +
 .../apache/xpath/functions/FuncInsertBefore.java   | 44 +++++++++-----
 .../apache/xpath/functions/FuncSubsequence.java    | 18 +++---
 src/org/apache/xpath/functions/FuncUnordered.java  | 71 ++++++++++++++++++++++
 src/org/apache/xpath/objects/ResultSequence.java   | 20 ++++++
 tests/fn_sort/gold/test14.out                      |  4 ++
 tests/fn_sort/gold/test15.out                      | 36 +++++++++++
 tests/fn_sort/test17.xsl                           | 43 +++++++++++++
 tests/fn_sort/test18.xsl                           | 45 ++++++++++++++
 tests/fn_sort/test1_h.xml                          | 17 ++++++
 tests/org/apache/xalan/xpath3/FnSortTests.java     | 20 ++++++
 tests/org/apache/xalan/xslt3/AllXsl3Tests.java     |  2 +-
 13 files changed, 307 insertions(+), 25 deletions(-)

diff --git a/src/org/apache/xpath/compiler/FunctionTable.java b/src/org/apache/xpath/compiler/FunctionTable.java
index 40a4b113..b7ebd456 100644
--- a/src/org/apache/xpath/compiler/FunctionTable.java
+++ b/src/org/apache/xpath/compiler/FunctionTable.java
@@ -299,6 +299,9 @@ public class FunctionTable
   
   /** The 'subsequence()' id. */
   public static final int FUNC_SUBSEQUENCE = 91;
+  
+  /** The 'unordered()' id. */
+  public static final int FUNC_UNORDERED = 92;
 
   // Proprietary
 
@@ -356,7 +359,7 @@ public class FunctionTable
    * Number of built in functions. Be sure to update this as
    * built-in functions are added.
    */
-  private static final int NUM_BUILT_IN_FUNCS = 92;
+  private static final int NUM_BUILT_IN_FUNCS = 93;
 
   /**
    * Number of built-in functions that may be added.
@@ -541,6 +544,8 @@ public class FunctionTable
       org.apache.xpath.functions.FuncReverse.class;
     m_functions[FUNC_SUBSEQUENCE] = 
       org.apache.xpath.functions.FuncSubsequence.class;
+    m_functions[FUNC_UNORDERED] = 
+      org.apache.xpath.functions.FuncUnordered.class;
   }
 
   static{
@@ -733,6 +738,8 @@ public class FunctionTable
                          new Integer(FunctionTable.FUNC_REVERSE));
          m_functionID.put(Keywords.FUNC_SUBSEQUENCE,
                          new Integer(FunctionTable.FUNC_SUBSEQUENCE));
+         m_functionID.put(Keywords.FUNC_UNORDERED,
+                         new Integer(FunctionTable.FUNC_UNORDERED));
   }
   
   public FunctionTable(){
diff --git a/src/org/apache/xpath/compiler/Keywords.java b/src/org/apache/xpath/compiler/Keywords.java
index 9a5ff0a4..f83a1a5b 100644
--- a/src/org/apache/xpath/compiler/Keywords.java
+++ b/src/org/apache/xpath/compiler/Keywords.java
@@ -410,6 +410,9 @@ public class Keywords
   /** subsequence function string. */
   public static final String FUNC_SUBSEQUENCE = "subsequence";
   
+  /** unordered function string. */
+  public static final String FUNC_UNORDERED = "unordered";
+  
   // Proprietary, built in functions
 
   /** current function string (Proprietary). */
diff --git a/src/org/apache/xpath/functions/FuncInsertBefore.java b/src/org/apache/xpath/functions/FuncInsertBefore.java
index 060b6060..bcd92c4a 100644
--- a/src/org/apache/xpath/functions/FuncInsertBefore.java
+++ b/src/org/apache/xpath/functions/FuncInsertBefore.java
@@ -59,26 +59,40 @@ public class FuncInsertBefore extends Function3Args {
             
             ResultSequence rsArg0 = XslTransformEvaluationHelper.getResultSequenceFromXObject(
                                                                                           xObject0, xctxt);
-            
-            int seqInsertPos = getSequenceInsertPosition(xObject1);
-            
-            if (seqInsertPos < 1) {
-               seqInsertPos = 1; 
-            }
-            
             ResultSequence rsArg2 = XslTransformEvaluationHelper.getResultSequenceFromXObject(
                                                                                           xObject2, xctxt);
             
-            for (int idx = 0; idx < (seqInsertPos - 1); idx++) {
-               result.add(rsArg0.item(idx));  
+            if (rsArg0.size() == 0) {
+                for (int idx = 0; idx < rsArg2.size(); idx++) {
+                   result.add(rsArg2.item(idx));   
+                }   
             }
-            
-            for (int idx = 0; idx < rsArg2.size(); idx++) {
-               result.add(rsArg2.item(idx));   
+            else if (rsArg2.size() == 0) {
+                for (int idx = 0; idx < rsArg0.size(); idx++) {
+                   result.add(rsArg0.item(idx));   
+                }
             }
-            
-            for (int idx = (seqInsertPos - 1); idx < rsArg0.size(); idx++) {
-               result.add(rsArg0.item(idx));  
+            else {
+                int seqInsertPos = getSequenceInsertPosition(xObject1);
+                
+                if (seqInsertPos < 1) {
+                   seqInsertPos = 1; 
+                }
+                else if (seqInsertPos > rsArg0.size()) {
+                   seqInsertPos = rsArg0.size() + 1;  
+                }
+                
+                for (int idx = 0; idx < (seqInsertPos - 1); idx++) {
+                   result.add(rsArg0.item(idx));  
+                }
+                
+                for (int idx = 0; idx < rsArg2.size(); idx++) {
+                   result.add(rsArg2.item(idx));   
+                }
+                
+                for (int idx = (seqInsertPos - 1); idx < rsArg0.size(); idx++) {
+                   result.add(rsArg0.item(idx));  
+                }
             }
         }
         catch (TransformerException ex) {
diff --git a/src/org/apache/xpath/functions/FuncSubsequence.java b/src/org/apache/xpath/functions/FuncSubsequence.java
index 6e98c692..9a662a4f 100644
--- a/src/org/apache/xpath/functions/FuncSubsequence.java
+++ b/src/org/apache/xpath/functions/FuncSubsequence.java
@@ -73,6 +73,8 @@ public class FuncSubsequence extends FunctionMultiArgs {
             XObject arg1Obj = arg1.execute(xctxt);
             int startingLoc = getIntFromXObject(arg1Obj);
             
+            startingLoc = (startingLoc <= 0) ? 1 : startingLoc; 
+            
             // This function call requires either two arguments, or three arguments
             if (numOfArgs == 2) {
                for (int idx = (startingLoc - 1); idx < rsArg0.size(); idx++) {
@@ -84,15 +86,15 @@ public class FuncSubsequence extends FunctionMultiArgs {
                arg2 = m_arg2;
                XObject arg2Obj = arg2.execute(xctxt);           
                int lengthVal = getIntFromXObject(arg2Obj);
-               if (lengthVal > rsArg0.size()) {
-                   throw new javax.xml.transform.TransformerException("FORG0006 : The third argument value " + 
-                                                                                         lengthVal + " of call to function fn:subsequence, is "
-                                                                                                   + "greater than the size of input sequence."); 
+               if (lengthVal < 0) {
+                  lengthVal = 0;    
+               }
+               else if ((startingLoc + lengthVal) > rsArg0.size()) {
+                  lengthVal = rsArg0.size() - startingLoc + 1;    
                }
-               else { 
-                  for (int idx = (startingLoc - 1); idx < ((startingLoc - 1) + lengthVal); idx++) {
-                     result.add(rsArg0.item(idx)); 
-                  }
+               
+               for (int idx = (startingLoc - 1); idx < ((startingLoc - 1) + lengthVal); idx++) {
+                  result.add(rsArg0.item(idx)); 
                }
             }
         }
diff --git a/src/org/apache/xpath/functions/FuncUnordered.java b/src/org/apache/xpath/functions/FuncUnordered.java
new file mode 100644
index 00000000..e235cc2d
--- /dev/null
+++ b/src/org/apache/xpath/functions/FuncUnordered.java
@@ -0,0 +1,71 @@
+/*
+ * 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.xpath.functions;
+
+import java.util.Collections;
+import java.util.List;
+
+import javax.xml.transform.SourceLocator;
+
+import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.ResultSequence;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Implementation of the unordered() function.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class FuncUnordered extends FunctionOneArg {
+
+    private static final long serialVersionUID = 4192924071383539197L;
+
+    /**
+     * Execute the function. The function must return a valid object.
+     * 
+     * @param xctxt The current execution context.
+     * @return A valid XObject.
+     *
+     * @throws javax.xml.transform.TransformerException
+     */
+    public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+    {
+        
+        ResultSequence result = new ResultSequence();
+        
+        SourceLocator srcLocator = xctxt.getSAXLocator();
+
+        XObject xObject0 = m_arg0.execute(xctxt);
+            
+        ResultSequence rsArg0 = XslTransformEvaluationHelper.getResultSequenceFromXObject(
+                                                                                      xObject0, xctxt);
+        List<XObject> sequenceAsList = rsArg0.getResultSequenceItems();
+        
+        // randomly permute the list of input sequence items
+        Collections.shuffle(sequenceAsList);
+        
+        for (int idx = 0; idx < sequenceAsList.size(); idx++) {
+           result.add(sequenceAsList.get(idx));  
+        }
+        
+        return result;
+    }
+
+}
diff --git a/src/org/apache/xpath/objects/ResultSequence.java b/src/org/apache/xpath/objects/ResultSequence.java
index 0e106c18..09b2dfbf 100644
--- a/src/org/apache/xpath/objects/ResultSequence.java
+++ b/src/org/apache/xpath/objects/ResultSequence.java
@@ -46,18 +46,38 @@ public class ResultSequence extends XObject
         return CLASS_RESULT_SEQUENCE;
     }
     
+    /** 
+     * Append an item at the end of the sequence.
+     */
     public void add(XObject item) {
         rsList.add(item);    
     }
     
+    /**
+     * Set an item at a particular index.
+     */
+    public void set(int idx, XObject item) {
+        rsList.set(idx, item);
+    }
+    
+    /**
+     * Get an item stored at a particular index.
+     */
     public XObject item(int idx) {
         return rsList.get(idx);     
     }
     
+    /**
+     * Get the size of the current sequence object.
+     */
     public int size() {
         return rsList.size();   
     }
     
+    /**
+     * Get the contents of this sequence object, as list of 
+     * XObject objects. 
+     */
     public List<XObject> getResultSequenceItems() {
         return rsList;   
     }
diff --git a/tests/fn_sort/gold/test14.out b/tests/fn_sort/gold/test14.out
new file mode 100644
index 00000000..b48c6680
--- /dev/null
+++ b/tests/fn_sort/gold/test14.out
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one sortOrder="ascending">a b p q</one>
+  <two sortOrder="descending">q p b a</two>
+</result>
diff --git a/tests/fn_sort/gold/test15.out b/tests/fn_sort/gold/test15.out
new file mode 100644
index 00000000..8cb46bde
--- /dev/null
+++ b/tests/fn_sort/gold/test15.out
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one sortOrder="ascending">
+    <part id="1">
+    <name>pqr</name>
+  </part>
+    <part id="2">
+    <name>mno</name>
+  </part>
+    <part id="3">
+    <name>abc</name>
+  </part>
+    <part id="4">
+    <name>lmn</name>
+  </part>
+    <part id="5">
+    <name>xyz</name>
+  </part>
+  </one>
+  <two sortOrder="descending">
+    <part id="5">
+    <name>xyz</name>
+  </part>
+    <part id="4">
+    <name>lmn</name>
+  </part>
+    <part id="3">
+    <name>abc</name>
+  </part>
+    <part id="2">
+    <name>mno</name>
+  </part>
+    <part id="1">
+    <name>pqr</name>
+  </part>
+  </two>
+</result>
diff --git a/tests/fn_sort/test17.xsl b/tests/fn_sort/test17.xsl
new file mode 100644
index 00000000..2462cfd9
--- /dev/null
+++ b/tests/fn_sort/test17.xsl
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="3.0">
+                
+   <!-- Author: mukulg@apache.org -->
+   
+   <!-- An XSLT stylesheet test case, to test an XPath 3.1 function
+        fn:sort which produces the result in an ascending order of input 
+        sequence items, and producing a descending ordered sort result
+        of input sequence items using the function fn:reverse on result
+        of call to function fn:sort. -->                            
+
+   <xsl:output method="xml" indent="yes"/>
+   
+   <xsl:variable name="seq1" select="('p','a','b','q')"/>
+   
+   <xsl:template match="/">
+      <xsl:variable name="sortResult" select="sort($seq1, ())"/>
+      <result>
+         <one sortOrder="ascending"><xsl:value-of select="$sortResult"/></one>
+         <two sortOrder="descending"><xsl:value-of select="reverse($sortResult)"/></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
diff --git a/tests/fn_sort/test18.xsl b/tests/fn_sort/test18.xsl
new file mode 100644
index 00000000..c18dfead
--- /dev/null
+++ b/tests/fn_sort/test18.xsl
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<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_h.xml -->
+   
+   <!-- An XSLT stylesheet test case, to test an XPath 3.1 function
+        fn:sort which produces the result in an ascending order of input 
+        sequence items, and producing a descending ordered sort result
+        of input sequence items using the function fn:reverse on result
+        of call to function fn:sort. -->                             
+
+   <xsl:output method="xml" indent="yes"/>
+   
+   <xsl:template match="/info">
+      <xsl:variable name="sortResult" select="sort(part, (), function($part) { xs:integer($part/@id) })"/>
+      <result>
+         <one sortOrder="ascending"><xsl:copy-of select="$sortResult"/></one>
+         <two sortOrder="descending"><xsl:copy-of select="reverse($sortResult)"/></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
diff --git a/tests/fn_sort/test1_h.xml b/tests/fn_sort/test1_h.xml
new file mode 100644
index 00000000..b5b457a9
--- /dev/null
+++ b/tests/fn_sort/test1_h.xml
@@ -0,0 +1,17 @@
+<info>
+  <part id="3">
+    <name>abc</name>
+  </part>
+  <part id="2">
+    <name>mno</name>
+  </part>
+  <part id="1">
+    <name>pqr</name>
+  </part>
+  <part id="5">
+    <name>xyz</name>
+  </part>
+  <part id="4">
+    <name>lmn</name>
+  </part>
+</info>
\ No newline at end of file
diff --git a/tests/org/apache/xalan/xpath3/FnSortTests.java b/tests/org/apache/xalan/xpath3/FnSortTests.java
index 10aed336..d8373c92 100644
--- a/tests/org/apache/xalan/xpath3/FnSortTests.java
+++ b/tests/org/apache/xalan/xpath3/FnSortTests.java
@@ -208,5 +208,25 @@ public class FnSortTests extends XslTransformTestsUtil {
         
         runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
     }
+    
+    @Test
+    public void xslFnSortTest17() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test17.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test17.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test14.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslFnSortTest18() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_h.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test18.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test15.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
 
 }
diff --git a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
index 9f90c976..d6e50b02 100644
--- a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
+++ b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
@@ -17,7 +17,6 @@
 package org.apache.xalan.xslt3;
 
 import org.apache.xalan.xpath3.BuiltinFunctionsNamespceTests;
-import org.apache.xalan.xpath3.XsDurationComponentExtractionFunctionTests;
 import org.apache.xalan.xpath3.DynamicFunctionCallTests;
 import org.apache.xalan.xpath3.FnAbsTests;
 import org.apache.xalan.xpath3.FnCodepointEqualTests;
@@ -52,6 +51,7 @@ import org.apache.xalan.xpath3.TrignometricAndExponentialFunctionTests;
 import org.apache.xalan.xpath3.ValueComparisonTests;
 import org.apache.xalan.xpath3.XPathArithmeticOnDurationValuesTests;
 import org.apache.xalan.xpath3.XsConstructorFunctionTests;
+import org.apache.xalan.xpath3.XsDurationComponentExtractionFunctionTests;
 import org.junit.runner.RunWith;
 import org.junit.runners.Suite;
 import org.junit.runners.Suite.SuiteClasses;


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