1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the  "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *     http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18/*
19 * $Id: FunctionDef1Arg.java 468655 2006-10-28 07:12:06Z minchau $
20 */
21package org.apache.xpath.functions;
22
23import org.apache.xalan.res.XSLMessages;
24import org.apache.xml.dtm.DTM;
25import org.apache.xml.utils.XMLString;
26import org.apache.xpath.XPathContext;
27import org.apache.xpath.objects.XString;
28import org.apache.xpath.res.XPATHErrorResources;
29
30/**
31 * Base class for functions that accept one argument that can be defaulted if
32 * not specified.
33 * @xsl.usage advanced
34 */
35public class FunctionDef1Arg extends FunctionOneArg
36{
37    static final long serialVersionUID = 2325189412814149264L;
38
39  /**
40   * Execute the first argument expression that is expected to return a
41   * nodeset.  If the argument is null, then return the current context node.
42   *
43   * @param xctxt Runtime XPath context.
44   *
45   * @return The first node of the executed nodeset, or the current context
46   *         node if the first argument is null.
47   *
48   * @throws javax.xml.transform.TransformerException if an error occurs while
49   *                                   executing the argument expression.
50   */
51  protected int getArg0AsNode(XPathContext xctxt)
52          throws javax.xml.transform.TransformerException
53  {
54
55    return (null == m_arg0)
56           ? xctxt.getCurrentNode() : m_arg0.asNode(xctxt);
57  }
58
59  /**
60   * Tell if the expression is a nodeset expression.
61   * @return true if the expression can be represented as a nodeset.
62   */
63  public boolean Arg0IsNodesetExpr()
64  {
65    return (null == m_arg0) ? true : m_arg0.isNodesetExpr();
66  }
67
68  /**
69   * Execute the first argument expression that is expected to return a
70   * string.  If the argument is null, then get the string value from the
71   * current context node.
72   *
73   * @param xctxt Runtime XPath context.
74   *
75   * @return The string value of the first argument, or the string value of the
76   *         current context node if the first argument is null.
77   *
78   * @throws javax.xml.transform.TransformerException if an error occurs while
79   *                                   executing the argument expression.
80   */
81  protected XMLString getArg0AsString(XPathContext xctxt)
82          throws javax.xml.transform.TransformerException
83  {
84    if(null == m_arg0)
85    {
86      int currentNode = xctxt.getCurrentNode();
87      if(DTM.NULL == currentNode)
88        return XString.EMPTYSTRING;
89      else
90      {
91        DTM dtm = xctxt.getDTM(currentNode);
92        return dtm.getStringValue(currentNode);
93      }
94
95    }
96    else
97      return m_arg0.execute(xctxt).xstr();
98  }
99
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}
168