1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 * @LastModified: Oct 2017 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 22 package com.sun.org.apache.xpath.internal.functions; 23 24 import com.sun.org.apache.xalan.internal.res.XSLMessages; 25 import com.sun.org.apache.xml.internal.utils.QName; 26 import com.sun.org.apache.xpath.internal.Expression; 27 import com.sun.org.apache.xpath.internal.ExpressionOwner; 28 import com.sun.org.apache.xpath.internal.XPathVisitor; 29 import java.util.List; 30 31 /** 32 * Base class for functions that accept two arguments. 33 * @xsl.usage advanced 34 */ 35 public class Function2Args extends FunctionOneArg 36 { 37 static final long serialVersionUID = 5574294996842710641L; 38 39 /** The second argument passed to the function (at index 1). 40 * @serial */ 41 Expression m_arg1; 42 43 /** 44 * Return the second argument passed to the function (at index 1). 45 * 46 * @return An expression that represents the second argument passed to the 47 * function. 48 */ 49 public Expression getArg1() 50 { 51 return m_arg1; 52 } 53 54 /** 55 * This function is used to fixup variables from QNames to stack frame 56 * indexes at stylesheet build time. 57 * @param vars List of QNames that correspond to variables. This list 58 * should be searched backwards for the first qualified name that 59 * corresponds to the variable reference qname. The position of the 60 * QName in the vector from the start of the vector will be its position 61 * in the stack frame (but variables above the globalsTop value will need 62 * to be offset to the current stack frame). 63 */ 64 public void fixupVariables(List<QName> vars, int globalsSize) 65 { 66 super.fixupVariables(vars, globalsSize); 67 if(null != m_arg1) 68 m_arg1.fixupVariables(vars, globalsSize); 69 } 70 71 72 /** 73 * Set an argument expression for a function. This method is called by the 74 * XPath compiler. 75 * 76 * @param arg non-null expression that represents the argument. 77 * @param argNum The argument number index. 78 * 79 * @throws WrongNumberArgsException If the argNum parameter is greater than 1. 80 */ 81 public void setArg(Expression arg, int argNum) 82 throws WrongNumberArgsException 83 { 84 85 // System.out.println("argNum: "+argNum); 86 if (argNum == 0) 87 super.setArg(arg, argNum); 88 else if (1 == argNum) 89 { 90 m_arg1 = arg; 91 arg.exprSetParent(this); 92 } 93 else 94 reportWrongNumberArgs(); 95 } 96 97 /** 98 * Check that the number of arguments passed to this function is correct. 99 * 100 * 101 * @param argNum The number of arguments that is being passed to the function. 102 * 103 * @throws WrongNumberArgsException 104 */ 105 public void checkNumberArgs(int argNum) throws WrongNumberArgsException 106 { 107 if (argNum != 2) 108 reportWrongNumberArgs(); 109 } 110 111 /** 112 * Constructs and throws a WrongNumberArgException with the appropriate 113 * message for this function object. 114 * 115 * @throws WrongNumberArgsException 116 */ 117 protected void reportWrongNumberArgs() throws WrongNumberArgsException { 118 throw new WrongNumberArgsException(XSLMessages.createXPATHMessage("two", null)); 119 } 120 121 /** 122 * Tell if this expression or it's subexpressions can traverse outside 123 * the current subtree. 124 * 125 * @return true if traversal outside the context node's subtree can occur. 126 */ 127 public boolean canTraverseOutsideSubtree() 128 { 129 return super.canTraverseOutsideSubtree() 130 ? true : m_arg1.canTraverseOutsideSubtree(); 131 } 132 133 class Arg1Owner implements ExpressionOwner 134 { 135 /** 136 * @see ExpressionOwner#getExpression() 137 */ 138 public Expression getExpression() 139 { 140 return m_arg1; 141 } 142 143 144 /** 145 * @see ExpressionOwner#setExpression(Expression) 146 */ 147 public void setExpression(Expression exp) 148 { 149 exp.exprSetParent(Function2Args.this); 150 m_arg1 = exp; 151 } 152 } 153 154 155 /** 156 * @see com.sun.org.apache.xpath.internal.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor) 157 */ 158 public void callArgVisitors(XPathVisitor visitor) 159 { 160 super.callArgVisitors(visitor); 161 if(null != m_arg1) 162 m_arg1.callVisitors(new Arg1Owner(), visitor); 163 } 164 165 /** 166 * @see Expression#deepEquals(Expression) 167 */ 168 public boolean deepEquals(Expression expr) 169 { 170 if(!super.deepEquals(expr)) 171 return false; 172 173 if(null != m_arg1) 174 { 175 if(null == ((Function2Args)expr).m_arg1) 176 return false; 177 178 if(!m_arg1.deepEquals(((Function2Args)expr).m_arg1)) 179 return false; 180 } 181 else if(null != ((Function2Args)expr).m_arg1) 182 return false; 183 184 return true; 185 } 186 187 }