santiagopg    2003/10/07 08:44:22

  Modified:    java/src/org/apache/xalan/xsltc/compiler Parser.java
                        xpath.cup
  Added:       java/src/org/apache/xalan/xsltc/compiler CastCall.java
  Log:
  Adding a new extension function for XSLTC. Using this extension function, it 
is
  possible to recover type information lost by the use of xsl:param (see 
Bugzilla
  19038). Here is an example:
  
  <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
      xmlns:java="http://xml.apache.org/xalan/java";
      xmlns:xsltc="http://xml.apache.org/xalan/xsltc";>
  
  <xsl:param name="object"/>
  
  <xsl:template match="/">
      <xsl:value-of select="java:length(xsltc:cast('java.lang.String', 
$object))"/>
  </xsl:template>
  
  </xsl:stylesheet>
  
  Without using xsltc:cast(), XSLTC will report an error as the type of param
  'object' cannot be determined statically. The type of xsltc:cast() is:
  
  object[T] cast('T', reference | object[R])
  
  where 'T' indicates that the type of the first argument must be a literal
  string. A ClassCastException may be thrown at runtime if R is not convertible
  to T.
  
  I believe we still need a fully-dynamic solution that does not rely on this
  extension function. However, the two solutions can coexists, especially since
  using xsltc:cast() will always be more efficient than any alternative based
  on Java reflection.
  
  Revision  Changes    Path
  1.60      +3 -1      
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.59
  retrieving revision 1.60
  diff -u -r1.59 -r1.60
  --- Parser.java       14 Aug 2003 16:27:43 -0000      1.59
  +++ Parser.java       7 Oct 2003 15:44:22 -0000       1.60
  @@ -782,6 +782,7 @@
        MethodType S_SS = new MethodType(Type.String, Type.String, Type.String);
        MethodType S_DS = new MethodType(Type.String, Type.Real, Type.String);
        MethodType S_SR = new MethodType(Type.String, Type.String, Type.Real);
  +     MethodType O_SO = new MethodType(Type.Reference, Type.String, 
Type.Reference);
   
        MethodType D_SS =
            new MethodType(Type.NodeSet, Type.String, Type.String);
  @@ -862,6 +863,7 @@
        // Extensions
           _symbolTable.addPrimop("nodeset", D_O);
           _symbolTable.addPrimop("objectType", S_O);
  +        _symbolTable.addPrimop("cast", O_SO);
   
        // Operators +, -, *, /, % defined on real types.
        _symbolTable.addPrimop("+", R_RR);      
  
  
  
  1.48      +8 -1      
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.47
  retrieving revision 1.48
  diff -u -r1.47 -r1.48
  --- xpath.cup 1 Apr 2003 21:09:00 -0000       1.47
  +++ xpath.cup 7 Oct 2003 15:44:22 -0000       1.48
  @@ -122,6 +122,10 @@
             return _parser.getQNameIgnoreDefaultNs(name);
       }    
   
  +    public QName getQName(String namespace, String prefix, String localname) 
{
  +        return _parser.getQName(namespace, prefix, localname);
  +    }        
  +
       public void setMultiDocument(boolean flag) {
             _xsltc.setMultiDocument(flag);
       }
  @@ -1021,6 +1025,9 @@
          }
             else if (fname == parser.getQNameIgnoreDefaultNs("namespace-uri")) 
{
               RESULT = new NamespaceUriCall(fname, argl);
  +       }
  +          else if (fname == parser.getQName(Constants.TRANSLET_URI, "xsltc", 
"cast")) {
  +            RESULT = new CastCall(fname, argl);
          }
          // Special case for extension function nodeset()
             else if (fname.getLocalPart().equals("nodeset") || 
fname.getLocalPart().equals("node-set")) {
  
  
  
  1.1                  
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/CastCall.java
  
  Index: CastCall.java
  ===================================================================
  /*
   * @(#)$Id: CastCall.java,v 1.1 2003/10/07 15:44:22 santiagopg Exp $
   *
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xalan" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 2001, Sun
   * Microsystems., http://www.sun.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * @author Santiago Pericas-Geertsen
   *
   */
  
  package org.apache.xalan.xsltc.compiler;
  
  import java.util.Vector;
  
  import org.apache.bcel.generic.ConstantPoolGen;
  import org.apache.bcel.generic.CHECKCAST;
  import org.apache.bcel.generic.InstructionList;
  import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
  import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
  import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
  import org.apache.xalan.xsltc.compiler.util.Type;
  import org.apache.xalan.xsltc.compiler.util.ObjectType;
  import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
  
  final class CastCall extends FunctionCall {
      
      /**
       * Name of the class that is the target of the cast. Must be a 
       * fully-qualified Java class Name.
       */
      private String _className;
  
      /**
       * A reference to the expression being casted.
       */
      private Expression _right;
  
      /**
       * Constructor.
       */
      public CastCall(QName fname, Vector arguments) {
        super(fname, arguments);
      }
  
      /**
       * Type check the two parameters for this function
       */
      public Type typeCheck(SymbolTable stable) throws TypeCheckError {
        // Check that the function was passed exactly two arguments
        if (argumentCount() != 2) {
            throw new TypeCheckError(new ErrorMsg(ErrorMsg.ILLEGAL_ARG_ERR,
                                                    getName(), this));
        }
  
          // The first argument must be a literal String
        Expression exp = argument(0);
          if (exp instanceof LiteralExpr) {
              _className = ((LiteralExpr) exp).getValue();
              _type = new ObjectType(_className);
          }
          else {
            throw new TypeCheckError(new ErrorMsg(ErrorMsg.NEED_LITERAL_ERR,
                                                    getName(), this));
          }
          
           // Second argument must be of type reference or object
          _right = argument(1);
          Type tright = _right.typeCheck(stable);
          if (tright != Type.Reference && 
              tright instanceof ObjectType == false) 
          {
            throw new TypeCheckError(new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
                                                    tright, _type, this));
          }
          
          return _type;
      }
      
      public void translate(ClassGenerator classGen, MethodGenerator methodGen) 
{
        final ConstantPoolGen cpg = classGen.getConstantPool();
        final InstructionList il = methodGen.getInstructionList();
  
          _right.translate(classGen, methodGen);
          il.append(new CHECKCAST(cpg.addClass(_className)));
      }
  }
  
  
  

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

Reply via email to