1/* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5/* 6 * Licensed to the Apache Software Foundation (ASF) under one or more 7 * contributor license agreements. See the NOTICE file distributed with 8 * this work for additional information regarding copyright ownership. 9 * The ASF licenses this file to You under the Apache License, Version 2.0 10 * (the "License"); you may not use this file except in compliance with 11 * the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22package com.sun.org.apache.xpath.internal.operations; 23 24import com.sun.org.apache.xpath.internal.Expression; 25import com.sun.org.apache.xpath.internal.ExpressionOwner; 26import com.sun.org.apache.xpath.internal.XPathContext; 27import com.sun.org.apache.xpath.internal.XPathVisitor; 28import com.sun.org.apache.xpath.internal.objects.XObject; 29 30/** 31 * The baseclass for a binary operation. 32 */ 33public class Operation extends Expression implements ExpressionOwner 34{ 35 static final long serialVersionUID = -3037139537171050430L; 36 37 /** The left operand expression. 38 * @serial */ 39 protected Expression m_left; 40 41 /** The right operand expression. 42 * @serial */ 43 protected Expression m_right; 44 45 /** 46 * This function is used to fixup variables from QNames to stack frame 47 * indexes at stylesheet build time. 48 * @param vars List of QNames that correspond to variables. This list 49 * should be searched backwards for the first qualified name that 50 * corresponds to the variable reference qname. The position of the 51 * QName in the vector from the start of the vector will be its position 52 * in the stack frame (but variables above the globalsTop value will need 53 * to be offset to the current stack frame). 54 */ 55 public void fixupVariables(java.util.Vector vars, int globalsSize) 56 { 57 m_left.fixupVariables(vars, globalsSize); 58 m_right.fixupVariables(vars, globalsSize); 59 } 60 61 62 /** 63 * Tell if this expression or it's subexpressions can traverse outside 64 * the current subtree. 65 * 66 * @return true if traversal outside the context node's subtree can occur. 67 */ 68 public boolean canTraverseOutsideSubtree() 69 { 70 71 if (null != m_left && m_left.canTraverseOutsideSubtree()) 72 return true; 73 74 if (null != m_right && m_right.canTraverseOutsideSubtree()) 75 return true; 76 77 return false; 78 } 79 80 /** 81 * Set the left and right operand expressions for this operation. 82 * 83 * 84 * @param l The left expression operand. 85 * @param r The right expression operand. 86 */ 87 public void setLeftRight(Expression l, Expression r) 88 { 89 m_left = l; 90 m_right = r; 91 l.exprSetParent(this); 92 r.exprSetParent(this); 93 } 94 95 /** 96 * Execute a binary operation by calling execute on each of the operands, 97 * and then calling the operate method on the derived class. 98 * 99 * 100 * @param xctxt The runtime execution context. 101 * 102 * @return The XObject result of the operation. 103 * 104 * @throws javax.xml.transform.TransformerException 105 */ 106 public XObject execute(XPathContext xctxt) 107 throws javax.xml.transform.TransformerException 108 { 109 110 XObject left = m_left.execute(xctxt, true); 111 XObject right = m_right.execute(xctxt, true); 112 113 XObject result = operate(left, right); 114 left.detach(); 115 right.detach(); 116 return result; 117 } 118 119 /** 120 * Apply the operation to two operands, and return the result. 121 * 122 * 123 * @param left non-null reference to the evaluated left operand. 124 * @param right non-null reference to the evaluated right operand. 125 * 126 * @return non-null reference to the XObject that represents the result of the operation. 127 * 128 * @throws javax.xml.transform.TransformerException 129 */ 130 public XObject operate(XObject left, XObject right) 131 throws javax.xml.transform.TransformerException 132 { 133 return null; // no-op 134 } 135 136 /** @return the left operand of binary operation, as an Expression. 137 */ 138 public Expression getLeftOperand(){ 139 return m_left; 140 } 141 142 /** @return the right operand of binary operation, as an Expression. 143 */ 144 public Expression getRightOperand(){ 145 return m_right; 146 } 147 148 class LeftExprOwner implements ExpressionOwner 149 { 150 /** 151 * @see ExpressionOwner#getExpression() 152 */ 153 public Expression getExpression() 154 { 155 return m_left; 156 } 157 158 /** 159 * @see ExpressionOwner#setExpression(Expression) 160 */ 161 public void setExpression(Expression exp) 162 { 163 exp.exprSetParent(Operation.this); 164 m_left = exp; 165 } 166 } 167 168 /** 169 * @see com.sun.org.apache.xpath.internal.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor) 170 */ 171 public void callVisitors(ExpressionOwner owner, XPathVisitor visitor) 172 { 173 if(visitor.visitBinaryOperation(owner, this)) 174 { 175 m_left.callVisitors(new LeftExprOwner(), visitor); 176 m_right.callVisitors(this, visitor); 177 } 178 } 179 180 /** 181 * @see ExpressionOwner#getExpression() 182 */ 183 public Expression getExpression() 184 { 185 return m_right; 186 } 187 188 /** 189 * @see ExpressionOwner#setExpression(Expression) 190 */ 191 public void setExpression(Expression exp) 192 { 193 exp.exprSetParent(this); 194 m_right = exp; 195 } 196 197 /** 198 * @see Expression#deepEquals(Expression) 199 */ 200 public boolean deepEquals(Expression expr) 201 { 202 if(!isSameClass(expr)) 203 return false; 204 205 if(!m_left.deepEquals(((Operation)expr).m_left)) 206 return false; 207 208 if(!m_right.deepEquals(((Operation)expr).m_right)) 209 return false; 210 211 return true; 212 } 213} 214