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 three arguments. 33 * @xsl.usage advanced 34 */ 35 public class Function3Args extends Function2Args 36 { 37 static final long serialVersionUID = 7915240747161506646L; 38 39 /** The third argument passed to the function (at index 2). 40 * @serial */ 41 Expression m_arg2; 42 43 /** 44 * Return the third argument passed to the function (at index 2). 45 * 46 * @return An expression that represents the third argument passed to the 47 * function. 48 */ 49 public Expression getArg2() 50 { 51 return m_arg2; 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_arg2) 68 m_arg2.fixupVariables(vars, globalsSize); 69 } 70 71 /** 72 * Set an argument expression for a function. This method is called by the 73 * XPath compiler. 74 * 75 * @param arg non-null expression that represents the argument. 76 * @param argNum The argument number index. 77 * 78 * @throws WrongNumberArgsException If the argNum parameter is greater than 2. 79 */ 80 public void setArg(Expression arg, int argNum) 81 throws WrongNumberArgsException 82 { 83 84 if (argNum < 2) 85 super.setArg(arg, argNum); 86 else if (2 == argNum) 87 { 88 m_arg2 = arg; 89 arg.exprSetParent(this); 90 } 91 else 92 reportWrongNumberArgs(); 93 } 94 95 /** 96 * Check that the number of arguments passed to this function is correct. 97 * 98 * 99 * @param argNum The number of arguments that is being passed to the function. 100 * 101 * @throws WrongNumberArgsException 102 */ 103 public void checkNumberArgs(int argNum) throws WrongNumberArgsException 104 { 105 if (argNum != 3) 106 reportWrongNumberArgs(); 107 } 108 109 /** 110 * Constructs and throws a WrongNumberArgException with the appropriate 111 * message for this function object. 112 * 113 * @throws WrongNumberArgsException 114 */ 115 protected void reportWrongNumberArgs() throws WrongNumberArgsException { 116 throw new WrongNumberArgsException(XSLMessages.createXPATHMessage("three", null)); 117 } 118 119 /** 120 * Tell if this expression or it's subexpressions can traverse outside 121 * the current subtree. 122 * 123 * @return true if traversal outside the context node's subtree can occur. 124 */ 125 public boolean canTraverseOutsideSubtree() 126 { 127 return super.canTraverseOutsideSubtree() 128 ? true : m_arg2.canTraverseOutsideSubtree(); 129 } 130 131 class Arg2Owner implements ExpressionOwner 132 { 133 /** 134 * @see ExpressionOwner#getExpression() 135 */ 136 public Expression getExpression() 137 { 138 return m_arg2; 139 } 140 141 142 /** 143 * @see ExpressionOwner#setExpression(Expression) 144 */ 145 public void setExpression(Expression exp) 146 { 147 exp.exprSetParent(Function3Args.this); 148 m_arg2 = exp; 149 } 150 } 151 152 153 /** 154 * @see com.sun.org.apache.xpath.internal.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor) 155 */ 156 public void callArgVisitors(XPathVisitor visitor) 157 { 158 super.callArgVisitors(visitor); 159 if(null != m_arg2) 160 m_arg2.callVisitors(new Arg2Owner(), visitor); 161 } 162 163 /** 164 * @see Expression#deepEquals(Expression) 165 */ 166 public boolean deepEquals(Expression expr) 167 { 168 if(!super.deepEquals(expr)) 169 return false; 170 171 if(null != m_arg2) 172 { 173 if(null == ((Function3Args)expr).m_arg2) 174 return false; 175 176 if(!m_arg2.deepEquals(((Function3Args)expr).m_arg2)) 177 return false; 178 } 179 else if (null != ((Function3Args)expr).m_arg2) 180 return false; 181 182 return true; 183 } 184 185 186 }