KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > components > treeprocessor > sitemap > CallFunctionNode


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.cocoon.components.treeprocessor.sitemap;
17
18 import java.util.ArrayList JavaDoc;
19 import java.util.Collections JavaDoc;
20 import java.util.List JavaDoc;
21 import java.util.Map JavaDoc;
22
23 import org.apache.avalon.framework.component.ComponentManager;
24 import org.apache.avalon.framework.component.Composable;
25 import org.apache.avalon.framework.configuration.Configurable;
26 import org.apache.avalon.framework.configuration.Configuration;
27 import org.apache.avalon.framework.configuration.ConfigurationException;
28 import org.apache.cocoon.ProcessingException;
29 import org.apache.cocoon.components.flow.Interpreter;
30 import org.apache.cocoon.components.treeprocessor.AbstractProcessingNode;
31 import org.apache.cocoon.components.treeprocessor.InvokeContext;
32 import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
33 import org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory;
34 import org.apache.cocoon.environment.Environment;
35 import org.apache.cocoon.environment.Redirector;
36 import org.apache.cocoon.sitemap.PatternException;
37
38 /**
39  * Node handler for calling functions and resuming continuations in
40  * the control flow layer.
41  *
42  * @author <a HREF="mailto:ovidiu@apache.org">Ovidiu Predescu</a>
43  * @since March 13, 2002
44  * @version CVS $Id: CallFunctionNode.java 232400 2005-08-12 22:14:26Z sylvain $
45  */

46 public class CallFunctionNode extends AbstractProcessingNode implements Configurable, Composable {
47     protected List JavaDoc parameters;
48     protected VariableResolver functionName;
49     protected VariableResolver continuationId;
50     protected ComponentManager manager;
51     protected Interpreter interpreter;
52
53     public static List JavaDoc resolveList(List JavaDoc expressions, ComponentManager manager, InvokeContext context, Map JavaDoc objectModel)
54         throws PatternException {
55         int size;
56         if (expressions == null || (size = expressions.size()) == 0)
57             return Collections.EMPTY_LIST;
58
59         List JavaDoc result = new ArrayList JavaDoc(size);
60
61         for (int i = 0; i < size; i++) {
62             Interpreter.Argument arg = (Interpreter.Argument)expressions.get(i);
63             String JavaDoc value = VariableResolverFactory.getResolver(arg.value, manager).resolve(context, objectModel);
64             result.add(new Interpreter.Argument(arg.name, value));
65         }
66
67         return result;
68     }
69
70     public CallFunctionNode(VariableResolver functionName, VariableResolver continuationId) {
71         this.functionName = functionName;
72         this.continuationId = continuationId;
73     }
74
75     public void setInterpreter(Interpreter interp) throws Exception JavaDoc {
76         this.interpreter = interp;
77     }
78
79     /**
80      * Obtain the configuration specific to this node type and update
81      * the internal state.
82      *
83      * @param config a <code>Configuration</code> value
84      * @exception ConfigurationException if an error occurs
85      */

86     public void configure(Configuration config) throws ConfigurationException {
87         //TODO (SW): Deprecate this in the future.
88
// It has be found to be bad practice to pass sitemap parameters
89
// as function arguments, as these are name-value pairs in the sitemap
90
// and positional arguments in the flowscript. If the user doesn't respect
91
// the argument order, this leads to difficult to solve bugs.
92
parameters = new ArrayList JavaDoc();
93
94         Configuration[] params = config.getChildren("parameter");
95         for (int i = 0; i < params.length; i++) {
96             Configuration param = params[i];
97             String JavaDoc name = param.getAttribute("name", null);
98             String JavaDoc value = param.getAttribute("value", null);
99             parameters.add(new Interpreter.Argument(name, value));
100         }
101     }
102
103     public void compose(ComponentManager manager) {
104         this.manager = manager;
105     }
106
107     public boolean invoke(Environment env, InvokeContext context) throws Exception JavaDoc {
108         List JavaDoc params = null;
109
110         // Resolve parameters
111
if (parameters != null) {
112             params = resolveList(parameters, manager, context, env.getObjectModel());
113         }
114
115         // Need redirector in any case
116
Redirector redirector = context.getRedirector();
117
118         // If the continuation id is not null, it takes precedence over
119
// the function call, so we invoke it here.
120
String JavaDoc continuation = continuationId.resolve(context, env.getObjectModel());
121         if (continuation != null && continuation.length() > 0) {
122             try {
123                 interpreter.handleContinuation(continuation, params, redirector);
124             } catch(Exception JavaDoc e) {
125                 throw ProcessingException.throwLocated("Sitemap: error calling continuation", e, getLocation());
126             }
127             if (!redirector.hasRedirected()) {
128                 throw new ProcessingException("Sitemap: <map:call continuation> did not send a response", getLocation());
129             }
130             return true;
131         }
132
133         // We don't have a continuation id passed in <map:call>, so invoke
134
// the specified function
135
String JavaDoc name = functionName.resolve(context, env.getObjectModel());
136         if (name != null && name.length() > 0) {
137             try {
138                 interpreter.callFunction(name, params, redirector);
139             } catch(Exception JavaDoc e) {
140                 throw ProcessingException.throwLocated("Sitemap: error calling function '" + name + "'", e, getLocation());
141             }
142             if (!redirector.hasRedirected()) {
143                 throw new ProcessingException("Sitemap: <map:call function> did not send a response", getLocation());
144             }
145             return true;
146         }
147
148         // Found neither continuation nor function to call
149
throw new ProcessingException("Sitemap: no function nor continuation given in <map:call function>", getLocation());
150     }
151 }
152
Popular Tags