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/02 10:52:36 UTC
[xalan-java] branch xalan-j_xslt3.0 updated: committing improvements to implementation of xsl:function instruction, along with minor changes to comments within one of xalanj class on this dev repos branch.
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 e52d7f36 committing improvements to implementation of xsl:function instruction, along with minor changes to comments within one of xalanj class on this dev repos branch.
new d542237b Merge pull request #95 from mukulga/xalan-j_xslt3.0_mukul
e52d7f36 is described below
commit e52d7f364ad5d80fc0e4555049a3e9bebe02e089
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Mon Oct 2 16:16:04 2023 +0530
committing improvements to implementation of xsl:function instruction, along with minor changes to comments within one of xalanj class on this dev repos branch.
---
src/org/apache/xalan/templates/ElemFunction.java | 197 +++++++++++++++--------
src/org/apache/xalan/templates/ElemParam.java | 56 +++----
src/org/apache/xalan/templates/ElemTemplate.java | 3 +-
src/org/apache/xalan/templates/ElemVariable.java | 4 +-
src/org/apache/xpath/VariableStack.java | 2 +-
5 files changed, 161 insertions(+), 101 deletions(-)
diff --git a/src/org/apache/xalan/templates/ElemFunction.java b/src/org/apache/xalan/templates/ElemFunction.java
index cb5bf133..c268347d 100644
--- a/src/org/apache/xalan/templates/ElemFunction.java
+++ b/src/org/apache/xalan/templates/ElemFunction.java
@@ -17,12 +17,18 @@
*/
package org.apache.xalan.templates;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
import javax.xml.transform.SourceLocator;
import javax.xml.transform.TransformerException;
import org.apache.xalan.transformer.TransformerImpl;
import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
import org.apache.xml.dtm.ref.DTMNodeList;
+import org.apache.xml.utils.PrefixResolver;
import org.apache.xml.utils.QName;
import org.apache.xpath.VariableStack;
import org.apache.xpath.XPath;
@@ -64,11 +70,6 @@ public class ElemFunction extends ElemTemplate
{
private static final long serialVersionUID = 4973132678982467288L;
-
- /**
- * The value of the "name" attribute.
- */
- private static QName m_name;
/**
* Class constructor.
@@ -82,7 +83,6 @@ public class ElemFunction extends ElemTemplate
public void setName(QName qName)
{
super.setName(qName);
- m_name = qName;
}
/**
@@ -124,69 +124,133 @@ public class ElemFunction extends ElemTemplate
ResultSequence argSequence) throws TransformerException {
XObject result = null;
- XPathContext xctxt = transformer.getXPathContext();
-
- SourceLocator srcLocator = xctxt.getSAXLocator();
-
- VariableStack varStack = xctxt.getVarStack();
-
- int thisframe = varStack.getStackFrame();
- int nextFrame = varStack.link(m_frameSize);
+ XPathContext xctxt = transformer.getXPathContext();
- varStack.setStackFrame(thisframe);
+ SourceLocator srcLocator = xctxt.getSAXLocator();
String funcLocalName = m_name.getLocalName();
- String funcNameSpaceUri = m_name.getNamespaceURI();
+ String funcNameSpaceUri = m_name.getNamespaceURI();
- int paramCount = 0;
- for (ElemTemplateElement elem = getFirstChildElem(); elem != null;
- elem = elem.getNextSiblingElem()) {
- if (elem.getXSLToken() == Constants.ELEMNAME_PARAMVARIABLE) {
- if (argSequence.size() < (paramCount + 1)) {
- throw new TransformerException("XPST0017 : Cannot find a " + argSequence.size() + " argument function named "
- + "{" + funcNameSpaceUri + "}" + funcLocalName + "() within a stylesheet scope. "
- + "The function name was recognized, but number of arguments is wrong.", srcLocator);
- }
- XObject argValue = argSequence.item(paramCount);
- XObject argConvertedVal = argValue;
- String paramAsAttrStrVal = ((ElemParam)elem).getAs();
- if (paramAsAttrStrVal != null) {
- try {
- argConvertedVal = SequenceTypeSupport.convertXDMValueToAnotherType(argValue, paramAsAttrStrVal, null, xctxt);
- if (argConvertedVal == null) {
- throw new TransformerException("XPTY0004 : Function call argument at position " + (paramCount + 1) + " for "
- + "function {" + funcNameSpaceUri + "}" + funcLocalName + "(), doesn't "
- + "match the declared parameter type " + paramAsAttrStrVal + ".", srcLocator);
- }
+ // Validate few of the information of xsl:function's xsl:param declarations.
+ Map<QName, Integer> xslParamMap = new HashMap<QName, Integer>();
+ int idx = 0;
+ PrefixResolver prefixResolver = xctxt.getNamespaceContext();
+ for (ElemTemplateElement elem = getFirstChildElem(); elem != null; elem = elem.getNextSiblingElem()) {
+ String nodeName = elem.getNodeName();
+ if (nodeName.contains(":")) {
+ String nsPrefix = nodeName.substring(0, nodeName.indexOf(':'));
+ String namespaceUri = prefixResolver.getNamespaceForPrefix(nsPrefix);
+ String nodeLocalName = nodeName.substring(nodeName.indexOf(':') + 1);
+ if ((Constants.ELEMNAME_PARAMVARIABLE_STRING).equals(nodeLocalName) &&
+ (Constants.S_XSLNAMESPACEURL).equals(namespaceUri)) {
+ String xslParamName = elem.getAttribute(Constants.ATTRNAME_NAME);
+ if (xslParamMap.get(new QName(xslParamName)) == null) {
+ xslParamMap.put(new QName(xslParamName), Integer.valueOf(idx));
}
- catch (TransformerException ex) {
- throw new TransformerException("XPTY0004 : Function call argument at position " + (paramCount + 1) + " for "
- + "function {" + funcNameSpaceUri + "}" + funcLocalName + "(), doesn't "
- + "match the declared parameter type " + paramAsAttrStrVal + ".", srcLocator);
- }
- }
-
- if (argConvertedVal instanceof ResultSequence) {
- XNodeSet nodeSet = XslTransformEvaluationHelper.getXNodeSetFromResultSequence((ResultSequence)argConvertedVal,
- xctxt);
- if (nodeSet != null) {
- argConvertedVal = nodeSet;
+ else {
+ throw new TransformerException("XPST0017 : The xsl:function " + "{" + funcNameSpaceUri + "}" + funcLocalName +
+ "(), has more than one xsl:param '" + xslParamName + "' declaration.", srcLocator);
}
+ }
+ }
+ else if (elem instanceof ElemParam) {
+ ElemParam elemParam = (ElemParam)elem;
+ QName elemParamQName = elemParam.getName();
+ if (xslParamMap.get(elemParamQName) == null) {
+ xslParamMap.put(elemParamQName, Integer.valueOf(idx));
}
-
- varStack.setLocalVariable(paramCount, argConvertedVal, nextFrame);
- paramCount++;
- }
- else {
- break;
- }
+ else {
+ throw new TransformerException("XPST0017 : The xsl:function " + "{" + funcNameSpaceUri + "}" + funcLocalName +
+ "(), has more than one xsl:param '" + elemParamQName + "' declaration.", srcLocator);
+ }
+ }
+
+ idx++;
+ }
+
+ if (xslParamMap.size() != argSequence.size()) {
+ throw new TransformerException("XPST0017 : For the xsl:function " + "{" + funcNameSpaceUri + "}" + funcLocalName +
+ "(), the number of arguments provided with function call is not equal "
+ + "to number of function's xsl:param declarations.", srcLocator);
+ }
+
+ Collection<Integer> xslParamIdxs = xslParamMap.values();
+ Object[] idxArr = xslParamIdxs.toArray();
+ if (idxArr.length > 0) {
+ Arrays.sort(idxArr);
+ int currVal = ((Integer)idxArr[0]).intValue();
+ if (currVal != 0) {
+ throw new TransformerException("XPST0017 : For the xsl:function " + "{" + funcNameSpaceUri + "}" + funcLocalName +
+ "(), there's a non xsl:param declaration as first child "
+ + "element of xsl:function.", srcLocator);
+ }
+
+ for (int idx1 = 1; idx1 < idxArr.length; idx1++) {
+ int nextVal = ((Integer)idxArr[idx1]).intValue();
+ if (nextVal != (currVal + 1)) {
+ throw new TransformerException("XPST0017 : For the xsl:function " + "{" + funcNameSpaceUri + "}" + funcLocalName +
+ "(), there's a non xsl:param declaration between two "
+ + "xsl:param declarations.", srcLocator);
+ }
+ else {
+ currVal = nextVal;
+ }
+ }
}
- varStack.setStackFrame(nextFrame);
+ // end, Validate few of the information of xsl:function's xsl:param declarations
- int df = transformer.transformToGlobalRTF(this);
+ if (xslParamMap.size() > 0) {
+ // Set all xsl:function parameters to xpath context's variable stack,
+ // so that XSL instructions after xsl:param declarations can dereference
+ // those parameters.
+
+ VariableStack varStack = xctxt.getVarStack();
+ int argsFrame = varStack.link(xslParamMap.size());
+
+ int paramIdx = 0;
+ for (ElemTemplateElement elem = getFirstChildElem(); elem != null;
+ elem = elem.getNextSiblingElem()) {
+ if (elem.getXSLToken() == Constants.ELEMNAME_PARAMVARIABLE) {
+ XObject argValue = argSequence.item(paramIdx);
+ XObject argConvertedVal = argValue;
+ String paramAsAttrStrVal = ((ElemParam)elem).getAs();
+ if (paramAsAttrStrVal != null) {
+ try {
+ argConvertedVal = SequenceTypeSupport.convertXDMValueToAnotherType(argValue, paramAsAttrStrVal, null, xctxt);
+ if (argConvertedVal == null) {
+ throw new TransformerException("XPTY0004 : Function call argument at position " + (paramIdx + 1) + " for "
+ + "function {" + funcNameSpaceUri + "}" + funcLocalName + "(), doesn't "
+ + "match the declared parameter type " + paramAsAttrStrVal + ".", srcLocator);
+ }
+ }
+ catch (TransformerException ex) {
+ throw new TransformerException("XPTY0004 : Function call argument at position " + (paramIdx + 1) + " for "
+ + "function {" + funcNameSpaceUri + "}" + funcLocalName + "(), doesn't "
+ + "match the declared parameter type " + paramAsAttrStrVal + ".", srcLocator);
+ }
+ }
+
+ if (argConvertedVal instanceof ResultSequence) {
+ XNodeSet nodeSet = XslTransformEvaluationHelper.getXNodeSetFromResultSequence((ResultSequence)argConvertedVal,
+ xctxt);
+ if (nodeSet != null) {
+ argConvertedVal = nodeSet;
+ }
+ }
+
+ varStack.setLocalVariable(paramIdx, argConvertedVal, argsFrame);
+ paramIdx++;
+ }
+ else {
+ break;
+ }
+ }
+ }
- NodeList nodeList = (new XRTreeFrag(df, xctxt, this)).convertToNodeset();
+ int nodeDtmHandle = transformer.transformToGlobalRTF(this);
+
+ NodeList nodeList = (new XRTreeFrag(nodeDtmHandle, xctxt, this)).convertToNodeset();
result = new XNodeSetForDOM(nodeList, xctxt);
@@ -257,7 +321,7 @@ public class ElemFunction extends ElemTemplate
}
/**
- * This method helps us solve, xsl:function and xsl:variable instruction use cases,
+ * This method helps us to implement xsl:function and xsl:variable instructions,
* when the XSL child contents of xsl:function or xsl:variable instructions contain
* xsl:sequence instruction(s).
*
@@ -265,9 +329,9 @@ public class ElemFunction extends ElemTemplate
* instructions, and the function's or variable's expected data type, cast an input data
* value to the supplied expected data type.
*/
- public static ResultSequence preprocessXslFunctionOrAVariableResult(XNodeSetForDOM xNodeSetForDOM,
- String sequenceTypeXPathExprStr,
- XPathContext xctxt, QName varQName) throws TransformerException {
+ public ResultSequence preprocessXslFunctionOrAVariableResult(XNodeSetForDOM xNodeSetForDOM,
+ String sequenceTypeXPathExprStr,
+ XPathContext xctxt, QName varQName) throws TransformerException {
ResultSequence resultSequence = null;
DTMNodeList dtmNodeList = (DTMNodeList)(xNodeSetForDOM.object());
@@ -336,12 +400,19 @@ public class ElemFunction extends ElemTemplate
return resultSequence;
}
+ /**
+ * A method that returns a default instance of this class.
+ */
+ public static ElemFunction getXSLFunctionService() {
+ return new ElemFunction();
+ }
+
/**
* Given XalanJ's integer code value of, an XML Schema built-in data type and a
* string representation of a data value, construct XalanJ's typed data object
* corresponding to the data type's integer code value.
*/
- private static XObject getXSTypedAtomicValue(String strVal, int sequenceType) throws TransformerException {
+ private XObject getXSTypedAtomicValue(String strVal, int sequenceType) throws TransformerException {
XObject result = null;
diff --git a/src/org/apache/xalan/templates/ElemParam.java b/src/org/apache/xalan/templates/ElemParam.java
index d9273360..93a01cd2 100644
--- a/src/org/apache/xalan/templates/ElemParam.java
+++ b/src/org/apache/xalan/templates/ElemParam.java
@@ -123,15 +123,7 @@ public class ElemParam extends ElemVariable
SourceLocator srcLocator = xctx.getSAXLocator();
- boolean isChildElemOfXslElemIterate = false;
- if (getParentElem() instanceof ElemIterate) {
- isChildElemOfXslElemIterate = true;
- }
-
- if (!vars.isLocalSet(m_index) || (isChildElemOfXslElemIterate && (xslIterateIterationIdx == 0))) {
- // The caller of an stylesheet callable component (associated with this xsl:param element),
- // didn't provide xsl:param's value via xsl:with-param instruction.
-
+ if (!vars.isLocalSet(m_index) || ((getParentElem() instanceof ElemIterate) && (xslIterateIterationIdx == 0))) {
int sourceNode = transformer.getXPathContext().getCurrentNode();
try {
@@ -151,31 +143,27 @@ public class ElemParam extends ElemVariable
+ "stylesheet context, or parameter's value cannot be cast to an expected type.", srcLocator);
}
}
- else {
- // The caller of an stylesheet callable component (associated with this xsl:param element),
- // has provided xsl:param's value via xsl:with-param instruction.
-
- // If the xsl:param instruction has an 'as' attribute, we check below
- // whether xsl:param's value conforms to the sequence type specified by
- // xsl:param's 'as' attribute.
- String asAttrVal = getAs();
-
- if (asAttrVal != null) {
- try {
- XObject var = transformer.getXPathContext().getVarStack().getLocalVariable(xctx, m_index);
- var = SequenceTypeSupport.convertXDMValueToAnotherType(var, asAttrVal, null,
- transformer.getXPathContext());
- if (var == null) {
- throw new TransformerException("XTTE0590 : The required item type of the value of parameter " +
- m_qname.toString() + " is " + asAttrVal + ". The supplied value "
- + "doesn't match the expected item type.", srcLocator);
- }
- }
- catch (TransformerException ex) {
- throw new TransformerException("XTTE0590 : The required item type of the value of parameter " +
- m_qname.toString() + " is " + asAttrVal + ". The supplied value "
- + "doesn't match the expected item type.", srcLocator);
- }
+ else {
+ if (!(getParentElem() instanceof ElemFunction)) {
+ String asAttrVal = getAs();
+
+ if (asAttrVal != null) {
+ try {
+ XObject var = transformer.getXPathContext().getVarStack().getLocalVariable(xctx, m_index);
+ var = SequenceTypeSupport.convertXDMValueToAnotherType(var, asAttrVal, null,
+ transformer.getXPathContext());
+ if (var == null) {
+ throw new TransformerException("XTTE0590 : The required item type of the value of parameter " +
+ m_qname.toString() + " is " + asAttrVal + ". The supplied value "
+ + "doesn't match the expected item type.", srcLocator);
+ }
+ }
+ catch (TransformerException ex) {
+ throw new TransformerException("XTTE0590 : The required item type of the value of parameter " +
+ m_qname.toString() + " is " + asAttrVal + ". The supplied value "
+ + "doesn't match the expected item type.", srcLocator);
+ }
+ }
}
}
diff --git a/src/org/apache/xalan/templates/ElemTemplate.java b/src/org/apache/xalan/templates/ElemTemplate.java
index 3b996461..82a7efba 100644
--- a/src/org/apache/xalan/templates/ElemTemplate.java
+++ b/src/org/apache/xalan/templates/ElemTemplate.java
@@ -190,9 +190,8 @@ public class ElemTemplate extends ElemTemplateElement
/**
* An xsl:template element with a name attribute specifies a named template.
- * @serial
*/
- private QName m_name = null;
+ protected QName m_name = null;
/**
* Set the "name" attribute.
diff --git a/src/org/apache/xalan/templates/ElemVariable.java b/src/org/apache/xalan/templates/ElemVariable.java
index c08010c3..9d2a55f3 100644
--- a/src/org/apache/xalan/templates/ElemVariable.java
+++ b/src/org/apache/xalan/templates/ElemVariable.java
@@ -559,7 +559,9 @@ public class ElemVariable extends ElemTemplateElement
XObject variableConvertedVal = null;
try {
- variableConvertedVal = ElemFunction.preprocessXslFunctionOrAVariableResult((XNodeSetForDOM)var, m_asAttr, xctxt, m_qname);
+ ElemFunction elemFunction = ElemFunction.getXSLFunctionService();
+ variableConvertedVal = elemFunction.preprocessXslFunctionOrAVariableResult((XNodeSetForDOM)var,
+ m_asAttr, xctxt, m_qname);
}
catch (TransformerException ex) {
throw new TransformerException(ex.getMessage(), srcLocator);
diff --git a/src/org/apache/xpath/VariableStack.java b/src/org/apache/xpath/VariableStack.java
index 26416586..4b5ce395 100644
--- a/src/org/apache/xpath/VariableStack.java
+++ b/src/org/apache/xpath/VariableStack.java
@@ -201,7 +201,7 @@ public class VariableStack implements Cloneable
* <a href="http://math.millikin.edu/mprogers/Courses/currentCourses/CS481-ComputerArchitecture/cs481.Motorola68000.html">
* Motorola 68000 assembler</a> memories.</p>
*
- * @param size The size of the stack frame allocation. This ammount should
+ * @param size The size of the stack frame allocation. This amount should
* normally be the maximum number of variables that you can have allocated
* at one time in the new stack frame.
*
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xalan.apache.org
For additional commands, e-mail: commits-help@xalan.apache.org