/* vim: set ts=2 et sw=2 cindent fo=qroca: */
package com.globant.katari.core.web;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.RequestDispatcher;
import org.apache.commons.lang.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** Wraps a request to hide the module from the delegated servlet.
*/
class ModuleRequestWrapper extends HttpServletRequestWrapper {
/** The class logger.
*/
private static Logger log = LoggerFactory.getLogger(
ModuleRequestWrapper.class);
/** The path where the application is mapped.
*/
private String contextPath;
/** The name of the module that receives the request.
*/
private String moduleName;
/** The fragment of the url that matched the servlet mapping.
*/
private String servletPath;
/** The fragment of the url that follows the servlet path.
*/
private String pathInfo;
/** The wrapped request.
*
* It is never null.
*/
private HttpServletRequest wrappedRequest;
/** Constructor, builds a new module request wrapper.
*
* @param theRequest The request wrapped by this object.
*
* @param theModuleName The name of the module that receives the wrapped
* request. It cannot be null.
*
* @param theServletPath The fragment of the url that matched the servlet
* mapping. It cannot be null.
*/
public ModuleRequestWrapper(final HttpServletRequest theRequest, final String
theModuleName, final String theServletPath) {
super(theRequest);
if (log.isTraceEnabled()) {
log.trace("Entering ModuleRequestWrapper(..., '" + theModuleName
+ "', '" + theServletPath + "')");
}
Validate.notNull(theModuleName, "The module name cannot be null");
Validate.notNull(theServletPath, "The servlet path cannot be null");
Validate.notNull(theRequest, "The request cannot be null");
wrappedRequest = theRequest;
moduleName = theModuleName;
if (isIncluded()) {
String includedContextPath = (String) theRequest.getAttribute(
"javax.servlet.include.context_path");
if (includedContextPath.equals("/")) {
contextPath = "";
} else {
contextPath = includedContextPath;
}
contextPath += (String) theRequest.getAttribute(
"javax.servlet.include.servlet_path")
+ "/" + moduleName;
} else {
if (theRequest.getContextPath().equals("/")) {
contextPath = "";
} else {
contextPath = theRequest.getContextPath();
}
contextPath += theRequest.getServletPath() + "/" + moduleName;
}
servletPath = theServletPath;
if (isIncluded()) {
pathInfo = (String) theRequest.getAttribute(
"javax.servlet.include.path_info");
} else {
pathInfo = theRequest.getPathInfo();
}
// Strips the /<module><servletPath> from the pathinfo.
if (pathInfo != null && pathInfo.length() != 0) {
pathInfo = pathInfo.substring(moduleName.length()
+ servletPath.length() + 1);
}
if (pathInfo != null && pathInfo.length() == 0) {
pathInfo = null;
}
log.trace("Leaving ModuleRequestWrapper");
}
/** Returns the wrapped request.
*
* @return Returns the wrapped request. It never returns null.
*/
public final HttpServletRequest getWrappedRequest() {
return wrappedRequest;
}
/** Returns the servlet plus module name as the context path to hide the
* existence of the module.
*
* @return Returns the context path corresponding to the module.
*/
public final String getContextPath() {
log.trace("Entering getContextPath");
String result;
if (isIncluded()) {
result = wrappedRequest.getContextPath();
} else {
result = contextPath;
}
if (log.isTraceEnabled()) {
log.trace("Leaving getContextPath with " + result);
}
return result;
}
/** Returns the fragment of the url that matched the servlet mapping.
*
* @return Returns the servlet path. It never returns null.
*/
public final String getServletPath() {
log.trace("Entering getServletPath");
String result;
if (isIncluded()) {
result = wrappedRequest.getServletPath();
} else {
result = servletPath;
}
if (log.isTraceEnabled()) {
log.trace("Leaving getServletPath with " + result);
}
return result;
}
/** Returns the path fragment after the module name and servlet path.
*
* @return Returns the path fragment.
*/
public final String getPathInfo() {
log.trace("Entering getPathInfo");
String result;
if (isIncluded()) {
result = wrappedRequest.getPathInfo();
} else {
result = pathInfo;
}
if (log.isTraceEnabled()) {
log.trace("Leaving getPathInfo with " + result);
}
return result;
}
/** Returns the value of the named attribute as an Object, or null if no
* attribute of the given name exists.
*
* @param name a String specifying the name of the attribute.
*
* @return an Object containing the value of the attribute, or null if the
* attribute does not exist.
*/
public Object getAttribute(final String name) {
Object result = wrappedRequest.getAttribute(name);
if (isIncluded()) {
if (name.equals("javax.servlet.include.context_path")) {
result = contextPath;
}
if (name.equals("javax.servlet.include.servlet_path")) {
result = servletPath;
}
if (name.equals("javax.servlet.include.path_info")) {
result = pathInfo;
}
}
return result;
}
/** Returns a request dispatcher capable of forwarding to a module.
*
* @todo This is not yet implemented.
*
* @param path The pathname to the resource. If it is relative, it must be
* relative against the current servlet.
*
* @return Returns a request dispatcher able to forward to the specified
* path.
*/
public final RequestDispatcher getRequestDispatcher(final String path) {
if (log.isTraceEnabled()) {
log.trace("Entering getRequestDispatcher('" + path + "')");
}
RequestDispatcher dispatcher = super.getRequestDispatcher(path);
dispatcher = new RootRequestDispatcher(path.startsWith("/WEB-INF"),
dispatcher);
log.trace("Leaving getRequestDispatcher");
return dispatcher;
}
/** Checks if the wrapped request correponds to a servlet include.
*
* @return true if it is an include, false otherwise.
*/
private boolean isIncluded() {
return wrappedRequest.getAttribute("javax.servlet.include.request_uri")
!= null;
}
}