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: UnaryOperation.java 468655 2006-10-28 07:12:06Z minchau $
020     */
021    package org.apache.xpath.operations;
022    
023    import org.apache.xpath.Expression;
024    import org.apache.xpath.ExpressionOwner;
025    import org.apache.xpath.XPathContext;
026    import org.apache.xpath.XPathVisitor;
027    import org.apache.xpath.objects.XObject;
028    
029    /**
030     * The unary operation base class.
031     */
032    public abstract class UnaryOperation extends Expression implements ExpressionOwner
033    {
034        static final long serialVersionUID = 6536083808424286166L;
035    
036      /** The operand for the operation.
037       *  @serial */
038      protected Expression m_right;
039      
040      /**
041       * This function is used to fixup variables from QNames to stack frame 
042       * indexes at stylesheet build time.
043       * @param vars List of QNames that correspond to variables.  This list 
044       * should be searched backwards for the first qualified name that 
045       * corresponds to the variable reference qname.  The position of the 
046       * QName in the vector from the start of the vector will be its position 
047       * in the stack frame (but variables above the globalsTop value will need 
048       * to be offset to the current stack frame).
049       */
050      public void fixupVariables(java.util.Vector vars, int globalsSize)
051      {
052        m_right.fixupVariables(vars, globalsSize);
053      }
054      
055      /**
056       * Tell if this expression or it's subexpressions can traverse outside
057       * the current subtree.
058       *
059       * @return true if traversal outside the context node's subtree can occur.
060       */
061      public boolean canTraverseOutsideSubtree()
062      {
063    
064        if (null != m_right && m_right.canTraverseOutsideSubtree())
065          return true;
066    
067        return false;
068      }
069    
070      /**
071       * Set the expression operand for the operation.
072       *
073       *
074       * @param r The expression operand to which the unary operation will be 
075       *          applied.
076       */
077      public void setRight(Expression r)
078      {
079        m_right = r;
080        r.exprSetParent(this);
081      }
082    
083      /**
084       * Execute the operand and apply the unary operation to the result.
085       *
086       *
087       * @param xctxt The runtime execution context.
088       *
089       * @return An XObject that represents the result of applying the unary 
090       *         operation to the evaluated operand.
091       *
092       * @throws javax.xml.transform.TransformerException
093       */
094      public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
095      {
096    
097        return operate(m_right.execute(xctxt));
098      }
099    
100      /**
101       * Apply the operation to two operands, and return the result.
102       *
103       *
104       * @param right non-null reference to the evaluated right operand.
105       *
106       * @return non-null reference to the XObject that represents the result of the operation.
107       *
108       * @throws javax.xml.transform.TransformerException
109       */
110      public abstract XObject operate(XObject right)
111        throws javax.xml.transform.TransformerException;
112    
113      /** @return the operand of unary operation, as an Expression.
114       */
115      public Expression getOperand(){
116        return m_right;
117      }
118      
119      /**
120       * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
121       */
122      public void callVisitors(ExpressionOwner owner, XPathVisitor visitor)
123      {
124            if(visitor.visitUnaryOperation(owner, this))
125            {
126                    m_right.callVisitors(this, visitor);
127            }
128      }
129    
130    
131      /**
132       * @see ExpressionOwner#getExpression()
133       */
134      public Expression getExpression()
135      {
136        return m_right;
137      }
138    
139      /**
140       * @see ExpressionOwner#setExpression(Expression)
141       */
142      public void setExpression(Expression exp)
143      {
144            exp.exprSetParent(this);
145            m_right = exp;
146      }
147      
148      /**
149       * @see Expression#deepEquals(Expression)
150       */
151      public boolean deepEquals(Expression expr)
152      {
153            if(!isSameClass(expr))
154                    return false;
155                    
156            if(!m_right.deepEquals(((UnaryOperation)expr).m_right))
157                    return false;
158                    
159            return true;
160      }
161    
162    
163    }