001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements. See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership. The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the  "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    /*
019     * $Id: Function.java 468655 2006-10-28 07:12:06Z minchau $
020     */
021    package org.apache.xpath.functions;
022    
023    import org.apache.xalan.res.XSLMessages;
024    import org.apache.xpath.Expression;
025    import org.apache.xpath.ExpressionOwner;
026    import org.apache.xpath.XPathContext;
027    import org.apache.xpath.XPathVisitor;
028    import org.apache.xpath.compiler.Compiler;
029    import org.apache.xpath.objects.XObject;
030    
031    /**
032     * This is a superclass of all XPath functions.  This allows two
033     * ways for the class to be called. One method is that the
034     * super class processes the arguments and hands the results to
035     * the derived class, the other method is that the derived
036     * class may process it's own arguments, which is faster since
037     * the arguments don't have to be added to an array, but causes
038     * a larger code footprint.
039     * @xsl.usage advanced
040     */
041    public abstract class Function extends Expression
042    {
043        static final long serialVersionUID = 6927661240854599768L;
044    
045      /**
046       * Set an argument expression for a function.  This method is called by the 
047       * XPath compiler.
048       *
049       * @param arg non-null expression that represents the argument.
050       * @param argNum The argument number index.
051       *
052       * @throws WrongNumberArgsException If the argNum parameter is beyond what 
053       * is specified for this function.
054       */
055      public void setArg(Expression arg, int argNum)
056              throws WrongNumberArgsException
057      {
058                            // throw new WrongNumberArgsException(XSLMessages.createXPATHMessage("zero", null));
059          reportWrongNumberArgs();
060      }
061    
062      /**
063       * Check that the number of arguments passed to this function is correct.
064       * This method is meant to be overloaded by derived classes, to check for 
065       * the number of arguments for a specific function type.  This method is 
066       * called by the compiler for static number of arguments checking.
067       *
068       * @param argNum The number of arguments that is being passed to the function.
069       *
070       * @throws WrongNumberArgsException
071       */
072      public void checkNumberArgs(int argNum) throws WrongNumberArgsException
073      {
074        if (argNum != 0)
075          reportWrongNumberArgs();
076      }
077    
078      /**
079       * Constructs and throws a WrongNumberArgException with the appropriate
080       * message for this function object.  This method is meant to be overloaded
081       * by derived classes so that the message will be as specific as possible.
082       *
083       * @throws WrongNumberArgsException
084       */
085      protected void reportWrongNumberArgs() throws WrongNumberArgsException {
086          throw new WrongNumberArgsException(XSLMessages.createXPATHMessage("zero", null));
087      }
088    
089      /**
090       * Execute an XPath function object.  The function must return
091       * a valid object.
092       * @param xctxt The execution current context.
093       * @return A valid XObject.
094       *
095       * @throws javax.xml.transform.TransformerException
096       */
097      public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
098      {
099    
100        // Programmer's assert.  (And, no, I don't want the method to be abstract).
101        System.out.println("Error! Function.execute should not be called!");
102    
103        return null;
104      }
105      
106      /**
107       * Call the visitors for the function arguments.
108       */
109      public void callArgVisitors(XPathVisitor visitor)
110      {
111      }
112    
113      
114      /**
115       * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
116       */
117      public void callVisitors(ExpressionOwner owner, XPathVisitor visitor)
118      {
119            if(visitor.visitFunction(owner, this))
120            {
121                    callArgVisitors(visitor);
122            }
123      }
124      
125      /**
126       * @see Expression#deepEquals(Expression)
127       */
128      public boolean deepEquals(Expression expr)
129      {
130            if(!isSameClass(expr))
131                    return false;
132                    
133            return true;
134      }
135    
136      /**
137       * This function is currently only being used by Position()
138       * and Last(). See respective functions for more detail.
139       */
140      public void postCompileStep(Compiler compiler)
141      {
142        // no default action
143      }
144    }