/* * Copyright 2001-2008 Geert Bevin (gbevin[remove] at uwyn dot com) * Licensed under the Apache License, Version 2.0 (the "License") * $Id: RifeServlet.java 3918 2008-04-14 17:35:35Z gbevin $ */ package com.uwyn.rife.servlet; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.uwyn.rife.engine.EngineClassLoader; import com.uwyn.rife.instrument.RifeAgent; public class RifeServlet extends HttpServlet { private static final long serialVersionUID = 781560128846727886L; private Object mLifeCycle = null; private Object mGate = null; private String mGateUrl = null; private ClassLoader mEngineClassloader = null; private Class mRequestClass = null; private Class mResponseClass = null; private Class mHttpRequestClass = null; private Class mHttpResponseClass = null; /** * Returns the gate that this filter sets up. * <p> * Note that this is deliberately returned as <code>Object</code> to prevent * the {@link com.uwyn.rife.engine.Gate} class to be loaded by the wrong * classloader. * * @return the {@link com.uwyn.rife.engine.Gate} that has been setup by this filter. * @since 1.6 */ public Object getGate() { return mGate; } public void init(ServletConfig config) throws ServletException { ClassLoader classloader = getClass().getClassLoader(); String enabled = config.getInitParameter("engineclassloader.enabled"); if (!(classloader instanceof EngineClassLoader) && (null == enabled || enabled.equalsIgnoreCase("true") || enabled.equalsIgnoreCase("t") || enabled.equalsIgnoreCase("yes") || enabled.equalsIgnoreCase("y") || enabled.equalsIgnoreCase("on") || enabled.equalsIgnoreCase("1"))) { String agent_active = System.getProperty(RifeAgent.AGENT_ACTIVE_PROPERTY, String.valueOf(false)); if (!agent_active.equals(String.valueOf(true))) { classloader = new EngineClassLoader(classloader); Thread.currentThread().setContextClassLoader(classloader); mEngineClassloader = classloader; } } try { Class initconfig_class = classloader.loadClass("com.uwyn.rife.engine.InitConfig"); Class initconfig_servlet_class = classloader.loadClass("com.uwyn.rife.engine.InitConfigServlet"); Constructor initconfig_servlet_constructor = initconfig_servlet_class.getConstructor(new Class[] {ServletConfig.class}); Object initconfig_servlet = initconfig_servlet_constructor.newInstance(new Object[] {config}); Class lifecycle_class = classloader.loadClass("com.uwyn.rife.servlet.RifeLifecycle"); mLifeCycle = lifecycle_class.newInstance(); Method lifecycle_init = lifecycle_class.getMethod("init", new Class[] {initconfig_class}); mGate = lifecycle_init.invoke(mLifeCycle, new Object[] {initconfig_servlet}); mRequestClass = classloader.loadClass("com.uwyn.rife.engine.Request"); mResponseClass = classloader.loadClass("com.uwyn.rife.engine.Response"); mHttpRequestClass = classloader.loadClass("com.uwyn.rife.servlet.HttpRequest"); mHttpResponseClass = classloader.loadClass("com.uwyn.rife.servlet.HttpResponse"); } catch (InvocationTargetException e) { if (e.getCause() != null) { if (e.getCause() instanceof RuntimeException) { throw (RuntimeException)e.getCause(); } else { throw new ServletException(e.getCause()); } } else { throw new ServletException(e); } } catch (Throwable e) { throw new ServletException(e); } } public void service(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException { if (mEngineClassloader != null) { Thread.currentThread().setContextClassLoader(mEngineClassloader); } try { // create the servlet path if (null == mGateUrl) { String context_path = httpServletRequest.getContextPath(); // build a correct gate URL by using the servlet path and ensuring the value is acceptable String servlet_path = httpServletRequest.getServletPath(); if (context_path != null && !context_path.equals(".") && !context_path.equals("/")) { mGateUrl = context_path; if (servlet_path != null && !servlet_path.equals(".") && !servlet_path.equals("/")) { mGateUrl += servlet_path; } } else { mGateUrl = ""; } } String element_url = httpServletRequest.getPathInfo(); Method gate_handlerequest = mGate.getClass().getMethod("handleRequest", new Class[] {String.class, String.class, mRequestClass, mResponseClass}); // handle the request Object http_request = mHttpRequestClass.getConstructor(new Class[] {HttpServletRequest.class}).newInstance(httpServletRequest); Object http_response = mHttpResponseClass.getConstructor(new Class[] {mRequestClass, HttpServletResponse.class, boolean.class}).newInstance(http_request, httpServletResponse, false); Boolean result = (Boolean)gate_handlerequest.invoke(mGate, new Object[] {mGateUrl, element_url, http_request, http_response}); if (!result.booleanValue()) { try { httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND); } catch (IOException e) { throw new RuntimeException(e); } } else { return; } } catch (InvocationTargetException e) { if (e.getCause() != null) { if (e.getCause() instanceof RuntimeException) { throw (RuntimeException)e.getCause(); } else { throw new ServletException(e.getCause()); } } else { throw new ServletException(e); } } catch (Throwable e) { throw new ServletException(e); } } public void destroy() { if (mEngineClassloader != null) { Thread.currentThread().setContextClassLoader(mEngineClassloader); } try { Class lifecycle_class = mLifeCycle.getClass(); Method lifecycle_destroy = lifecycle_class.getMethod("destroy", (Class[])null); lifecycle_destroy.invoke(mLifeCycle, (Object[])null); } catch (InvocationTargetException e) { if (e.getCause() != null) { if (e.getCause() instanceof RuntimeException) { throw (RuntimeException)e.getCause(); } else { throw new RuntimeException(e.getCause()); } } else { throw new RuntimeException(e); } } catch (Throwable e) { throw new RuntimeException(e); } } }