/**
* Licensed under the Artistic License; you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://displaytag.sourceforge.net/license.html
*
* THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
package org.displaytag.filter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.displaytag.Messages;
import org.displaytag.tags.TableTag;
import org.displaytag.tags.TableTagParameters;
/**
* <p>
* Allow the author of an included JSP page to reset the content type to something else (like a binary stream), and then
* write the new info back as the exclusive response, clearing the buffers of all previously added content.
* </p>
* <p>
* This filter allows TableTag users to perform exports from pages that are run as includes, such as from Struts or a
* jsp:include. If that is your intention, just add this Filter to your web.xml and map it to the appropriate requests,
* using something like:
* </p>
*
* <pre>
* <filter>
* <filter-name>ResponseOverrideFilter</filter-name>
* <filter-class>org.displaytag.filter.ResponseOverrideFilter</filter-class>
* </filter>
* <filter-mapping>
* <filter-name>ResponseOverrideFilter</filter-name>
* <url-pattern>*.do</url-pattern>
* </filter-mapping>
* <filter-mapping>
* <filter-name>ResponseOverrideFilter</filter-name>
* <url-pattern>*.jsp</url-pattern>
* </filter-mapping>
* </pre>
*
* <p>
* By default the filter buffers all the export content before writing it out. You can set an optional parameter
* <code>buffer</code> to <code>false</code> to make the filter write directly to the output stream. This could be
* faster and uses less memory, but the content length will not be set.
* </p>
*
* <pre>
* <filter>
* <filter-name>ResponseOverrideFilter</filter-name>
* <filter-class>org.displaytag.filter.ResponseOverrideFilter</filter-class>
* <init-param>
* <param-name>buffer</param-name>
* <param-value>false</param-value>
* </init-param>
* </filter>
* </pre>
*
* @author rapruitt
* @author Fabrizio Giustina
* @version $Revision: 8904 $ ($Author: charles $)
*/
public class ResponseOverrideFilter implements Filter
{
/**
* Logger.
*/
private Log log;
/**
* Force response buffering. Enabled by default.
*/
private boolean buffer = true;
/**
* {@inheritDoc}
*/
public void init(FilterConfig filterConfig)
{
log = LogFactory.getLog(ResponseOverrideFilter.class);
String bufferParam = filterConfig.getInitParameter("buffer");
if (log.isDebugEnabled())
{
log.debug("bufferParam=" + bufferParam);
}
buffer = bufferParam == null || StringUtils.equalsIgnoreCase("true", bufferParam);
log.info("Filter initialized. Response buffering is " + (buffer ? "enabled" : "disabled"));
}
/**
* {@inheritDoc}
*/
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException
{
if (servletRequest.getParameter(TableTagParameters.PARAMETER_EXPORTING) == null)
{
if (log.isDebugEnabled())
{
log.debug(Messages.getString("ResponseOverrideFilter.parameternotfound")); //$NON-NLS-1$
}
// don't filter!
filterChain.doFilter(servletRequest, servletResponse);
return;
}
HttpServletRequest request = (HttpServletRequest) servletRequest;
BufferedResponseWrapper wrapper = new BufferedResponseWrapper13Impl((HttpServletResponse) servletResponse);
Map contentBean = new HashMap(4);
if (buffer)
{
contentBean.put(TableTagParameters.BEAN_BUFFER, Boolean.TRUE);
}
request.setAttribute(TableTag.FILTER_CONTENT_OVERRIDE_BODY, contentBean);
filterChain.doFilter(request, wrapper);
ExportDelegate.writeExport((HttpServletResponse) servletResponse, servletRequest, wrapper);
}
/**
* {@inheritDoc}
*/
public void destroy()
{
// nothing to destroy
}
}