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 2024/05/23 06:16:25 UTC

(xalan-java) branch xalan-j_xslt3.0 updated: Committing implementation, of xpath 3.1's SequenceType for xpath map expressions, along with few new relevant working 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 05dae167 Committing implementation, of xpath 3.1's SequenceType for xpath map expressions, along with few new relevant working test cases
05dae167 is described below

commit 05dae1678788e7225b5726cab1046c3ea04890e9
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Thu May 23 11:46:07 2024 +0530

    Committing implementation, of xpath 3.1's SequenceType for xpath map expressions, along with few new relevant working test cases
---
 src/org/apache/xalan/templates/ElemVariable.java   |  20 +-
 src/org/apache/xpath/compiler/XPathParserImpl.java | 257 ++++++++++++++++++++-
 .../apache/xpath/composite/SequenceTypeData.java   |  10 +
 .../xpath/composite/SequenceTypeFunctionTest.java  |   2 +-
 ...eFunctionTest.java => SequenceTypeMapTest.java} |  44 ++--
 .../xpath/composite/SequenceTypeSupport.java       |  49 +++-
 .../xpath/composite/XPathSequenceTypeExpr.java     |  15 +-
 tests/org/apache/xalan/xpath3/XPathMapTests.java   |  30 +++
 tests/xpath_maps/gold/test10.out                   |   1 +
 tests/xpath_maps/gold/test11.out                   |   1 +
 tests/xpath_maps/gold/test12.out                   |  13 ++
 tests/xpath_maps/test10.xsl                        |  40 ++++
 tests/xpath_maps/test11.xsl                        |  40 ++++
 tests/xpath_maps/test12.xsl                        |  34 +++
 tests/xpath_maps/test8.xsl                         |   4 +-
 15 files changed, 522 insertions(+), 38 deletions(-)

diff --git a/src/org/apache/xalan/templates/ElemVariable.java b/src/org/apache/xalan/templates/ElemVariable.java
index 02383a71..221770a5 100644
--- a/src/org/apache/xalan/templates/ElemVariable.java
+++ b/src/org/apache/xalan/templates/ElemVariable.java
@@ -44,6 +44,7 @@ import org.apache.xpath.objects.XNodeSet;
 import org.apache.xpath.objects.XNodeSetForDOM;
 import org.apache.xpath.objects.XNumber;
 import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XPathMap;
 import org.apache.xpath.objects.XRTreeFrag;
 import org.apache.xpath.objects.XRTreeFragSelectWrapper;
 import org.apache.xpath.objects.XString;
@@ -609,7 +610,24 @@ public class ElemVariable extends ElemTemplateElement
           else {
              var = SequenceTypeSupport.convertXDMValueToAnotherType(var, m_asAttr, null, xctxt); 
           }
-       }       
+       }
+       else if (var instanceof XPathMap) {
+    	  try {
+    	     var = SequenceTypeSupport.convertXDMValueToAnotherType(var, m_asAttr, null, xctxt);
+    	  }
+    	  catch (TransformerException ex) {
+    		 String errMesg = ex.getMessage();
+    		 boolean indicatorOne = errMesg.contains("The string value"); 
+    		 boolean indicatorTwo = errMesg.contains("cannot be cast to a type");
+    		 if (indicatorOne && indicatorTwo) {
+    		    errMesg = errMesg + " An error occured, while evaluating xdm map's key or value [map's sequenceType is '" + m_asAttr + "'].";
+    		    throw new TransformerException(errMesg, srcLocator);
+    		 }
+    		 else {
+    		    throw new TransformerException(errMesg, srcLocator);
+    		 }
+    	  }    	   
+       }
        else {
           var = SequenceTypeSupport.convertXDMValueToAnotherType(var, m_asAttr, null, xctxt); 
        }
diff --git a/src/org/apache/xpath/compiler/XPathParserImpl.java b/src/org/apache/xpath/compiler/XPathParserImpl.java
index dd6f8f07..6b19bd47 100644
--- a/src/org/apache/xpath/compiler/XPathParserImpl.java
+++ b/src/org/apache/xpath/compiler/XPathParserImpl.java
@@ -44,6 +44,7 @@ import org.apache.xpath.composite.QuantifiedExpr;
 import org.apache.xpath.composite.SequenceTypeData;
 import org.apache.xpath.composite.SequenceTypeFunctionTest;
 import org.apache.xpath.composite.SequenceTypeKindTest;
+import org.apache.xpath.composite.SequenceTypeMapTest;
 import org.apache.xpath.composite.SequenceTypeSupport;
 import org.apache.xpath.composite.XPathSequenceConstructor;
 import org.apache.xpath.composite.SquareArrayConstructor;
@@ -57,8 +58,16 @@ import org.apache.xpath.objects.XString;
 import org.apache.xpath.res.XPATHErrorResources;
 
 /**
- * Tokenizes and parses XPath expressions, as specified by 
- * XPath 3.1 spec.
+ * Tokenizes and parses XPath expressions.
+ * 
+ * Author: Scott Boag,
+ *         Myriam Midy,
+ *         Joseph Kesselman
+ * 
+ * @modification notes: Mukul Gandhi 
+ * XalanJ's XPath 1.0 implementation class XPathParser has been renamed to 
+ * XPathParserImpl, with modifications/additions to implement XPath 3.1 grammar
+ * to produce the present form of this class.
  * 
  * @xsl.usage general
  */
@@ -1137,7 +1146,7 @@ public class XPathParserImpl
    * @throws javax.xml.transform.TransformerException
    */
   protected void Expr() throws javax.xml.transform.TransformerException
-  {
+  {	  
       if (fIsBeginParse && (tokenIs("(") || tokenIs("["))) {
     	  boolean isSquareArrayConstructor = false;
     	  if (tokenIs("[")) {
@@ -1300,13 +1309,18 @@ public class XPathParserImpl
       else if (fIsBeginParse && tokenIs("map")) {
     	  // Parse an XPath "map" expression
     	  int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
+    	  
+    	  if (fIsSequenceTypeXPathExpr) {
+             fXpathSequenceTypeExpr = SequenceTypeExpr(false);
+             return;
+          }
           
           nextToken();
 
           insertOp(opPos, 2, OpCodes.OP_MAP_CONSTRUCTOR_EXPR);
           
           fMapConstructor = new MapConstructor();
-          Map<String, String> nativeMapVar = new HashMap<String, String>();
+          Map<String, String> nativeMapVar = new HashMap<String, String>();                    
           
           consumeExpected('{');
           
@@ -1329,13 +1343,28 @@ public class XPathParserImpl
  	        	 else {
  	        		// The map's key value here is a simple value (i.e, not an array or 
  	        		// map).
- 	        		mapValueExprStr = m_token; 
+ 	        		mapValueExprStr = m_token;
+ 	        		while (!(tokenIs(',') || tokenIs('}'))) {
+ 	        		   nextToken();
+ 	        		   if (!(tokenIs(',') || tokenIs('}'))) {
+ 	        		      mapValueExprStr += m_token;
+ 	        		   }
+ 	        		}
  	        	 }
  	        	 nativeMapVar.put(mapKeyExprStr, mapValueExprStr);
- 	        	 nextToken();
  	        	 if (tokenIs(',')) {
  	        		consumeExpected(','); 
  	        	 }
+ 	        	 else if (tokenIs(']')) {
+ 	        	    consumeExpected(']');
+ 	        	    if (tokenIs(',')) {
+ 	 	        	   consumeExpected(','); 
+ 	 	        	}
+ 	        	    else if (tokenIs('}')) {
+ 	        	       consumeExpected('}');
+ 	 	        	   break;
+ 	        	    }
+ 	        	 }
  	        	 else if (tokenIs('}')) {
  	        		consumeExpected('}');
  	        		break;
@@ -1469,7 +1498,8 @@ public class XPathParserImpl
   }
   
   /**
-   * Get the count of a specific character within a string.
+   * Get the count of specified character within 
+   * a string.
    */
   private int countCharInStr(String str, char cVal) {
 	 int count = 0;
@@ -4145,7 +4175,7 @@ public class XPathParserImpl
     	  SequenceTypeFunctionTest sequenceTypeFunctionTest = null;
     	  
     	  if (lookahead('(', 1) && lookahead('*', 2) && lookahead(')', 3)) {
-    		  // Handles FunctionTest of variety AnyFunctionTest
+    		  // handles FunctionTest of variety AnyFunctionTest
 	    	  sequenceTypeFunctionTest = new SequenceTypeFunctionTest();
 	    	  sequenceTypeFunctionTest.setIsAnyFunctionTest(true);
 	    	  nextToken();
@@ -4155,7 +4185,7 @@ public class XPathParserImpl
 	          xpathSequenceTypeExpr.setSequenceTypeFunctionTest(sequenceTypeFunctionTest);
 	      }
     	  else {
-    		  // Handles FunctionTest of variety TypedFunctionTest
+    		  // handles FunctionTest of variety TypedFunctionTest
     		  sequenceTypeFunctionTest = new SequenceTypeFunctionTest();
     		  nextToken();
     		  consumeExpected('(');
@@ -4222,6 +4252,215 @@ public class XPathParserImpl
     		  xpathSequenceTypeExpr.setSequenceTypeFunctionTest(sequenceTypeFunctionTest);
     	  }
       }
+      else if (tokenIs("map")) {
+    	  SequenceTypeMapTest sequenceTypeMapTest = null;
+    	  
+    	  if (lookahead('(', 1) && lookahead('*', 2) && lookahead(')', 3)) {
+    		  // handles MapTest of variety AnyMapTest
+    		  sequenceTypeMapTest = new SequenceTypeMapTest();
+    		  sequenceTypeMapTest.setIsAnyMapTest(true);
+	    	  nextToken();
+	    	  consumeExpected('(');
+	          consumeExpected('*');
+	          consumeExpected(')');
+	          xpathSequenceTypeExpr.setSequenceTypeMapTest(sequenceTypeMapTest);
+	      }
+    	  else {
+    		  // handles MapTest of variety TypedMapTest
+    		  sequenceTypeMapTest = new SequenceTypeMapTest();
+    		  nextToken();
+    		  consumeExpected('(');
+    		  /*String mapEntryKeyTypeStr = "";
+    		  String mapEntryValueTypeStr = "";
+	    	  consumeExpected('(');
+	    	  while (m_token != null) {
+	    		 while (!tokenIs(',')) {
+	    			mapEntryKeyTypeStr += m_token;
+	    			nextToken();
+	    		 }
+	    		 consumeExpected(',');
+	    		 while (!tokenIs(')')) {
+	    			mapEntryValueTypeStr += m_token;
+	    			nextToken();
+	    		 }
+	    		 consumeExpected(')');
+	    	  }*/
+    		  
+    		  SequenceTypeData keySequenceTypeData = new SequenceTypeData();    		  
+    		  SequenceTypeData valueSequenceTypeData = new SequenceTypeData();
+    		  
+    		  while ((m_token != null) && !tokenIs(',')) {
+    			 if (tokenIs(XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
+    			    consumeExpected(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+    			    consumeExpected(':');
+    			    
+    			    switch (m_token) {
+	    	            case Keywords.FUNC_BOOLEAN_STRING :
+	    	            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.BOOLEAN);
+	    	               break;
+	    	            case Keywords.XS_STRING :
+	    	            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.STRING);
+	    	               break; 
+	    	            case Keywords.XS_NORMALIZED_STRING :
+	    	            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_NORMALIZED_STRING);
+	    	                break;
+	    	            case Keywords.XS_TOKEN :
+	    	            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_TOKEN);
+	    	                break;
+	    	            case Keywords.XS_DECIMAL :
+	    	            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_DECIMAL);
+	    	                break; 
+	    	            case Keywords.XS_FLOAT :
+	    	            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_FLOAT);
+	    	               break; 
+	    	            case Keywords.XS_DOUBLE :
+	    	            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_DOUBLE);
+	    	               break;
+	    	            case Keywords.XS_INTEGER :
+	    	            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_INTEGER);
+	    	               break;
+	    	            case Keywords.XS_LONG :
+	    	            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_LONG);
+	    	               break; 
+	    	            case Keywords.XS_INT :
+	    	            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_INT);
+	    	               break;
+	    	            case Keywords.XS_DATE :
+	    	            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_DATE);
+	    	               break;
+	    	            case Keywords.XS_DATETIME :
+	    	            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_DATETIME);
+	    	               break;
+	    	            case Keywords.XS_DURATION :
+	    	            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_DURATION);
+	    	               break;
+	    	            case Keywords.XS_YEAR_MONTH_DURATION :
+	    	            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_YEARMONTH_DURATION);
+	    	               break;
+	    	            case Keywords.XS_DAY_TIME_DURATION :
+	    	            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_DAYTIME_DURATION);
+	    	               break;
+	    	            case Keywords.XS_TIME :
+	    	            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_TIME);
+	    	               break;
+	    	            case Keywords.XS_ANY_URI :
+	    	            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_ANY_URI);
+	    	               break;
+	    	            case Keywords.XS_QNAME :
+	    	            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_QNAME);
+	    	               break;
+	    	            case Keywords.XS_ANY_ATOMIC_TYPE :
+	    	            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_ANY_ATOMIC_TYPE);
+	    	               break;
+	    	            case Keywords.XS_UNTYPED_ATOMIC :
+	    	            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_UNTYPED_ATOMIC);
+	    	               break;
+	    	            case Keywords.XS_UNTYPED :
+	    	            	keySequenceTypeData.setSequenceType(SequenceTypeSupport.XS_UNTYPED);
+	    	               break;
+	    	            default :
+	    	               throw new javax.xml.transform.TransformerException("XPST0051 : An XML Schema type 'xs:" + m_token + "' is not "
+    	                                                                                          + "recognized, within the provided sequence type expression.");        
+    	         }
+    			 
+    			 nextToken();
+    		   }
+    		}
+    		  
+    		consumeExpected(',');
+    		  
+    		while ((m_token != null) && !tokenIs(')')) {
+     			 if (tokenIs(XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
+     			    consumeExpected(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+     			    consumeExpected(':');
+     			    
+     			    switch (m_token) {
+ 	    	            case Keywords.FUNC_BOOLEAN_STRING :
+ 	    	               valueSequenceTypeData.setSequenceType(SequenceTypeSupport.BOOLEAN);
+ 	    	               break;
+ 	    	            case Keywords.XS_STRING :
+ 	    	            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.STRING);
+ 	    	               break; 
+ 	    	            case Keywords.XS_NORMALIZED_STRING :
+ 	    	            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_NORMALIZED_STRING);
+ 	    	                break;
+ 	    	            case Keywords.XS_TOKEN :
+ 	    	            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_TOKEN);
+ 	    	                break;
+ 	    	            case Keywords.XS_DECIMAL :
+ 	    	            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_DECIMAL);
+ 	    	                break; 
+ 	    	            case Keywords.XS_FLOAT :
+ 	    	            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_FLOAT);
+ 	    	               break; 
+ 	    	            case Keywords.XS_DOUBLE :
+ 	    	            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_DOUBLE);
+ 	    	               break;
+ 	    	            case Keywords.XS_INTEGER :
+ 	    	            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_INTEGER);
+ 	    	               break;
+ 	    	            case Keywords.XS_LONG :
+ 	    	            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_LONG);
+ 	    	               break; 
+ 	    	            case Keywords.XS_INT :
+ 	    	            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_INT);
+ 	    	               break;
+ 	    	            case Keywords.XS_DATE :
+ 	    	            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_DATE);
+ 	    	               break;
+ 	    	            case Keywords.XS_DATETIME :
+ 	    	            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_DATETIME);
+ 	    	               break;
+ 	    	            case Keywords.XS_DURATION :
+ 	    	            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_DURATION);
+ 	    	               break;
+ 	    	            case Keywords.XS_YEAR_MONTH_DURATION :
+ 	    	            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_YEARMONTH_DURATION);
+ 	    	               break;
+ 	    	            case Keywords.XS_DAY_TIME_DURATION :
+ 	    	            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_DAYTIME_DURATION);
+ 	    	               break;
+ 	    	            case Keywords.XS_TIME :
+ 	    	            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_TIME);
+ 	    	               break;
+ 	    	            case Keywords.XS_ANY_URI :
+ 	    	            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_ANY_URI);
+ 	    	               break;
+ 	    	            case Keywords.XS_QNAME :
+ 	    	            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_QNAME);
+ 	    	               break;
+ 	    	            case Keywords.XS_ANY_ATOMIC_TYPE :
+ 	    	            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_ANY_ATOMIC_TYPE);
+ 	    	               break;
+ 	    	            case Keywords.XS_UNTYPED_ATOMIC :
+ 	    	            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_UNTYPED_ATOMIC);
+ 	    	               break;
+ 	    	            case Keywords.XS_UNTYPED :
+ 	    	            	valueSequenceTypeData.setSequenceType(SequenceTypeSupport.XS_UNTYPED);
+ 	    	               break;
+ 	    	            default :
+ 	    	               throw new javax.xml.transform.TransformerException("XPST0051 : An XML Schema type 'xs:" + m_token + "' is not "
+     	                                                                                          + "recognized, within the provided sequence type expression.");        
+     	         }    	             	         
+     	         
+     	         nextToken();
+     	         
+     	         /*if (m_token != null) {
+     	            if (!tokenIs(')') && (valueSequenceTypeData.getSequenceType() > 0)) {
+      	               setSequenceTypeOccurenceIndicator(valueSequenceTypeExpr, isInlineFunction);
+      	            }
+     	         }*/
+     	         
+     	         consumeExpected(')');
+     		   }     			      		   
+     		}
+	    	
+    		sequenceTypeMapTest.setKeySequenceTypeData(keySequenceTypeData);
+    		sequenceTypeMapTest.setValueSequenceTypeData(valueSequenceTypeData);
+	    	  
+	    	xpathSequenceTypeExpr.setSequenceTypeMapTest(sequenceTypeMapTest);
+    	 }    	  
+      }
       else {
           throw new javax.xml.transform.TransformerException("XPST0051 The sequence type '" + m_token + "' is not "
                                                                                    + "recognized, within the provided sequence type expression."); 
diff --git a/src/org/apache/xpath/composite/SequenceTypeData.java b/src/org/apache/xpath/composite/SequenceTypeData.java
index ff9d0cbc..0bbe7590 100644
--- a/src/org/apache/xpath/composite/SequenceTypeData.java
+++ b/src/org/apache/xpath/composite/SequenceTypeData.java
@@ -42,6 +42,8 @@ public class SequenceTypeData extends XObject {
     private SequenceTypeKindTest sequenceTypeKindTest;
     
     private SequenceTypeFunctionTest fSequenceTypeFunctionTest;
+    
+    private SequenceTypeMapTest fSequenceTypeMapTest;
 
     public int getSequenceType() {
         return fSequenceType;
@@ -75,6 +77,14 @@ public class SequenceTypeData extends XObject {
 		this.fSequenceTypeFunctionTest = sequenceTypeFunctionTest;
 	}
 	
+	public SequenceTypeMapTest getSequenceTypeMapTest() {
+		return fSequenceTypeMapTest;
+	}
+
+	public void setSequenceTypeMapTest(SequenceTypeMapTest sequenceTypeMapTest) {
+		this.fSequenceTypeMapTest = sequenceTypeMapTest;
+	}
+	
     /**
      * Check whether, one SequenceTypeData object is functionally
      * equal to another SequenceTypeData object.  
diff --git a/src/org/apache/xpath/composite/SequenceTypeFunctionTest.java b/src/org/apache/xpath/composite/SequenceTypeFunctionTest.java
index 2cabb919..ca773b14 100644
--- a/src/org/apache/xpath/composite/SequenceTypeFunctionTest.java
+++ b/src/org/apache/xpath/composite/SequenceTypeFunctionTest.java
@@ -20,7 +20,7 @@ import java.util.List;
 
 /**
  * An object of this class stores, an XSLT transformation run-time
- * information for an occurrence of a XPath 3.1 sequence type
+ * information for an occurrence of a XPath 3.1 sequence type 
  * FunctionTest.
  * 
  * @author Mukul Gandhi <mu...@apache.org>
diff --git a/src/org/apache/xpath/composite/SequenceTypeFunctionTest.java b/src/org/apache/xpath/composite/SequenceTypeMapTest.java
similarity index 52%
copy from src/org/apache/xpath/composite/SequenceTypeFunctionTest.java
copy to src/org/apache/xpath/composite/SequenceTypeMapTest.java
index 2cabb919..b9dd601d 100644
--- a/src/org/apache/xpath/composite/SequenceTypeFunctionTest.java
+++ b/src/org/apache/xpath/composite/SequenceTypeMapTest.java
@@ -16,47 +16,49 @@
  */
 package org.apache.xpath.composite;
 
-import java.util.List;
-
 /**
  * An object of this class stores, an XSLT transformation run-time
- * information for an occurrence of a XPath 3.1 sequence type
- * FunctionTest.
+ * information for an occurrence of a XPath 3.1 sequence type 
+ * MapTest.
  * 
  * @author Mukul Gandhi <mu...@apache.org>
  * 
  * @xsl.usage advanced
  */
-public class SequenceTypeFunctionTest {
+public class SequenceTypeMapTest {
 
-    private boolean fIsAnyFunctionTest;
+    private boolean fIsAnyMapTest;
 
-    private List<String> typedFunctionTestPrefixList;
+    private SequenceTypeData keySequenceTypeData;
     
-    private String typedFunctionTestReturnType;
+    private SequenceTypeData valueSequenceTypeData;
 
-	public boolean isAnyFunctionTest() {
-		return fIsAnyFunctionTest;
+	public boolean isfIsAnyMapTest() {
+		return fIsAnyMapTest;
 	}
 
-	public void setIsAnyFunctionTest(boolean isAnyFunctionTest) {
-		this.fIsAnyFunctionTest = isAnyFunctionTest;
+	public boolean getIsAnyMapTest() {
+		return fIsAnyMapTest;
+	}
+	
+	public void setIsAnyMapTest(boolean isAnyMapTest) {
+		this.fIsAnyMapTest = isAnyMapTest;
 	}
 
-	public List<String> getTypedFunctionTestPrefixList() {
-		return typedFunctionTestPrefixList;
+	public SequenceTypeData getKeySequenceTypeData() {
+		return keySequenceTypeData;
 	}
 
-	public void setTypedFunctionTestPrefixList(List<String> typedFunctionTestPrefix) {
-		this.typedFunctionTestPrefixList = typedFunctionTestPrefix;
+	public void setKeySequenceTypeData(SequenceTypeData keySequenceTypeData) {
+		this.keySequenceTypeData = keySequenceTypeData;
 	}
 
-	public String getTypedFunctionTestReturnType() {
-		return typedFunctionTestReturnType;
+	public SequenceTypeData getValueSequenceTypeData() {
+		return valueSequenceTypeData;
 	}
 
-	public void setTypedFunctionTestReturnType(String typedFunctionTestReturnType) {
-		this.typedFunctionTestReturnType = typedFunctionTestReturnType;
-	} 
+	public void setValueSequenceTypeData(SequenceTypeData valueSequenceTypeData) {
+		this.valueSequenceTypeData = valueSequenceTypeData;
+	}
 
 }
diff --git a/src/org/apache/xpath/composite/SequenceTypeSupport.java b/src/org/apache/xpath/composite/SequenceTypeSupport.java
index 210ece51..783b8909 100644
--- a/src/org/apache/xpath/composite/SequenceTypeSupport.java
+++ b/src/org/apache/xpath/composite/SequenceTypeSupport.java
@@ -17,7 +17,10 @@
 package org.apache.xpath.composite;
 
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import javax.xml.transform.SourceLocator;
 import javax.xml.transform.TransformerException;
@@ -37,6 +40,7 @@ import org.apache.xpath.objects.XNodeSet;
 import org.apache.xpath.objects.XNodeSetForDOM;
 import org.apache.xpath.objects.XNumber;
 import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XPathMap;
 import org.apache.xpath.objects.XString;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
@@ -234,7 +238,7 @@ public class SequenceTypeSupport {
             XObject seqTypeExpressionEvalResult = null;
             SequenceTypeData seqExpectedTypeData = null;
             
-            if (xctxt != null) {
+            if ((xctxt != null) && (sequenceTypeXPathExprStr != null) && (seqExpectedTypeDataInp == null)) {
                seqTypeXPath = new XPath(sequenceTypeXPathExprStr, srcLocator, 
                                                                           xctxt.getNamespaceContext(), XPath.SELECT, null, true);
             
@@ -317,7 +321,7 @@ public class SequenceTypeSupport {
                                                                                                          xsNumericType.stringType(), sequenceTypeXPathExprStr);
                      }
                      catch (TransformerException ex2) {
-                        throw ex2; 
+                        throw ex2;
                      }
                   }
                   else {
@@ -492,6 +496,47 @@ public class SequenceTypeSupport {
             	  }
                }
             }
+            else if (srcValue instanceof XPathMap) {
+            	SequenceTypeMapTest sequenceTypeMapTest = seqExpectedTypeData.getSequenceTypeMapTest();
+                if (sequenceTypeMapTest != null) {
+             	   if (sequenceTypeMapTest.isfIsAnyMapTest()) {
+             		  result = srcValue; 
+             	   }
+             	   else {
+             		  XPathMap xpathMap = (XPathMap)srcValue;
+             		  Map<XObject, XObject> nativeMap = xpathMap.getNativeMap();
+             		  Set<XObject> mapKeys = nativeMap.keySet();
+             		  Iterator<XObject> keysIter = mapKeys.iterator();
+             		  // We check below each of map's entry, with expected type of map entry's keys and values 
+             		  while (keysIter.hasNext()) {
+             			 XObject mapKey = keysIter.next();
+             			 XObject mapEntry = nativeMap.get(mapKey);
+             			 String keyStrVal = XslTransformEvaluationHelper.getStrVal(mapKey);
+             			 if (mapKey instanceof ResultSequence) {
+             				mapKey = ((ResultSequence)mapKey).item(0);
+             			 }
+             			 if (mapEntry instanceof ResultSequence) {
+             				mapEntry = ((ResultSequence)mapEntry).item(0);
+             			 }
+             			 SequenceTypeData keySeqTypeData = sequenceTypeMapTest.getKeySequenceTypeData();
+             			 SequenceTypeData valueSeqTypeData = sequenceTypeMapTest.getValueSequenceTypeData();
+             			 XObject mapKeyValTypeCheckResult = SequenceTypeSupport.convertXDMValueToAnotherType(mapKey, null, keySeqTypeData, xctxt);
+             			 String mapSequenceTypeStr = (sequenceTypeXPathExprStr != null) ? sequenceTypeXPathExprStr : "";
+             			 if (mapKeyValTypeCheckResult == null) {             				
+             				throw new TransformerException("XPTY0004 : XPath map entry key's [entry's key name: '" + keyStrVal + "'] value doesn't conform to the key's expected "
+             						                                            + "type [map's sequenceType is '" + mapSequenceTypeStr + "']."); 
+             			 }
+             			 XObject mapEntryValTypeCheckResult = SequenceTypeSupport.convertXDMValueToAnotherType(mapEntry, null, valueSeqTypeData, xctxt);
+             			 if (mapEntryValTypeCheckResult == null) {
+             				throw new TransformerException("XPTY0004 : XPath map entry's [entry's key name: '" + keyStrVal + "'] value doesn't conform to the map entry value's expected "
+             						                                            + "type [map's sequenceType is '" + mapSequenceTypeStr + "'].");  
+             			 }           			 
+             		  }
+             		  
+             		  result = srcValue; 
+             	   }
+                }
+            }
         }
         catch (TransformerException ex) {
            if (ex.getLocator() != null) {
diff --git a/src/org/apache/xpath/composite/XPathSequenceTypeExpr.java b/src/org/apache/xpath/composite/XPathSequenceTypeExpr.java
index bb64bc6d..740cb074 100644
--- a/src/org/apache/xpath/composite/XPathSequenceTypeExpr.java
+++ b/src/org/apache/xpath/composite/XPathSequenceTypeExpr.java
@@ -45,6 +45,8 @@ public class XPathSequenceTypeExpr extends Expression {
     private SequenceTypeKindTest fSequenceTypeKindTest;
     
     private SequenceTypeFunctionTest fSequenceTypeFunctionTest;
+    
+    private SequenceTypeMapTest fSequenceTypeMapTest;
 
     @Override
     public XObject execute(XPathContext xctxt) throws TransformerException {
@@ -54,6 +56,7 @@ public class XPathSequenceTypeExpr extends Expression {
        sequenceTypeData.setSequenceTypeKindTest(fSequenceTypeKindTest);       
        sequenceTypeData.setItemTypeOccurrenceIndicator(fItemTypeOccurrenceIndicator);
        sequenceTypeData.setSequenceTypeFunctionTest(fSequenceTypeFunctionTest);
+       sequenceTypeData.setSequenceTypeMapTest(fSequenceTypeMapTest);
        
        return sequenceTypeData;
     }
@@ -97,8 +100,16 @@ public class XPathSequenceTypeExpr extends Expression {
 		return fSequenceTypeFunctionTest;
 	}
 
-	public void setSequenceTypeFunctionTest(SequenceTypeFunctionTest fSequenceTypeFunctionTest) {
-		this.fSequenceTypeFunctionTest = fSequenceTypeFunctionTest;
+	public void setSequenceTypeFunctionTest(SequenceTypeFunctionTest sequenceTypeFunctionTest) {
+		this.fSequenceTypeFunctionTest = sequenceTypeFunctionTest;
+	}
+	
+    public SequenceTypeMapTest getSequenceTypeMapTest() {
+		return fSequenceTypeMapTest;
+	}
+
+	public void setSequenceTypeMapTest(SequenceTypeMapTest sequenceTypeMapTest) {
+		this.fSequenceTypeMapTest = sequenceTypeMapTest;
 	}
 
 	@Override
diff --git a/tests/org/apache/xalan/xpath3/XPathMapTests.java b/tests/org/apache/xalan/xpath3/XPathMapTests.java
index 5a9cecbb..23351c25 100644
--- a/tests/org/apache/xalan/xpath3/XPathMapTests.java
+++ b/tests/org/apache/xalan/xpath3/XPathMapTests.java
@@ -137,5 +137,35 @@ public class XPathMapTests extends XSLTransformTestsUtil {
         
         runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
     }
+    
+    @Test
+    public void xslMapTest10() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test10.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test10.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test10.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslMapTest11() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test11.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test11.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test11.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslMapTest12() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test12.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test12.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test12.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
 
 }
diff --git a/tests/xpath_maps/gold/test10.out b/tests/xpath_maps/gold/test10.out
new file mode 100644
index 00000000..db07d8ce
--- /dev/null
+++ b/tests/xpath_maps/gold/test10.out
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><result>2</result>
diff --git a/tests/xpath_maps/gold/test11.out b/tests/xpath_maps/gold/test11.out
new file mode 100644
index 00000000..db07d8ce
--- /dev/null
+++ b/tests/xpath_maps/gold/test11.out
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><result>2</result>
diff --git a/tests/xpath_maps/gold/test12.out b/tests/xpath_maps/gold/test12.out
new file mode 100644
index 00000000..b5679d9c
--- /dev/null
+++ b/tests/xpath_maps/gold/test12.out
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <map noOfEntries="2">
+    <entry value="false" key="zero"/>
+    <entry value="true" key="one"/>
+  </map>
+  <map noOfEntries="5">
+    <entry value="Mukul" key="1"/>
+    <entry value="Joseph" key="2"/>
+    <entry value="Gary" key="3"/>
+    <entry value="John" key="4"/>
+    <entry value="Henry" key="5"/>
+  </map>
+</result>
diff --git a/tests/xpath_maps/test10.xsl b/tests/xpath_maps/test10.xsl
new file mode 100644
index 00000000..dfdea04a
--- /dev/null
+++ b/tests/xpath_maps/test10.xsl
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                xmlns:map="http://www.w3.org/2005/xpath-functions/map"
+				exclude-result-prefixes="xs map"
+                version="3.0">
+                
+   <!-- Author: mukulg@apache.org -->                 				
+
+   <xsl:output method="xml" indent="yes"/>
+   
+   <!-- An XPath 3.1 test case, to test map constructor expression
+        and the associated map functions. -->
+
+   <xsl:template match="/">
+	  <xsl:variable name="map1" select="map {'true' : xs:boolean(1), 'false' : xs:boolean(0)}"/>
+      <result>
+         <xsl:value-of select="count(map:keys($map1))"/>   
+	  </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>
diff --git a/tests/xpath_maps/test11.xsl b/tests/xpath_maps/test11.xsl
new file mode 100644
index 00000000..f938577a
--- /dev/null
+++ b/tests/xpath_maps/test11.xsl
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                xmlns:map="http://www.w3.org/2005/xpath-functions/map"
+				exclude-result-prefixes="xs map"
+                version="3.0">				
+
+   <!-- Author: mukulg@apache.org -->                 				
+
+   <xsl:output method="xml" indent="yes"/>
+   
+   <!-- An XPath 3.1 test case, to test SequenceType MapTest specified as 
+        value of xsl:variable's "as" attribute. -->
+
+   <xsl:template match="/">
+	  <xsl:variable name="map1" select="map {'true' : xs:boolean(1), 'false' : xs:boolean(0)}" as="map(*)"/>
+      <result>
+         <xsl:value-of select="count(map:keys($map1))"/>   
+	  </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>
diff --git a/tests/xpath_maps/test12.xsl b/tests/xpath_maps/test12.xsl
new file mode 100644
index 00000000..d8d1e9e5
--- /dev/null
+++ b/tests/xpath_maps/test12.xsl
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                xmlns:map="http://www.w3.org/2005/xpath-functions/map"
+				exclude-result-prefixes="xs map"
+                version="3.0">				
+
+   <!-- Author: mukulg@apache.org -->                 				
+
+   <xsl:output method="xml" indent="yes"/>
+   
+   <!-- An XPath 3.1 test case, to test SequenceType MapTest specified as 
+        value of xsl:variable's "as" attribute. -->
+
+   <xsl:template match="/">	  
+      <result>
+	     <xsl:variable name="map1" select="map {'zero' : xs:boolean(0), 'one' : xs:boolean(1)}" as="map(xs:string, xs:boolean)"/>		 
+	     <map noOfEntries="{count(map:keys($map1))}">
+            <xsl:for-each select="map:keys($map1)">
+			   <xsl:variable name="key" select="."/>
+			   <entry key="{$key}" value="{map:get($map1, $key)}"/>
+			</xsl:for-each>
+		 </map>		 
+		 <xsl:variable name="map2" select="map {1 : 'Mukul', 2 : 'Joseph', 3 : 'Gary', 4 : 'John', 5 : 'Henry'}" as="map(xs:integer, xs:string)"/>
+		 <map noOfEntries="{count(map:keys($map2))}">
+            <xsl:for-each select="map:keys($map2)">
+			   <xsl:variable name="key" select="."/>
+			   <entry key="{$key}" value="{map:get($map2, $key)}"/>
+			</xsl:for-each>
+		 </map>
+	  </result>
+   </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tests/xpath_maps/test8.xsl b/tests/xpath_maps/test8.xsl
index 98303d31..265d7359 100644
--- a/tests/xpath_maps/test8.xsl
+++ b/tests/xpath_maps/test8.xsl
@@ -28,8 +28,8 @@
 			    'one' : map {
 				           'x1' : 'p',
 						   'x2' : 'q',
-						   'x3' : 'r'
-                           'x4' : 's' 
+						   'x3' : 'r',
+                           'x4' : 's', 
                            'x5' : 't' 						   
 				        },
 				'two' : 2,


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