morten      01/08/17 06:17:45

  Modified:    java/src/org/apache/xalan/xsltc/compiler IdKeyPattern.java
                        Key.java KeyCall.java Parser.java Sort.java
                        xpath.cup
               java/src/org/apache/xalan/xsltc/compiler/util
                        CompareGenerator.java NodeSortRecordGenerator.java
               java/src/org/apache/xalan/xsltc/dom DTDMonitor.java
                        DupFilterIterator.java KeyIndex.java
                        NodeSortRecord.java NodeSortRecordFactory.java
               java/src/org/apache/xalan/xsltc/runtime
                        AbstractTranslet.java BasisLibrary.java
  Log:
  Major update for id() and key(). Patterns containing id() and key() are
  now 100% supported (about time), and id() and key() expressions should
  now work in all (at least most) combinations.
  PR:           bugzilla 1376 (!!!) and 2624
  Obtained from:        n/a
  Submitted by: [EMAIL PROTECTED]
  Reviewed by:  [EMAIL PROTECTED]
  
  Revision  Changes    Path
  1.5       +3 -3      
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/IdKeyPattern.java
  
  Index: IdKeyPattern.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/IdKeyPattern.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- IdKeyPattern.java 2001/08/16 12:17:15     1.4
  +++ IdKeyPattern.java 2001/08/17 13:17:44     1.5
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: IdKeyPattern.java,v 1.4 2001/08/16 12:17:15 morten Exp $
  + * @(#)$Id: IdKeyPattern.java,v 1.5 2001/08/17 13:17:44 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -123,10 +123,10 @@
        // Initialises a KeyIndex to return nodes with specific values
        final int lookupId = cpg.addMethodref(KEY_INDEX_CLASS,
                                              "containsID",
  -                                           "(ILjava/lang/String;)I");
  +                                           "(ILjava/lang/Object;)I");
        final int lookupKey = cpg.addMethodref(KEY_INDEX_CLASS,
                                               "containsKey",
  -                                            "(ILjava/lang/String;)I");
  +                                            "(ILjava/lang/Object;)I");
   
        // Call getKeyIndex in AbstractTranslet with the name of the key
        // to get the index for this key (which is also a node iterator).
  
  
  
  1.7       +57 -28    xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Key.java
  
  Index: Key.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Key.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- Key.java  2001/08/01 11:52:58     1.6
  +++ Key.java  2001/08/17 13:17:44     1.7
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: Key.java,v 1.6 2001/08/01 11:52:58 morten Exp $
  + * @(#)$Id: Key.java,v 1.7 2001/08/17 13:17:44 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -74,18 +74,31 @@
   import org.apache.xalan.xsltc.dom.Axis;
   
   final class Key extends TopLevelElement {
  -    private QName      _name;
  -    private Pattern    _match;
  -    private Expression _use;
  -    private Type       _useType;
   
  +    private QName      _name;     // The name of this key (ie. index)
  +    private Pattern    _match;    // The nodes to generate index keys from
  +    private Expression _use;      // The nodes to include in the key
  +    private Type       _useType;  // The data type of the key's contents
  +
  +    private final String USE_TYPE_ERR =
  +     "The use-attribute of <key> must be node, node-set, string or number.";
  +
  +    /**
  +     * Parse the <xsl:key> element and attributes
  +     * @param parser A reference to the stylesheet parser
  +     */
       public void parseContents(Parser parser) {
  -     // make sure values are provided
  +
  +     // Get the required attributes and parser XPath expressions
        _name = parser.getQName(getAttribute("name"));
        _match = parser.parsePattern(this, "match", null);
        _use = parser.parseExpression(this, "use", null);
   
  -        // make sure required attribute(s) have been set
  +        // Make sure required attribute(s) have been set
  +        if (_name == null) {
  +         reportError(this, parser, ErrorMsg.NREQATTR_ERR, "name");
  +         return;
  +        }
           if (_match.isDummy()) {
            reportError(this, parser, ErrorMsg.NREQATTR_ERR, "match");
            return;
  @@ -96,16 +109,9 @@
           }
       }
   
  -    public Pattern getPattern() {
  -     return(_match);
  -    }
  -
  -    public StepPattern getKernelPattern() {
  -     return(((LocationPathPattern)_match).getKernelPattern());
  -    }
  -
       /**
  -     *
  +     * Returns a String-representation of this key's name
  +     * @return The key's name (from the <xsl:key> elements 'name' attribute).
        */
       public String getName() {
        String name;
  @@ -119,22 +125,28 @@
       /**
        * Run type check on the "use" attribute and make sure it is something
        * we can use to extract some value from nodes.
  +     * @param stable The stylesheet parser's symbol table
  +     * @return The data-type of this key (always void)
  +     * @throws TypeCheckError If the use attribute does not represent a string,
  +     *   a node-set or a number
        */
       public Type typeCheck(SymbolTable stable) throws TypeCheckError {
        _match.typeCheck(stable);
        _useType = _use.typeCheck(stable);
  -     // If the 'use' attribute is not a string...
  -     if (!(_useType instanceof StringType)) {
  +
  +     // Cast node values to string values
  +     if (_useType instanceof NodeType) {
  +         _use = new CastExpr(_use, Type.String);
  +         _useType = Type.String;
  +     }
   
  -         // ...it must hold an expression for a node...
  -         if (_useType instanceof NodeType) {
  -             _use = new CastExpr(_use, Type.String);
  -         }
  -         // ...or a node-set.
  -         else if (!(_useType instanceof NodeSetType)) {
  -             throw new TypeCheckError(this);
  -         }
  +     // If the 'use' attribute is not a string, node-set or number
  +     if (!(_useType instanceof StringType) &&
  +         !(_useType instanceof NodeSetType) &&
  +         !(_useType instanceof RealType)) {
  +         throw new TypeCheckError(new ErrorMsg(USE_TYPE_ERR));
        }
  +
        return Type.Void;
       }
   
  @@ -142,6 +154,8 @@
        * This method is called if the "use" attribute of the key contains a
        * node set. In this case we must traverse all nodes in the set and
        * create one entry in this key's index for each node in the set.
  +     * @param classGen The Java class generator
  +     * @param methodGen The method generator
        */
       public void traverseNodeSet(ClassGenerator classGen,
                                MethodGenerator methodGen,
  @@ -205,6 +219,8 @@
       /**
        * Gather all nodes that match the expression in the attribute "match"
        * and add one (or more) entries in this key's index.
  +     * @param classGen The Java class generator
  +     * @param methodGen The method generator
        */
       public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
   
  @@ -215,7 +231,7 @@
        // AbstractTranslet.buildKeyIndex(name,node_id,value) => void
        final int key = cpg.addMethodref(TRANSLET_CLASS,
                                         "buildKeyIndex",
  -                                      "("+STRING_SIG+"I"+STRING_SIG+")V");
  +                                      "("+STRING_SIG+"I"+OBJECT_SIG+")V");
   
        // DOM.getAxisIterator(root) => NodeIterator
        final int git = cpg.addMethodref(classGen.getDOMClass(),
  @@ -247,7 +263,20 @@
        
        // If this is just a single node we should convert that to a string
        // and use that string as the value in the index for this key.
  -     if ((_useType instanceof NodeType) || (_useType instanceof StringType)) {
  +     if (_useType instanceof RealType) {
  +         final int dbl = cpg.addMethodref(DOUBLE_CLASS,"<init>", "(D)V");
  +
  +         il.append(classGen.loadTranslet());
  +         il.append(new PUSH(cpg, _name.toString()));
  +         il.append(methodGen.loadCurrentNode());
  +         il.append(new NEW(cpg.addClass(DOUBLE_CLASS)));
  +         il.append(DUP);
  +         _use.translate(classGen,methodGen);
  +         il.append(new INVOKESPECIAL(dbl));
  +         il.append(new INVOKEVIRTUAL(key));
  +
  +     }
  +     else if (_useType instanceof StringType) {
            il.append(classGen.loadTranslet());
            il.append(new PUSH(cpg, _name.toString()));
            il.append(methodGen.loadCurrentNode());
  
  
  
  1.5       +46 -18    xml-xalan/java/src/org/apache/xalan/xsltc/compiler/KeyCall.java
  
  Index: KeyCall.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/KeyCall.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- KeyCall.java      2001/08/16 12:17:15     1.4
  +++ KeyCall.java      2001/08/17 13:17:44     1.5
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: KeyCall.java,v 1.4 2001/08/16 12:17:15 morten Exp $
  + * @(#)$Id: KeyCall.java,v 1.5 2001/08/17 13:17:44 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -69,11 +69,11 @@
   import org.apache.xalan.xsltc.compiler.util.*;
   
   final class KeyCall extends FunctionCall {
  -    private final Expression _name;
  -    private Expression _value;
  -    private Type _valueType;
  -    private String _expandedName;
   
  +    private Expression _name;      // The name of this key
  +    private Expression _value;     // The value to look up in the key/index
  +    private Type       _valueType; // The value's data type
  +
       /**
        * Get the parameters passed to function:
        *   key(String name, String value)
  @@ -82,6 +82,9 @@
        * one holding the key name and one holding the value(s) to look up. The
        * vector has only one parameter for id() calls (the key name is always
        * "##id" for id() calls).
  +     *
  +     * @param fname The function name (should be 'key' or 'id')
  +     * @param arguments A vector containing the arguments the the function
        */
       public KeyCall(QName fname, Vector arguments) {
        super(fname, arguments);
  @@ -104,14 +107,18 @@
        * Type check the parameters for the id() or key() function.
        * The index name (for key() call only) must be a string or convertable
        * to a string, and the lookup-value must be a string or a node-set.
  +     * @param stable The parser's symbol table
  +     * @throws TypeCheckError When the parameters have illegal type
        */
       public Type typeCheck(SymbolTable stable) throws TypeCheckError {
        final Type returnType = super.typeCheck(stable);
  -     // Run type check on the key name (first argument) - must be a string
  +
  +     // Run type check on the key name (first argument) - must be a string,
  +     // and if it is not it must be converted to one using string() rules.
        if (_name != null) {
            final Type nameType = _name.typeCheck(stable); 
            if (!(nameType instanceof StringType)) {
  -             throw new TypeCheckError(this);
  +             _name = new CastExpr(_name, Type.String);
            }
        }
   
  @@ -126,8 +133,10 @@
   
        if ((_valueType != Type.NodeSet) &&
            (_valueType != Type.ResultTree) &&
  -         (_valueType != Type.String)) {
  -         _value = new CastExpr(_value,Type.String);
  +         (_valueType != Type.String) &&
  +         (_valueType != Type.Real) &&
  +         (_valueType != Type.Int)) {
  +         _value = new CastExpr(_value, Type.String);
        }
   
        return returnType;
  @@ -136,30 +145,36 @@
       /**
        * This method is called when the constructor is compiled in
        * Stylesheet.compileConstructor() and not as the syntax tree is traversed.
  +     * This method is a wrapper for the real translation method, which is
  +     * the private method translateCall() below. All this method does is to
  +     * wrap the KeyIndex that this function returns inside a duplicate filter.
  +     * The duplicate filter is used both to eliminate duplicates and to
  +     * cache the nodes in the index.
  +     * @param classGen The Java class generator
  +     * @param methodGen The method generator
        */
       public void translate(ClassGenerator classGen,
                          MethodGenerator methodGen) {
        final ConstantPoolGen cpg = classGen.getConstantPool();
        final InstructionList il = methodGen.getInstructionList();
   
  +     // Wrap the KeyIndex (iterator) inside a duplicate filter iterator
  +     // to pre-read the indexed nodes and cache them.
        final int dupInit = cpg.addMethodref(DUP_FILTERED_ITERATOR,
                                             "<init>",
                                             "("+NODE_ITERATOR_SIG+")V");
  -
  -     // Wrap the KeyIndex (iterator) inside a duplicate filter iterator to
  -     // pre-read the indexed nodes and cache them.
        il.append(new NEW(cpg.addClass(DUP_FILTERED_ITERATOR)));
        il.append(DUP);
  -
        translateCall(classGen, methodGen);
  -
        il.append(new INVOKESPECIAL(dupInit));
       }
   
       /**
        * Translate the actual index lookup - leaves KeyIndex (iterator) on stack
  +     * @param classGen The Java class generator
  +     * @param methodGen The method generator
        */
  -    public void translateCall(ClassGenerator classGen,
  +    private void translateCall(ClassGenerator classGen,
                              MethodGenerator methodGen) {
   
        final ConstantPoolGen cpg = classGen.getConstantPool();
  @@ -179,10 +194,10 @@
        // Initialises a KeyIndex to return nodes with specific values
        final int lookupId = cpg.addMethodref(KEY_INDEX_CLASS,
                                              "lookupId",
  -                                           "(Ljava/lang/String;)V");
  +                                           "(Ljava/lang/Object;)V");
        final int lookupKey = cpg.addMethodref(KEY_INDEX_CLASS,
                                               "lookupKey",
  -                                            "(Ljava/lang/String;)V");
  +                                            "(Ljava/lang/Object;)V");
   
        // Merges the nodes in two KeyIndex objects
        final int merge = cpg.addMethodref(KEY_INDEX_CLASS,
  @@ -289,7 +304,20 @@
            // Now use the value in the second argument to determine what nodes
            // the iterator should return.
            il.append(DUP);
  -         _value.translate(classGen, methodGen);
  +
  +         if (_valueType == Type.Int || _valueType == Type.Real) {
  +             final int dbl = cpg.addMethodref(DOUBLE_CLASS,"<init>", "(D)V");
  +             il.append(new NEW(cpg.addClass(DOUBLE_CLASS)));
  +             il.append(DUP);
  +             _value.translate(classGen, methodGen);
  +             if (_valueType == Type.Int)
  +                 il.append(new I2D());
  +             il.append(new INVOKESPECIAL(dbl));
  +         }
  +         else {
  +             _value.translate(classGen, methodGen);
  +         }
  +
            if (_name == null)
                il.append(new INVOKEVIRTUAL(lookupId));
            else
  
  
  
  1.24      +2 -15     xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Parser.java
  
  Index: Parser.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Parser.java,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- Parser.java       2001/08/16 12:17:15     1.23
  +++ Parser.java       2001/08/17 13:17:44     1.24
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: Parser.java,v 1.23 2001/08/16 12:17:15 morten Exp $
  + * @(#)$Id: Parser.java,v 1.24 2001/08/17 13:17:44 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -1023,16 +1023,13 @@
       public void startPrefixMapping(String prefix, String uri) {
        if (_prefixMapping == null) _prefixMapping = new Hashtable();
        _prefixMapping.put(prefix, uri);
  -     //System.err.println("starting mapping for \""+prefix+"\"=\""+uri+"\"");
       }
   
       /**
        * SAX2: End the scope of a prefix-URI Namespace mapping.
        *       This has to be passed on to the symbol table!
        */
  -    public void endPrefixMapping(String prefix) {
  -     //System.err.println("ending mapping for \""+prefix+"\"");
  -    }
  +    public void endPrefixMapping(String prefix) { }
   
       /**
        * SAX2: Receive notification of the beginning of an element.
  @@ -1042,11 +1039,6 @@
       public void startElement(String uri, String localname,
                             String qname, Attributes attributes) 
        throws SAXException {
  -     /*
  -     System.err.println("start element uri=\""+uri+
  -                        "\", local=\""+localname+
  -                        "\", qname=\""+qname+"\"");
  -     */
        final int col = qname.lastIndexOf(':');
        final String prefix;
        if (col == -1)
  @@ -1093,11 +1085,6 @@
        * SAX2: Receive notification of the end of an element.
        */
       public void endElement(String uri, String localname, String qname) {
  -     /*
  -     System.err.println("end element uri=\""+uri+
  -                        "\", local=\""+localname+
  -                        "\", qname=\""+qname+"\"");
  -     */
        _parentStack.pop();
       }
   
  
  
  
  1.5       +3 -2      xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Sort.java
  
  Index: Sort.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Sort.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- Sort.java 2001/07/23 15:24:00     1.4
  +++ Sort.java 2001/08/17 13:17:44     1.5
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: Sort.java,v 1.4 2001/07/23 15:24:00 morten Exp $
  + * @(#)$Id: Sort.java,v 1.5 2001/08/17 13:17:44 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -83,6 +83,7 @@
   
   
   final class Sort extends Instruction {
  +
       private Expression     _select;
       private AttributeValue _order;
       private AttributeValue _caseOrder;
  @@ -419,7 +420,7 @@
                                     Util.getJCRefType(DOM_INTF_SIG),
                                     de.fub.bytecode.generic.Type.INT,
                                     de.fub.bytecode.generic.Type.INT,
  -                                  Util.getJCRefType(TRANSLET_INTF_SIG),
  +                                  Util.getJCRefType(TRANSLET_SIG),
                                     de.fub.bytecode.generic.Type.INT
                                 },
                                 new String[] { "dom",
  
  
  
  1.10      +3 -3      xml-xalan/java/src/org/apache/xalan/xsltc/compiler/xpath.cup
  
  Index: xpath.cup
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/xpath.cup,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- xpath.cup 2001/08/16 14:10:49     1.9
  +++ xpath.cup 2001/08/17 13:17:44     1.10
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: xpath.cup,v 1.9 2001/08/16 14:10:49 tmiller Exp $
  + * @(#)$Id: xpath.cup,v 1.10 2001/08/17 13:17:44 morten Exp $
    *
    * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.
    * 
  @@ -494,12 +494,12 @@
   
           // CASE I: no filtering, nodes OK but have dups,
           //   results of test suite in file: 'REP_UNFILT'
  -        //RESULT = path; 
  +        RESULT = path; 
   
              // CASE II: Filtered Abs Loc Path -
           //    all tests fail except desOrSelf test,
           //    results of test suite in file: 'REP-FILT'
  -        RESULT = new FilteredAbsoluteLocationPath(path); 
  +        //RESULT = new FilteredAbsoluteLocationPath(path); 
   
   
           // CASE III: Filtered Parent Loc Path -
  
  
  
  1.3       +24 -1     
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/CompareGenerator.java
  
  Index: CompareGenerator.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/CompareGenerator.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- CompareGenerator.java     2001/08/01 11:52:59     1.2
  +++ CompareGenerator.java     2001/08/17 13:17:44     1.3
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: CompareGenerator.java,v 1.2 2001/08/01 11:52:59 morten Exp $
  + * @(#)$Id: CompareGenerator.java,v 1.3 2001/08/17 13:17:44 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -65,6 +65,8 @@
   
   import de.fub.bytecode.generic.Type;
   import de.fub.bytecode.generic.*;
  +
  +import org.apache.xalan.xsltc.compiler.Constants;
   import org.apache.xalan.xsltc.compiler.Template;
   
   public final class CompareGenerator extends MethodGenerator {
  @@ -74,11 +76,14 @@
       private static int LEVEL_INDEX    = 3;
       private static int TRANSLET_INDEX = 4;
       private static int LAST_INDEX     = 5;
  +    private int ITERATOR_INDEX = 6;
   
       private final Instruction _iloadCurrent;
       private final Instruction _istoreCurrent;
       private final Instruction _aloadDom;
       private final Instruction _iloadLast;
  +    private final Instruction _aloadIterator;
  +    private final Instruction _astoreIterator;
   
       public CompareGenerator(int access_flags, Type return_type,
                            Type[] arg_types, String[] arg_names,
  @@ -91,6 +96,16 @@
        _istoreCurrent = new ISTORE(CURRENT_INDEX);
        _aloadDom = new ALOAD(DOM_INDEX);
        _iloadLast = new ILOAD(LAST_INDEX);
  +
  +     LocalVariableGen iterator =
  +         addLocalVariable("iterator",
  +                          Util.getJCRefType(Constants.NODE_ITERATOR_SIG),
  +                          null, null);
  +     ITERATOR_INDEX = iterator.getIndex();
  +     _aloadIterator = new ALOAD(ITERATOR_INDEX);
  +     _astoreIterator = new ASTORE(ITERATOR_INDEX);
  +     il.append(new ACONST_NULL());
  +     il.append(storeIterator());
       }
   
       public Instruction loadLastNode() {
  @@ -115,6 +130,14 @@
   
       public int getIteratorIndex() {
        return INVALID_INDEX;
  +    }
  +
  +    public Instruction storeIterator() {
  +     return _astoreIterator;
  +    }
  +    
  +    public Instruction loadIterator() {
  +     return _aloadIterator;
       }
   
       //??? may not be used anymore
  
  
  
  1.3       +4 -1      
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/NodeSortRecordGenerator.java
  
  Index: NodeSortRecordGenerator.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/NodeSortRecordGenerator.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- NodeSortRecordGenerator.java      2001/06/28 15:36:33     1.2
  +++ NodeSortRecordGenerator.java      2001/08/17 13:17:44     1.3
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: NodeSortRecordGenerator.java,v 1.2 2001/06/28 15:36:33 morten Exp $
  + * @(#)$Id: NodeSortRecordGenerator.java,v 1.3 2001/08/17 13:17:44 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -64,7 +64,10 @@
   
   package org.apache.xalan.xsltc.compiler.util;
   
  +import org.apache.xalan.xsltc.compiler.util.Type;
   import de.fub.bytecode.generic.*;
  +import org.apache.xalan.xsltc.compiler.util.*;
  +
   import org.apache.xalan.xsltc.compiler.Stylesheet;
   
   /**
  
  
  
  1.4       +2 -2      xml-xalan/java/src/org/apache/xalan/xsltc/dom/DTDMonitor.java
  
  Index: DTDMonitor.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/DTDMonitor.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- DTDMonitor.java   2001/05/22 17:26:37     1.3
  +++ DTDMonitor.java   2001/08/17 13:17:45     1.4
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: DTDMonitor.java,v 1.3 2001/05/22 17:26:37 morten Exp $
  + * @(#)$Id: DTDMonitor.java,v 1.4 2001/08/17 13:17:45 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -214,7 +214,7 @@
   
            while (( node = niter.next()) != NodeIterator.END) {
                // get id value for the node
  -             String idValue = dom.getAttributeValue(attributeType, node);
  +             Object idValue = dom.getAttributeValue(attributeType, node);
                // add entry into ##id index for KeyCall to handle
                translet.buildKeyIndex(ID_INDEX_NAME, mask|node, idValue);
            }
  
  
  
  1.5       +5 -1      
xml-xalan/java/src/org/apache/xalan/xsltc/dom/DupFilterIterator.java
  
  Index: DupFilterIterator.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/DupFilterIterator.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- DupFilterIterator.java    2001/08/16 15:28:29     1.4
  +++ DupFilterIterator.java    2001/08/17 13:17:45     1.5
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: DupFilterIterator.java,v 1.4 2001/08/16 15:28:29 morten Exp $
  + * @(#)$Id: DupFilterIterator.java,v 1.5 2001/08/17 13:17:45 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -107,6 +107,10 @@
        * @return A reference to this node iterator
        */
       public NodeIterator setStartNode(int node) {
  +     // KeyIndex iterators are always relative to the root node, so there
  +     // is never any point in re-reading the iterator (and we SHOULD NOT).
  +     if ((_source instanceof KeyIndex) && (_data != null)) return this;
  +
        // If the _data array is populated, and the current start node is
        // equal to the new start node, we know we already have what we need.
        if ((_data == null) || (node != _startNode)) {
  
  
  
  1.4       +33 -29    xml-xalan/java/src/org/apache/xalan/xsltc/dom/KeyIndex.java
  
  Index: KeyIndex.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/KeyIndex.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- KeyIndex.java     2001/07/09 10:17:50     1.3
  +++ KeyIndex.java     2001/08/17 13:17:45     1.4
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: KeyIndex.java,v 1.3 2001/07/09 10:17:50 morten Exp $
  + * @(#)$Id: KeyIndex.java,v 1.4 2001/08/17 13:17:45 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -90,7 +90,7 @@
        * Adds a node to the node list for a given value.
        * The BitArray object makes sure duplicate nodes are eliminated.
        */
  -    public void add(String value, int node) {
  +    public void add(Object value, int node) {
        if ((_nodes = (BitArray)_index.get(value)) == null) {
            _nodes = new BitArray(_arraySize);
            _nodes.setMask(node & 0xff000000);
  @@ -127,29 +127,31 @@
        * list of tokens for the id() function, but a single string for the
        * key() function.
        */
  -    public void lookupId(String value) {
  -     if (value.indexOf(' ') > -1) {
  -         StringTokenizer values = new StringTokenizer(value);
  -         while (values.hasMoreElements()) {
  -             BitArray nodes = (BitArray)_index.get(values.nextElement());
  -             if (nodes != null) {
  -                 if (_nodes == null)
  -                     _nodes = nodes;
  -                 else
  -                     _nodes = _nodes.merge(nodes);
  +    public void lookupId(Object value) {
  +     if (value instanceof String) {
  +         final String string = (String)value;
  +         if (string.indexOf(' ') > -1) {
  +             StringTokenizer values = new StringTokenizer(string);
  +             while (values.hasMoreElements()) {
  +                 BitArray nodes = (BitArray)_index.get(values.nextElement());
  +                 if (nodes != null) {
  +                     if (_nodes == null)
  +                         _nodes = nodes;
  +                     else
  +                         _nodes = _nodes.merge(nodes);
  +                 }
                }
  +             return;
            }
        }
  -     else {
  -         _nodes = (BitArray)_index.get(value);
  -     }
  +     _nodes = (BitArray)_index.get(value);
       }
   
       /**
        * This method must be called by the code generated by the key() function
        * prior to returning the node iterator.
        */
  -    public void lookupKey(String value) {
  +    public void lookupKey(Object value) {
        _nodes = (BitArray)_index.get(value);
       }
   
  @@ -163,23 +165,25 @@
        return(_node | _nodes.getMask());
       }
   
  -    public int containsID(int node, String value) { 
  -     if (value.indexOf(' ') > -1) {
  -         StringTokenizer values = new StringTokenizer(value);
  -         while (values.hasMoreElements()) {
  -             BitArray nodes = (BitArray)_index.get(values.nextElement());
  -             if ((nodes != null) && (nodes.getBit(node))) return(1);
  +    public int containsID(int node, Object value) { 
  +     if (value instanceof String) {
  +         final String string = (String)value;
  +         if (string.indexOf(' ') > -1) {
  +             StringTokenizer values = new StringTokenizer(string);
  +             while (values.hasMoreElements()) {
  +                 BitArray nodes = (BitArray)_index.get(values.nextElement());
  +                 if ((nodes != null) && (nodes.getBit(node))) return(1);
  +             }
  +             return(0);
            }
  -         return(0);
        }
  -     else {
  -         BitArray nodes = (BitArray)_index.get(value);
  -         if ((nodes != null) && (nodes.getBit(node))) return(1);
  -         return(0);
  -     }
  +
  +     BitArray nodes = (BitArray)_index.get(value);
  +     if ((nodes != null) && (nodes.getBit(node))) return(1);
  +     return(0);
       }
   
  -    public int containsKey(int node, String value) { 
  +    public int containsKey(int node, Object value) { 
        BitArray nodes = (BitArray)_index.get(value);
        if ((nodes != null) && (nodes.getBit(node))) return(1);
        return(0);
  
  
  
  1.3       +8 -5      
xml-xalan/java/src/org/apache/xalan/xsltc/dom/NodeSortRecord.java
  
  Index: NodeSortRecord.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/NodeSortRecord.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- NodeSortRecord.java       2001/07/23 15:24:00     1.2
  +++ NodeSortRecord.java       2001/08/17 13:17:45     1.3
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: NodeSortRecord.java,v 1.2 2001/07/23 15:24:00 morten Exp $
  + * @(#)$Id: NodeSortRecord.java,v 1.3 2001/08/17 13:17:45 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -69,7 +69,7 @@
   import java.text.CollationKey;
   
   import org.apache.xalan.xsltc.DOM;
  -import org.apache.xalan.xsltc.Translet;
  +import org.apache.xalan.xsltc.runtime.AbstractTranslet;
   
   /**
    * Base class for sort records containing application specific sort keys 
  @@ -86,7 +86,8 @@
       protected static int[] _sortOrder;
       protected static int _levels = 1;
   
  -    private Translet _translet = null;
  +    private AbstractTranslet _translet = null;
  +
       private DOM    _dom = null;
       private int    _node;           // The position in the current iterator
       private int    _last = 0;       // Number of nodes in the current iterator
  @@ -112,7 +113,8 @@
        * This method allows the caller to set the values that could not be passed
        * to the default constructor.
        */
  -    public final void initialize(int node,int last,DOM dom,Translet translet) {
  +    public final void initialize(int node, int last, DOM dom,
  +                              AbstractTranslet translet) {
        _dom = dom;
        _node = node;
        _last = last;
  @@ -217,6 +219,7 @@
        * Extract the sort value for a level of this key.
        */
       public abstract String extractValueFromDOM(DOM dom, int current, int level,
  -                                            Translet translet, int last);
  +                                            AbstractTranslet translet,
  +                                            int last);
   
   }
  
  
  
  1.3       +5 -3      
xml-xalan/java/src/org/apache/xalan/xsltc/dom/NodeSortRecordFactory.java
  
  Index: NodeSortRecordFactory.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/NodeSortRecordFactory.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- NodeSortRecordFactory.java        2001/07/23 15:24:00     1.2
  +++ NodeSortRecordFactory.java        2001/08/17 13:17:45     1.3
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: NodeSortRecordFactory.java,v 1.2 2001/07/23 15:24:00 morten Exp $
  + * @(#)$Id: NodeSortRecordFactory.java,v 1.3 2001/08/17 13:17:45 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -67,13 +67,15 @@
   import org.apache.xalan.xsltc.DOM;
   import org.apache.xalan.xsltc.Translet;
   import org.apache.xalan.xsltc.TransletException;
  +import org.apache.xalan.xsltc.runtime.AbstractTranslet;
   
   public class NodeSortRecordFactory {
       private final DOM      _dom;
       private final Class    _class;
       private final String   _className;
  -    private final Translet _translet;
   
  +    private final AbstractTranslet _translet;
  +
       /**
        * Creates a NodeSortRecord producing object. The DOM specifies which tree
        * to get the nodes to sort from, the class name specifies what auxillary
  @@ -87,7 +89,7 @@
            _dom = dom;
            _className = className;
            _class = Class.forName(className);
  -         _translet = translet;
  +         _translet = (AbstractTranslet)translet;
        }
        catch (ClassNotFoundException e) {
            throw new TransletException("Could not find class " + className);
  
  
  
  1.19      +3 -3      
xml-xalan/java/src/org/apache/xalan/xsltc/runtime/AbstractTranslet.java
  
  Index: AbstractTranslet.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/AbstractTranslet.java,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- AbstractTranslet.java     2001/08/16 12:29:19     1.18
  +++ AbstractTranslet.java     2001/08/17 13:17:45     1.19
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: AbstractTranslet.java,v 1.18 2001/08/16 12:29:19 morten Exp $
  + * @(#)$Id: AbstractTranslet.java,v 1.19 2001/08/17 13:17:45 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -395,9 +395,9 @@
        *   @node is the node id of the node to insert
        *   @value is the value that will look up the node in the given index
        */
  -    public void buildKeyIndex(String name, int node, String value) {
  +    public void buildKeyIndex(String name, int node, Object value) {
        if (_keyIndexes == null) _keyIndexes = new Hashtable();
  -
  +     
        KeyIndex index = (KeyIndex)_keyIndexes.get(name);
        if (index == null) {
            _keyIndexes.put(name, index = new KeyIndex(_indexSize));
  
  
  
  1.9       +46 -27    
xml-xalan/java/src/org/apache/xalan/xsltc/runtime/BasisLibrary.java
  
  Index: BasisLibrary.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/BasisLibrary.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- BasisLibrary.java 2001/07/10 17:46:26     1.8
  +++ BasisLibrary.java 2001/08/17 13:17:45     1.9
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: BasisLibrary.java,v 1.8 2001/07/10 17:46:26 morten Exp $
  + * @(#)$Id: BasisLibrary.java,v 1.9 2001/08/17 13:17:45 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -82,8 +82,11 @@
    * and the DOM as their last two arguments.
    */
   public final class BasisLibrary implements Operators {
  +
  +    private final static String EMPTYSTRING = "";
  +
       /**
  -     * XSLT Standard function count(node-set)
  +     * Standard function count(node-set)
        */
       public static int countF(NodeIterator iterator) {
        int counter = 0;
  @@ -211,7 +214,7 @@
            return  ((Boolean) obj).booleanValue();
        }
        else if (obj instanceof String) {
  -         return !((String) obj).equals("");
  +         return !((String) obj).equals(EMPTYSTRING);
        }
        else if (obj instanceof NodeIterator) {
            NodeIterator iter = (NodeIterator) obj;
  @@ -222,7 +225,7 @@
        }
        else if (obj instanceof DOM) {
            String temp = ((DOM) obj).getStringValue();
  -         return !temp.equals("");
  +         return !temp.equals(EMPTYSTRING);
        }
        else {
            runTimeError("Invalid argument type in call to number().");
  @@ -236,13 +239,14 @@
        */
       public static String substringF(String value, double start) {
        try {
  -         final int valuel = value.length();
  -         final int istart = (int)Math.round(start);
  +         final int strlen = value.length();
  +         int istart = (int)Math.round(start);
   
  -         if (Double.isNaN(start)) return("");
  +         if (Double.isNaN(start)) return(EMPTYSTRING);
   
  -         return value.substring(istart < 1 ? 0 : 
  -                                istart > valuel ? valuel : istart - 1);
  +         if ((istart < 1) || (istart > strlen)) istart = 0;
  +
  +         return value.substring(istart);
        }
        catch (IndexOutOfBoundsException e) {
            runTimeInternalError();
  @@ -256,18 +260,19 @@
        */
       public static String substringF(String value, double start, double length) {
        try {
  -         final int valuel  = value.length();
  -         final int istart  = (int)Math.round(start);
  -         final int ilength = (int)Math.round(length);
  -         final int isum    = istart + ilength;
  -
  -         if (Double.isNaN(start) || Double.isNaN(length)) return("");
  -
  -         return value.substring(istart < 1 || istart > valuel
  -                                ? 0 : istart - 1, 
  -                                ilength < 0
  -                                ? 0 : isum - 1 > valuel
  -                                ? valuel : isum < 1 ? 0 : isum - 1);
  +         final int strlen  = value.length();
  +         int istart = (int)Math.round(start) - 1;
  +         int isum   = istart + (int)Math.round(length);
  +
  +         if (Double.isNaN(start) || Double.isNaN(length))
  +             return(EMPTYSTRING);
  +
  +         if ((istart < 1) || (istart > strlen)) istart = 0;
  +
  +         if ((isum < 0) || (isum > strlen))
  +             return value.substring(istart);
  +         else
  +             return value.substring(istart, isum);
        }
        catch (IndexOutOfBoundsException e) {
            runTimeInternalError();
  @@ -280,7 +285,10 @@
        */
       public static String substring_afterF(String value, String substring) {
        final int index = value.indexOf(substring);
  -     return index >= 0 ? value.substring(index + substring.length()) : "";
  +     if (index >= 0)
  +         return value.substring(index + substring.length());
  +     else
  +         return EMPTYSTRING;
       }
   
       /**
  @@ -288,7 +296,10 @@
        */
       public static String substring_beforeF(String value, String substring) {
        final int index = value.indexOf(substring);
  -     return index >= 0 ? value.substring(0, index) : "";
  +     if (index >= 0)
  +         return value.substring(0, index);
  +     else
  +         return EMPTYSTRING;
       }
   
       /**
  @@ -351,7 +362,12 @@
        * XSLT Standard function generate-id(). 
        */
       public static String generate_idF(int node) {
  -     return "N" + node;
  +     if (node > 0)
  +         // Only generate ID if node exists
  +         return "N" + node;
  +     else
  +         // Otherwise return an empty string
  +         return EMPTYSTRING;
       }
       
       /**
  @@ -398,7 +414,7 @@
        
        runTimeError("Invalid argument type '"+name+
                     "' in call to system-property().");
  -     return("");
  +     return(EMPTYSTRING);
       }
   
       /**
  @@ -407,7 +423,10 @@
       public static String namespace_uriF(int node, DOM dom) {
        final String value = dom.getNodeName(node);
        final int colon = value.lastIndexOf(':');
  -     return colon >= 0 ? value.substring(0, colon) : "";
  +     if (colon >= 0)
  +         return value.substring(0, colon);
  +     else
  +         return EMPTYSTRING;
       }
   
       //-- Begin utility functions
  @@ -821,7 +840,7 @@
        catch (IllegalArgumentException e) {
            runTimeError("Attempting to format number '"+ number +
                         "' using pattern '" + pattern + "'.");
  -         return("");
  +         return(EMPTYSTRING);
        }
       }
       
  
  
  

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

Reply via email to