1 16 package org.apache.cocoon.components.flow.java; 17 18 import java.lang.reflect.InvocationTargetException ; 19 import java.lang.reflect.Method ; 20 import java.util.HashMap ; 21 import java.util.Iterator ; 22 import java.util.List ; 23 import java.util.Map ; 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 47 public class JavaInterpreter extends AbstractInterpreter implements Configurable { 48 49 private boolean initialized = false; 50 51 private int timeToLive = 600000; 52 53 56 public static final String USER_GLOBAL_SCOPE = "JAVA GLOBAL SCOPE"; 57 58 private ClassLoader classloader; 59 60 private Map methods = new HashMap (); 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 { 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 scripts = needResolve.iterator(); scripts.hasNext();) { 83 84 String classname = (String ) 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 clazz = classloader.loadClass(classname); 94 95 final Map m = ReflectionUtils.discoverMethods(clazz); 96 methods.putAll(m); 97 98 initialized = true; 100 101 } 102 } catch (final Exception e) { 103 throw new ConfigurationException("Cannot initialize JavaInterpreter", e); 104 } 105 106 107 } 108 109 120 public void callFunction(String function, List params, Redirector redirector) throws Exception { 121 122 if (!initialized) 123 initialize(); 124 125 Method method = (Method ) 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 userScopes = (HashMap ) session.getAttribute(USER_GLOBAL_SCOPE); 137 if (userScopes == null) 138 userScopes = new HashMap (); 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 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 [0]); 173 174 } catch (InvocationTargetException ite) { 175 if (ite.getTargetException() != null) { 176 if (ite.getTargetException() instanceof Exception ) 177 throw (Exception ) ite.getTargetException(); 178 else if (ite.getTargetException() instanceof Error ) 179 throw new ProcessingException("An internal error occured", ite.getTargetException()); 180 else if (ite.getTargetException() instanceof RuntimeException ) 181 throw (RuntimeException ) ite.getTargetException(); 182 else 183 throw ite; 184 } else { 185 throw ite; 186 } 187 } finally { 188 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 id, List params, Redirector redirector) 199 throws Exception { 200 if (!initialized) 201 initialize(); 202 203 WebContinuation parentwk = continuationsMgr.lookupWebContinuation(id, getInterpreterID()); 204 205 if (parentwk == null) { 206 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 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 userScopes = (HashMap ) session.getAttribute(USER_GLOBAL_SCOPE); 234 235 Continuable flow = (Continuable) context.getObject(); 236 Method 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 [0]); 246 247 } catch (InvocationTargetException ite) { 248 if (ite.getTargetException() != null) { 249 if (ite.getTargetException() instanceof Exception ) 250 throw (Exception ) ite.getTargetException(); 251 else if (ite.getTargetException() instanceof Error ) 252 throw new ProcessingException("An internal error occured", ite.getTargetException()); 253 else if (ite.getTargetException() instanceof RuntimeException ) 254 throw (RuntimeException ) ite.getTargetException(); 255 else 256 throw ite; 257 } else { 258 throw ite; 259 } 260 } finally { 261 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 |