Re: java.lang.ClassCastException: cannot be cast to com.ocpsoft.pretty.faces.rewrite

Splash Forums PrettyFaces Users java.lang.ClassCastException: cannot be cast to com.ocpsoft.pretty.faces.rewrite Re: java.lang.ClassCastException: cannot be cast to com.ocpsoft.pretty.faces.rewrite

#20002

Well, strange, I’m sorry it’s being tricky; what you have should be working for you. Could you attempt to reproduce this problem in a sample app and send it over? It works fine for me:

import com.ocpsoft.pretty.faces.config.rewrite.RewriteRule;
import com.ocpsoft.pretty.faces.rewrite.Processor;

public class RemoveEmptyParams implements Processor
{
public String process(final RewriteRule rule, final String url)
{
String result = url.replaceAll("\?[^=]+=&", "?");
result = result.replaceAll("&[^=]+=&", "&");
result = result.replaceAll("&[^=]+=$", "");
return result;
}
}

However, I needed to fix a bug in PrettyFilter. You can copy this file into your classpath to see the fix now, but this will be in the next of 3.0.2-SNAPSHOT (after I clean up the hack-ish code that I wrote to get it working:

package com.ocpsoft.pretty;

/*
* PrettyFaces is an OpenSource JSF library to create bookmarkable URLs.
* Copyright (C) 2009 - Lincoln Baxter, III <lincoln@ocpsoft.com> This program
* is free software: you can redistribute it and/or modify it under the terms of
* the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version. This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. You should have received a copy of the GNU Lesser General
* Public License along with this program. If not, see the file COPYING.LESSER
* or visit the GNU website at <http://www.gnu.org/licenses/>.
*/
import java.io.IOException;
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 javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.ocpsoft.pretty.faces.config.PrettyConfig;
import com.ocpsoft.pretty.faces.config.PrettyConfigurator;
import com.ocpsoft.pretty.faces.config.mapping.PathParameter;
import com.ocpsoft.pretty.faces.config.rewrite.Redirect;
import com.ocpsoft.pretty.faces.config.rewrite.RewriteRule;
import com.ocpsoft.pretty.faces.rewrite.RewriteEngine;
import com.ocpsoft.pretty.faces.servlet.PrettyFacesWrappedRequest;
import com.ocpsoft.pretty.faces.servlet.PrettyFacesWrappedResponse;
import com.ocpsoft.pretty.faces.url.QueryString;
import com.ocpsoft.pretty.faces.url.URL;

/**
* @author Lincoln Baxter, III <lincoln@ocpsoft.com>
*/
public class PrettyFilter implements Filter
{
private static final Log log = LogFactory.getLog(PrettyFilter.class);

private static final String REWRITE_OCCURRED_KEY = "com.ocpsoft.pretty.rewrite";

private ServletContext servletContext;
private String facesDynaViewId = "";

/**
* Determine if the current request is mapped using PrettyFaces. If it is, process the pattern, storing parameters
* into the request map, then forward the request to the specified viewId.
*/
public void doFilter(final ServletRequest req, final ServletResponse resp, final FilterChain chain)
throws IOException, ServletException
{
ServletResponse response = new PrettyFacesWrappedResponse((HttpServletResponse) resp, getConfig());

try
{
log.debug("Character encoding: " + req.getCharacterEncoding());

// TODO refactor this into a chain?
rewrite((HttpServletRequest) req, (HttpServletResponse) resp);
if (resp.isCommitted())
{
log.trace("Rewrite occurred, reponse is committed - ending request.");
}
else
{
URL url = getRequestURL(req);
if (getConfig().isURLMapped(url))
{
PrettyContext prettyContext = PrettyContext.newInstance((HttpServletRequest) req);

String viewId = prettyContext.getCurrentViewId();
if (!response.isCommitted())
{
if (prettyContext.shouldProcessDynaview())
{
log.trace("Forwarding mapped request [" + url.getURL() + "] to dynaviewId [" + viewId + "]");
req.getRequestDispatcher(facesDynaViewId).forward(req, response);
}
else
{
List<PathParameter> params = prettyContext.getCurrentMapping().getPatternParser().parse(url);
QueryString query = QueryString.build(params);

ServletRequest request = new PrettyFacesWrappedRequest((HttpServletRequest) req,
query.getParameterMap());

log.trace("Sending mapped request [" + url.getURL() + "] to resource [" + viewId + "]");
if (url.getDecodedURL().matches(viewId))
{
chain.doFilter(request, response);
}
else
{
req.getRequestDispatcher(viewId).forward(request, response);
}
}
}
}
else
{
ensurePopulatedContext(req);
log.trace("Request is not mapped using PrettyFaces. Continue.");
chain.doFilter(req, response);
}
}
}
catch (Exception e)
{
throw new ServletException(e);
}
}

/**
* Apply the given list of {@link RewriteRule}s to the URL (in order,) perform a redirect/forward if required.
* Canonicalization is only invoked if it has not previously been invoked on this request. This method operates on
* the requestUri, excluding contextPath.
*
* @return True if forward/redirect occurred, false if not.
*/
private void rewrite(final HttpServletRequest req, final HttpServletResponse resp)
{
/*
* FIXME Refactor this horrible method.
*/
if (!rewriteOccurred(req))
{
RewriteEngine rewriteEngine = new RewriteEngine();
URL url = getRequestURL(req);

try
{

String queryString = req.getQueryString();
if ((queryString != null) && !"".equals(queryString))
{
queryString = "?" + queryString;
}
else if (queryString == null)
{
queryString = "";
}

String decodedUrl = url.getDecodedURL() + queryString;
String newUrl = decodedUrl;
for (RewriteRule c : getConfig().getGlobalRewriteRules())
{
if (c.matches(newUrl))
{
newUrl = rewriteEngine.processInbound(c, newUrl);
if (!Redirect.CHAIN.equals(c.getRedirect()))
{
/*
* An HTTP redirect has been triggered; issue one if we have a url or if the current url has been
* modified.
*/
if (c.getUrl().isEmpty() && !decodedUrl.equals(newUrl))
{
/*
* The current URL has been rewritten - URLEncode it and redirect
*/
// TODO fix this garbage
String[] parts = newUrl.split("\?", 2);
URL decoded = new URL(parts[0]);
decoded.setEncoding(url.getEncoding());
newUrl = decoded.getEncodedURL() + ((parts[1] == null) || "".equals(parts[1]) ? "" : "?")
+ parts[1];

String redirectURL = resp.encodeRedirectURL(req.getContextPath() + newUrl);
resp.setHeader("Location", redirectURL);
resp.setStatus(c.getRedirect().getStatus());
resp.flushBuffer();
break;
}
else if (!c.getUrl().isEmpty())
{
/*
* This is a custom location - don't URLEncode, just redirect
*/
String redirectURL = resp.encodeRedirectURL(newUrl);
resp.setHeader("Location", redirectURL);
resp.setStatus(c.getRedirect().getStatus());
resp.flushBuffer();
break;
}
}
}
}

if (!decodedUrl.equals(newUrl) && !resp.isCommitted())
{
/*
* The URL was modified, but no redirect occurred; forward instead.
*/
req.getRequestDispatcher(newUrl).forward(req, resp);
}

}
catch (Exception e)
{
throw new PrettyException("Error occurred during canonicalization of request <[" + url + "]>", e);
}
finally
{
setRewriteOccurred(req);
}
}
}

private void setRewriteOccurred(final ServletRequest req)
{
req.setAttribute(REWRITE_OCCURRED_KEY, true);
}

private boolean rewriteOccurred(final ServletRequest req)
{
return Boolean.TRUE.equals(req.getAttribute(REWRITE_OCCURRED_KEY));
}

private void ensurePopulatedContext(final ServletRequest request)
{
PrettyContext.getCurrentInstance((HttpServletRequest) request);
}

public PrettyConfig getConfig()
{
if (servletContext == null)
{
log.warn("PrettyFilter is not registered in web.xml, but is registered with JSF "
+ "Navigation and Action handlers -- this could cause unpredictable behavior.");
return new PrettyConfig();
}
return (PrettyConfig) servletContext.getAttribute(PrettyContext.CONFIG_FILES_ATTR);
}

private URL getRequestURL(final ServletRequest request)
{
String url = ((HttpServletRequest) request).getRequestURI();
String contextPath = ((HttpServletRequest) request).getContextPath();

if (url.startsWith(contextPath))
{
url = url.substring(contextPath.length());
}

URL result = new URL(url);

String encoding = request.getCharacterEncoding();
if (encoding != null)
{
result.setEncoding(encoding);
}

return result;
}

/**
* Load and cache configurations
*/
public void init(final FilterConfig filterConfig) throws ServletException
{
log.info("PrettyFilter starting up...");
servletContext = filterConfig.getServletContext();

PrettyConfigurator configurator = new PrettyConfigurator(servletContext);
configurator.configure();
facesDynaViewId = configurator.getFacesDynaViewId();

log.info("PrettyFilter initialized.");
}

public void destroy()
{
}
}