You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@xalan.apache.org by bu...@apache.org on 2001/10/08 03:49:44 UTC

DO NOT REPLY [Bug 4016] New: - Lazy evaluation of variables causes problems when variables are set in global space

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=4016>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=4016

Lazy evaluation of variables causes problems when variables are set in global space

           Summary: Lazy evaluation of variables causes problems when
                    variables are set in global space
           Product: XalanJ2
           Version: 2.2.x
          Platform: PC
        OS/Version: Windows NT/2K
            Status: NEW
          Severity: Major
          Priority: Other
         Component: org.apache.xpath
        AssignedTo: xalan-dev@xml.apache.org
        ReportedBy: dmachak@tibco.com


I'm using:
Xalan 2.2 D11
Crimson 1.1
JDK 1.3
Win 2K

This is a bug that has broken a large number of stylesheets that were working 
in Xalan 1. Note that I've put the Serverity as Major, since although there is 
a workaround, it would mean having to re-do a large number of templates from 
Xalan1 that would otherwise work OK. 

We have a number of templates that import another stylesheet that contains the 
extension function initialization code. An object is passed into the stylesheet 
that is then used to initialize the default object bound to a particular 
extension namespace.

What I've found now in Xalan2 is that execution of the variable (which is in 
the global space) is not performed until it is actually referenced. This was 
never done in our templates since the variable is only a dummy used to 
initialize the default object. Below is some code, a stylesheet, and sample 
output that illustrate the problem.

Sample Code:
####################################################################
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import java.io.*;

public class ExtensionTest {
    private String m_value = "original value";
    public static void main(String[] args) {
        try {
            String filename = args[0];
            TransformerFactory factory = TransformerFactory.newInstance();
            Templates sheet = factory.newTemplates(new StreamSource(new File
(filename)));
            Transformer transformer = sheet.newTransformer();
            Result result = new StreamResult(System.out);
            Source source = new StreamSource(new StringReader("<content/>"));

            ExtensionTest et = new ExtensionTest();
            Context etc = new Context("new value");
            transformer.setParameter("context", etc);
            transformer.transform(source, result);
        }
        catch (Throwable t) {
            System.out.println(t.toString());
            t.printStackTrace();
        }
    }

    public ExtensionTest() {}
    public String getvalue() {return m_value;}
    public void init(Context context) {
        System.out.print("In ExtensionTest.init(Context)");
        m_value = context.m_contextValue;
    }

    public static class Context {
        String m_contextValue = null;
        public Context(String value) {m_contextValue = value;}
    }
}
####################################################################


StyleSheet
####################################################################
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:lxslt="http://xml.apache.org/xslt"
    xmlns:ext="xalan://ExtensionTest"
    exclude-result-prefixes="ext"
    extension-element-prefixes="ext"
    version="1.0">


<lxslt:component prefix="ext" elements="init" functions="init getvalue">
    <lxslt:script lang="javaclass" src="xalan://ExtensionTest"/>
</lxslt:component>

<xsl:param name="context"/>
<!-- The following variable declaration doesn't get evaluated until
     the variable is actually referenced. This is a problem because 
     this call initializes the default object bound to the ext: namespace -->
<xsl:variable name="temp" select="ext:init($context)"/>

<xsl:template match="/">
    In Root Template. The default object for the ext: namespace
    should have been initialized by now with the Context passed in.
    
    <!-- The following reference is made relative to the default object bound
         to the ext: namespace. Since the init method has not yet been called,
         it creates a default instance and calls the getvalue method on that
         object. -->
    Value of ext:getvalue(). 
        Should be "new value": <xsl:value-of select="ext:getvalue()"/>
    
    <!--  This causes the expression for the $temp variable to be 
          executed, which initializes the default object with the 
          context value passed in. -->
    Now ref the var 'temp'   : <xsl:variable name="temp2" select="$temp"/>

    Value of ext:getvalue(). 
        Now it is correct    : <xsl:value-of select="ext:getvalue()"/>

    Finished.
</xsl:template>

</xsl:stylesheet>
####################################################################

Sample Output:
####################################################################
C:>c:\jdk1.3\bin\java ExtensionTest sheet.xslt
<?xml version="1.0" encoding="UTF-8"?>

    In Root Template. The default object for the ext: namespace
    should have been initialized by now with the Context passed in.


    Value of ext:getvalue().
        Should be "new value": original value


    Now ref the var 'temp'   : In ExtensionTest.init(Context)

    Value of ext:getvalue().
        Now it is correct    : new value

    Finished.

####################################################################