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: RifeFilter.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.*;
016: import javax.servlet.http.HttpServletRequest;
017: import javax.servlet.http.HttpServletResponse;
018:
019: import com.uwyn.rife.engine.EngineClassLoader;
020: import com.uwyn.rife.instrument.RifeAgent;
021:
022: public class RifeFilter implements Filter {
023: private Object mLifeCycle = null;
024: private Object mGate = null;
025: private String mGateUrl = null;
026: private ClassLoader mEngineClassloader = null;
027: private Class mRequestClass = null;
028: private Class mResponseClass = null;
029: private Class mHttpRequestClass = null;
030: private Class mHttpResponseClass = null;
031:
032: /**
033: * Returns the gate that this filter sets up.
034: * <p>
035: * Note that this is deliberately returned as <code>Object</code> to prevent
036: * the {@link com.uwyn.rife.engine.Gate} class to be loaded by the wrong
037: * classloader.
038: *
039: * @return the {@link com.uwyn.rife.engine.Gate} that has been setup by this filter.
040: * @since 1.6
041: */
042: public Object getGate() {
043: return mGate;
044: }
045:
046: public void init(FilterConfig config) throws ServletException {
047: ClassLoader classloader = getClass().getClassLoader();
048: String enabled = config
049: .getInitParameter("engineclassloader.enabled");
050: if (!(classloader instanceof EngineClassLoader)
051: && (null == enabled || enabled.equalsIgnoreCase("true")
052: || enabled.equalsIgnoreCase("t")
053: || enabled.equalsIgnoreCase("yes")
054: || enabled.equalsIgnoreCase("y")
055: || enabled.equalsIgnoreCase("on") || enabled
056: .equalsIgnoreCase("1"))) {
057: String agent_active = System.getProperty(
058: RifeAgent.AGENT_ACTIVE_PROPERTY, String
059: .valueOf(false));
060: if (!agent_active.equals(String.valueOf(true))) {
061: classloader = new EngineClassLoader(classloader);
062: Thread.currentThread().setContextClassLoader(
063: classloader);
064:
065: mEngineClassloader = classloader;
066: }
067: }
068:
069: try {
070: Class initconfig_class = classloader
071: .loadClass("com.uwyn.rife.engine.InitConfig");
072:
073: Class initconfig_filter_class = classloader
074: .loadClass("com.uwyn.rife.engine.InitConfigFilter");
075: Constructor initconfig_filter_constructor = initconfig_filter_class
076: .getConstructor(new Class[] { FilterConfig.class });
077: Object initconfig_filter = initconfig_filter_constructor
078: .newInstance(new Object[] { config });
079:
080: String lifecycle_classname = config
081: .getInitParameter("lifecycle.classname");
082: if (null == lifecycle_classname) {
083: lifecycle_classname = "com.uwyn.rife.servlet.RifeLifecycle";
084: }
085: Class lifecycle_class = classloader
086: .loadClass(lifecycle_classname);
087: mLifeCycle = lifecycle_class.newInstance();
088:
089: Method lifecycle_init = lifecycle_class.getMethod("init",
090: new Class[] { initconfig_class });
091: mGate = lifecycle_init.invoke(mLifeCycle,
092: new Object[] { initconfig_filter });
093:
094: mRequestClass = classloader
095: .loadClass("com.uwyn.rife.engine.Request");
096: mResponseClass = classloader
097: .loadClass("com.uwyn.rife.engine.Response");
098: mHttpRequestClass = classloader
099: .loadClass("com.uwyn.rife.servlet.HttpRequest");
100: mHttpResponseClass = classloader
101: .loadClass("com.uwyn.rife.servlet.HttpResponse");
102: } catch (InvocationTargetException e) {
103: if (e.getCause() != null) {
104: if (e.getCause() instanceof RuntimeException) {
105: throw (RuntimeException) e.getCause();
106: } else {
107: throw new ServletException(e.getCause());
108: }
109: } else {
110: throw new ServletException(e);
111: }
112: } catch (Throwable e) {
113: throw new ServletException(e);
114: }
115: }
116:
117: public void doFilter(ServletRequest request,
118: ServletResponse response, FilterChain chain)
119: throws IOException, ServletException {
120: if (mEngineClassloader != null) {
121: Thread.currentThread().setContextClassLoader(
122: mEngineClassloader);
123: }
124:
125: if (request instanceof HttpServletRequest
126: && response instanceof HttpServletResponse) {
127: HttpServletRequest http_servlet_request = (HttpServletRequest) request;
128: HttpServletResponse http_servlet_response = (HttpServletResponse) response;
129:
130: try {
131: // create the servlet path
132: if (null == mGateUrl) {
133: String context_path = http_servlet_request
134: .getContextPath();
135:
136: // ensure a valid context path
137: if (context_path != null
138: && !context_path.equals(".")
139: && !context_path.equals("/")) {
140: mGateUrl = context_path;
141: } else {
142: mGateUrl = "";
143: }
144: }
145:
146: // construct the element url by stripping away the gate url
147: String element_url = http_servlet_request
148: .getRequestURI().substring(mGateUrl.length());
149: Method gate_handlerequest = mGate.getClass().getMethod(
150: "handleRequest",
151: new Class[] { String.class, String.class,
152: mRequestClass, mResponseClass });
153:
154: // handle the request
155: Object http_request = mHttpRequestClass.getConstructor(
156: new Class[] { HttpServletRequest.class })
157: .newInstance(http_servlet_request);
158: Object http_response = mHttpResponseClass
159: .getConstructor(
160: new Class[] { mRequestClass,
161: HttpServletResponse.class,
162: boolean.class }).newInstance(
163: http_request, http_servlet_response,
164: false);
165:
166: Boolean result = (Boolean) gate_handlerequest.invoke(
167: mGate, new Object[] { mGateUrl, element_url,
168: http_request, http_response });
169: if (result.booleanValue()) {
170: return;
171: }
172: } catch (InvocationTargetException e) {
173: if (e.getCause() != null) {
174: if (e.getCause() instanceof RuntimeException) {
175: throw (RuntimeException) e.getCause();
176: } else {
177: throw new ServletException(e.getCause());
178: }
179: } else {
180: throw new ServletException(e);
181: }
182: } catch (Throwable e) {
183: throw new ServletException(e);
184: }
185: }
186:
187: chain.doFilter(request, response);
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: }
|