You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by jk...@locus.apache.org on 2000/09/21 21:10:17 UTC

cvs commit: xml-xalan/java/src/trax trax.properties

jkesselm    00/09/21 12:10:13

  Modified:    java/src/org/apache/xalan/processor
                        CompilingStylesheetHandler.java
               java/src/org/apache/xalan/res XSLTInfo.properties
               java/src/trax trax.properties
  Log:
  Fixed known reentrancy problem; CompiledTemplates should now be runnable in multiple threads.
  
  Revision  Changes    Path
  1.2       +27 -19    xml-xalan/java/src/org/apache/xalan/processor/CompilingStylesheetHandler.java
  
  Index: CompilingStylesheetHandler.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/processor/CompilingStylesheetHandler.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- CompilingStylesheetHandler.java	2000/09/20 23:33:09	1.1
  +++ CompilingStylesheetHandler.java	2000/09/21 19:09:59	1.2
  @@ -247,18 +247,14 @@
   
           // Namespace context tracking. Note that this is dynamic state
           // during execution, _NOT_ the static state tied to a single 
  -        // ElemTemplateElement during parsing
  -//GONK//		
  -        // TODO: ***** PROBLEM: THIS ISN'T THREADSAFE. It needs to be
  -		// a class field rather than an automatic in order to support
  -		// callback via getNamespaceForPrefix. But it also needs to be
  -		// thread-specific. Unfortunately, that callback doesn't pass 
  -		// the xctxt as a parameter, so we can't stash it there.
  -		// Best thought I've got is a Thread-indexed hashtable... ugh.
  -        synthetic.reflection.Field m_nsSupport=
  -            tClass.declareField("m_nsSupport");
  -        m_nsSupport.setType(tClass.forClass(org.xml.sax.helpers.NamespaceSupport.class));
  -        m_nsSupport.setInitializer("new org.xml.sax.helpers.NamespaceSupport()");
  +        // ElemTemplateElement during parsing. Also note that it needs to
  +		// be set in execute() but testable in getNamespaceForPrefix --
  +		// and the latter, most unfortunately, is not passed the xctxt so
  +		// making that threadsafe is a bit ugly. 
  +        synthetic.reflection.Field m_nsThreadContexts=
  +            tClass.declareField("m_nsThreadContexts");
  +        m_nsThreadContexts.setType(tClass.forClass(java.util.Hashtable.class));
  +        m_nsThreadContexts.setInitializer("new java.util.Hashtable()");
           // And accessor, to let kids query current state
           synthetic.reflection.Method getNSURI =
               tClass.declareMethod("getNamespaceForPrefix");
  @@ -266,7 +262,10 @@
           getNSURI.setReturnType(tClass.forClass(java.lang.String.class));
           getNSURI.setModifiers(java.lang.reflect.Modifier.PUBLIC);
           getNSURI.getBody().append(
  -			"String nsuri=m_nsSupport.getURI(nsprefix);\n"
  +			"String nsuri=\"\";\n"								  
  +			+"org.xml.sax.helpers.NamespaceSupport nsSupport=(org.xml.sax.helpers.NamespaceSupport)m_nsThreadContexts.get(Thread.currentThread());\n"
  +			+"if(null!=nsSupport)\n"
  +			+"\tnsuri=nsSupport.getURI(nsprefix);\n"
   			+"if(null==nsuri || nsuri.length()==0)\n"
   			+"nsuri=m_parentNode.getNamespaceForPrefix(nsprefix);\n"
   			+"return nsuri;\n"
  @@ -372,12 +371,21 @@
                 +"if (check)\n"
                 +"  transformer.getStackGuard().push(this, sourceNode);\n"
                 +"String avtStringedValue; // ***** Optimize away?\n\n"
  -				);
  +		  // Establish dynamic namespace context for this invocation
  +			  +"org.xml.sax.helpers.NamespaceSupport nsSupport=new org.xml.sax.helpers.NamespaceSupport();\n"
  +			  +"org.xml.sax.helpers.NamespaceSupport savedNsSupport=(org.xml.sax.helpers.NamespaceSupport)m_nsThreadContexts.get(Thread.currentThread());\n"
  +			  +"m_nsThreadContexts.put(Thread.currentThread(),nsSupport);\n"
  +			  );
  +
             
             compileChildTemplates(source,body,interpretVector);
             
  +		  // Body Cleanup
             body.append(
  -              "// Decrement infinite-loop check\n"
  +		  // Restore dynamic namespace context for this invocation
  +			  "if(null!=savedNsSupport) m_nsThreadContexts.put(Thread.currentThread(),savedNsSupport);\n"
  +			  +"else m_nsThreadContexts.remove(Thread.currentThread());\n\n"
  +              +"// Decrement infinite-loop check\n"
                 +"if (check)\n"
                 +"  transformer.getStackGuard().pop();\n"
                 );
  @@ -487,7 +495,7 @@
       int n = prefixTable.size();
       boolean newNSlevel=(n>0);
       if(newNSlevel)
  -        body.append("m_nsSupport.pushContext();\n");
  +        body.append("nsSupport.pushContext();\n");
       for(int i = 0; i < n; i++)
       {
         XMLNSDecl decl = (XMLNSDecl)prefixTable.elementAt(i);
  @@ -500,7 +508,7 @@
               );
         // CompiledTemplate state
           body.append(
  -            "m_nsSupport.declarePrefix(\""
  +            "nsSupport.declarePrefix(\""
               +decl.getPrefix()+"\",\""
               +decl.getURI()+"\");\n"
               );
  @@ -572,7 +580,7 @@
                   +ele.getLocalName()+"\",\""
                   +ele.getRawName()+"\");\n");
       if(newNSlevel)
  -        body.append("m_nsSupport.popContext();\n");
  +        body.append("nsSupport.popContext();\n");
     }
   
     // Detect and report AttributeSet loops.
  @@ -834,7 +842,7 @@
                   // TODO: ***** BIG ISSUE: What about uncompiled nodes? Do we need
                   //         to become their parent and support gNFP()?
                   //       Bigger restructuring than I've been doing.
  -                +attrNameSpace+"=m_nsSupport.getURI("+nsprefix+");\n"
  +                +attrNameSpace+"=nsSupport.getURI("+nsprefix+");\n"
                   
                   // The if here substitutes for early returns in original code
                   +"if(!"+attributeHandled+")\n{\n"
  
  
  
  1.2       +2 -1      xml-xalan/java/src/org/apache/xalan/res/XSLTInfo.properties
  
  Index: XSLTInfo.properties
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/res/XSLTInfo.properties,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XSLTInfo.properties	2000/06/19 16:52:23	1.1
  +++ XSLTInfo.properties	2000/09/21 19:10:07	1.2
  @@ -7,7 +7,8 @@
   vendor-url=http://xml.apache.org/xalan
   
   # The TRaX Stylesheet processor
  -trax.processor.xslt=org.apache.xalan.processor.StylesheetProcessor
  +# trax.processor.xslt=org.apache.xalan.processor.StylesheetProcessor
  +trax.processor.xslt=org.apache.xalan.processor.CompilingStylesheetProcessor
   
   # The XML Parser for SAX2
   org.xml.sax.driver=org.apache.xerces.parsers.SAXParser
  
  
  
  1.2       +3 -3      xml-xalan/java/src/trax/trax.properties
  
  Index: trax.properties
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/trax/trax.properties,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- trax.properties	2000/06/20 16:30:18	1.1
  +++ trax.properties	2000/09/21 19:10:10	1.2
  @@ -1,5 +1,5 @@
   #
  -# $Revision: 1.1 $ $Date: 2000/06/20 16:30:18 $
  +# $Revision: 1.2 $ $Date: 2000/09/21 19:10:10 $
   #
   # Note: This properties file is provided for illustrative purposes
   #       only and is not part of the interface definition.
  @@ -9,11 +9,11 @@
   #
   
   #
  -# Lis the methods supported by this implementation
  +# List the methods supported by this implementation
   #
   serialize.methods=xml,html,xhtml,text,wml:wml
   
   #
   # Use the Xalan serializer implementation for the default XSLT processor
   #
  -trax.processor.xslt=org.apache.xalan.processor.StylesheetProcessor
  +trax.processor.xslt=org.apache.xalan.processor.CompilingStylesheetProcessor