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