[jboss-cvs] jboss-seam/src/main/org/jboss/seam/web ...
Shane Bryzak
Shane_Bryzak at symantec.com
Sat Feb 10 02:32:35 EST 2007
User: sbryzak2
Date: 07/02/10 02:32:35
Added: src/main/org/jboss/seam/web BaseFilter.java
CharacterEncodingFilter.java ExceptionFilter.java
MultipartFilter.java MultipartRequest.java
RedirectFilter.java SeamFilter.java
ServletFilter.java package-info.java
Log:
JBSEAM-790
Revision Changes Path
1.1 date: 2007/02/10 07:32:34; author: sbryzak2; state: Exp;jboss-seam/src/main/org/jboss/seam/web/BaseFilter.java
Index: BaseFilter.java
===================================================================
package org.jboss.seam.web;
import javax.servlet.Filter;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
public abstract class BaseFilter implements Filter
{
private ServletContext servletContext;
/**
* By default the filter is enabled
*/
private boolean disabled = false;
/**
* By default match all requests
*/
private String urlPattern = "/*";
public void init(FilterConfig filterConfig) throws ServletException
{
servletContext = filterConfig.getServletContext();
}
protected ServletContext getServletContext()
{
return servletContext;
}
public String getUrlPattern()
{
return urlPattern;
}
public void setUrlPattern(String urlPattern)
{
this.urlPattern = urlPattern;
}
public boolean isDisabled()
{
return disabled;
}
public void setDisabled(boolean disabled)
{
this.disabled = disabled;
}
/**
* Pattern matching code, adapted from Tomcat. This method checks to see if
* the specified path matches the specified pattern.
*
* @param request ServletRequest The request containing the path
* @return boolean True if the path matches the pattern, false otherwise
*/
boolean matchesRequestPath(ServletRequest request)
{
if (!(request instanceof HttpServletRequest))
return true;
String path = ((HttpServletRequest) request).getServletPath();
String pattern = getUrlPattern();
if (path == null || "".equals(path)) path = "/";
if (pattern == null || "".equals(pattern)) pattern = "/";
// Check for an exact match
if (path.equals(pattern)) return true;
// Check for path prefix matching
if (pattern.startsWith("/") && pattern.endsWith("/*"))
{
pattern = pattern.substring(0, pattern.length() - 2);
if (pattern.length() == 0) return true;
if (path.endsWith("/")) path = path.substring(0, path.length() - 1);
while (true)
{
if (pattern.equals(path)) return true;
int slash = path.lastIndexOf('/');
if (slash <= 0) break;
path = path.substring(0, slash);
}
return false;
}
// Check for suffix matching
if (pattern.startsWith("*."))
{
int slash = path.lastIndexOf('/');
int period = path.lastIndexOf('.');
if ((slash >= 0) && (period > slash) && path.endsWith(pattern.substring(1)))
{
return true;
}
return false;
}
// Check for universal mapping
if (pattern.equals("/")) return true;
return false;
}
public void destroy() { }
}
1.1 date: 2007/02/10 07:32:34; author: sbryzak2; state: Exp;jboss-seam/src/main/org/jboss/seam/web/CharacterEncodingFilter.java
Index: CharacterEncodingFilter.java
===================================================================
package org.jboss.seam.web;
import static org.jboss.seam.InterceptionType.NEVER;
import static org.jboss.seam.ScopeType.APPLICATION;
import static org.jboss.seam.annotations.Install.BUILT_IN;
import java.io.IOException;
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 org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Intercept;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Startup;
/**
* A servlet filter that lets you set the character encoding of
* submitted data. There are two init parameters: "encoding" and
* "overrideClient".
*
* @author Gavin King
*
*/
@Startup
@Scope(APPLICATION)
@Name("org.jboss.seam.servlet.characterEncodingFilter")
@Install(precedence = BUILT_IN)
@Intercept(NEVER)
public class CharacterEncodingFilter implements Filter
{
private String encoding;
private boolean overrideClient;
public void destroy() {}
public void init(FilterConfig config) throws ServletException
{
encoding = config.getInitParameter("encoding");
overrideClient = "true".equals( config.getInitParameter("overrideClient") );
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException
{
if ( overrideClient || request.getCharacterEncoding() == null )
{
request.setCharacterEncoding(encoding);
}
filterChain.doFilter(request, response);
}
public String getEncoding()
{
return encoding;
}
public void setEncoding(String encoding)
{
this.encoding = encoding;
}
public boolean getOverrideClient()
{
return overrideClient;
}
public void setOverrideClient(boolean overrideClient)
{
this.overrideClient = overrideClient;
}
}
1.1 date: 2007/02/10 07:32:34; author: sbryzak2; state: Exp;jboss-seam/src/main/org/jboss/seam/web/ExceptionFilter.java
Index: ExceptionFilter.java
===================================================================
/*
* JBoss, Home of Professional Open Source
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.seam.web;
import static org.jboss.seam.InterceptionType.NEVER;
import static org.jboss.seam.ScopeType.APPLICATION;
import static org.jboss.seam.annotations.Install.BUILT_IN;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Intercept;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Startup;
import org.jboss.seam.contexts.Lifecycle;
import org.jboss.seam.core.Exceptions;
import org.jboss.seam.log.LogProvider;
import org.jboss.seam.log.Logging;
import org.jboss.seam.mock.MockApplication;
import org.jboss.seam.mock.MockExternalContext;
import org.jboss.seam.mock.MockFacesContext;
import org.jboss.seam.util.Transactions;
/**
* As a last line of defence, rollback uncommitted transactions
* at the very end of the request.
*
* @author Gavin King
*/
@Startup
@Scope(APPLICATION)
@Name("org.jboss.seam.servlet.exceptionFilter")
@Install(precedence = BUILT_IN)
@Intercept(NEVER)
public class ExceptionFilter extends BaseFilter
{
private static final LogProvider log = Logging.getLogProvider(ExceptionFilter.class);
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
{
try
{
chain.doFilter(request, response);
//There is a bug in JBoss AS where JBoss does not clean up
//any orphaned tx at the end of the request. It is possible
//that a Seam-managed tx could be left orphaned if, eg.
//facelets handles an exceptions and displays the debug page.
rollbackTransactionIfNecessary();
}
catch (Exception e)
{
log.error("uncaught exception", e);
if (e instanceof ServletException)
{
log.error("exception root cause", ( (ServletException) e ).getRootCause() );
}
rollbackTransactionIfNecessary();
endWebRequestAfterException( (HttpServletRequest) request, (HttpServletResponse) response, e);
}
finally
{
Lifecycle.setPhaseId(null);
}
}
private void endWebRequestAfterException(HttpServletRequest request, HttpServletResponse response, Exception e)
throws ServletException, IOException
{
log.debug("ending request");
//the FacesContext is gone - create a fake one for Redirect and HttpError to call
MockFacesContext facesContext = createFacesContext(request, response);
facesContext.setCurrent();
Lifecycle.beginExceptionRecovery( facesContext.getExternalContext() );
try
{
Exceptions.instance().handle(e);
}
catch (ServletException se)
{
throw se;
}
catch (IOException ioe)
{
throw ioe;
}
catch (Exception ehe)
{
throw new ServletException(ehe);
}
finally
{
try
{
Lifecycle.endRequest( facesContext.getExternalContext() );
facesContext.release();
log.debug("ended request");
}
catch (Exception ere)
{
log.error("could not destroy contexts", e);
}
}
}
private MockFacesContext createFacesContext(HttpServletRequest request, HttpServletResponse response)
{
return new MockFacesContext( new MockExternalContext(getServletContext(), request, response), new MockApplication() );
}
private void rollbackTransactionIfNecessary()
{
try {
if ( Transactions.isTransactionActiveOrMarkedRollback() )
{
log.debug("killing transaction");
Transactions.getUserTransaction().rollback();
}
}
catch (Exception te)
{
log.error("could not roll back transaction", te);
}
}
}
1.1 date: 2007/02/10 07:32:34; author: sbryzak2; state: Exp;jboss-seam/src/main/org/jboss/seam/web/MultipartFilter.java
Index: MultipartFilter.java
===================================================================
package org.jboss.seam.web;
import static org.jboss.seam.InterceptionType.NEVER;
import static org.jboss.seam.ScopeType.APPLICATION;
import static org.jboss.seam.annotations.Install.BUILT_IN;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Intercept;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Startup;
@Startup
@Scope(APPLICATION)
@Name("org.jboss.seam.servlet.multipartFilter")
@Install(precedence = BUILT_IN)
@Intercept(NEVER)
public class MultipartFilter extends BaseFilter
{
public static final String MULTIPART = "multipart/";
/**
* Flag indicating whether a temporary file should be used to cache the uploaded file
*/
private boolean createTempFiles = false;
/**
* The maximum size of a file upload request. 0 means no limit.
*/
private int maxRequestSize = 0;
public boolean getCreateTempFiles()
{
return createTempFiles;
}
public void setCreateTempFiles(boolean createTempFiles)
{
this.createTempFiles = createTempFiles;
}
public int getMaxRequestSize()
{
return maxRequestSize;
}
public void setMaxRequestSize(int maxFileSize)
{
this.maxRequestSize = maxFileSize;
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
{
if (!(response instanceof HttpServletResponse))
{
chain.doFilter(request, response);
return;
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
if (isMultipartRequest(httpRequest))
{
chain.doFilter(new MultipartRequest(httpRequest, createTempFiles,
maxRequestSize), response);
}
else
{
chain.doFilter(request, response);
}
}
private boolean isMultipartRequest(HttpServletRequest request)
{
if (!"post".equals(request.getMethod().toLowerCase()))
{
return false;
}
String contentType = request.getContentType();
if (contentType == null)
{
return false;
}
if (contentType.toLowerCase().startsWith(MULTIPART))
{
return true;
}
return false;
}
}
1.1 date: 2007/02/10 07:32:34; author: sbryzak2; state: Exp;jboss-seam/src/main/org/jboss/seam/web/MultipartRequest.java
Index: MultipartRequest.java
===================================================================
package org.jboss.seam.web;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.rmi.server.UID;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
/**
* Request wrapper for supporting multipart requests, used for file uploading.
*
* @author Shane Bryzak
*/
public class MultipartRequest extends HttpServletRequestWrapper
{
public static final String WWW_FORM_URLENCODED_TYPE = "application/x-www-form-urlencoded";
private static final String PARAM_NAME = "name";
private static final String PARAM_FILENAME = "filename";
private static final String PARAM_CONTENT_TYPE = "Content-Type";
private static final int BUFFER_SIZE = 2048;
private static final int CHUNK_SIZE = 512;
private boolean createTempFiles;
private int maxRequestSize;
private String encoding = null;
private Map<String,Param> parameters = null;
private enum ReadState { BOUNDARY, HEADERS, DATA }
private static final byte CR = 0x0d;
private static final byte LF = 0x0a;
private static final byte[] CR_LF = {CR,LF};
private abstract class Param
{
private String name;
public Param(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public abstract void appendData(byte[] data, int start, int length)
throws IOException;
}
private class ValueParam extends Param
{
private Object value = null;
private ByteArrayOutputStream buf = new ByteArrayOutputStream();
public ValueParam(String name)
{
super(name);
}
@Override
public void appendData(byte[] data, int start, int length)
throws IOException
{
buf.write(data, start, length);
}
public void complete()
throws UnsupportedEncodingException
{
String val = encoding == null ? new String(buf.toByteArray()) :
new String(buf.toByteArray(), encoding);
if (value == null)
{
value = val;
}
else
{
if (!(value instanceof List))
{
List<String> v = new ArrayList<String>();
v.add((String) value);
value = v;
}
((List) value).add(val);
}
buf.reset();
}
public Object getValue()
{
return value;
}
}
private class FileParam extends Param
{
private String filename;
private String contentType;
private ByteArrayOutputStream bOut = null;
private FileOutputStream fOut = null;
private File tempFile = null;
public FileParam(String name)
{
super(name);
}
public String getFilename()
{
return filename;
}
public void setFilename(String filename)
{
this.filename = filename;
}
public String getContentType()
{
return contentType;
}
public void setContentType(String contentType)
{
this.contentType = contentType;
}
public void createTempFile()
{
try
{
tempFile = File.createTempFile(new UID().toString().replace(":", "-"), ".upload");
tempFile.deleteOnExit();
fOut = new FileOutputStream(tempFile);
}
catch (IOException ex)
{
throw new RuntimeException("Could not create temporary file");
}
}
@Override
public void appendData(byte[] data, int start, int length)
throws IOException
{
if (fOut != null)
{
fOut.write(data, start, length);
}
else
{
if (bOut == null) bOut = new ByteArrayOutputStream();
bOut.write(data, start, length);
}
}
public byte[] getData()
{
if (bOut != null)
{
return bOut.toByteArray();
}
else if (tempFile != null)
{
if (tempFile.exists())
{
try
{
FileInputStream fIn = new FileInputStream(tempFile);
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
byte[] buf = new byte[512];
int read = fIn.read(buf);
while (read != -1)
{
bOut.write(buf, 0, read);
read = fIn.read(buf);
}
bOut.flush();
return bOut.toByteArray();
}
catch (IOException ex) { /* too bad? */}
}
}
return null;
}
public InputStream getInputStream()
{
if (bOut != null)
{
return new ByteArrayInputStream(bOut.toByteArray());
}
else
{
try
{
return new FileInputStream(tempFile);
}
catch (FileNotFoundException ex) { }
}
return null;
}
}
private HttpServletRequest request;
public MultipartRequest(HttpServletRequest request, boolean createTempFiles,
int maxRequestSize)
{
super(request);
this.request = request;
this.createTempFiles = createTempFiles;
this.maxRequestSize = maxRequestSize;
String contentLength = request.getHeader("Content-Length");
if (contentLength != null && maxRequestSize > 0 &&
Integer.parseInt(contentLength) > maxRequestSize)
{
throw new RuntimeException("Multipart request is larger than allowed size");
}
}
private void parseRequest()
{
byte[] boundaryMarker = getBoundaryMarker(request.getContentType());
if (boundaryMarker == null)
{
throw new RuntimeException("the request was rejected because "
+ "no multipart boundary was found");
}
encoding = request.getCharacterEncoding();
parameters = new HashMap<String,Param>();
try
{
byte[] buffer = new byte[BUFFER_SIZE];
Map<String,String> headers = new HashMap<String,String>();
ReadState readState = ReadState.BOUNDARY;
InputStream input = request.getInputStream();
int read = input.read(buffer);
int pos = 0;
Param p = null;
while (read != -1)
{
for (int i = 0; i < read; i++)
{
switch (readState)
{
case BOUNDARY:
{
if (checkSequence(buffer, i, boundaryMarker) && checkSequence(buffer, i + 2, CR_LF))
{
readState = ReadState.HEADERS;
i += 2;
pos = i + 1;
}
break;
}
case HEADERS:
{
if (checkSequence(buffer, i, CR_LF))
{
parseParams(new String(buffer, pos, i - pos - 1), ";", headers);
if (checkSequence(buffer, i + CR_LF.length, CR_LF))
{
readState = ReadState.DATA;
i += CR_LF.length;
pos = i + 1;
String paramName = headers.get(PARAM_NAME);
if (paramName != null)
{
if (headers.containsKey(PARAM_FILENAME))
{
FileParam fp = new FileParam(paramName);
if (createTempFiles) fp.createTempFile();
fp.setContentType(headers.get(PARAM_CONTENT_TYPE));
fp.setFilename(headers.get(PARAM_FILENAME));
p = fp;
}
else
{
p = new ValueParam(paramName);
}
parameters.put(paramName, p);
}
headers.clear();
}
else
{
pos = i + 1;
}
}
break;
}
case DATA:
{
if (checkSequence(buffer, i - boundaryMarker.length - CR_LF.length, CR_LF) &&
checkSequence(buffer, i, boundaryMarker))
{
if (pos < i - boundaryMarker.length - CR_LF.length - 1)
{
p.appendData(buffer, pos, i - pos - boundaryMarker.length - CR_LF.length - 1);
}
if (p instanceof ValueParam) ((ValueParam) p).complete();
if (checkSequence(buffer, i + CR_LF.length, CR_LF))
{
i += CR_LF.length;
pos = i + 1;
}
else
{
pos = i;
}
readState = ReadState.HEADERS;
}
else if (i > (pos + boundaryMarker.length + CHUNK_SIZE + CR_LF.length))
{
p.appendData(buffer, pos, CHUNK_SIZE);
pos += CHUNK_SIZE;
}
break;
}
}
}
if (pos < read)
{
// move the bytes that weren't read to the start of the buffer
int bytesNotRead = read - pos;
System.arraycopy(buffer, pos, buffer, 0, bytesNotRead);
read = input.read(buffer, bytesNotRead, buffer.length - bytesNotRead);
read += bytesNotRead;
}
else
{
read = input.read(buffer);
}
pos = 0;
}
}
catch (IOException ex)
{
throw new RuntimeException("IO Error parsing multipart request", ex);
}
}
private byte[] getBoundaryMarker(String contentType)
{
Map<String, Object> params = parseParams(contentType, ";");
String boundaryStr = (String) params.get("boundary");
if (boundaryStr == null) return null;
try
{
return boundaryStr.getBytes("ISO-8859-1");
}
catch (UnsupportedEncodingException e)
{
return boundaryStr.getBytes();
}
}
/**
* Checks if a specified sequence of bytes ends at a specific position
* within a byte array.
*
* @param data
* @param pos
* @param seq
* @return boolean indicating if the sequence was found at the specified position
*/
private boolean checkSequence(byte[] data, int pos, byte[] seq)
{
if (pos - seq.length < 0 || pos > data.length)
return false;
for (int i = 0; i < seq.length; i++)
{
if (data[(pos - seq.length) + i + 1] != seq[i])
return false;
}
return true;
}
private static final Pattern PARAM_VALUE_PATTERN = Pattern
.compile("^\\s*([^\\s=]+)\\s*[=:]\\s*(.+)\\s*$");
private Map parseParams(String paramStr, String separator)
{
Map<String,String> paramMap = new HashMap<String, String>();
parseParams(paramStr, separator, paramMap);
return paramMap;
}
private void parseParams(String paramStr, String separator, Map paramMap)
{
String[] parts = paramStr.split("[" + separator + "]");
for (String part : parts)
{
Matcher m = PARAM_VALUE_PATTERN.matcher(part);
if (m.matches())
{
String key = m.group(1);
String value = m.group(2);
// Strip double quotes
if (value.startsWith("\"") && value.endsWith("\""))
value = value.substring(1, value.length() - 1);
paramMap.put(key, value);
}
}
}
private Param getParam(String name)
{
if (parameters == null)
parseRequest();
return parameters.get(name);
}
@Override
public Enumeration getParameterNames()
{
if (parameters == null)
parseRequest();
return Collections.enumeration(parameters.keySet());
}
public byte[] getFileBytes(String name)
{
Param p = getParam(name);
return (p != null && p instanceof FileParam) ?
((FileParam) p).getData() : null;
}
public InputStream getFileInputStream(String name)
{
Param p = getParam(name);
return (p != null && p instanceof FileParam) ?
((FileParam) p).getInputStream() : null;
}
public String getFileContentType(String name)
{
Param p = getParam(name);
return (p != null && p instanceof FileParam) ?
((FileParam) p).getContentType() : null;
}
public String getFileName(String name)
{
Param p = getParam(name);
return (p != null && p instanceof FileParam) ?
((FileParam) p).getFilename() : null;
}
@Override
public String getParameter(String name)
{
Param p = getParam(name);
if (p != null && p instanceof ValueParam)
{
ValueParam vp = (ValueParam) p;
if (vp.getValue() instanceof String) return (String) vp.getValue();
}
else
{
return super.getParameter(name);
}
return null;
}
@Override
public String[] getParameterValues(String name)
{
Param p = getParam(name);
if (p != null && p instanceof ValueParam)
{
ValueParam vp = (ValueParam) p;
if (vp.getValue() instanceof List)
{
List vals = (List) vp.getValue();
String[] values = new String[vals.size()];
vals.toArray(values);
return values;
}
else
{
return new String[] {(String) vp.getValue()};
}
}
else
{
return super.getParameterValues(name);
}
}
@Override
public Map getParameterMap()
{
if (parameters == null)
parseRequest();
Map<String,Object> params = super.getParameterMap();
for (String name : parameters.keySet())
{
Param p = parameters.get(name);
if (p instanceof ValueParam)
{
ValueParam vp = (ValueParam) p;
if (vp.getValue() instanceof String)
{
params.put(name, vp.getValue());
}
else if (vp.getValue() instanceof List)
{
params.put(name, getParameterValues(name));
}
}
}
return params;
}
@Override
public String getContentType()
{
return WWW_FORM_URLENCODED_TYPE;
}
}
1.1 date: 2007/02/10 07:32:34; author: sbryzak2; state: Exp;jboss-seam/src/main/org/jboss/seam/web/RedirectFilter.java
Index: RedirectFilter.java
===================================================================
package org.jboss.seam.web;
import static org.jboss.seam.InterceptionType.NEVER;
import static org.jboss.seam.ScopeType.APPLICATION;
import static org.jboss.seam.annotations.Install.BUILT_IN;
import java.io.IOException;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Intercept;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Startup;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.core.Manager;
import org.jboss.seam.core.Pages;
/**
* Propagates the conversation context across a browser redirect
*
* @author Gavin King
*/
@Startup
@Scope(APPLICATION)
@Name("org.jboss.seam.servlet.redirectFilter")
@Install(precedence = BUILT_IN)
@Intercept(NEVER)
public class RedirectFilter extends BaseFilter
{
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException
{
chain.doFilter( request, wrapResponse( (HttpServletResponse) response ) );
}
private static ServletResponse wrapResponse(HttpServletResponse response)
{
return new HttpServletResponseWrapper(response)
{
@Override
public void sendRedirect(String url) throws IOException
{
if ( Contexts.isEventContextActive() )
{
String viewId = getViewId(url);
if (viewId!=null)
{
url = Pages.instance().encodePageParameters( FacesContext.getCurrentInstance(), url, viewId );
}
url = Manager.instance().appendConversationIdFromRedirectFilter(url);
}
super.sendRedirect(url);
}
};
}
public static String getViewId(String url)
{
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
String pathInfo = externalContext.getRequestPathInfo();
String servletPath = externalContext.getRequestServletPath();
String contextPath = externalContext.getRequestContextPath();
return getViewId(url, pathInfo, servletPath, contextPath);
}
protected static String getViewId(String url, String pathInfo, String servletPath, String contextPath)
{
if (pathInfo!=null)
{
//for /seam/* style servlet mappings
return url.substring( contextPath.length() + servletPath.length(), getParamLoc(url) );
}
else if ( url.startsWith(contextPath) )
{
//for *.seam style servlet mappings
String extension = servletPath.substring( servletPath.lastIndexOf('.') );
if ( url.endsWith(extension) || url.contains(extension + '?') )
{
String suffix = Pages.getSuffix();
return url.substring( contextPath.length(), getParamLoc(url) - extension.length() ) + suffix;
}
else
{
return null;
}
}
else
{
return null;
}
}
private static int getParamLoc(String url)
{
int loc = url.indexOf('?');
if (loc<0) loc = url.length();
return loc;
}
}
1.1 date: 2007/02/10 07:32:34; author: sbryzak2; state: Exp;jboss-seam/src/main/org/jboss/seam/web/SeamFilter.java
Index: SeamFilter.java
===================================================================
package org.jboss.seam.web;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
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;
import org.jboss.seam.contexts.Context;
import org.jboss.seam.contexts.WebApplicationContext;
import org.jboss.seam.core.Init;
import org.jboss.seam.log.LogProvider;
import org.jboss.seam.log.Logging;
public class SeamFilter implements Filter
{
private static final LogProvider log = Logging.getLogProvider(SeamFilter.class);
private ServletContext servletContext;
private List<Filter> filters = new ArrayList<Filter>();
private class FilterChainImpl implements FilterChain
{
private FilterChain chain;
private Iterator<Filter> iter;
public FilterChainImpl(FilterChain chain, Iterator<Filter> iter)
{
this.chain = chain;
this.iter = iter;
}
public void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException
{
if (iter.hasNext())
{
Filter filter = iter.next();
if (filter instanceof BaseFilter)
{
BaseFilter bf = (BaseFilter) filter;
if (bf.getUrlPattern() == null || bf.matchesRequestPath(request))
{
filter.doFilter(request, response, this);
}
else
{
this.doFilter(request, response);
}
}
else
{
filter.doFilter(request, response, this);
}
}
else
{
chain.doFilter(request, response);
}
}
}
protected ServletContext getServletContext()
{
return servletContext;
}
public void init(FilterConfig filterConfig)
throws ServletException
{
servletContext = filterConfig.getServletContext();
initFilters(filterConfig);
}
protected void initFilters(FilterConfig filterConfig)
throws ServletException
{
Context ctx = new WebApplicationContext(servletContext);
Init init = (Init) ctx.get(Init.class);
for (Class filterClass : init.getInstalledFilters())
{
log.info("Installed filter " + filterClass.getName());
addFilter((Filter) ctx.get(filterClass), filterConfig);
}
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException
{
new FilterChainImpl(chain, filters.iterator()).doFilter(request, response);
}
protected boolean addFilter(Filter filter, FilterConfig filterConfig)
throws ServletException
{
if (filter instanceof BaseFilter && ((BaseFilter) filter).isDisabled())
return false;
filter.init(filterConfig);
return filters.add(filter);
}
public void destroy() {}
}
1.1 date: 2007/02/10 07:32:34; author: sbryzak2; state: Exp;jboss-seam/src/main/org/jboss/seam/web/ServletFilter.java
Index: ServletFilter.java
===================================================================
package org.jboss.seam.web;
import static org.jboss.seam.InterceptionType.NEVER;
import static org.jboss.seam.ScopeType.APPLICATION;
import static org.jboss.seam.annotations.Install.BUILT_IN;
import java.io.IOException;
import javax.faces.event.PhaseId;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Intercept;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Startup;
import org.jboss.seam.contexts.ContextAdaptor;
import org.jboss.seam.contexts.Lifecycle;
import org.jboss.seam.core.Manager;
import org.jboss.seam.log.LogProvider;
import org.jboss.seam.log.Logging;
/**
* Manages the Seam contexts associated with a request to any servlet.
*
* @author Gavin King
*/
@Startup
@Scope(APPLICATION)
@Name("org.jboss.seam.servlet.servletFilter")
@Install(precedence = BUILT_IN)
@Intercept(NEVER)
public class ServletFilter extends BaseFilter
{
private static final LogProvider log = Logging.getLogProvider(ServletFilter.class);
private boolean explicitDisabled = false;
/**
* This filter is disabled by default, unless a urlPattern is set
*/
public ServletFilter()
{
super.setDisabled(true);
}
@Override
public void setUrlPattern(String urlPattern)
{
super.setUrlPattern(urlPattern);
if (!explicitDisabled) setDisabled(false);
}
@Override
public void setDisabled(boolean disabled)
{
super.setDisabled(disabled);
if (disabled) explicitDisabled = true;
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
{
log.debug("beginning request");
HttpSession session = ( (HttpServletRequest) request ).getSession(true);
Lifecycle.setPhaseId(PhaseId.INVOKE_APPLICATION);
Lifecycle.setServletRequest(request);
Lifecycle.beginRequest(getServletContext(), session, request);
Manager.instance().restoreConversation( request.getParameterMap() );
Lifecycle.resumeConversation(session);
Manager.instance().handleConversationPropagation( request.getParameterMap() );
try
{
chain.doFilter(request, response);
//TODO: conversation timeout
Manager.instance().endRequest( ContextAdaptor.getSession(session) );
Lifecycle.endRequest(session);
}
catch (Exception e)
{
Lifecycle.endRequest();
log.error("ended request due to exception", e);
throw new ServletException(e);
}
finally
{
Lifecycle.setServletRequest(null);
Lifecycle.setPhaseId(null);
log.debug("ended request");
}
}
}
1.1 date: 2007/02/10 07:32:34; author: sbryzak2; state: Exp;jboss-seam/src/main/org/jboss/seam/web/package-info.java
Index: package-info.java
===================================================================
@Namespace(value="http://jboss.com/products/seam/web", prefix="org.jboss.seam.web")
package org.jboss.seam.web;
import org.jboss.seam.annotations.*;
More information about the jboss-cvs-commits
mailing list