zongaro     2002/11/05 12:55:32

  Modified:    java/src/org/apache/xalan/xsltc/compiler Tag: XSLTC_DTM
                        ValueOf.java
  Log:
  The DOM.characters(int, TransletOutputHandler) method is now able to send
  the string value of an arbitrary node to the TransletOutputHandler.  Earlier
  versions could only do that for a text node.  As an optimization, use that
  method for xsl:value-of, if the type of the select expression is node or
  node-set.
  
  I believe that DOM.characters could also be used when the select expression is
  a result-tree fragment, but I ran into some problems with that.
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.7.6.1   +80 -43    
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ValueOf.java
  
  Index: ValueOf.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ValueOf.java,v
  retrieving revision 1.7
  retrieving revision 1.7.6.1
  diff -u -r1.7 -r1.7.6.1
  --- ValueOf.java      1 Feb 2002 20:07:08 -0000       1.7
  +++ ValueOf.java      5 Nov 2002 20:55:32 -0000       1.7.6.1
  @@ -73,61 +73,98 @@
   final class ValueOf extends Instruction {
       private Expression _select;
       private boolean _escaping = true;
  -     
  +    private boolean _isString = false;
  +
       public void display(int indent) {
  -     indent(indent);
  -     Util.println("ValueOf");
  -     indent(indent + IndentIncrement);
  -     Util.println("select " + _select.toString());
  +        indent(indent);
  +        Util.println("ValueOf");
  +        indent(indent + IndentIncrement);
  +        Util.println("select " + _select.toString());
       }
  -             
  +
       public void parseContents(Parser parser) {
  -     _select = parser.parseExpression(this, "select", null);
  +        _select = parser.parseExpression(this, "select", null);
   
           // make sure required attribute(s) have been set
           if (_select.isDummy()) {
  -         reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "select");
  -         return;
  +            reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "select");
  +            return;
           }
           final String str = getAttribute("disable-output-escaping");
  -     if ((str != null) && (str.equals("yes"))) _escaping = false;
  +        if ((str != null) && (str.equals("yes"))) _escaping = false;
       }
   
       public Type typeCheck(SymbolTable stable) throws TypeCheckError {
  -     Type type = _select.typeCheck(stable);
  -     if ((type != null) && (type.identicalTo(Type.String) == false))
  -         _select = new CastExpr(_select, Type.String);
  -     return Type.Void;
  +        Type type = _select.typeCheck(stable);
  +
  +        // Prefer to handle the value as a node; fall back to String, 
otherwise
  +        if (type != null && !type.identicalTo(Type.Node)) {
  +            /***
  +             *** %HZ% Would like to treat result-tree fragments in the same
  +             *** %HZ% way as node sets for value-of, but that's running into
  +             *** %HZ% some snags.  Instead, they'll be converted to String
  +            if (type.identicalTo(Type.ResultTree)) {
  +                _select = new CastExpr(new CastExpr(_select, Type.NodeSet),
  +                                       Type.Node);
  +            } else
  +            ***/
  +            if (type.identicalTo(Type.NodeSet)) {
  +                _select = new CastExpr(_select, Type.Node);
  +            } else {
  +                _isString = true;
  +                if (!type.identicalTo(Type.String)) {
  +                    _select = new CastExpr(_select, Type.String);
  +                }
  +                _isString = true;
  +            }
  +        }
  +        return Type.Void;
       }
   
       public void translate(ClassGenerator classGen, MethodGenerator 
methodGen) {
  -     final ConstantPoolGen cpg = classGen.getConstantPool();
  -     final InstructionList il = methodGen.getInstructionList();
  -     final int setEscaping = cpg.addInterfaceMethodref(OUTPUT_HANDLER,
  -                                                       "setEscaping","(Z)Z");
  -     final int characters = cpg.addMethodref(TRANSLET_CLASS,
  -                                             CHARACTERSW,
  -                                             CHARACTERSW_SIG);
  -
  -     // Turn off character escaping if so is wanted.
  -     if (!_escaping) {
  -         il.append(methodGen.loadHandler());
  -         il.append(new PUSH(cpg,false));
  -         il.append(new INVOKEINTERFACE(setEscaping,2));
  -     }
  -
  -     // Translate the contents.
  -     il.append(classGen.loadTranslet());
  -     _select.translate(classGen, methodGen); 
  -     il.append(methodGen.loadHandler());
  -     il.append(new INVOKEVIRTUAL(characters));
  -
  -     // Restore character escaping setting to whatever it was.
  -     if (!_escaping) {
  -         il.append(methodGen.loadHandler());
  -         il.append(SWAP);
  -         il.append(new INVOKEINTERFACE(setEscaping,2));
  -         il.append(POP);
  -     }
  +        final ConstantPoolGen cpg = classGen.getConstantPool();
  +        final InstructionList il = methodGen.getInstructionList();
  +        final int setEscaping = cpg.addInterfaceMethodref(OUTPUT_HANDLER,
  +                                                          
"setEscaping","(Z)Z");
  +
  +        // Turn off character escaping if so is wanted.
  +        if (!_escaping) {
  +            il.append(methodGen.loadHandler());
  +            il.append(new PUSH(cpg,false));
  +            il.append(new INVOKEINTERFACE(setEscaping,2));
  +        }
  +
  +        // Translate the contents.  If the value is a string, use the
  +        // translet.characters(String, TranslatOutputHandler) method.
  +        // Otherwise, the value is a node, and the
  +        // dom.characters(int node, TransletOutputHandler) method can 
dispatch
  +        // the string value of the node to the output handler more 
efficiently.
  +        if (_isString) {
  +            final int characters = cpg.addMethodref(TRANSLET_CLASS,
  +                                                    CHARACTERSW,
  +                                                    CHARACTERSW_SIG);
  +
  +            il.append(classGen.loadTranslet());
  +            _select.translate(classGen, methodGen);
  +            il.append(methodGen.loadHandler());
  +            il.append(new INVOKEVIRTUAL(characters));
  +        } else {
  +            final int characters = cpg.addInterfaceMethodref(DOM_INTF,
  +                                                             CHARACTERS,
  +                                                             CHARACTERS_SIG);
  +
  +            il.append(methodGen.loadDOM());
  +            _select.translate(classGen, methodGen);
  +            il.append(methodGen.loadHandler());
  +            il.append(new INVOKEINTERFACE(characters, 3));
  +        }
  +
  +        // Restore character escaping setting to whatever it was.
  +        if (!_escaping) {
  +            il.append(methodGen.loadHandler());
  +            il.append(SWAP);
  +            il.append(new INVOKEINTERFACE(setEscaping,2));
  +            il.append(POP);
  +        }
       }
   }
  
  
  

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

Reply via email to