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
  
  
  

Reply via email to