net.jawr.web.servlet.RendererRequestUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jawr-core Show documentation
Show all versions of jawr-core Show documentation
Javascript/CSS bundling and compressing tool for java web apps.
By using jawr resources are automatically bundled together and optionally minified and gzipped.
Jawr provides tag libraries to reference a generated bundle either by id or by using the name of any of its members.
The newest version!
/**
* Copyright 2007-2016 Jordi Hernández Sellés, Matt Ruby, Ibrahim Chaehoi
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
package net.jawr.web.servlet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.jawr.web.JawrConstant;
import net.jawr.web.config.JawrConfig;
import net.jawr.web.config.jmx.JawrApplicationConfigManager;
import net.jawr.web.context.ThreadLocalJawrContext;
import net.jawr.web.resource.bundle.factory.util.PathNormalizer;
import net.jawr.web.resource.bundle.renderer.BundleRenderer;
import net.jawr.web.resource.bundle.renderer.BundleRendererContext;
/**
* Utilities for tag rendering components, which help in handling request
* lifecycle aspects.
*
* @author Jordi Hernández Sellés
* @author Matt Ruby
* @author Ibrahim Chaehoi
*
*/
public class RendererRequestUtils {
/** The logger */
private static final Logger LOGGER = LoggerFactory.getLogger(RendererRequestUtils.class.getName());
/** The bundle renderer context attribute name */
private static final String BUNDLE_RENDERER_CONTEXT_ATTR_PREFIX = "net.jawr.web.resource.renderer.BUNDLE_RENDERER_CONTEXT";
/** The IE user agent pattern */
private static final Pattern IE_USER_AGENT_PATTERN = Pattern.compile("MSIE (\\d+)");
/**
* The attribute name of the exception in the request when a dispatch error
* happens
*/
private static final String ERROR_EXCEPTION = "javax.servlet.error.exception";
/**
* The attribute name of the request uri attribute in the request when there
* is a forward
*/
private static final String FORWARD_REQUEST_URI = "javax.servlet.forward.request_uri";
/**
* The attribute name of the flag indicating if Jawr is handling a error
* dispatch
*/
private static final String JAWR_ERROR_DISPATCH = "net.jawr.error.dispatch";
/**
* The attribute name of the flag indicating if Jawr is handling a forward
* dispatch
*/
private static final String JAWR_FOWARD_DISPATCH = "net.jawr.forward.dispatch";
/**
* Returns the bundle renderer context.
*
* @param request
* the request
* @param renderer
* the bundle renderer
* @return the bundle renderer context.
*/
public static BundleRendererContext getBundleRendererContext(HttpServletRequest request, BundleRenderer renderer) {
String bundleRendererCtxAttributeName = BUNDLE_RENDERER_CONTEXT_ATTR_PREFIX + renderer.getResourceType();
// If we are handling a error dispatch, we should remove the current
// RendererContext to use a new one
String jawrErrorDispathAttributeName = JAWR_ERROR_DISPATCH + renderer.getResourceType();
clearRequestWhenDispatch(request, ERROR_EXCEPTION, bundleRendererCtxAttributeName,
jawrErrorDispathAttributeName);
// If we are handling a forward dispatch, we should remove the current
// RendererContext to use a new one
String jawrForwardDispathAttributeName = JAWR_FOWARD_DISPATCH + renderer.getResourceType();
clearRequestWhenDispatch(request, FORWARD_REQUEST_URI, bundleRendererCtxAttributeName,
jawrForwardDispathAttributeName);
BundleRendererContext ctx = (BundleRendererContext) request.getAttribute(bundleRendererCtxAttributeName);
if (ctx == null) {
ctx = new BundleRendererContext(request, renderer.getBundler().getConfig());
request.setAttribute(bundleRendererCtxAttributeName, ctx);
}
return ctx;
}
/**
* Clears the request when dispatch
*
* @param request
* the request
* @param requestDispatchAttribute
* the request attribute name to determine the dispatch type
* @param bundleRendererCtxAttributeName
* the bundle renderer context attriubte to clean
* @param jawrDispathAttributeName
* the jawr dispatch attribute used to ensure that the clear is
* done only once
*/
protected static void clearRequestWhenDispatch(HttpServletRequest request, String requestDispatchAttribute,
String bundleRendererCtxAttributeName, String jawrDispathAttributeName) {
if (request.getAttribute(requestDispatchAttribute) != null
&& request.getAttribute(jawrDispathAttributeName) == null) {
request.removeAttribute(bundleRendererCtxAttributeName);
request.setAttribute(jawrDispathAttributeName, Boolean.TRUE);
}
}
/**
* Sets the bundle renderer context.
*
* @param request
* the request
* @param resourceType
* the resource type
* @param ctx
* the bundle renderer context to set.
*/
public static void setBundleRendererContext(ServletRequest request, String resourceType,
BundleRendererContext ctx) {
String globalBundleAddedAttributeName = BUNDLE_RENDERER_CONTEXT_ATTR_PREFIX + resourceType;
request.setAttribute(globalBundleAddedAttributeName, ctx);
}
/**
* Determines wether gzip is suitable for the current request given the
* current config.
*
* @param req
* @param jawrConfig
* @return
*/
public static boolean isRequestGzippable(HttpServletRequest req, JawrConfig jawrConfig) {
boolean rets;
// If gzip is completely off, return false.
if (!jawrConfig.isGzipResourcesModeOn())
rets = false;
else if (req.getHeader("Accept-Encoding") != null && req.getHeader("Accept-Encoding").contains("gzip")) {
// If gzip for IE6 or less is off, the user agent is checked to
// avoid compression.
if (!jawrConfig.isGzipResourcesForIESixOn() && isIE6orLess(req)) {
rets = false;
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Gzip enablement for IE executed, with result:" + rets);
}
} else
rets = true;
} else
rets = false;
return rets;
}
/**
* Checks if the user agent is IE
*
* @param req
* the request
* @return true if the user agent is IE
*/
public static boolean isIE(HttpServletRequest req) {
String agent = req.getHeader("User-Agent");
return null != agent && agent.contains("MSIE");
}
/**
* Checks if the user agent is IE6 or less
*
* @param req
* the request
* @return true if the user agent is IE6 or less
*/
public static boolean isIE6orLess(HttpServletRequest req) {
return isIEVersionInferiorOrEqualTo(req, 6);
}
/**
* Checks if the user agent is IE7 or less
*
* @param req
* the request
* @return true if the user agent is IE7 or less
*/
public static boolean isIE7orLess(HttpServletRequest req) {
return isIEVersionInferiorOrEqualTo(req, 7);
}
/**
* Checks if the user agent is IE and the version is equal or less than the
* one passed in parameter
*
* @param req
* the request
* @param the
* ie version to check
* @return true if the user agent is IE and the version is equal or less
* than the one passed in parameter
*/
private static boolean isIEVersionInferiorOrEqualTo(HttpServletRequest req, int ieVersion) {
boolean result = false;
String agent = req.getHeader("User-Agent");
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("User-Agent for this request:" + agent);
}
if (agent != null) {
Matcher matcher = IE_USER_AGENT_PATTERN.matcher(agent);
if (matcher.find()) {
int version = Integer.parseInt(matcher.group(1));
if (version <= ieVersion) {
result = true;
}
}
}
return result;
}
/**
* Determines wether to override the debug settings. Sets the debugOverride
* status on ThreadLocalJawrContext
*
* @param req
* the request
* @param jawrConfig
* the jawr config
*
*/
public static void setRequestDebuggable(HttpServletRequest req, JawrConfig jawrConfig) {
// make sure we have set an overrideKey
// make sure the overrideKey exists in the request
// lastly, make sure the keys match
if (jawrConfig.getDebugOverrideKey().length() > 0
&& null != req.getParameter(JawrConstant.OVERRIDE_KEY_PARAMETER_NAME) && jawrConfig
.getDebugOverrideKey().equals(req.getParameter(JawrConstant.OVERRIDE_KEY_PARAMETER_NAME))) {
ThreadLocalJawrContext.setDebugOverriden(true);
} else {
ThreadLocalJawrContext.setDebugOverriden(false);
}
// Inherit the debuggable property of the session if the session is a
// debuggable one
inheritSessionDebugProperty(req);
}
/**
* Sets a request debuggable if the session is a debuggable session.
*
* @param request
* the request
*/
public static void inheritSessionDebugProperty(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session != null) {
String sessionId = session.getId();
JawrApplicationConfigManager appConfigMgr = (JawrApplicationConfigManager) session.getServletContext()
.getAttribute(JawrConstant.JAWR_APPLICATION_CONFIG_MANAGER);
// If the session ID is a debuggable session ID, activate debug mode
// for the request.
if (appConfigMgr != null && appConfigMgr.isDebugSessionId(sessionId)) {
ThreadLocalJawrContext.setDebugOverriden(true);
}
}
}
/**
* Returns true if the request URL is a SSL request (https://)
*
* @param request
* the request
* @return true if the request URL is a SSL request
*/
public static boolean isSslRequest(HttpServletRequest request) {
String scheme = request.getScheme();
return JawrConstant.HTTPS.equals(scheme);
}
/**
* Renders the URL taking in account the context path, the jawr config
*
* @param url
* the URL
* @param jawrConfig
* the jawr config
* @param contextPath
* the context path
* @param sslRequest
* the flag indicating if it's an SSL request or not
* @return the new URL
*/
public static String getRenderedUrl(String url, JawrConfig jawrConfig, String contextPath, boolean sslRequest) {
String contextPathOverride = getContextPathOverride(sslRequest, jawrConfig);
// If the contextPathOverride is not null and we are in production mode,
// or if we are in debug mode but we should use the contextPathOverride
// even in debug mode
// then use the contextPathOverride
String renderedUrl = url;
if (contextPathOverride != null
&& ((jawrConfig.isDebugModeOn() && jawrConfig.isUseContextPathOverrideInDebugMode())
|| !jawrConfig.isDebugModeOn())) {
String override = contextPathOverride;
// Blank override, create url relative to path
if ("".equals(override)) {
if (url.startsWith("/")) {
renderedUrl = renderedUrl.substring(1);
}
} else {
renderedUrl = PathNormalizer.joinPaths(override, renderedUrl);
}
} else {
renderedUrl = PathNormalizer.joinPaths(contextPath, renderedUrl);
}
return renderedUrl;
}
/**
* Returns the context path depending on the request mode (SSL or not)
*
* @param isSslRequest
* the flag indicating that the request is an SSL request
* @return the context path depending on the request mode
*/
private static String getContextPathOverride(boolean isSslRequest, JawrConfig config) {
String contextPathOverride = null;
if (isSslRequest) {
contextPathOverride = config.getContextPathSslOverride();
} else {
contextPathOverride = config.getContextPathOverride();
}
return contextPathOverride;
}
/**
* Refresh the Jawr config if a manual reload has been ask using the refresh
* key parameter from the URL
*
* @param request
* the request
* @param jawrConfig
* the Jawr config
*
* @return true if the config has been refreshed
*/
public static boolean refreshConfigIfNeeded(HttpServletRequest request, JawrConfig jawrConfig) {
boolean refreshed = false;
if (request.getAttribute(JawrConstant.JAWR_BUNDLE_REFRESH_CHECK) == null) {
request.setAttribute(JawrConstant.JAWR_BUNDLE_REFRESH_CHECK, Boolean.TRUE);
if (jawrConfig.getRefreshKey().length() > 0 && null != request.getParameter(JawrConstant.REFRESH_KEY_PARAM)
&& jawrConfig.getRefreshKey().equals(request.getParameter(JawrConstant.REFRESH_KEY_PARAM))) {
JawrApplicationConfigManager appConfigMgr = (JawrApplicationConfigManager) request.getSession()
.getServletContext().getAttribute(JawrConstant.JAWR_APPLICATION_CONFIG_MANAGER);
if (appConfigMgr == null) {
throw new IllegalStateException(
"JawrApplicationConfigManager is not present in servlet context. Initialization of Jawr either failed or never occurred.");
}
appConfigMgr.refreshConfig();
refreshed = true;
}
}
return refreshed;
}
}