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: Function3Args.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.XPathVisitor;
027
028 /**
029 * Base class for functions that accept three arguments.
030 * @xsl.usage advanced
031 */
032 public class Function3Args extends Function2Args
033 {
034 static final long serialVersionUID = 7915240747161506646L;
035
036 /** The third argument passed to the function (at index 2).
037 * @serial */
038 Expression m_arg2;
039
040 /**
041 * Return the third argument passed to the function (at index 2).
042 *
043 * @return An expression that represents the third argument passed to the
044 * function.
045 */
046 public Expression getArg2()
047 {
048 return m_arg2;
049 }
050
051 /**
052 * This function is used to fixup variables from QNames to stack frame
053 * indexes at stylesheet build time.
054 * @param vars List of QNames that correspond to variables. This list
055 * should be searched backwards for the first qualified name that
056 * corresponds to the variable reference qname. The position of the
057 * QName in the vector from the start of the vector will be its position
058 * in the stack frame (but variables above the globalsTop value will need
059 * to be offset to the current stack frame).
060 */
061 public void fixupVariables(java.util.Vector vars, int globalsSize)
062 {
063 super.fixupVariables(vars, globalsSize);
064 if(null != m_arg2)
065 m_arg2.fixupVariables(vars, globalsSize);
066 }
067
068 /**
069 * Set an argument expression for a function. This method is called by the
070 * XPath compiler.
071 *
072 * @param arg non-null expression that represents the argument.
073 * @param argNum The argument number index.
074 *
075 * @throws WrongNumberArgsException If the argNum parameter is greater than 2.
076 */
077 public void setArg(Expression arg, int argNum)
078 throws WrongNumberArgsException
079 {
080
081 if (argNum < 2)
082 super.setArg(arg, argNum);
083 else if (2 == argNum)
084 {
085 m_arg2 = arg;
086 arg.exprSetParent(this);
087 }
088 else
089 reportWrongNumberArgs();
090 }
091
092 /**
093 * Check that the number of arguments passed to this function is correct.
094 *
095 *
096 * @param argNum The number of arguments that is being passed to the function.
097 *
098 * @throws WrongNumberArgsException
099 */
100 public void checkNumberArgs(int argNum) throws WrongNumberArgsException
101 {
102 if (argNum != 3)
103 reportWrongNumberArgs();
104 }
105
106 /**
107 * Constructs and throws a WrongNumberArgException with the appropriate
108 * message for this function object.
109 *
110 * @throws WrongNumberArgsException
111 */
112 protected void reportWrongNumberArgs() throws WrongNumberArgsException {
113 throw new WrongNumberArgsException(XSLMessages.createXPATHMessage("three", null));
114 }
115
116 /**
117 * Tell if this expression or it's subexpressions can traverse outside
118 * the current subtree.
119 *
120 * @return true if traversal outside the context node's subtree can occur.
121 */
122 public boolean canTraverseOutsideSubtree()
123 {
124 return super.canTraverseOutsideSubtree()
125 ? true : m_arg2.canTraverseOutsideSubtree();
126 }
127
128 class Arg2Owner implements ExpressionOwner
129 {
130 /**
131 * @see ExpressionOwner#getExpression()
132 */
133 public Expression getExpression()
134 {
135 return m_arg2;
136 }
137
138
139 /**
140 * @see ExpressionOwner#setExpression(Expression)
141 */
142 public void setExpression(Expression exp)
143 {
144 exp.exprSetParent(Function3Args.this);
145 m_arg2 = exp;
146 }
147 }
148
149
150 /**
151 * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
152 */
153 public void callArgVisitors(XPathVisitor visitor)
154 {
155 super.callArgVisitors(visitor);
156 if(null != m_arg2)
157 m_arg2.callVisitors(new Arg2Owner(), visitor);
158 }
159
160 /**
161 * @see Expression#deepEquals(Expression)
162 */
163 public boolean deepEquals(Expression expr)
164 {
165 if(!super.deepEquals(expr))
166 return false;
167
168 if(null != m_arg2)
169 {
170 if(null == ((Function3Args)expr).m_arg2)
171 return false;
172
173 if(!m_arg2.deepEquals(((Function3Args)expr).m_arg2))
174 return false;
175 }
176 else if (null != ((Function3Args)expr).m_arg2)
177 return false;
178
179 return true;
180 }
181
182
183 }