001: /*
002:
003: This software is OSI Certified Open Source Software.
004: OSI Certified is a certification mark of the Open Source Initiative.
005:
006: The license (Mozilla version 1.0) can be read at the MMBase site.
007: See http://www.MMBase.org/license
008:
009: */
010: package org.mmbase.util.functions;
011:
012: import java.util.*;
013:
014: import org.mmbase.util.logging.Logger;
015: import org.mmbase.util.logging.Logging;
016:
017: /**
018: * A function provider maintains a set of {@link Function} objects.
019: *
020: * @since MMBase-1.8
021: * @author Pierre van Rooden
022: * @version $Id: FunctionProvider.java,v 1.17 2007/11/25 18:25:49 nklasens Exp $
023: */
024: public abstract class FunctionProvider {
025: private static final Logger log = Logging
026: .getLoggerInstance(FunctionProvider.class);
027:
028: protected Map<String, Function<?>> functions = Collections
029: .synchronizedMap(new HashMap<String, Function<?>>());
030: /**
031: * Every Function Provider provides least the 'getFunctions' function, which returns a Set of all functions which it provides.
032: */
033: protected Function<Collection<Function<?>>> getFunctions = new AbstractFunction<Collection<Function<?>>>(
034: "getFunctions") {
035: {
036: setDescription("The 'getFunctions' returns the collections of al Function object which are available on this FunctionProvider");
037: }
038:
039: public Collection<Function<?>> getFunctionValue(
040: Parameters arguments) {
041: return getFunctions();
042: }
043: };
044: {
045: addFunction(getFunctions);
046: }
047:
048: /**
049: * The constructor of an FunctionProvider guesses the functions using reflection.
050: * @todo Should this last thing not only be done on MMObjectBuilders?
051: */
052: public FunctionProvider() {
053: // determine parameters through reflection
054: Map<String, Parameter<?>[]> parameterDefinitions = Functions
055: .getParameterDefinitonsByReflection(this .getClass(),
056: new HashMap<String, Parameter<?>[]>());
057: try {
058: for (Map.Entry<String, Parameter<?>[]> entry : parameterDefinitions
059: .entrySet()) {
060: Function<?> fun = newFunctionInstance(entry.getKey(),
061: entry.getValue(), ReturnType.UNKNOWN);
062: fun
063: .setDescription("Function automaticly found by reflection on public Parameter[] members");
064: addFunction(fun);
065: }
066: } catch (UnsupportedOperationException uoo) {
067: log
068: .warn("Found parameter definition array in "
069: + this .getClass()
070: + " but newFunctionInstance was not implemented for that");
071: }
072: }
073:
074: protected Function<?> newFunctionInstance(String name,
075: Parameter<?>[] parameters, ReturnType returnType) {
076: throw new UnsupportedOperationException(
077: "This class is not a fully implemented function-provider");
078: }
079:
080: /**
081: * Adds a function to the FunctionProvider. So, you can implement any function and add it to the
082: * provider, to make it provide this function too.
083: * @return The function previously assigned with this name or <code>null</code> if no such function.
084: */
085: public Function<?> addFunction(Function<?> function) {
086: Function<?> oldValue = functions.put(function.getName(),
087: function);
088: if (oldValue != null) {
089: log.debug("Replaced " + oldValue + " by " + function);
090: }
091: return oldValue;
092: }
093:
094: /**
095: * Creates a new empty Parameters object for given function.
096: * @return A new empty Parameters object, or <code>null</code> if no such function.
097: */
098: public Parameters createParameters(String functionName) {
099: Function<?> function = getFunction(functionName);
100: if (function != null) {
101: return function.createParameters();
102: } else {
103: return null;
104: }
105: }
106:
107: /**
108: * Executes a function, and returns the function value.
109: * @return The function value or <code>null</code> if no such function.
110: */
111: public Object getFunctionValue(String functionName,
112: List<?> parameters) {
113: Function<?> function = getFunction(functionName);
114: if (function != null) {
115: return function.getFunctionValueWithList(parameters);
116: } else {
117: return null;
118: }
119: }
120:
121: /**
122: * Returns the Function object with given name.
123: * @return Function object or <code>null</code> if no such function is provided.
124: */
125: public Function<?> getFunction(String functionName) {
126: return functions.get(functionName);
127: }
128:
129: /**
130: * Returns a Collection of all functions currently provided by the FunctionProvider.
131: */
132: public Collection<Function<?>> getFunctions() {
133: return Collections.unmodifiableCollection(functions.values());
134: }
135:
136: }
|