package org.jboss.test.faces.staging;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* Holds a filter instance and reference to the next executable server object (
* filter or servlet ) in the chain.
*
* @author asmirnov
*
*/
public class FilterContainer implements RequestChain {
private static final Logger log = ServerLogger.SERVER.getLogger();
/**
* Servlet filter instance.
*/
private final Filter filter;
/**
* Next object in the chain.
*/
private final RequestChain next;
/**
* Filter name.
*/
private String name = "Default";
/**
* Filter initialization parameters.
*/
private final Map<String, String> initParameters;
/**
* Initialization flag to avoid double calls.
*/
private boolean initialized = false;
/**
* @param filter
* instance of the web application filter.
* @param next
* next executable object in the filter chain.
* @throws NullPointerException if any of parameter is null.
*/
public FilterContainer(Filter filter, RequestChain next) {
if(null == filter || null == next){
throw new NullPointerException();
}
this.filter = filter;
this.next = next;
this.initParameters = new HashMap<String, String>();
}
/**
* @return filter name.
*/
public String getName() {
return name;
}
/**
* @param name
* new filter name.
*/
public void setName(String name) {
if (initialized) {
throw new IllegalStateException(
"Filter have already been initialized, name can't be changed");
}
this.name = name;
}
/*
* (non-Javadoc)
*
* @see
* org.jboss.test.faces.staging.RequestChain#execute(javax.servlet.ServletRequest
* , javax.servlet.ServletResponse)
*/
public void execute(ServletRequest request, ServletResponse response)
throws ServletException, IOException {
if (!initialized) {
throw new IllegalStateException(
"Filter "+getName()+" have not been initialized, could'n execute request");
}
log.finest("Request '"+request+"' executes by the '"+getName()+"' filter");
FilterChain chain = new FilterChain() {
// Execute next object in the chain.
public void doFilter(ServletRequest request,
ServletResponse response) throws IOException,
ServletException {
next.execute(request, response);
}
};
filter.doFilter(request, response, chain);
}
/**
* Append filter initialization parameter. Name and value are same as
* defined in the web.xml
*
* <code>
* <init-param>
* <param-name>foo</param-name>
* <param-value>bar</param-value>
* </init-param>
* </code>
*
* @param name
* name of the parameter
* @param value
* its value
*/
public void addInitParameter(String name, String value) {
if (initialized) {
throw new IllegalStateException(
"Filter have already been initialized, init parameters can't be changed");
}
initParameters.put(name, value);
}
/* (non-Javadoc)
* @see org.jboss.test.faces.staging.RequestChain#isApplicable(java.lang.String)
*/
public boolean isApplicable(String path) {
// Delegate to the next object. Filter has a same mapping as target servlet.
return next.isApplicable(path);
}
/* (non-Javadoc)
* @see org.jboss.test.faces.staging.RequestChain#destroy()
*/
public void destroy() {
if (initialized) {
next.destroy();
filter.destroy();
initialized = false;
}
}
/* (non-Javadoc)
* @see org.jboss.test.faces.staging.RequestChain#init(org.jboss.test.faces.staging.StagingServletContext)
*/
public void init(final ServletContext context)
throws ServletException {
if (!initialized) {
filter.init(new FilterConfig() {
public String getFilterName() {
return name;
}
public String getInitParameter(String name) {
return initParameters.get(name);
}
@SuppressWarnings("unchecked")
public Enumeration getInitParameterNames() {
return Collections.enumeration(initParameters.keySet());
}
public ServletContext getServletContext() {
return context;
}
});
next.init(context);
initialized = true;
}
}
/* (non-Javadoc)
* @see org.jboss.test.faces.staging.RequestChain#getPathInfo(java.lang.String)
*/
public String getPathInfo(String path) {
// Delegate to the next object. Filter has a same mapping as target servlet.
return next.getPathInfo(path);
}
/* (non-Javadoc)
* @see org.jboss.test.faces.staging.RequestChain#getServletPath(java.lang.String)
*/
public String getServletPath(String path) {
// Delegate to the next object. Filter has a same mapping as target servlet.
return next.getServletPath(path);
}
}