001: /*
002: * Copyright 1999-2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: /*
017: * $Id: Function2Args.java,v 1.15 2005/01/23 01:08:21 mcnamara Exp $
018: */
019: package org.apache.xpath.functions;
020:
021: import org.apache.xalan.res.XSLMessages;
022: import org.apache.xpath.Expression;
023: import org.apache.xpath.ExpressionOwner;
024: import org.apache.xpath.XPathVisitor;
025:
026: /**
027: * Base class for functions that accept two arguments.
028: * @xsl.usage advanced
029: */
030: public class Function2Args extends FunctionOneArg {
031: static final long serialVersionUID = 5574294996842710641L;
032:
033: /** The second argument passed to the function (at index 1).
034: * @serial */
035: Expression m_arg1;
036:
037: /**
038: * Return the second argument passed to the function (at index 1).
039: *
040: * @return An expression that represents the second argument passed to the
041: * function.
042: */
043: public Expression getArg1() {
044: return m_arg1;
045: }
046:
047: /**
048: * This function is used to fixup variables from QNames to stack frame
049: * indexes at stylesheet build time.
050: * @param vars List of QNames that correspond to variables. This list
051: * should be searched backwards for the first qualified name that
052: * corresponds to the variable reference qname. The position of the
053: * QName in the vector from the start of the vector will be its position
054: * in the stack frame (but variables above the globalsTop value will need
055: * to be offset to the current stack frame).
056: */
057: public void fixupVariables(java.util.Vector vars, int globalsSize) {
058: super .fixupVariables(vars, globalsSize);
059: if (null != m_arg1)
060: m_arg1.fixupVariables(vars, globalsSize);
061: }
062:
063: /**
064: * Set an argument expression for a function. This method is called by the
065: * XPath compiler.
066: *
067: * @param arg non-null expression that represents the argument.
068: * @param argNum The argument number index.
069: *
070: * @throws WrongNumberArgsException If the argNum parameter is greater than 1.
071: */
072: public void setArg(Expression arg, int argNum)
073: throws WrongNumberArgsException {
074:
075: // System.out.println("argNum: "+argNum);
076: if (argNum == 0)
077: super .setArg(arg, argNum);
078: else if (1 == argNum) {
079: m_arg1 = arg;
080: arg.exprSetParent(this );
081: } else
082: reportWrongNumberArgs();
083: }
084:
085: /**
086: * Check that the number of arguments passed to this function is correct.
087: *
088: *
089: * @param argNum The number of arguments that is being passed to the function.
090: *
091: * @throws WrongNumberArgsException
092: */
093: public void checkNumberArgs(int argNum)
094: throws WrongNumberArgsException {
095: if (argNum != 2)
096: reportWrongNumberArgs();
097: }
098:
099: /**
100: * Constructs and throws a WrongNumberArgException with the appropriate
101: * message for this function object.
102: *
103: * @throws WrongNumberArgsException
104: */
105: protected void reportWrongNumberArgs()
106: throws WrongNumberArgsException {
107: throw new WrongNumberArgsException(XSLMessages
108: .createXPATHMessage("two", null));
109: }
110:
111: /**
112: * Tell if this expression or it's subexpressions can traverse outside
113: * the current subtree.
114: *
115: * @return true if traversal outside the context node's subtree can occur.
116: */
117: public boolean canTraverseOutsideSubtree() {
118: return super .canTraverseOutsideSubtree() ? true : m_arg1
119: .canTraverseOutsideSubtree();
120: }
121:
122: class Arg1Owner implements ExpressionOwner {
123: /**
124: * @see ExpressionOwner#getExpression()
125: */
126: public Expression getExpression() {
127: return m_arg1;
128: }
129:
130: /**
131: * @see ExpressionOwner#setExpression(Expression)
132: */
133: public void setExpression(Expression exp) {
134: exp.exprSetParent(Function2Args.this );
135: m_arg1 = exp;
136: }
137: }
138:
139: /**
140: * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
141: */
142: public void callArgVisitors(XPathVisitor visitor) {
143: super .callArgVisitors(visitor);
144: if (null != m_arg1)
145: m_arg1.callVisitors(new Arg1Owner(), visitor);
146: }
147:
148: /**
149: * @see Expression#deepEquals(Expression)
150: */
151: public boolean deepEquals(Expression expr) {
152: if (!super .deepEquals(expr))
153: return false;
154:
155: if (null != m_arg1) {
156: if (null == ((Function2Args) expr).m_arg1)
157: return false;
158:
159: if (!m_arg1.deepEquals(((Function2Args) expr).m_arg1))
160: return false;
161: } else if (null != ((Function2Args) expr).m_arg1)
162: return false;
163:
164: return true;
165: }
166:
167: }
|