/*
* Copyright 2001-2008 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
* $Id: RifeFilter.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.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.uwyn.rife.engine.EngineClassLoader;
import com.uwyn.rife.instrument.RifeAgent;
public class RifeFilter implements Filter
{
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(FilterConfig 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_filter_class = classloader.loadClass("com.uwyn.rife.engine.InitConfigFilter");
Constructor initconfig_filter_constructor = initconfig_filter_class.getConstructor(new Class[] {FilterConfig.class});
Object initconfig_filter = initconfig_filter_constructor.newInstance(new Object[] {config});
String lifecycle_classname = config.getInitParameter("lifecycle.classname");
if (null == lifecycle_classname)
{
lifecycle_classname = "com.uwyn.rife.servlet.RifeLifecycle";
}
Class lifecycle_class = classloader.loadClass(lifecycle_classname);
mLifeCycle = lifecycle_class.newInstance();
Method lifecycle_init = lifecycle_class.getMethod("init", new Class[] {initconfig_class});
mGate = lifecycle_init.invoke(mLifeCycle, new Object[] {initconfig_filter});
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 doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
{
if (mEngineClassloader != null)
{
Thread.currentThread().setContextClassLoader(mEngineClassloader);
}
if (request instanceof HttpServletRequest &&
response instanceof HttpServletResponse)
{
HttpServletRequest http_servlet_request = (HttpServletRequest)request;
HttpServletResponse http_servlet_response = (HttpServletResponse)response;
try
{
// create the servlet path
if (null == mGateUrl)
{
String context_path = http_servlet_request.getContextPath();
// ensure a valid context path
if (context_path != null &&
!context_path.equals(".") &&
!context_path.equals("/"))
{
mGateUrl = context_path;
}
else
{
mGateUrl = "";
}
}
// construct the element url by stripping away the gate url
String element_url = http_servlet_request.getRequestURI().substring(mGateUrl.length());
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(http_servlet_request);
Object http_response = mHttpResponseClass.getConstructor(new Class[] {mRequestClass, HttpServletResponse.class, boolean.class}).newInstance(http_request, http_servlet_response, false);
Boolean result = (Boolean)gate_handlerequest.invoke(mGate, new Object[] {mGateUrl, element_url, http_request, http_response});
if (result.booleanValue())
{
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);
}
}
chain.doFilter(request, response);
}
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);
}
}
}