santiagopg    02/05/03 07:17:32

  Modified:    java/src/org/apache/xalan/xsltc/compiler Mode.java
  Log:
  Fixed for Bugzilla 2886 (node15).
  
  Revision  Changes    Path
  1.20      +162 -82   xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Mode.java
  
  Index: Mode.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Mode.java,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- Mode.java 1 Feb 2002 20:07:08 -0000       1.19
  +++ Mode.java 3 May 2002 14:17:32 -0000       1.20
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: Mode.java,v 1.19 2002/02/01 20:07:08 tmiller Exp $
  + * @(#)$Id: Mode.java,v 1.20 2002/05/03 14:17:32 santiagopg Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -82,21 +82,54 @@
    */
   final class Mode implements Constants {
   
  -    private final QName      _name;       // The QName of this mode
  -    private final Stylesheet _stylesheet; // The owning stylesheet
  -    private final String     _methodName; // The method name for this mode
  -    private Vector           _templates;  // All templates in this mode
  -
  -    // Pattern/test sequence for pattern with node()-type kernel
  -    private Vector    _nodeGroup = null;
  -    private TestSeq   _nodeTestSeq = null;
  -
  -    // Pattern/test sequence for pattern with id() or key()-type kernel
  -    private Vector    _idxGroup = null;
  -    private TestSeq   _idxTestSeq = null;
  +    /**
  +     * The name of this mode as defined in the stylesheet.
  +     */
  +    private final QName _name;
  +
  +    /**
  +     * A reference to the stylesheet object that owns this mode.
  +     */
  +    private final Stylesheet _stylesheet; 
  +
  +    /**
  +     * The name of the method in which this mode is compiled.
  +     */
  +    private final String _methodName;
  +
  +    /**
  +     * A vector of all the templates in this mode.
  +     */
  +    private Vector _templates; 
  +
  +    /**
  +     * Group for patterns with node()-type kernel.
  +     */
  +    private Vector _nodeGroup = null;
  +
  +    /**
  +     * Test sequence for patterns with node()-type kernel.
  +     */
  +    private TestSeq _nodeTestSeq = null;
  +
  +    /**
  +     * Group for patterns with id() or key()-type kernel.
  +     */
  +    private Vector _idxGroup = null;
   
  -    // Pattern/test sequence for patterns with any other kernel type
  +    /**
  +     * Test sequence for patterns with id() or key()-type kernel.
  +     */
  +    private TestSeq  _idxTestSeq = null;
  +
  +    /**
  +     * Group for patterns with any other kernel type.
  +     */
       private Vector[]  _patternGroups;
  +
  +    /**
  +     * Test sequence for patterns with any other kernel type.
  +     */
       private TestSeq[] _testSeq;
   
       private Hashtable _neededTemplates = new Hashtable();
  @@ -114,7 +147,8 @@
   
   
       /**
  -     * Creates a new Mode
  +     * Creates a new Mode.
  +     *
        * @param name A textual representation of the mode's QName
        * @param stylesheet The Stylesheet in which the mode occured
        * @param suffix A suffix to append to the method name for this mode
  @@ -200,15 +234,20 @@
            // Get the next template
            final Template template = (Template)templates.nextElement();
   
  -         // Add this template to a table of named templates if it has a name.
  -         // If there are multiple templates with the same name, all but one
  -         // (the one with highest priority) will be disabled.
  -         if (template.isNamed() && !template.disabled())
  +         /* 
  +          * Add this template to a table of named templates if it has a name.
  +          * If there are multiple templates with the same name, all but one
  +          * (the one with highest priority) will be disabled.
  +          */
  +         if (template.isNamed() && !template.disabled()) {
                _namedTemplates.put(template, this);
  +         }
   
            // Add this template to a test sequence if it has a pattern
            final Pattern pattern = template.getPattern();
  -         if (pattern != null) flattenAlternative(pattern, template, keys);
  +         if (pattern != null) {
  +             flattenAlternative(pattern, template, keys);
  +         }
        }
        prepareTestSequences();
       }
  @@ -261,10 +300,7 @@
        Vector patterns;
   
        // Use the vector for id()/key()/node() patterns if no kernel type
  -     if (kernelType == -1)
  -         patterns = _nodeGroup;
  -     else
  -         patterns = _patternGroups[kernelType];
  +     patterns = (kernelType == -1) ? _nodeGroup : _patternGroups[kernelType];
   
        // Create a new vector if needed and insert the very first pattern
        if (patterns == null) {
  @@ -389,7 +425,8 @@
   
       private void compileTemplates(ClassGenerator classGen,
                                  MethodGenerator methodGen,
  -                               InstructionHandle next) {
  +                               InstructionHandle next) 
  +    {
           Enumeration templates = _namedTemplates.keys();
           while (templates.hasMoreElements()) {
               final Template template = (Template)templates.nextElement();
  @@ -563,22 +600,16 @@
       }
   
       /**
  -     * Auxillary method to determine if a qname describes an attribute/element
  +     * Auxiliary method to determine if a qname describes an attribute/element
        */
       private static boolean isAttributeName(String qname) {
        final int col = qname.lastIndexOf(':') + 1;
  -     if (qname.charAt(col) == '@')
  -         return(true);
  -     else
  -         return(false);
  +     return (qname.charAt(col) == '@');
       }
   
       private static boolean isNamespaceName(String qname) {
        final int col = qname.lastIndexOf(':');
  -     if ((col > -1) && (qname.charAt(qname.length()-1) == '*'))
  -         return(true);
  -     else
  -         return(false);
  +     return (col > -1 && qname.charAt(qname.length()-1) == '*');
       }
   
       /**
  @@ -588,9 +619,9 @@
       public void compileApplyTemplates(ClassGenerator classGen) {
        final XSLTC xsltc = classGen.getParser().getXSLTC();
        final ConstantPoolGen cpg = classGen.getConstantPool();
  -     final Vector names      = xsltc.getNamesIndex();
  +     final Vector names = xsltc.getNamesIndex();
   
  -     // (*) Create the applyTemplates() method
  +     // Create the applyTemplates() method
        final org.apache.bcel.generic.Type[] argTypes =
            new org.apache.bcel.generic.Type[3];
        argTypes[0] = Util.getJCRefType(DOM_INTF_SIG);
  @@ -611,20 +642,20 @@
                                classGen.getConstantPool());
        methodGen.addException("org.apache.xalan.xsltc.TransletException");
   
  -     // (*) Create the local variablea
  +     // Create a local variable to hold the current node
        final LocalVariableGen current;
        current = methodGen.addLocalVariable2("current",
                                              org.apache.bcel.generic.Type.INT,
                                              mainIL.getEnd());
        _currentIndex = current.getIndex();
   
  -     // (*) Create the "body" instruction list that will eventually hold the
  -     //     code for the entire method (other ILs will be appended).
  +     // Create the "body" instruction list that will eventually hold the
  +     // code for the entire method (other ILs will be appended).
        final InstructionList body = new InstructionList();
        body.append(NOP);
   
  -     // (*) Create an instruction list that contains the default next-node
  -     //     iteration
  +     // Create an instruction list that contains the default next-node
  +     // iteration
        final InstructionList ilLoop = new InstructionList();
        ilLoop.append(methodGen.loadIterator());
        ilLoop.append(methodGen.nextNode());
  @@ -635,41 +666,44 @@
        // by a single IFNE(body.getStart()) instruction - need workaround:
           final BranchHandle ifeq = ilLoop.append(new IFEQ(null));
        final BranchHandle loop = ilLoop.append(new GOTO_W(null));
  -     ifeq.setTarget(ilLoop.append(RETURN)); // applyTemplates() ends here!
  +     ifeq.setTarget(ilLoop.append(RETURN));  // applyTemplates() ends here!
        final InstructionHandle ihLoop = ilLoop.getStart();
   
  -     // (*) Compile default handling of elements (traverse children)
  +     // Compile default handling of elements (traverse children)
        InstructionList ilRecurse =
            compileDefaultRecursion(classGen, methodGen, ihLoop);
        InstructionHandle ihRecurse = ilRecurse.getStart();
   
  -     // (*) Compile default handling of text/attribute nodes (output text)
  +     // Compile default handling of text/attribute nodes (output text)
        InstructionList ilText =
            compileDefaultText(classGen, methodGen, ihLoop);
        InstructionHandle ihText = ilText.getStart();
   
        // Distinguish attribute/element/namespace tests for further processing
        final int[] types = new int[DOM.NTYPES + names.size()];
  -     for (int i = 0; i < types.length; i++) types[i] = i;
  +     for (int i = 0; i < types.length; i++) {
  +         types[i] = i;
  +     }
   
  +     // Initialize isAttribute[] and isNamespace[] arrays
        final boolean[] isAttribute = new boolean[types.length];
        final boolean[] isNamespace = new boolean[types.length];
        for (int i = 0; i < names.size(); i++) {
            final String name = (String)names.elementAt(i);
  -         isAttribute[i+DOM.NTYPES] = isAttributeName(name);
  -         isNamespace[i+DOM.NTYPES] = isNamespaceName(name);
  +         isAttribute[i + DOM.NTYPES] = isAttributeName(name);
  +         isNamespace[i + DOM.NTYPES] = isNamespaceName(name);
        }
   
  -     // (*) Compile all templates - regardless of pattern type
  +     // Compile all templates - regardless of pattern type
        compileTemplates(classGen, methodGen, ihLoop);
   
  -     // (*) Handle template with explicit "*" pattern
  +     // Handle template with explicit "*" pattern
        final TestSeq elemTest = _testSeq[DOM.ELEMENT];
        InstructionHandle ihElem = ihRecurse;
        if (elemTest != null)
            ihElem = elemTest.compile(classGen, methodGen, ihRecurse);
   
  -     // (*) Handle template with explicit "@*" pattern
  +     // Handle template with explicit "@*" pattern
        final TestSeq attrTest = _testSeq[DOM.ATTRIBUTE];
        InstructionHandle ihAttr = ihText;
        if (attrTest != null)
  @@ -685,39 +719,58 @@
            loop.setTarget(body.getStart());
        }
   
  -     // (*) If there is a match on node() we need to replace ihElem
  -     //     and ihText (default behaviour for elements & text).
  +     // If there is a match on node() we need to replace ihElem
  +     // and ihText if the priority of node() is higher
        if (_nodeTestSeq != null) {
  -         double nodePrio = -0.5; //_nodeTestSeq.getPriority();
  +
  +         // Compare priorities of node() and "*"
  +         double nodePrio = -0.5;     //_nodeTestSeq.getPriority();
            int    nodePos  = _nodeTestSeq.getPosition();
            double elemPrio = (0 - Double.MAX_VALUE);
            int    elemPos  = Integer.MIN_VALUE;
  +
            if (elemTest != null) {
                elemPrio = elemTest.getPriority();
                elemPos  = elemTest.getPosition();
            }
  -         if ((elemPrio == Double.NaN) || (elemPrio < nodePrio) ||
  -             ((elemPrio == nodePrio) && (elemPos < nodePos))) {
  +         if (elemPrio == Double.NaN || elemPrio < nodePrio || 
  +             (elemPrio == nodePrio && elemPos < nodePos)) 
  +         {
                ihElem = _nodeTestSeq.compile(classGen, methodGen, ihLoop);
  -             ihText = ihElem;
  +         }
  +
  +         // Compare priorities of node() and text()
  +         final TestSeq textTest = _testSeq[DOM.TEXT];
  +         double textPrio = (0 - Double.MAX_VALUE);
  +         int    textPos  = Integer.MIN_VALUE;
  +
  +         if (textTest != null) {
  +             textPrio = textTest.getPriority();
  +             textPos  = textTest.getPosition();
  +         }
  +         if (textPrio == Double.NaN || textPrio < nodePrio ||
  +             (textPrio == nodePrio && textPos < nodePos)) 
  +         {
  +             ihText = _nodeTestSeq.compile(classGen, methodGen, ihLoop);
  +             _testSeq[DOM.TEXT] = _nodeTestSeq;
            }
        }
   
  -     // (*) Handle templates with "ns:*" pattern
  +     // Handle templates with "ns:*" pattern
        InstructionHandle elemNamespaceHandle = ihElem;
        InstructionList nsElem = compileNamespaces(classGen, methodGen,
                                                   isNamespace, isAttribute,
                                                   false, ihElem);
        if (nsElem != null) elemNamespaceHandle = nsElem.getStart();
   
  -     // (*) Handle templates with "ns:@*" pattern
  +     // Handle templates with "ns:@*" pattern
        InstructionHandle attrNamespaceHandle = ihAttr;
        InstructionList nsAttr = compileNamespaces(classGen, methodGen,
                                                   isNamespace, isAttribute,
                                                   true, ihAttr);
        if (nsAttr != null) attrNamespaceHandle = nsAttr.getStart();
   
  -     // (*) Handle templates with "ns:elem" or "ns:@attr" pattern
  +     // Handle templates with "ns:elem" or "ns:@attr" pattern
        final InstructionHandle[] targets = new InstructionHandle[types.length];
        for (int i = DOM.NTYPES; i < targets.length; i++) {
            final TestSeq testSeq = _testSeq[i];
  @@ -902,7 +955,7 @@
        // Process all patterns from those templates
        processPatterns(_keys);
   
  -     // (*) Create the applyTemplates() method
  +     // Create the applyTemplates() method
        final org.apache.bcel.generic.Type[] argTypes =
            new org.apache.bcel.generic.Type[3];
        argTypes[0] = Util.getJCRefType(DOM_INTF_SIG);
  @@ -936,20 +989,20 @@
            return;
        }
   
  -     // (*) Create the local variablea
  +     // Create the local variablea
        final LocalVariableGen current;
        current = methodGen.addLocalVariable2("current",
                                              org.apache.bcel.generic.Type.INT,
                                              mainIL.getEnd());
        _currentIndex = current.getIndex();
   
  -     // (*) Create the "body" instruction list that will eventually hold the
  -     //     code for the entire method (other ILs will be appended).
  +     // Create the "body" instruction list that will eventually hold the
  +     // code for the entire method (other ILs will be appended).
        final InstructionList body = new InstructionList();
        body.append(NOP);
   
  -     // (*) Create an instruction list that contains the default next-node
  -     //     iteration
  +     // Create an instruction list that contains the default next-node
  +     // iteration
        final InstructionList ilLoop = new InstructionList();
        ilLoop.append(methodGen.loadIterator());
        ilLoop.append(methodGen.nextNode());
  @@ -965,7 +1018,9 @@
   
        // Distinguish attribute/element/namespace tests for further processing
        final int[] types = new int[DOM.NTYPES + names.size()];
  -     for (int i = 0; i < types.length; i++) types[i] = i;
  +     for (int i = 0; i < types.length; i++) {
  +         types[i] = i;
  +     }
   
        final boolean[] isAttribute = new boolean[types.length];
        final boolean[] isNamespace = new boolean[types.length];
  @@ -975,20 +1030,22 @@
            isNamespace[i+DOM.NTYPES] = isNamespaceName(name);
        }
   
  -     // (*) Compile all templates - regardless of pattern type
  +     // Compile all templates - regardless of pattern type
        compileTemplateCalls(classGen, methodGen, ihLoop, min, max);
   
  -     // (*) Handle template with explicit "*" pattern
  +     // Handle template with explicit "*" pattern
        final TestSeq elemTest = _testSeq[DOM.ELEMENT];
        InstructionHandle ihElem = ihLoop;
  -     if (elemTest != null)
  +     if (elemTest != null) {
            ihElem = elemTest.compile(classGen, methodGen, ihLoop);
  +     }
   
  -     // (*) Handle template with explicit "@*" pattern
  +     // Handle template with explicit "@*" pattern
        final TestSeq attrTest = _testSeq[DOM.ATTRIBUTE];
        InstructionHandle ihAttr = ihLoop;
  -     if (attrTest != null)
  +     if (attrTest != null) {
            ihAttr = attrTest.compile(classGen, methodGen, ihAttr);
  +     }
   
        // Do tests for id() and key() patterns first
        InstructionList ilKey = null;
  @@ -1000,40 +1057,61 @@
            loop.setTarget(body.getStart());
        }
   
  -     // (*) If there is a match on node() we need to replace ihElem
  -     //     and ihText (default behaviour for elements & text).
  +     // If there is a match on node() we need to replace ihElem
  +     // and ihText if the priority of node() is higher
        InstructionHandle ihText = ihLoop;
        if (_nodeTestSeq != null) {
  -         double nodePrio = -0.5; //_nodeTestSeq.getPriority();
  +
  +         // Compare priorities of node() and "*"
  +         double nodePrio = -0.5;     //_nodeTestSeq.getPriority();
            int    nodePos  = _nodeTestSeq.getPosition();
            double elemPrio = (0 - Double.MAX_VALUE);
            int    elemPos  = Integer.MIN_VALUE;
  +
            if (elemTest != null) {
                elemPrio = elemTest.getPriority();
                elemPos  = elemTest.getPosition();
            }
  -         if ((elemPrio == Double.NaN) || (elemPrio < nodePrio) ||
  -             ((elemPrio == nodePrio) && (elemPos < nodePos))) {
  +
  +         if (elemPrio == Double.NaN || elemPrio < nodePrio || 
  +             (elemPrio == nodePrio && elemPos < nodePos)) 
  +         {
                ihElem = _nodeTestSeq.compile(classGen, methodGen, ihLoop);
  -             ihText = ihElem;
  +         }
  +
  +         // Compare priorities of node() and text()
  +         final TestSeq textTest = _testSeq[DOM.TEXT];
  +         double textPrio = (0 - Double.MAX_VALUE);
  +         int    textPos  = Integer.MIN_VALUE;
  +
  +         if (textTest != null) {
  +             textPrio = textTest.getPriority();
  +             textPos  = textTest.getPosition();
  +         }
  +
  +         if (textPrio == Double.NaN || textPrio < nodePrio ||
  +             (textPrio == nodePrio && textPos < nodePos)) 
  +         {
  +             ihText = _nodeTestSeq.compile(classGen, methodGen, ihLoop);
  +             _testSeq[DOM.TEXT] = _nodeTestSeq;
            }
        }
   
  -     // (*) Handle templates with "ns:*" pattern
  +     // Handle templates with "ns:*" pattern
        InstructionHandle elemNamespaceHandle = ihElem;
        InstructionList nsElem = compileNamespaces(classGen, methodGen,
                                                   isNamespace, isAttribute,
                                                   false, ihElem);
        if (nsElem != null) elemNamespaceHandle = nsElem.getStart();
   
  -     // (*) Handle templates with "ns:@*" pattern
  +     // Handle templates with "ns:@*" pattern
        InstructionList nsAttr = compileNamespaces(classGen, methodGen,
                                                   isNamespace, isAttribute,
                                                   true, ihAttr);
        InstructionHandle attrNamespaceHandle = ihAttr;
        if (nsAttr != null) attrNamespaceHandle = nsAttr.getStart();
   
  -     // (*) Handle templates with "ns:elem" or "ns:@attr" pattern
  +     // Handle templates with "ns:elem" or "ns:@attr" pattern
        final InstructionHandle[] targets = new InstructionHandle[types.length];
        for (int i = DOM.NTYPES; i < targets.length; i++) {
            final TestSeq testSeq = _testSeq[i];
  @@ -1080,12 +1158,14 @@
        // Match on processing instruction - default: loop
        InstructionHandle ihPI = ihLoop;
        if (_nodeTestSeq != null) ihPI = ihElem;
  -     if (_testSeq[DOM.PROCESSING_INSTRUCTION] != null)
  +     if (_testSeq[DOM.PROCESSING_INSTRUCTION] != null) {
            targets[DOM.PROCESSING_INSTRUCTION] =
                _testSeq[DOM.PROCESSING_INSTRUCTION].
                compile(classGen, methodGen, ihPI);
  -     else
  +     }
  +     else {
            targets[DOM.PROCESSING_INSTRUCTION] = ihPI;
  +     }
        
        // Match on comments - default: process next node
        InstructionHandle ihComment = ihLoop;
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to