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    */
getArg1()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    */
fixupVariables(java.util.Vector vars, int globalsSize)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    */
setArg(Expression arg, int argNum)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    */
checkNumberArgs(int argNum)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    */
reportWrongNumberArgs()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    */
canTraverseOutsideSubtree()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      */
getExpression()135     public Expression getExpression()
136     {
137       return m_arg1;
138     }
139 
140 
141     /**
142      * @see ExpressionOwner#setExpression(Expression)
143      */
setExpression(Expression exp)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    */
callArgVisitors(XPathVisitor visitor)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    */
deepEquals(Expression expr)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