1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 /* 19 * $Id: Function3Args.java 468655 2006-10-28 07:12:06Z minchau $ 20 */ 21 package org.apache.xpath.functions; 22 23 import org.apache.xalan.res.XSLMessages; 24 import org.apache.xpath.Expression; 25 import org.apache.xpath.ExpressionOwner; 26 import org.apache.xpath.XPathVisitor; 27 28 /** 29 * Base class for functions that accept three arguments. 30 * @xsl.usage advanced 31 */ 32 public class Function3Args extends Function2Args 33 { 34 static final long serialVersionUID = 7915240747161506646L; 35 36 /** The third argument passed to the function (at index 2). 37 * @serial */ 38 Expression m_arg2; 39 40 /** 41 * Return the third argument passed to the function (at index 2). 42 * 43 * @return An expression that represents the third argument passed to the 44 * function. 45 */ 46 public Expression getArg2() 47 { 48 return m_arg2; 49 } 50 51 /** 52 * This function is used to fixup variables from QNames to stack frame 53 * indexes at stylesheet build time. 54 * @param vars List of QNames that correspond to variables. This list 55 * should be searched backwards for the first qualified name that 56 * corresponds to the variable reference qname. The position of the 57 * QName in the vector from the start of the vector will be its position 58 * in the stack frame (but variables above the globalsTop value will need 59 * to be offset to the current stack frame). 60 */ 61 public void fixupVariables(java.util.Vector vars, int globalsSize) 62 { 63 super.fixupVariables(vars, globalsSize); 64 if(null != m_arg2) 65 m_arg2.fixupVariables(vars, globalsSize); 66 } 67 68 /** 69 * Set an argument expression for a function. This method is called by the 70 * XPath compiler. 71 * 72 * @param arg non-null expression that represents the argument. 73 * @param argNum The argument number index. 74 * 75 * @throws WrongNumberArgsException If the argNum parameter is greater than 2. 76 */ 77 public void setArg(Expression arg, int argNum) 78 throws WrongNumberArgsException 79 { 80 81 if (argNum < 2) 82 super.setArg(arg, argNum); 83 else if (2 == argNum) 84 { 85 m_arg2 = arg; 86 arg.exprSetParent(this); 87 } 88 else 89 reportWrongNumberArgs(); 90 } 91 92 /** 93 * Check that the number of arguments passed to this function is correct. 94 * 95 * 96 * @param argNum The number of arguments that is being passed to the function. 97 * 98 * @throws WrongNumberArgsException 99 */ 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 } 184