KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > bridge > jsp > taglib > functions > AbstractFunctionTag


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.bridge.jsp.taglib.functions;
11
12
13 import java.lang.reflect.Method JavaDoc;
14 import java.util.Iterator JavaDoc;
15
16 import javax.servlet.jsp.JspTagException JavaDoc;
17
18 import org.mmbase.bridge.NotFoundException;
19 import org.mmbase.bridge.jsp.taglib.*;
20 import org.mmbase.bridge.jsp.taglib.containers.*;
21 import org.mmbase.bridge.jsp.taglib.util.*;
22 import java.util.Map JavaDoc;
23 import org.mmbase.util.functions.*;
24 import org.mmbase.util.functions.Functions;
25 import org.mmbase.util.logging.*;
26
27 /**
28  * The function tags can be used as a child of a 'NodeProvider' tag (though posisbly
29  * not on clusternodes).
30  * It can also be used stand alone, when using the attributes to specify on which object the
31  * function must be called (besides nodes, it can be called on node-manager, modules, sets).
32  *
33  * This is the absctract implementation, providing only the result of the function. The several
34  * extensions cast to the right type, and handle it on a specific way.
35  *
36  *
37  * @author Michiel Meeuwissen
38  * @since MMBase-1.7
39  * @version $Id: AbstractFunctionTag.java,v 1.27.2.2 2006/11/17 13:08:10 nklasens Exp $
40  */

41 abstract public class AbstractFunctionTag extends NodeReferrerTag {
42
43     private static final Logger log = Logging.getLoggerInstance(AbstractFunctionTag.class);
44
45     public static final String JavaDoc THISPAGE = "THISPAGE";
46
47     protected Attribute container = Attribute.NULL;
48     protected Attribute name = Attribute.NULL;
49     protected Attribute parametersAttr = Attribute.NULL;
50
51     protected Attribute module = Attribute.NULL;
52     protected Attribute nodeManager = Attribute.NULL;
53
54     protected Attribute functionSet = Attribute.NULL;
55
56     protected Attribute functionClass = Attribute.NULL;
57
58     protected Attribute referids = Attribute.NULL;
59
60     public void setName(String JavaDoc n) throws JspTagException JavaDoc {
61         name = getAttribute(n);
62     }
63
64     public void setContainer(String JavaDoc c) throws JspTagException JavaDoc {
65         container = getAttribute(c);
66     }
67
68     public void setParameters(String JavaDoc p) throws JspTagException JavaDoc {
69         parametersAttr = getAttribute(p);
70     }
71
72     public void setModule(String JavaDoc m) throws JspTagException JavaDoc {
73         module = getAttribute(m);
74     }
75
76     public void setNodemanager(String JavaDoc n) throws JspTagException JavaDoc {
77         nodeManager = getAttribute(n);
78     }
79
80     public void setSet(String JavaDoc s) throws JspTagException JavaDoc {
81         functionSet = getAttribute(s);
82     }
83
84     public void setClassname(String JavaDoc c) throws JspTagException JavaDoc {
85         functionClass = getAttribute(c);
86     }
87
88     public void setReferids(String JavaDoc r) throws JspTagException JavaDoc {
89         referids = getAttribute(r);
90     }
91
92     /**
93      * Gets function object, and checks consistency of attributes.
94      */

95     protected final Function getFunction(String JavaDoc functionName) throws JspTagException JavaDoc {
96         Function function;
97         // now determin on what the object the function must be done.
98
if (nodeManager != Attribute.NULL) {
99             if (module != Attribute.NULL || functionSet != Attribute.NULL || functionClass != Attribute.NULL || parentNodeId != Attribute.NULL) {
100                 throw new TaglibException("You can only use one of 'nodemanager', 'module', 'set', 'class' or 'node' on a function tag");
101             }
102             return getCloudVar().getNodeManager(nodeManager.getString(this)).getFunction(functionName);
103         } else if (module != Attribute.NULL) {
104             if (nodeManager != Attribute.NULL || functionSet != Attribute.NULL || functionClass != Attribute.NULL || parentNodeId != Attribute.NULL) {
105                 throw new TaglibException("You can only use one of 'nodemanager', 'module', 'set', 'class' or 'node' on a function tag");
106             }
107             return FunctionFactory.getFunction(getCloudContext().getModule(module.getString(this)), functionName); // or: module.getFunction(functionName);
108
} else if (functionSet != Attribute.NULL) {
109             if (nodeManager != Attribute.NULL || module != Attribute.NULL || parentNodeId != Attribute.NULL || functionClass != Attribute.NULL) {
110                 throw new TaglibException("You can only use one of 'nodemanager', 'module', 'set', 'class' or 'node' on a function tag");
111             }
112             String JavaDoc set = functionSet.getString(this);
113             if (set.equals(THISPAGE)) {
114                 Class JavaDoc jspClass = pageContext.getPage().getClass();
115                 Method JavaDoc method = Functions.getMethodFromClass(jspClass, functionName);
116                 return FunctionFactory.getFunction(method, functionName); // or: new MethodFunction(method, functionName);
117
} else {
118                 CloudProvider cp = findCloudProvider(false);
119                 if (cp != null) {
120                     return FunctionFactory.getFunction(cp.getCloudVar(), set, functionName);
121                 } else {
122                     return FunctionFactory.getFunction(set, functionName);
123                 }
124             }
125         } else if (functionClass != Attribute.NULL) {
126             if (nodeManager != Attribute.NULL || module != Attribute.NULL || parentNodeId != Attribute.NULL || functionSet != Attribute.NULL) {
127                 throw new TaglibException("You can only use one of 'nodemanager', 'module', 'set', 'class' or 'node' on a function tag");
128             }
129             String JavaDoc className = functionClass.getString(this);
130             try {
131                 Class JavaDoc clazz;
132                 if (className.indexOf(".") == -1) {
133                     Class JavaDoc jspClass = pageContext.getPage().getClass();
134                     clazz = BeanFunction.getClass(jspClass, className);
135                 } else {
136                     clazz = Class.forName(className);
137                 }
138                 return FunctionFactory.getFunction(clazz, functionName); // BeanFunction.getFunction(clazz,functionName)
139
} catch (Exception JavaDoc e) {
140                 // possible execptions thrown when instantiating bean functions:
141
// IllegalArgumentException, IllegalAccessException, InstantiationException, InvocationTargetException
142
throw new TaglibException(e);
143             }
144
145         } else { // working as Node-referrer unless explicitely specified that it should not (a container must be present!)
146

147             log.debug("Node-referrer?");
148             if (container != Attribute.NULL || "".equals(parentNodeId.getValue(this)) || functionName == null) { // explicitit container
149
log.debug("explicitely not");
150                 FunctionContainerTag functionContainer = (FunctionContainerTag) findParentTag(FunctionContainer.class, (String JavaDoc) container.getValue(this), false);
151                 if (functionContainer != null) {
152                     function = functionContainer.getFunction(functionName);
153                     return function;
154                 } else {
155                     // ignore.
156
}
157             }
158             // it is possible that a 'closer' node provider is meant
159
FunctionContainerOrNodeProvider functionOrNode;
160             log.debug("Checking for 'closer' node provider");
161             if (parentNodeId != Attribute.NULL) {
162                 log.debug("explicitely specified node");
163                 functionOrNode = findNodeProvider();
164             } else {
165                 functionOrNode = (FunctionContainerOrNodeProvider) findParentTag(FunctionContainerOrNodeProvider.class, null, false);
166             }
167             if (log.isDebugEnabled()) {
168                 log.debug("Found functionOrNode " + functionOrNode);
169             }
170             if (functionOrNode != null) {
171                 if (functionOrNode instanceof NodeProvider) { // wow, indeed, that we are going to use
172
log.debug("using node-function!");
173                     return ((NodeProvider) functionOrNode).getNodeVar().getFunction(functionName);
174                 } else { // just use the functioncontainer
175
return ((FunctionContainerTag) functionOrNode).getFunction(functionName);
176                 }
177             } else {
178                 return null;
179             }
180         }
181
182     }
183
184     protected final Function getFunction() throws JspTagException JavaDoc {
185         String JavaDoc functionName = name.getString(this);
186         FunctionContainerTag functionContainer = (FunctionContainerTag) findParentTag(FunctionContainer.class, (String JavaDoc) container.getValue(this), false);
187         if(log.isDebugEnabled()) {
188             log.debug("Getting function value. Container " + functionContainer);
189         }
190
191         Function function;
192         if ("".equals(functionName)) { // no name given, certainly must use container.
193
if (functionContainer == null) throw new JspTagException JavaDoc("No function name given, and no function container tag found either");
194             function = functionContainer.getFunction(functionContainer.getName());
195             if (function == null) {
196                 throw new JspTagException JavaDoc("Could not determine the name of the function to be executed");
197             }
198         } else {
199             log.debug("Trying self for function " + functionName);
200             // name given, try self:
201
function = getFunction(functionName);
202             if (function == null) {
203                 throw new NotFoundException("Could not find function with the name '" + functionName + "'");
204             }
205         }
206         return function;
207
208     }
209
210     protected final Object JavaDoc getFunctionValue() throws JspTagException JavaDoc {
211         return getFunctionValue(true);
212     }
213
214
215     protected final Object JavaDoc getFunctionValue(boolean register) throws JspTagException JavaDoc {
216         String JavaDoc functionName = name.getString(this);
217         Object JavaDoc value;
218         if (getReferid() != null) {
219             if (! "".equals(functionName)) {
220                 throw new TaglibException("Cannot specify both 'referid' and 'name' attributes on a function tag");
221             }
222             value = getObject(getReferid());
223         } else {
224             Function function = null;
225             try {
226                 function = getFunction();
227             } catch (RuntimeException JavaDoc e) {
228                 if ("log".equals(pageContext.getServletContext().getInitParameter("mmbase.taglib.function.nonExistance"))) {
229                     log.error("Could not find function with the name '" + functionName + "'");
230                     return null;
231                 }
232                 throw e;
233              }
234
235             if (log.isDebugEnabled()) {
236                 log.debug("Function to use " + function);
237             }
238             Parameters params;
239             try {
240                 params = function.createParameters();
241             } catch (IllegalStateException JavaDoc ise) {
242                 log.warn("Undefined parameters for function '" + functionName + "', trying without definition.");
243                 params = new AutodefiningParameters();
244             }
245             params.setAutoCasting(true);
246
247             FunctionContainerTag functionContainer = (FunctionContainerTag) findParentTag(FunctionContainer.class, (String JavaDoc) container.getValue(this), false);
248             try {
249                 if (functionContainer != null) {
250                     Iterator JavaDoc i = functionContainer.getParameters().iterator();
251                     while (i.hasNext()) {
252                         Map.Entry JavaDoc entry = (Map.Entry JavaDoc) i.next();
253                         params.set((String JavaDoc) entry.getKey(), entry.getValue());
254                     }
255                 }
256                 if (referids != Attribute.NULL) {
257                     params.setAll(Referids.getReferids(referids, this));
258                 }
259
260                 fillStandardParameters(params);
261
262                 if (log.isDebugEnabled()) {
263                     log.debug("using parameters " + params + " on " + function.getClass() + " " + function);
264                 }
265
266                 params.checkRequiredParameters();
267             } catch (Throwable JavaDoc e) {
268                 throw new IllegalArgumentException JavaDoc("function " + functionName + " " + e.getMessage());
269             }
270
271             value = function.getFunctionValue(params);
272
273         }
274         if (register && getId() != null) {
275             getContextProvider().getContextContainer().register(getId(), value);
276         }
277         return value;
278     }
279
280 }
281
Popular Tags