KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > components > flow > java > JavaInterpreter


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.flow.java;
17
18 import java.lang.reflect.InvocationTargetException JavaDoc;
19 import java.lang.reflect.Method JavaDoc;
20 import java.util.HashMap JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.Map JavaDoc;
24
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.avalon.framework.parameters.Parameters;
29 import org.apache.cocoon.ProcessingException;
30 import org.apache.cocoon.components.ContextHelper;
31 import org.apache.cocoon.components.flow.AbstractInterpreter;
32 import org.apache.cocoon.components.flow.FlowHelper;
33 import org.apache.cocoon.components.flow.InvalidContinuationException;
34 import org.apache.cocoon.components.flow.WebContinuation;
35 import org.apache.cocoon.environment.Redirector;
36 import org.apache.cocoon.environment.Request;
37 import org.apache.cocoon.environment.Session;
38 import org.apache.cocoon.util.ReflectionUtils;
39 import org.apache.commons.jxpath.JXPathIntrospector;
40
41 /**
42  * Implementation of the java flow interpreter.
43  *
44  * @author <a HREF="mailto:stephan@apache.org">Stephan Michels</a>
45  * @version CVS $Id: JavaInterpreter.java 170618 2005-05-17 17:10:22Z gregor $
46  */

47 public class JavaInterpreter extends AbstractInterpreter implements Configurable {
48
49     private boolean initialized = false;
50
51     private int timeToLive = 600000;
52
53     /**
54      * Key for storing a global scope object in the Cocoon session
55      */

56     public static final String JavaDoc USER_GLOBAL_SCOPE = "JAVA GLOBAL SCOPE";
57
58     private ClassLoader JavaDoc classloader;
59
60     private Map JavaDoc methods = new HashMap JavaDoc();
61
62     static {
63         JXPathIntrospector.registerDynamicClass(VarMap.class, VarMapHandler.class);
64     }
65
66     public void configure(Configuration config) throws ConfigurationException {
67         super.configure(config);
68     }
69
70     public synchronized void initialize() throws Exception JavaDoc {
71
72         if (initialized) {
73             return;
74         }
75
76         try {
77             if (getLogger().isDebugEnabled())
78                 getLogger().debug("initialize java flow interpreter");
79
80             classloader = new ContinuationClassLoader(Thread.currentThread().getContextClassLoader());
81
82             for (Iterator JavaDoc scripts = needResolve.iterator(); scripts.hasNext();) {
83
84                 String JavaDoc classname = (String JavaDoc) scripts.next();
85                 if (getLogger().isDebugEnabled())
86                     getLogger().debug("registered java class \"" + classname + "\" for flow");
87
88                 if (!Continuable.class.isAssignableFrom(Class.forName(classname))) {
89                     getLogger().error("java class \"" + classname + "\" doesn't implement Continuable");
90                     continue;
91                 }
92
93                 Class JavaDoc clazz = classloader.loadClass(classname);
94
95                 final Map JavaDoc m = ReflectionUtils.discoverMethods(clazz);
96                 methods.putAll(m);
97                 
98                 //Only initialize if everything so far hasn't thrown any exceptions.
99
initialized = true;
100
101             }
102         } catch (final Exception JavaDoc e) {
103             throw new ConfigurationException("Cannot initialize JavaInterpreter", e);
104         }
105
106        
107     }
108
109     /**
110      * Calls a Java function, passing <code>params</code> as its
111      * arguments. In addition to this, it makes available the parameters
112      * through the <code>cocoon.parameters</code> Java array
113      * (indexed by the parameter names).
114      *
115      * @param function a <code>String</code> value
116      * @param params a <code>List</code> value
117      * @param redirector
118      * @exception Exception if an error occurs
119      */

120     public void callFunction(String JavaDoc function, List JavaDoc params, Redirector redirector) throws Exception JavaDoc {
121
122         if (!initialized)
123             initialize();
124
125         Method JavaDoc method = (Method JavaDoc) methods.get(function);
126
127         if (method == null) {
128             throw new ProcessingException("No method '" + function + "' found. " + methods);
129         }
130
131         if (getLogger().isDebugEnabled())
132             getLogger().debug("calling method \"" + method + "\"");
133
134         Request request = ContextHelper.getRequest(this.avalonContext);
135         Session session = request.getSession(true);
136         HashMap JavaDoc userScopes = (HashMap JavaDoc) session.getAttribute(USER_GLOBAL_SCOPE);
137         if (userScopes == null)
138             userScopes = new HashMap JavaDoc();
139
140         Continuable flow = (Continuable) userScopes.get(method.getDeclaringClass());
141
142         ContinuationContext context = new ContinuationContext();
143         context.setObject(flow);
144         context.setMethod(method);
145         context.setAvalonContext(avalonContext);
146         context.setLogger(getLogger());
147         context.setServiceManager(manager);
148         context.setRedirector(redirector);
149         Parameters parameters = new Parameters();
150         for(Iterator JavaDoc i=params.iterator(); i.hasNext();) {
151             Argument argument = (Argument)i.next();
152             parameters.setParameter(argument.name, argument.value);
153         }
154         context.setParameters(parameters);
155
156         Continuation continuation = new Continuation(context);
157
158         WebContinuation wk = continuationsMgr.createWebContinuation(
159                 continuation, null, timeToLive, getInterpreterID(), null);
160         FlowHelper.setWebContinuation(ContextHelper.getObjectModel(this.avalonContext), wk);
161
162         continuation.registerThread();
163         try {
164             if (flow == null) {
165                 if (getLogger().isDebugEnabled())
166                     getLogger().debug("create new instance of \""+method.getDeclaringClass()+"\"");
167
168                 flow = (Continuable) method.getDeclaringClass().newInstance();
169                 context.setObject(flow);
170             }
171
172             method.invoke(flow, new Object JavaDoc[0]);
173
174         } catch (InvocationTargetException JavaDoc ite) {
175             if (ite.getTargetException() != null) {
176                 if (ite.getTargetException() instanceof Exception JavaDoc)
177                     throw (Exception JavaDoc) ite.getTargetException();
178                 else if (ite.getTargetException() instanceof Error JavaDoc)
179                     throw new ProcessingException("An internal error occured", ite.getTargetException());
180                 else if (ite.getTargetException() instanceof RuntimeException JavaDoc)
181                     throw (RuntimeException JavaDoc) ite.getTargetException();
182                 else
183                     throw ite;
184             } else {
185                 throw ite;
186             }
187         } finally {
188             // remove last object reference, which is not needed to
189
// reconstruct the invocation path
190
if (continuation.isCapturing())
191                 continuation.getStack().popReference();
192             continuation.deregisterThread();
193         }
194         userScopes.put(method.getDeclaringClass(), flow);
195         session.setAttribute(USER_GLOBAL_SCOPE, userScopes);
196     }
197
198     public void handleContinuation(String JavaDoc id, List JavaDoc params, Redirector redirector)
199             throws Exception JavaDoc {
200         if (!initialized)
201             initialize();
202
203         WebContinuation parentwk = continuationsMgr.lookupWebContinuation(id, getInterpreterID());
204
205         if (parentwk == null) {
206             /*
207              * Throw an InvalidContinuationException to be handled inside the
208              * <map:handle-errors> sitemap element.
209              */

210             throw new InvalidContinuationException("The continuation ID " + id + " is invalid.");
211         }
212
213         Continuation parentContinuation = (Continuation) parentwk.getContinuation();
214         ContinuationContext parentContext = (ContinuationContext) parentContinuation.getContext();
215         ContinuationContext context = new ContinuationContext();
216         context.setObject(parentContext.getObject());
217         context.setMethod(parentContext.getMethod());
218         context.setAvalonContext(avalonContext);
219         context.setLogger(getLogger());
220         context.setServiceManager(manager);
221         context.setRedirector(redirector);
222         Parameters parameters = new Parameters();
223         for(Iterator JavaDoc i=params.iterator(); i.hasNext();) {
224             Argument argument = (Argument)i.next();
225             parameters.setParameter(argument.name, argument.value);
226         }
227         context.setParameters(parameters);
228
229         Continuation continuation = new Continuation(parentContinuation, context);
230
231         Request request = ContextHelper.getRequest(this.avalonContext);
232         Session session = request.getSession(true);
233         HashMap JavaDoc userScopes = (HashMap JavaDoc) session.getAttribute(USER_GLOBAL_SCOPE);
234
235         Continuable flow = (Continuable) context.getObject();
236         Method JavaDoc method = context.getMethod();
237
238         WebContinuation wk = continuationsMgr.createWebContinuation(
239                 continuation, parentwk, timeToLive, getInterpreterID(), null);
240         FlowHelper.setWebContinuation(ContextHelper.getObjectModel(this.avalonContext), wk);
241
242         continuation.registerThread();
243         try {
244
245             method.invoke(flow, new Object JavaDoc[0]);
246
247         } catch (InvocationTargetException JavaDoc ite) {
248             if (ite.getTargetException() != null) {
249                 if (ite.getTargetException() instanceof Exception JavaDoc)
250                     throw (Exception JavaDoc) ite.getTargetException();
251                 else if (ite.getTargetException() instanceof Error JavaDoc)
252                     throw new ProcessingException("An internal error occured", ite.getTargetException());
253                 else if (ite.getTargetException() instanceof RuntimeException JavaDoc)
254                     throw (RuntimeException JavaDoc) ite.getTargetException();
255                 else
256                     throw ite;
257             } else {
258                 throw ite;
259             }
260         } finally {
261             // remove last object reference, which is not needed to reconstruct
262
// the invocation path
263
if (continuation.isCapturing())
264               continuation.getStack().popReference();
265             continuation.deregisterThread();
266         }
267
268         userScopes.put(method.getDeclaringClass(), flow);
269         session.setAttribute(USER_GLOBAL_SCOPE, userScopes);
270     }
271 }
272
Popular Tags