All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.jawr.web.servlet.RendererRequestUtils Maven / Gradle / Ivy

Go to download

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;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy