001: /*
002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: * $Id: RifeServlet.java 3678 2007-03-01 10:40:23Z gbevin $
007: */
008: package com.uwyn.rife.servlet;
009:
010: import java.io.IOException;
011: import java.lang.reflect.Constructor;
012: import java.lang.reflect.InvocationTargetException;
013: import java.lang.reflect.Method;
014:
015: import javax.servlet.ServletConfig;
016: import javax.servlet.ServletException;
017: import javax.servlet.http.HttpServlet;
018: import javax.servlet.http.HttpServletRequest;
019: import javax.servlet.http.HttpServletResponse;
020:
021: import com.uwyn.rife.engine.EngineClassLoader;
022: import com.uwyn.rife.instrument.RifeAgent;
023:
024: public class RifeServlet extends HttpServlet {
025: private static final long serialVersionUID = 781560128846727886L;
026:
027: private Object mLifeCycle = null;
028: private Object mGate = null;
029: private String mGateUrl = null;
030: private ClassLoader mEngineClassloader = null;
031: private Class mRequestClass = null;
032: private Class mResponseClass = null;
033: private Class mHttpRequestClass = null;
034: private Class mHttpResponseClass = null;
035:
036: /**
037: * Returns the gate that this filter sets up.
038: * <p>
039: * Note that this is deliberately returned as <code>Object</code> to prevent
040: * the {@link com.uwyn.rife.engine.Gate} class to be loaded by the wrong
041: * classloader.
042: *
043: * @return the {@link com.uwyn.rife.engine.Gate} that has been setup by this filter.
044: * @since 1.6
045: */
046: public Object getGate() {
047: return mGate;
048: }
049:
050: public void init(ServletConfig config) throws ServletException {
051: ClassLoader classloader = getClass().getClassLoader();
052: String enabled = config
053: .getInitParameter("engineclassloader.enabled");
054: if (!(classloader instanceof EngineClassLoader)
055: && (null == enabled || enabled.equalsIgnoreCase("true")
056: || enabled.equalsIgnoreCase("t")
057: || enabled.equalsIgnoreCase("yes")
058: || enabled.equalsIgnoreCase("y")
059: || enabled.equalsIgnoreCase("on") || enabled
060: .equalsIgnoreCase("1"))) {
061: String agent_active = System.getProperty(
062: RifeAgent.AGENT_ACTIVE_PROPERTY, String
063: .valueOf(false));
064: if (!agent_active.equals(String.valueOf(true))) {
065: classloader = new EngineClassLoader(classloader);
066: Thread.currentThread().setContextClassLoader(
067: classloader);
068:
069: mEngineClassloader = classloader;
070: }
071: }
072:
073: try {
074: Class initconfig_class = classloader
075: .loadClass("com.uwyn.rife.engine.InitConfig");
076:
077: Class initconfig_servlet_class = classloader
078: .loadClass("com.uwyn.rife.engine.InitConfigServlet");
079: Constructor initconfig_servlet_constructor = initconfig_servlet_class
080: .getConstructor(new Class[] { ServletConfig.class });
081: Object initconfig_servlet = initconfig_servlet_constructor
082: .newInstance(new Object[] { config });
083:
084: Class lifecycle_class = classloader
085: .loadClass("com.uwyn.rife.servlet.RifeLifecycle");
086: mLifeCycle = lifecycle_class.newInstance();
087:
088: Method lifecycle_init = lifecycle_class.getMethod("init",
089: new Class[] { initconfig_class });
090: mGate = lifecycle_init.invoke(mLifeCycle,
091: new Object[] { initconfig_servlet });
092:
093: mRequestClass = classloader
094: .loadClass("com.uwyn.rife.engine.Request");
095: mResponseClass = classloader
096: .loadClass("com.uwyn.rife.engine.Response");
097: mHttpRequestClass = classloader
098: .loadClass("com.uwyn.rife.servlet.HttpRequest");
099: mHttpResponseClass = classloader
100: .loadClass("com.uwyn.rife.servlet.HttpResponse");
101: } catch (InvocationTargetException e) {
102: if (e.getCause() != null) {
103: if (e.getCause() instanceof RuntimeException) {
104: throw (RuntimeException) e.getCause();
105: } else {
106: throw new ServletException(e.getCause());
107: }
108: } else {
109: throw new ServletException(e);
110: }
111: } catch (Throwable e) {
112: throw new ServletException(e);
113: }
114: }
115:
116: public void service(HttpServletRequest httpServletRequest,
117: HttpServletResponse httpServletResponse)
118: throws ServletException {
119: if (mEngineClassloader != null) {
120: Thread.currentThread().setContextClassLoader(
121: mEngineClassloader);
122: }
123:
124: try {
125: // create the servlet path
126: if (null == mGateUrl) {
127: String context_path = httpServletRequest
128: .getContextPath();
129:
130: // build a correct gate URL by using the servlet path and ensuring the value is acceptable
131: String servlet_path = httpServletRequest
132: .getServletPath();
133: if (context_path != null && !context_path.equals(".")
134: && !context_path.equals("/")) {
135: mGateUrl = context_path;
136: if (servlet_path != null
137: && !servlet_path.equals(".")
138: && !servlet_path.equals("/")) {
139: mGateUrl += servlet_path;
140: }
141: } else {
142: mGateUrl = "";
143: }
144: }
145:
146: String element_url = httpServletRequest.getPathInfo();
147: Method gate_handlerequest = mGate.getClass().getMethod(
148: "handleRequest",
149: new Class[] { String.class, String.class,
150: mRequestClass, mResponseClass });
151:
152: // handle the request
153: Object http_request = mHttpRequestClass.getConstructor(
154: new Class[] { HttpServletRequest.class })
155: .newInstance(httpServletRequest);
156: Object http_response = mHttpResponseClass.getConstructor(
157: new Class[] { mRequestClass,
158: HttpServletResponse.class, boolean.class })
159: .newInstance(http_request, httpServletResponse,
160: false);
161:
162: Boolean result = (Boolean) gate_handlerequest.invoke(mGate,
163: new Object[] { mGateUrl, element_url, http_request,
164: http_response });
165: if (!result.booleanValue()) {
166: try {
167: httpServletResponse
168: .sendError(HttpServletResponse.SC_NOT_FOUND);
169: } catch (IOException e) {
170: throw new RuntimeException(e);
171: }
172: } else {
173: return;
174: }
175: } catch (InvocationTargetException e) {
176: if (e.getCause() != null) {
177: if (e.getCause() instanceof RuntimeException) {
178: throw (RuntimeException) e.getCause();
179: } else {
180: throw new ServletException(e.getCause());
181: }
182: } else {
183: throw new ServletException(e);
184: }
185: } catch (Throwable e) {
186: throw new ServletException(e);
187: }
188: }
189:
190: public void destroy() {
191: if (mEngineClassloader != null) {
192: Thread.currentThread().setContextClassLoader(
193: mEngineClassloader);
194: }
195:
196: try {
197: Class lifecycle_class = mLifeCycle.getClass();
198: Method lifecycle_destroy = lifecycle_class.getMethod(
199: "destroy", (Class[]) null);
200: lifecycle_destroy.invoke(mLifeCycle, (Object[]) null);
201: } catch (InvocationTargetException e) {
202: if (e.getCause() != null) {
203: if (e.getCause() instanceof RuntimeException) {
204: throw (RuntimeException) e.getCause();
205: } else {
206: throw new RuntimeException(e.getCause());
207: }
208: } else {
209: throw new RuntimeException(e);
210: }
211: } catch (Throwable e) {
212: throw new RuntimeException(e);
213: }
214: }
215: }
|