/* vim: set ts=2 et sw=2 cindent fo=qroca: */ package com.globant.katari.core.sitemesh; import java.util.Properties; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.opensymphony.module.sitemesh.Decorator; import com.opensymphony.module.sitemesh.Page; import com.opensymphony.module.sitemesh.Config; import com.opensymphony.module.sitemesh.DecoratorMapper; import com.opensymphony.module.sitemesh.mapper.AbstractDecoratorMapper; import com.opensymphony.module.sitemesh.mapper.ConfigLoader; /** A sitemesh decorator mapper. * * Reads decorators and mappings from the <code>config</code> property (default * '/WEB-INF/decorators.xml'). This is almost the same as the default decorator * mapper, except that it matches against the request including the path info. * * Additionally, a page can force sitemesh to skip decorating it adding a * request attribute called katari-skip-decoration, with any value. */ public class FullUriConfigDecoratorMapper extends AbstractDecoratorMapper { /** The class logger. */ private static Logger log = LoggerFactory.getLogger( FullUriConfigDecoratorMapper.class); /** The configuration loader. * * This is never null once this class is initialized.. */ private ConfigLoader configLoader = null; /** Create new ConfigLoader using '/WEB-INF/decorators.xml' file. * * @param config The sitemesh configuration. * * @param properties The filter properties. * * @param parent The parent of this mapper. If this mapper cannot resolve the * decorator, it delegates to the parent mapper. * * @throws InstantiationException in case an error ocurred loading the * configuration. */ public void init(final Config config, final Properties properties, final DecoratorMapper parent) throws InstantiationException { log.trace("Entering init"); super.init(config, properties, parent); try { String fileName = properties.getProperty("config", "/WEB-INF/decorators.xml"); if (log.isDebugEnabled()) { log.debug("Loading decorators from " + fileName); } configLoader = new ConfigLoader(fileName, config); } catch (Exception e) { InstantiationException instantiation = new InstantiationException("Error" + " loading configuration: " + e.toString()); instantiation.initCause(e); throw instantiation; } log.trace("Leaving init"); } /** Sets the configuration loader. * * This is a package access metthod used for testing purposes only. * * @param loader The config loader. It cannot be null. */ void setConfigLoader(final ConfigLoader loader) { configLoader = loader; } /** Retrieve {@link com.opensymphony.module.sitemesh.Decorator} based on * 'pattern' tag. * * @param request The user request. It cannot be null. * * @param page The content of the undecorated page. It cannot be null. * * @return the decorator to use to decorate the page, null if the page * should not be decorated. */ public Decorator getDecorator(final HttpServletRequest request, final Page page) { log.trace("Entering getDecorator"); if (request.getAttribute("katari-skip-decoration") != null) { return null; } String thisPath = request.getServletPath(); String pathInfo = request.getPathInfo(); // getServletPath() returns null unless the mapping corresponds to a servlet if (thisPath == null) { thisPath = request.getRequestURI(); } else if (pathInfo != null) { thisPath += pathInfo; } if (log.isDebugEnabled()) { log.debug("Request uri: " + request.getRequestURI()); log.debug("Servlet context path: " + request.getContextPath()); log.debug("Searching decorator for url:" + thisPath); } String name = null; try { name = configLoader.getMappedName(thisPath); } catch (ServletException e) { throw new RuntimeException(e); } Decorator result = getNamedDecorator(request, name); if (result == null) { result = super.getDecorator(request, page); } if (result == null) { log.trace("Leaving getDecorator with null decorator"); } else { log.trace("Leaving getDecorator with non null decorator"); } return result; } /** Retrieve Decorator named in 'name' attribute. * * Checks the role if specified. * * @param request the user http request. It cannot be null. * * @param name The name of the decorator to obtain. It cannot be null. * * @return Returns the named decorator, or null if not found. */ public Decorator getNamedDecorator(final HttpServletRequest request, final String name) { Decorator result = null; try { result = configLoader.getDecoratorByName(name); } catch (ServletException e) { throw new RuntimeException(e); } if (result == null || (result.getRole() != null && !request.isUserInRole(result.getRole()))) { // if the result is null or the user is not in the role return super.getNamedDecorator(request, name); } else { return result; } } }