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: import org.mmbase.util.logging.Logger;
014: import org.mmbase.util.logging.Logging;
015:
016: /**
017: * A combined function combines other function object. Depending on the provided filled paramters it calls the right function.
018: *
019: * @author Michiel Meeuwissen
020: * @version $Id: CombinedFunction.java,v 1.7 2007/11/25 18:25:49 nklasens Exp $
021: * @since MMBase-1.9
022: */
023: public class CombinedFunction<R> implements Function<R> {
024:
025: private static final Logger log = Logging
026: .getLoggerInstance(CombinedFunction.class);
027:
028: private final List<Function<R>> functions = new ArrayList<Function<R>>();
029:
030: private Parameter<?>[] parameterDefinition = null;
031: private ReturnType<R> returnType = null;
032: private final String name;
033: private String description;
034:
035: public CombinedFunction(String name) {
036: this .name = name;
037: }
038:
039: public void addFunction(Function<R> func) {
040: parameterDefinition = null;
041: if (returnType == null) {
042: returnType = func.getReturnType();
043: } else {
044: ReturnType<R> funcType = func.getReturnType();
045: if (returnType.getTypeAsClass().isAssignableFrom(
046: funcType.getTypeAsClass())) {
047: //
048: } else if (funcType.getTypeAsClass().isAssignableFrom(
049: returnType.getTypeAsClass())) {
050: returnType = funcType;
051: } else {
052: throw new IllegalStateException("" + func
053: + " is not compatible");
054: }
055: }
056: functions.add(func);
057: }
058:
059: public Parameters createParameters() {
060: if (parameterDefinition == null)
061: determinDefinition();
062: return new Parameters(parameterDefinition);
063: }
064:
065: public R getFunctionValue(Parameters parameters) {
066: if (parameterDefinition == null)
067: determinDefinition();
068: float maxscore = -1;
069: Function<R> function = null;
070: for (Function<R> f : functions) {
071: // determin score here
072: int scoreCounter = 0;
073: for (Parameter<?> p : f.getParameterDefinition()) {
074: if (p.isRequired() && parameters.get(p) == null) {
075: // required parameter missing, that is baaad!
076: scoreCounter = 0;
077: break;
078: }
079: Object v = parameters.get(p);
080: if (v != null && !"".equals(v)) {
081: log.info("Scoring with parameter " + p);
082: scoreCounter++;
083: }
084: }
085: if (scoreCounter > maxscore) {
086: function = f;
087: maxscore = scoreCounter;
088: log.debug("???Using function " + function
089: + " (with score " + maxscore
090: + ") and parameters " + parameters);
091: }
092: }
093: log.debug("Using function " + function + " (with score "
094: + maxscore + ") and parameters " + parameters);
095: R r = function.getFunctionValue(parameters);
096: log.debug(" ==> '" + r + "'");
097: return r;
098: }
099:
100: protected void determinDefinition() {
101: if (functions.size() == 0)
102: throw new IllegalStateException("No functions added");
103: for (Function<R> f : functions) {
104: Parameter<?>[] fd = f.getParameterDefinition();
105: if (parameterDefinition == null) {
106: parameterDefinition = fd;
107: continue;
108: }
109: List<Parameter<?>> existing = new ArrayList<Parameter<?>>(
110: Arrays.asList(parameterDefinition));
111: for (Parameter<?> extra : fd) {
112: if (!existing.contains(extra)) {
113: existing.add(extra);
114: }
115:
116: }
117: parameterDefinition = existing.toArray(Parameter
118: .emptyArray());
119: }
120: }
121:
122: public R getFunctionValueWithList(List<?> parameters) {
123: Parameters params = createParameters();
124: params.setAll(parameters);
125: return getFunctionValue(params);
126: }
127:
128: public R getFunctionValue(Object... parameters) {
129: Parameters params = createParameters();
130: params.setAll(parameters);
131: return getFunctionValue(params);
132: }
133:
134: public void setDescription(String description) {
135: this .description = description;
136: }
137:
138: public String getDescription() {
139: return description;
140: }
141:
142: public String getName() {
143: return name;
144: }
145:
146: public Parameter<?>[] getParameterDefinition() {
147: if (parameterDefinition == null)
148: determinDefinition();
149: return parameterDefinition;
150: }
151:
152: public void setParameterDefinition(Parameter<?>[] params) {
153: throw new UnsupportedOperationException();
154: }
155:
156: public ReturnType<R> getReturnType() {
157: return returnType;
158: }
159:
160: public void setReturnType(ReturnType<R> type) {
161: throw new UnsupportedOperationException();
162: }
163:
164: public String toString() {
165: if (parameterDefinition == null && functions.size() > 0)
166: determinDefinition();
167: return ""
168: + returnType
169: + " "
170: + "Combined("
171: + getName()
172: + ", "
173: + functions.size()
174: + " entries)"
175: + (parameterDefinition == null ? "EMPTY" : ""
176: + Arrays.asList(parameterDefinition));
177:
178: }
179:
180: }
|