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 }