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: Function2Args.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 two arguments. 30 * @xsl.usage advanced 31 */ 32 public class Function2Args extends FunctionOneArg 33 { 34 static final long serialVersionUID = 5574294996842710641L; 35 36 /** The second argument passed to the function (at index 1). 37 * @serial */ 38 Expression m_arg1; 39 40 /** 41 * Return the second argument passed to the function (at index 1). 42 * 43 * @return An expression that represents the second argument passed to the 44 * function. 45 */ 46 public Expression getArg1() 47 { 48 return m_arg1; 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_arg1) 65 m_arg1.fixupVariables(vars, globalsSize); 66 } 67 68 69 /** 70 * Set an argument expression for a function. This method is called by the 71 * XPath compiler. 72 * 73 * @param arg non-null expression that represents the argument. 74 * @param argNum The argument number index. 75 * 76 * @throws WrongNumberArgsException If the argNum parameter is greater than 1. 77 */ 78 public void setArg(Expression arg, int argNum) 79 throws WrongNumberArgsException 80 { 81 82 // System.out.println("argNum: "+argNum); 83 if (argNum == 0) 84 super.setArg(arg, argNum); 85 else if (1 == argNum) 86 { 87 m_arg1 = arg; 88 arg.exprSetParent(this); 89 } 90 else 91 reportWrongNumberArgs(); 92 } 93 94 /** 95 * Check that the number of arguments passed to this function is correct. 96 * 97 * 98 * @param argNum The number of arguments that is being passed to the function. 99 * 100 * @throws WrongNumberArgsException 101 */ 102 public void checkNumberArgs(int argNum) throws WrongNumberArgsException 103 { 104 if (argNum != 2) 105 reportWrongNumberArgs(); 106 } 107 108 /** 109 * Constructs and throws a WrongNumberArgException with the appropriate 110 * message for this function object. 111 * 112 * @throws WrongNumberArgsException 113 */ 114 protected void reportWrongNumberArgs() throws WrongNumberArgsException { 115 throw new WrongNumberArgsException(XSLMessages.createXPATHMessage("two", null)); 116 } 117 118 /** 119 * Tell if this expression or it's subexpressions can traverse outside 120 * the current subtree. 121 * 122 * @return true if traversal outside the context node's subtree can occur. 123 */ 124 public boolean canTraverseOutsideSubtree() 125 { 126 return super.canTraverseOutsideSubtree() 127 ? true : m_arg1.canTraverseOutsideSubtree(); 128 } 129 130 class Arg1Owner implements ExpressionOwner 131 { 132 /** 133 * @see ExpressionOwner#getExpression() 134 */ 135 public Expression getExpression() 136 { 137 return m_arg1; 138 } 139 140 141 /** 142 * @see ExpressionOwner#setExpression(Expression) 143 */ 144 public void setExpression(Expression exp) 145 { 146 exp.exprSetParent(Function2Args.this); 147 m_arg1 = exp; 148 } 149 } 150 151 152 /** 153 * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor) 154 */ 155 public void callArgVisitors(XPathVisitor visitor) 156 { 157 super.callArgVisitors(visitor); 158 if(null != m_arg1) 159 m_arg1.callVisitors(new Arg1Owner(), visitor); 160 } 161 162 /** 163 * @see Expression#deepEquals(Expression) 164 */ 165 public boolean deepEquals(Expression expr) 166 { 167 if(!super.deepEquals(expr)) 168 return false; 169 170 if(null != m_arg1) 171 { 172 if(null == ((Function2Args)expr).m_arg1) 173 return false; 174 175 if(!m_arg1.deepEquals(((Function2Args)expr).m_arg1)) 176 return false; 177 } 178 else if(null != ((Function2Args)expr).m_arg1) 179 return false; 180 181 return true; 182 } 183 184 } 185