KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > util > functions > Functions


1 /*
2
3 This software is OSI Certified Open Source Software.
4 OSI Certified is a certification mark of the Open Source Initiative.
5
6 The license (Mozilla version 1.0) can be read at the MMBase site.
7 See http://www.MMBase.org/license
8
9 */

10 package org.mmbase.util.functions;
11
12 import java.lang.reflect.*;
13 import java.lang.reflect.Field JavaDoc;
14 import java.util.*;
15
16 import org.mmbase.util.logging.*;
17
18
19 /**
20  * This class defines static methods for defining Function and Parameters objects.
21  * These methods include ways to retrieve Function definitions for a class using reflection,
22  * and methods to convert a List to a Parameters object, and a Parameter array to a
23  * List.
24  *
25  * @since MMBase-1.8
26  * @author Pierre van Rooden
27  * @author Daniel Ockeloen
28  * @author Michiel Meeuwissen
29  * @version $Id: Functions.java,v 1.12 2006/01/13 15:37:24 pierre Exp $
30  */

31 public class Functions {
32
33     private static final Logger log = Logging.getLoggerInstance(Functions.class);
34
35     /**
36      * Converts a certain List to an Parameters if it is not already one.
37      */

38     public static Parameters buildParameters(Parameter[] def, List args) {
39         Parameters a;
40         if (args instanceof Parameters) {
41             a = (Parameters) args;
42         } else {
43             a = new Parameters(def, args);
44         }
45         return a;
46     }
47
48     /**
49      * Adds the definitions to a List. Resolves the {@link Parameter.Wrapper}'s (recursively).
50      * @return List with only simple Parameter's.
51      */

52     public static List define(Parameter[] def, List list) {
53         if (def == null) return list;
54         for (int i = 0; i < def.length; i++) {
55             if (def[i] instanceof Parameter.Wrapper) {
56                 define(((Parameter.Wrapper) def[i]).arguments, list);
57             } else {
58                 list.add(def[i]);
59             }
60         }
61         return list;
62     }
63
64     /**
65      * @javadoc
66      */

67     public static Method getMethodFromClass(Class JavaDoc claz, String JavaDoc name) {
68         Method method = null;
69         Method[] methods = claz.getMethods();
70         for (int j = 0; j < methods.length; j++) {
71             if (methods[j].getName().equals(name)) {
72                 if (method != null) {
73                     throw new IllegalArgumentException JavaDoc("There is more than one method with name '" + name + "' in " + claz);
74                 }
75                 method = methods[j];
76             }
77         }
78         if (method == null) {
79             throw new IllegalArgumentException JavaDoc("There is no method with name '" + name + "' in " + claz);
80         }
81         return method;
82     }
83
84     /**
85      * Generates a map of Parameter[] objects for a given class through reflection.
86      * The map keys are the names of te function the Parameter[] object belongs to.
87      * <br />
88      * The method parses the given class for constants (final static public members)
89      * of type Parameter[]. The member name up to the first underscore in that name
90      * is considered the name for a function supported by that class.
91      * i.e. :
92      * <pre>
93      * public final static Parameter[] AGE_PARAMETERS = {};
94      * </pre>
95      * defines a function 'age' which takes no parameters.
96      * <pre>
97      * public final static Parameter[] GUI_PARAMETERS = {
98      * new Parameter("field", String.class),
99      * Parameter.LANGUAGE
100      * }
101      * </pre>
102      * defines a function 'gui' which two parameters: 'field' and 'language'.
103      * Results form reflection are stored in an internal cache.
104      * The method returns the Parameter[] value (if any) of the function whose
105      * name was given in the call. If the function cannot be derived through
106      * reflection, the method returns <code>null</code>.<br />
107      * Note that, since this way of determining functions cannot determine
108      * return value types, it is advised to use {@link FunctionProvider#addFunction}
109      * instead.
110      *
111      * @see Parameter
112      * @param clazz the class to perform reflection on.
113      * @param map
114      * @return A map of parameter definitions (Parameter[] objects), keys by function name (String)
115     */

116     public static Map getParameterDefinitonsByReflection(Class JavaDoc clazz, Map map) {
117
118         log.debug("Searching " + clazz);
119         Field JavaDoc[] fields = clazz.getDeclaredFields();
120         for (int i = 0 ; i < fields.length; i++) {
121             Field JavaDoc field = fields[i];
122             int mod = field.getModifiers();
123             // only static public final Parameter[] constants are considered
124
if (Modifier.isStatic(mod) && Modifier.isPublic(mod) && Modifier.isFinal(mod) &&
125                     field.getType().equals(Parameter[].class)) {
126                 // get name (using convention)
127
String JavaDoc name = field.getName().toLowerCase();
128                 int underscore = name.indexOf("_");
129                 if (underscore > 0) {
130                     name = name.substring(0, underscore);
131                 }
132                 if (! map.containsKey(name)) { // overriding works, but don't do backwards :-)
133
try {
134                         Parameter[] params = (Parameter[])field.get(null);
135                         if (log.isDebugEnabled()) {
136                             log.debug("Found a function definition '" + name + "' in " + clazz + " with parameters " + Arrays.asList(params));
137                         }
138                         map.put(name, params);
139                     } catch (IllegalAccessException JavaDoc iae) {
140                         // should not be thrown!
141
log.error("Found inaccessible parameter[] constant: " + field.getName());
142                     }
143                 }
144              }
145         }
146         Class JavaDoc sup = clazz.getSuperclass();
147         if (sup != null) {
148             getParameterDefinitonsByReflection(sup, map);
149         }
150         return map;
151     }
152
153 }
154
Popular Tags