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: FunctionDef1Arg.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.xml.dtm.DTM;
025 import org.apache.xml.utils.XMLString;
026 import org.apache.xpath.XPathContext;
027 import org.apache.xpath.objects.XString;
028 import org.apache.xpath.res.XPATHErrorResources;
029
030 /**
031 * Base class for functions that accept one argument that can be defaulted if
032 * not specified.
033 * @xsl.usage advanced
034 */
035 public class FunctionDef1Arg extends FunctionOneArg
036 {
037 static final long serialVersionUID = 2325189412814149264L;
038
039 /**
040 * Execute the first argument expression that is expected to return a
041 * nodeset. If the argument is null, then return the current context node.
042 *
043 * @param xctxt Runtime XPath context.
044 *
045 * @return The first node of the executed nodeset, or the current context
046 * node if the first argument is null.
047 *
048 * @throws javax.xml.transform.TransformerException if an error occurs while
049 * executing the argument expression.
050 */
051 protected int getArg0AsNode(XPathContext xctxt)
052 throws javax.xml.transform.TransformerException
053 {
054
055 return (null == m_arg0)
056 ? xctxt.getCurrentNode() : m_arg0.asNode(xctxt);
057 }
058
059 /**
060 * Tell if the expression is a nodeset expression.
061 * @return true if the expression can be represented as a nodeset.
062 */
063 public boolean Arg0IsNodesetExpr()
064 {
065 return (null == m_arg0) ? true : m_arg0.isNodesetExpr();
066 }
067
068 /**
069 * Execute the first argument expression that is expected to return a
070 * string. If the argument is null, then get the string value from the
071 * current context node.
072 *
073 * @param xctxt Runtime XPath context.
074 *
075 * @return The string value of the first argument, or the string value of the
076 * current context node if the first argument is null.
077 *
078 * @throws javax.xml.transform.TransformerException if an error occurs while
079 * executing the argument expression.
080 */
081 protected XMLString getArg0AsString(XPathContext xctxt)
082 throws javax.xml.transform.TransformerException
083 {
084 if(null == m_arg0)
085 {
086 int currentNode = xctxt.getCurrentNode();
087 if(DTM.NULL == currentNode)
088 return XString.EMPTYSTRING;
089 else
090 {
091 DTM dtm = xctxt.getDTM(currentNode);
092 return dtm.getStringValue(currentNode);
093 }
094
095 }
096 else
097 return m_arg0.execute(xctxt).xstr();
098 }
099
100 /**
101 * Execute the first argument expression that is expected to return a
102 * number. If the argument is null, then get the number value from the
103 * current context node.
104 *
105 * @param xctxt Runtime XPath context.
106 *
107 * @return The number value of the first argument, or the number value of the
108 * current context node if the first argument is null.
109 *
110 * @throws javax.xml.transform.TransformerException if an error occurs while
111 * executing the argument expression.
112 */
113 protected double getArg0AsNumber(XPathContext xctxt)
114 throws javax.xml.transform.TransformerException
115 {
116
117 if(null == m_arg0)
118 {
119 int currentNode = xctxt.getCurrentNode();
120 if(DTM.NULL == currentNode)
121 return 0;
122 else
123 {
124 DTM dtm = xctxt.getDTM(currentNode);
125 XMLString str = dtm.getStringValue(currentNode);
126 return str.toDouble();
127 }
128
129 }
130 else
131 return m_arg0.execute(xctxt).num();
132 }
133
134 /**
135 * Check that the number of arguments passed to this function is correct.
136 *
137 * @param argNum The number of arguments that is being passed to the function.
138 *
139 * @throws WrongNumberArgsException if the number of arguments is not 0 or 1.
140 */
141 public void checkNumberArgs(int argNum) throws WrongNumberArgsException
142 {
143 if (argNum > 1)
144 reportWrongNumberArgs();
145 }
146
147 /**
148 * Constructs and throws a WrongNumberArgException with the appropriate
149 * message for this function object.
150 *
151 * @throws WrongNumberArgsException
152 */
153 protected void reportWrongNumberArgs() throws WrongNumberArgsException {
154 throw new WrongNumberArgsException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_ZERO_OR_ONE, null)); //"0 or 1");
155 }
156
157 /**
158 * Tell if this expression or it's subexpressions can traverse outside
159 * the current subtree.
160 *
161 * @return true if traversal outside the context node's subtree can occur.
162 */
163 public boolean canTraverseOutsideSubtree()
164 {
165 return (null == m_arg0) ? false : super.canTraverseOutsideSubtree();
166 }
167 }