    1   /*
    2    * Copyright 1999-2004 The Apache Software Foundation
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *     http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  package org.apache.commons.jxpath.ri.compiler;
    17
    18  import java.util.Arrays;
    19
    20  import org.apache.commons.jxpath.Function;
    21  import org.apache.commons.jxpath.JXPathException;
    22  import org.apache.commons.jxpath.ri.EvalContext;
    23  import org.apache.commons.jxpath.ri.QName;
    24
    25  /***
    26   * Represents  an element of the parse tree representing an extension function
    27   * call.
    28   *
    29   * @author Dmitri Plotnikov
    30   * @version $Revision: 1.13 $ $Date: 2004/03/25 05:42:01 $
    31   */
    32  public class ExtensionFunction extends Operation {
    33
    34      private QName functionName;
    35
    36      public ExtensionFunction(QName functionName, Expression args[]) {
    37          super(args);
    38          this.functionName = functionName;
    39      }
    40
    41      public QName getFunctionName() {
    42          return functionName;
    43      }
    44
    45      /***
    46       * An extension function gets the current context, therefore it MAY be
    47       * context dependent.
    48       */
    49      public boolean computeContextDependent() {
    50          return true;
    51      }
    52
    53      public String toString() {
    54          StringBuffer buffer = new StringBuffer();
    55          buffer.append(functionName);
    56          buffer.append('(');
    57          Expression args[] = getArguments();
    58          if (args != null) {
    59              for (int i = 0; i < args.length; i++) {
    60                  if (i > 0) {
    61                      buffer.append(", ");
    62                  }
    63                  buffer.append(args[i]);
    64              }
    65          }
    66          buffer.append(')');
    67          return buffer.toString();
    68      }
    69
    70      public Object compute(EvalContext context) {
    71          return computeValue(context);
    72      }
    73
    74      public Object computeValue(EvalContext context) {
    75          Object[] parameters = null;
    76          if (args != null) {
    77              parameters = new Object[args.length];
    78              for (int i = 0; i < args.length; i++) {
    79                  parameters[i] = convert(args[i].compute(context));
    80              }
    81          }
    82
    83          Function function =
    84              context.getRootContext().getFunction(functionName, parameters);
    85          if (function == null) {
    86              throw new JXPathException(
    87                  "No such function: "
    88                      + functionName
    89                      + Arrays.asList(parameters));
    90          }
    91
    92          return function.invoke(context, parameters);
    93      }
    94
    95      private Object convert(Object object) {
    96          if (object instanceof EvalContext) {
    97              return ((EvalContext) object).getValue();
    98          }
    99          return object;
    100     }
    101 }