View Javadoc

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;
17  
18  import java.lang.reflect.Constructor;
19  import java.lang.reflect.Method;
20  import java.util.Collections;
21  import java.util.Set;
22  
23  import org.apache.commons.jxpath.functions.ConstructorFunction;
24  import org.apache.commons.jxpath.functions.MethodFunction;
25  import org.apache.commons.jxpath.util.MethodLookupUtils;
26  
27  /***
28   * Extension functions provided by a Java class.
29   *
30   * Let's say, we declared a ClassFunction like this:
31   * <blockquote><pre>
32   *     new ClassFunctions(Integer.class, "int")
33   * </pre></blockquote>
34   *
35   * We can now use XPaths like:
36   * <dl>
37   *  <dt><code>"int:new(3)"</code></dt>
38   *  <dd>Equivalent to <code>new Integer(3)</code></dd>
39   *  <dt><code>"int:getInteger('foo')"</code></dt>
40   *  <dd>Equivalent to <code>Integer.getInteger("foo")</code></dd>
41   *  <dt><code>"int:floatValue(int:new(4))"</code></dt>
42   *  <dd>Equivalent to <code>new Integer(4).floatValue()</code></dd>
43   * </dl>
44   *
45   * <p>
46   * If the first argument of a method is ExpressionContext, the
47   * expression context in which the function is evaluated is passed to
48   * the method.
49   *
50   * @author Dmitri Plotnikov
51   * @version $Revision: 1.9 $ $Date: 2004/02/29 14:17:42 $
52   */
53  public class ClassFunctions implements Functions {
54      private Class functionClass;
55      private String namespace;
56      private static final Object[] EMPTY_ARRAY = new Object[0];
57  
58      public ClassFunctions(Class functionClass, String namespace) {
59          this.functionClass = functionClass;
60          this.namespace = namespace;
61      }
62  
63      /***
64       * Returns a set of one namespace - the one specified in the constructor.
65       *
66       * @returns a singleton
67       */
68      public Set getUsedNamespaces() {
69          return Collections.singleton(namespace);
70      }
71  
72      /***
73       * Returns a Function, if any, for the specified namespace,
74       * name and parameter types.
75       *
76       * @param namespace if it is not the namespace specified in the constructor,
77       *     the method returns null
78       * @param name is a function name or "new" for a constructor.
79       *
80       * @return a MethodFunction, a ConstructorFunction or null if there is no
81       *      such function.
82       */
83      public Function getFunction(
84          String namespace,
85          String name,
86          Object[] parameters) 
87      {
88          if (!namespace.equals(this.namespace)) {
89              return null;
90          }
91  
92          if (parameters == null) {
93              parameters = EMPTY_ARRAY;
94          }
95  
96          if (name.equals("new")) {
97              Constructor constructor =
98                  MethodLookupUtils.lookupConstructor(functionClass, parameters);
99              if (constructor != null) {
100                 return new ConstructorFunction(constructor);
101             }
102         }
103         else {
104             Method method = MethodLookupUtils.
105                 lookupStaticMethod(functionClass, name, parameters);
106             if (method != null) {
107                 return new MethodFunction(method);
108             }
109 
110             method = MethodLookupUtils.
111                 lookupMethod(functionClass, name, parameters);
112             if (method != null) {
113                 return new MethodFunction(method);
114             }
115         }
116 
117         return null;
118     }
119 }