mmidy 00/11/03 14:39:29
Modified: src/org/apache/xalan/xslt Arg.java Stylesheet.java
VariableStack.java XSLTEngineImpl.java
Log:
Needs review: Lazy evaluation of variables.
Revision Changes Path
1.5 +13 -0 xml-xalan/src/org/apache/xalan/xslt/Arg.java
Index: Arg.java
===================================================================
RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/Arg.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- Arg.java 2000/03/02 10:22:58 1.4
+++ Arg.java 2000/11/03 22:39:17 1.5
@@ -70,6 +70,7 @@
XObject m_val;
String m_expression;
boolean m_isParamVar;
+ ElemVariable m_elem;
/**
* Construct a dummy parameter argument.
@@ -112,6 +113,18 @@
{
m_qname = qname;
m_val = val;
+ m_isParamVar = isParamVar;
+ m_expression = null;
+ }
+
+ /**
+ * Construct a parameter argument.
+ */
+ Arg(QName qname, ElemVariable var, boolean isParamVar)
+ {
+ m_qname = qname;
+ m_elem = var;
+ m_val = null;
m_isParamVar = isParamVar;
m_expression = null;
}
1.37 +7 -3 xml-xalan/src/org/apache/xalan/xslt/Stylesheet.java
Index: Stylesheet.java
===================================================================
RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/Stylesheet.java,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -r1.36 -r1.37
--- Stylesheet.java 2000/10/12 20:56:56 1.36
+++ Stylesheet.java 2000/11/03 22:39:18 1.37
@@ -970,7 +970,11 @@
}
if(!isParam)
{
- var.execute(transformContext, transformContext.m_rootDoc,
transformContext.m_rootDoc, null);
+ //var.execute(transformContext, transformContext.m_rootDoc,
transformContext.m_rootDoc, null);
+ // Push if a variable of this name
doesn't already exist,
+ // don't evaluate the variable value
yet.
+ if
(transformContext.getVarStack().getVariable(var.m_qname) == null)
+
transformContext.getVarStack().pushElemVariable(var.m_qname, var);
}
}
int nImports = m_imports.size();
@@ -1058,8 +1062,8 @@
{
m_attributeSets = new Vector();
}
- // Insert elements by order of importance
- m_attributeSets.insertElementAt(attrSet, 0);
+ // Insert elements by order of importance
+ m_attributeSets.insertElementAt(attrSet, 0);
}
/**
1.8 +32 -4 xml-xalan/src/org/apache/xalan/xslt/VariableStack.java
Index: VariableStack.java
===================================================================
RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/VariableStack.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- VariableStack.java 2000/03/08 13:40:59 1.7
+++ VariableStack.java 2000/11/03 22:39:19 1.8
@@ -204,6 +204,15 @@
{
push(new Arg(qname, val, false));
}
+
+ /**
+ * Push an argument onto the stack. Don't evaluate
+ * it yet.
+ */
+ public void pushElemVariable(QName qname, ElemVariable var)
+ {
+ push(new Arg(qname, var, false));
+ }
/**
* Given a template, search for
@@ -271,10 +280,15 @@
if(obj == contextMarker)
{
break;
- }
+ }
else if(((Arg)obj).equals(qname))
{
val = ((Arg)obj).m_val;
+ // If val is null, the variable probably has
not been
+ // evaluated yet. Return the argument so that
the caller
+ // can evaluate the variable.
+ if (val == null)
+ val = new XObject(obj);
break;
}
}
@@ -300,7 +314,13 @@
}
else if(((Arg)obj).equals(name))
{
- return ((Arg)obj).m_val;
+ XObject val = ((Arg)obj).m_val;
+ // If val is null, the variable probably has
not been
+ // evaluated yet. Return the argument so that
the caller
+ // can evaluate the variable.
+ if (val == null)
+ val = new XObject(obj);
+ return val;
}
}
@@ -310,8 +330,16 @@
Object obj = elementAt(i);
if(obj == contextMarker)
break;
- else if(((Arg)obj).equals(name))
- return ((Arg)obj).m_val;
+ else if(((Arg)obj).equals(name))
+ {
+ XObject val = ((Arg)obj).m_val;
+ // If val is null, the variable probably has
not been
+ // evaluated yet. Return the argument so that
the caller
+ // can evaluate the variable.
+ if (val == null)
+ val = new XObject(obj);
+ return val;
+ }
}
return null;
1.79 +32 -4 xml-xalan/src/org/apache/xalan/xslt/XSLTEngineImpl.java
Index: XSLTEngineImpl.java
===================================================================
RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/XSLTEngineImpl.java,v
retrieving revision 1.78
retrieving revision 1.79
diff -u -r1.78 -r1.79
--- XSLTEngineImpl.java 2000/11/03 00:55:33 1.78
+++ XSLTEngineImpl.java 2000/11/03 22:39:20 1.79
@@ -2997,10 +2997,38 @@
throws org.xml.sax.SAXException
{
Object obj = getVarStack().getVariable(qname);
- if((null != obj) && !(obj instanceof XObject))
- {
- obj = new XObject(obj);
- }
+ if(null != obj)
+ {
+ // If the object is an Arg, then the variable has not
been
+ // evaluated yet. it will be done right here, and the
new value
+ // will replace the value will be set in Arg.
+ if (obj instanceof XObject && (((XObject)obj).object()
instanceof Arg))
+ {
+ ElemVariable var
=((Arg)(((XObject)obj).object())).m_elem;
+ try
+ {
+ //Save the current frame index then
force us to look
+ // only in the global space. Don't
forget to restore
+ // current frame index. Not sure this
is right!!!
+ // Also double check the parameters to
var.getValue().
+ int savIndex =
getVarStack().getCurrentStackFrameIndex();
+
getVarStack().setCurrentStackFrameIndex(-1);
+ XObject val = var.getValue(this,
+
this.m_rootDoc, this.m_rootDoc);
+ ((Arg)(((XObject)obj).object())).m_val
= val;
+
getVarStack().setCurrentStackFrameIndex(savIndex);
+ return val;
+ }
+ catch (Exception ex)
+ {
+ throw new org.xml.sax.SAXException(ex);
+ }
+ }
+ else if(!(obj instanceof XObject))
+ {
+ obj = new XObject(obj);
+ }
+ }
return (XObject)obj;
}