org.carewebframework.ui.FrameworkWebSupport.java Source code

Java tutorial

Introduction

Here is the source code for org.carewebframework.ui.FrameworkWebSupport.java

Source

/**
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 
 * If a copy of the MPL was not distributed with this file, You can obtain one at 
 * http://mozilla.org/MPL/2.0/.
 * 
 * This Source Code Form is also subject to the terms of the Health-Related Additional
 * Disclaimer of Warranty and Limitation of Liability available at
 * http://www.carewebframework.org/licensing/disclaimer.
 */
package org.carewebframework.ui;

import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;

import org.carewebframework.api.FrameworkUtil;
import org.carewebframework.api.property.PropertyUtil;
import org.carewebframework.common.StrUtil;
import org.carewebframework.ui.util.RequestUtil;

import org.zkoss.zk.ui.Desktop;
import org.zkoss.zk.ui.Execution;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.Session;

/**
 * Class to manage instantiation of framework containers.
 */
public class FrameworkWebSupport {

    private static final String REQUEST_PARAMS = "_CWFRequestParams";

    private static final String REQUEST_URL = "_CWFRequestUrl";

    private static final ThreadLocal<Desktop> _desktops = new ThreadLocal<Desktop>();

    /**
     * Converts the queryString to a map.
     * 
     * @param queryString The query string (leading "?" is optional)
     * @return A map containing the parameters from the query string. This may return null if the
     *         queryString is empty. Multiple values for a parameter are separated by commas.
     */
    public static Map<String, String> queryStringToMap(final String queryString) {
        return queryStringToMap(queryString, ",");
    }

    /**
     * Converts the queryString to a map.
     * 
     * @param queryString The query string (leading "?" is optional)
     * @param valueDelimiter String to use to delimit multiple values for a parameter. May be null.
     * @return A map containing the arguments from the query string. This may return null if the
     *         queryString is empty.
     */
    public static Map<String, String> queryStringToMap(final String queryString, String valueDelimiter) {
        if (queryString == null || queryString.isEmpty()) {
            return null;
        }

        try {
            valueDelimiter = valueDelimiter == null ? "" : valueDelimiter;
            URI uri = new URI(queryString.startsWith("?") ? queryString : ("?" + queryString));
            List<NameValuePair> params = URLEncodedUtils.parse(uri, StrUtil.CHARSET);

            final Map<String, String> result = new HashMap<String, String>();

            for (NameValuePair nvp : params) {
                String value = result.get(nvp.getName());
                result.put(nvp.getName(), (value == null ? "" : value + valueDelimiter) + nvp.getValue());
            }

            return result;
        } catch (URISyntaxException e) {
            return null;
        }
    }

    /**
     * Returns the current desktop. Returns null if unable to determine current execution.
     * 
     * @return Current desktop or null.
     */
    public static Desktop getDesktop() {
        final Execution exec = Executions.getCurrent();
        return exec == null ? _desktops.get() : exec.getDesktop();
    }

    /**
     * Return current Desktop ID or null if unavailable.
     * 
     * @return Desktop ID or null if unavailable.
     */
    public static String getDesktopId() {
        Desktop desktop = getDesktop();
        return desktop == null ? null : desktop.getId();
    }

    /**
     * Associates the specified desktop with the current thread. Used for background threads that
     * need to reference the desktop.
     * 
     * @param desktop If not null, associates this desktop with the current thread. If null, removes
     *            any existing association.
     */
    public static void associateDesktop(Desktop desktop) {
        if (desktop != null) {
            _desktops.set(desktop);
        } else {
            _desktops.remove();
        }
    }

    /**
     * Adds the specified query string to the url.
     * 
     * @param url url to receive the query string.
     * @param queryString Query string to add.
     * @return The updated url.
     * @throws IllegalArgumentException if url is null
     */
    public static String addQueryString(String url, final String queryString) {
        Validate.notNull(url, "The url must not be null");

        if (!StringUtils.isEmpty(queryString)) {
            if (url.endsWith("?")) {
                url += queryString;
            } else if (url.contains("?")) {
                url += "&" + queryString;
            } else {
                url += "?" + queryString;
            }
        }

        return url;
    }

    /**
     * Returns the original request parameters from the current request.
     * 
     * @return the String value for key represented by constant {@link #REQUEST_PARAMS}.
     */
    public static String getRequestParams() {
        return (String) FrameworkUtil.getAttribute(REQUEST_PARAMS);
    }

    /**
     * Save the request parameters as an attribute of the framework
     * 
     * @param value String value to set for key represented by constant {@link #REQUEST_PARAMS}.
     */
    public static void setRequestParams(final String value) {
        FrameworkUtil.setAttribute(REQUEST_PARAMS, value);
    }

    /**
     * Returns the original request url from the current request.
     * 
     * @return the String value for key represented by constant {@link #REQUEST_URL}
     */
    public static String getRequestUrl() {
        return (String) FrameworkUtil.getAttribute(REQUEST_URL);
    }

    /**
     * Save the request url.
     * 
     * @param value String value to set for key represented by constant {@link #REQUEST_URL}.
     */
    public static void setRequestUrl(final String value) {
        FrameworkUtil.setAttribute(REQUEST_URL, value);
    }

    /**
     * Returns the HttpServletRequest object for the current execution.
     * 
     * @return the HttpServletRequest
     */
    public static HttpServletRequest getHttpServletRequest() {
        return RequestUtil.getRequest();
    }

    /**
     * Returns the HttpServletResponse object for the current execution.
     * 
     * @return the HttpServletResponse
     */
    public static HttpServletResponse getHttpServletResponse() {
        final Execution exec = Executions.getCurrent();
        return exec == null ? null : (HttpServletResponse) exec.getNativeResponse();
    }

    /**
     * Returns the named cookie from the current request.
     * 
     * @param cookieName Name of cookie.
     * @see #getCookie(String, HttpServletRequest)
     * @return A cookie, or null if not found.
     * @throws IllegalArgumentException if argument is null or {@link #getHttpServletRequest()}
     *             returns null
     */
    public static Cookie getCookie(final String cookieName) {
        return getCookie(cookieName, getHttpServletRequest());
    }

    /**
     * Returns the named cookie from the specified request. When values are retrieved, they should
     * be decoded.
     * 
     * @see #decodeCookieValue(String)
     * @param cookieName Name of cookie
     * @param httpRequest Request containing cookie.
     * @return A cookie, or null if not found.
     * @throws IllegalArgumentException if arguments are null
     */
    public static Cookie getCookie(final String cookieName, final HttpServletRequest httpRequest) {
        Validate.notNull(cookieName, "The cookieName must not be null");
        Validate.notNull(httpRequest, "The httpRequest must not be null");
        final Cookie[] cookies = httpRequest.getCookies();

        if (cookies != null) {
            for (final Cookie cookie : httpRequest.getCookies()) {
                if (cookieName.equals(cookie.getName())) {
                    return cookie;
                }
            }
        }

        return null;
    }

    /**
     * Returns the value from the named cookie from the specified request. The value is decoded with
     * for security and consistency (Version 0+ of Cookies and web containers)
     * 
     * @see #getCookie(String, HttpServletRequest)
     * @see #decodeCookieValue(String)
     * @param cookieName Name of cookie
     * @param httpRequest Request containing cookie. If null, it will check
     *            {@link Execution#getNativeRequest()}
     * @return A cookie value, or null if not found.
     * @throws IllegalArgumentException if arguments are null
     */
    public static String getCookieValue(final String cookieName, final HttpServletRequest httpRequest) {
        final Cookie cookie = getCookie(cookieName, httpRequest);
        return cookie == null ? null : decodeCookieValue(cookie.getValue());
    }

    /**
     * <p>
     * Encodes a plain text cookie value.
     * </p>
     * <i>Note: The direction to use a two-phase encode/decode process (i.e. instead of the Base64
     * class URL_SAFE option) was intentional</i>
     * 
     * @see URLEncoder#encode(String, String)
     * @see Base64#encodeBase64String(byte[])
     * @param cookieValuePlainText The plain text to encode
     * @return encoded cookie value
     * @throws IllegalArgumentException If the argument is null
     */
    public static String encodeCookieValue(final String cookieValuePlainText) {
        Validate.notNull(cookieValuePlainText, "The cookieValuePlainText must not be null");
        try {
            return URLEncoder.encode(Base64.encodeBase64String(cookieValuePlainText.getBytes()), StrUtil.CHARSET);
        } catch (final Exception e) {
            throw new RuntimeException("Unexpected exception occurred encoding cookie value", e);
        }
    }

    /**
     * <p>
     * Decodes an encoded cookie value
     * </p>
     * <i>Note: The direction to use a two-phase encode/decode process (i.e. instead of the Base64
     * class URL_SAFE option) was intentional</i>
     * 
     * @see URLDecoder#decode(String, String)
     * @see Base64#decode(String)
     * @param encodedCookieValue The encoded cookie value
     * @return decoded cookie value
     * @throws IllegalArgumentException If the argument is null
     */
    public static String decodeCookieValue(final String encodedCookieValue) {
        Validate.notNull(encodedCookieValue, "The encodedCookieValue must not be null");
        try {
            return new String(Base64.decodeBase64(URLDecoder.decode(encodedCookieValue, StrUtil.CHARSET)));
        } catch (final Exception e) {
            throw new RuntimeException("Unexpected exception occurred decoding cookie value", e);
        }
    }

    /**
     * Returns the value from the named cookie from the specified request. The value is decoded.
     * 
     * @see #getCookieValue(String, HttpServletRequest)
     * @param cookieName Name of cookie
     * @return A cookie value, or null if not found.
     * @throws IllegalArgumentException if argument is null or if underlying HttpServletRequest is
     *             null
     */
    public static String getCookieValue(final String cookieName) {
        return getCookieValue(cookieName, getHttpServletRequest());
    }

    /**
     * Sets a cookie into the current response.
     * 
     * @see #setCookie(String, String, HttpServletResponse, HttpServletRequest)
     * @param cookieName Name of cookie.
     * @param value Value of cookie.
     * @return Newly created cookie.
     * @throws IllegalArgumentException if {@link #getHttpServletResponse()} is null
     */
    public static Cookie setCookie(final String cookieName, final String value) {
        return setCookie(cookieName, value, getHttpServletResponse(), getHttpServletRequest());
    }

    /**
     * Sets a cookie into the response. Cookies are URLEncoded for consistency (Version 0+ of
     * Cookies)
     * 
     * @param cookieName Name of cookie.
     * @param value Value of cookie. If null, the cookie is removed from the client if it exists.
     * @param httpResponse Response object.
     * @param httpRequest Request object.
     * @return Newly created cookie.
     * @throws IllegalArgumentException if cookieName, httpResponse, or httpRequest arguments are
     *             null
     */
    public static Cookie setCookie(final String cookieName, String value, final HttpServletResponse httpResponse,
            final HttpServletRequest httpRequest) {
        Validate.notNull(httpResponse, "The httpResponse must not be null");
        Cookie cookie = getCookie(cookieName, httpRequest);
        if (value != null) {
            value = encodeCookieValue(value);
        }

        if (cookie == null) {
            if (value == null) {
                return null;
            }
            cookie = new Cookie(cookieName, value);
        } else if (value == null) {
            cookie.setMaxAge(0);
        } else {
            cookie.setValue(value);
        }

        if (httpRequest.isSecure()) {
            cookie.setSecure(true);
        }

        httpResponse.addCookie(cookie);
        return cookie;
    }

    /**
     * Returns a session attribute value, removing it from the session.
     * 
     * @param session Session containing attributes of interest.
     * @param name Name of attribute to retrieve.
     * @return Value of attribute or null if it does not exist.
     */
    public static Object extractSessionAttribute(final Session session, final String name) {
        return extractSessionAttribute(session, name, null);
    }

    /**
     * Returns a session attribute value, removing it from the session.
     * 
     * @param session Session containing attributes of interest.
     * @param name Name of attribute to retrieve.
     * @param dflt Default value if none exists.
     * @return Value of attribute.
     */
    public static Object extractSessionAttribute(final Session session, final String name, final Object dflt) {
        final Object value = session.removeAttribute(name);
        return value == null ? dflt : value;
    }

    /**
     * Returns framework property first by looking for an HTTP request parameter and then by looking
     * at the property store. Assumes the property and the request parameter names are the same.
     * 
     * @param propertyName Property name.
     * @return Property value.
     */
    public static String getFrameworkProperty(final String propertyName) {
        return getFrameworkProperty(propertyName, propertyName);
    }

    /**
     * Returns framework property first by looking for an HTTP request parameter and then by looking
     * at the property store.
     * 
     * @param parameterName Name of parameter in execution.
     * @param propertyName Name of property in property store.
     * @return Property value.
     */
    public static String getFrameworkProperty(final String parameterName, final String propertyName) {
        Execution exec = Executions.getCurrent();
        String value = exec == null ? null : exec.getParameter(parameterName);
        return value == null ? PropertyUtil.getValue(propertyName, null) : value;
    }

    /**
     * Enforce static class.
     */
    private FrameworkWebSupport() {
    };
}