/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.rdf.negotiation;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
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.log4j.Logger;
import org.dspace.rdf.RDFUtil;
import org.dspace.services.factory.DSpaceServicesFactory;
/**
*
* @author Pascal-Nicolas Becker (dspace -at- pascal -hyphen- becker -dot- de)
*/
public class NegotiationFilter implements Filter
{
public static final String ACCEPT_HEADER_NAME = "Accept";
private static final Logger log = Logger.getLogger(NegotiationFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// nothing to todo here.
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException
{
try
{
if (!DSpaceServicesFactory.getInstance().getConfigurationService()
.getBooleanProperty(RDFUtil.CONTENT_NEGOTIATION_KEY, false))
{
chain.doFilter(request, response);
return;
}
}
catch (Exception ex)
{
log.warn("Will deliver HTML, as I cannot determine if content "
+ "negotiation should be enabled or not:\n"
+ ex.getMessage(), ex);
chain.doFilter(request, response);
return;
}
if (!(request instanceof HttpServletRequest)
|| !(response instanceof HttpServletResponse))
{
// just pass request and response to the next filter, if we don't
// have a HttpServletRequest.
chain.doFilter(request, response);
return;
}
// cast HttpServletRequest and HttpServletResponse
HttpServletRequest hrequest = (HttpServletRequest) request;
HttpServletResponse hresponse = (HttpServletResponse) response;
String acceptHeader = hrequest.getHeader(ACCEPT_HEADER_NAME);
String handle = null;
String extraPathInfo = null;
String path = hrequest.getPathInfo();
// in JSPUI the pathInfo starts after /handle, in XMLUI it starts with /handle
Pattern handleCheckPattern = Pattern.compile("^/*handle/(.*)$");
Matcher handleCheckMatcher = handleCheckPattern.matcher(path);
if (handleCheckMatcher.matches())
{
// remove trailing /handle
path = handleCheckMatcher.group(1);
}
// we expect the path to be in the form <prefix>/<suffix>/[<stuff>],
// where <prefix> is a handle prefix, <suffix> is the handle suffix
// and <stuff> may be further information.
log.debug("PathInfo: " + path);
if (path == null) path = "";
Pattern pathPattern =
Pattern.compile("^/*([^/]+)/+([^/]+)(?:/*||/+(.*))?$");
Matcher pathMatcher = pathPattern.matcher(path);
if (pathMatcher.matches())
{
handle = pathMatcher.group(1) + "/" + pathMatcher.group(2);
extraPathInfo = pathMatcher.group(3);
}
log.debug("handle: " + handle + "\n" + "extraPathInfo: " + extraPathInfo);
int requestedContent = Negotiator.negotiate(acceptHeader);
if (!Negotiator.sendRedirect(hresponse, handle, extraPathInfo,
requestedContent, false))
{
// as we do content negotiation, we should send a vary caching so
// browsers can adopt their caching strategy
// the method Negotiator.sendRedirect does this only if it actually
// does the redirection itself.
hresponse.setHeader("Vary", "Accept");
// send html as default => no forwarding necessary
chain.doFilter(request, response);
}
}
@Override
public void destroy() {
// nothing to do here.
}
}