com.thruzero.common.jsf.utils.FlashUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.thruzero.common.jsf.utils.FlashUtils.java

Source

/*
 *   Copyright 2012 George Norman
 *
 *   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 com.thruzero.common.jsf.utils;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;

import com.thruzero.common.core.support.SimpleIdGenerator;

/**
 * This is a "temporary" work-around for issues encountered with the JSF 2 flash scope (it's not working for me). Flash
 * scope is useful if you want to enable users to be able to open multiple tabs/windows in the same browser (session).
 *
 * @author George Norman
 */
public class FlashUtils {

    /** Request parameter key used to pass a cached FlashHack attribute from one request to the next. */
    public static final String FLASH_HACK_REQUEST_PARAMETER_KEY = "fhk";

    /** Session key used to store the one and only FlashHack instance. */
    private static final String FLASH_HACK_SESSION_KEY = FlashHack.class.getName();

    // ------------------------------------------------------
    // FlashHack --- EXPERIMENTAL (and hopefully temporary)
    // ------------------------------------------------------

    /**
     * TODO-p0(george) The JSF 2.0 "...getExternalContext().getFlash()" wasn't working for me. Not sure if there was a
     * bug in my code or if there's an issue with flash on my platform (Stack Overflow hinted at platform issues). Anyway,
     * will get back to this later, for now using a homebrew solution.
     */
    static class FlashHack {
        private Map<String, Object> attributes = new ConcurrentHashMap<String, Object>();

        public Object removeAttribute(String key) {
            return attributes.remove(key);
        }

        public Object getAttribute(String key) {
            return attributes.get(key);
        }

        public void setAttribute(String key, Object value) {
            attributes.put(key, value);
        }

        public int getTotalCount() {
            return attributes.size();
        }
    }

    // ============================================================================
    // FlashUtils
    // ============================================================================

    /**
     * Return the "flash" attribute for the given flashHackKey; the key is unique per session and was returned when the attribute
     * was saved.
     */
    @SuppressWarnings("unchecked")
    public static <T> T getFlashAttribute(String flashHackKey) {
        T result = null;

        if (StringUtils.isNotEmpty(flashHackKey)) {
            FlashHack flashHack = getFlashHack(false);

            if (flashHack != null) {
                result = (T) flashHack.getAttribute(flashHackKey);
            }
        }

        return result;
    }

    /**
     * Return the "flash" attribute using the value of the "fhk" request parameter as the flash key (e.g., "foo?fhk=312" specifies that
     * "321" be used as the flash key).
     */
    public static <T> T getFlashAttribute() {
        String fhk = FacesUtils.getRequest().getParameter(FlashUtils.FLASH_HACK_REQUEST_PARAMETER_KEY);

        // type parameters of <T>T cannot be determined; no unique maximal instance exists for type variable T with upper bounds T,java.lang.Object
        // requires java 7 to compile without this fix: FlashUtils.getFlashAttribute(fhk) => FlashUtils.<T>getFlashAttribute(fhk).
        T result = FlashUtils.<T>getFlashAttribute(fhk); // http://stackoverflow.com/questions/314572/bug-in-eclipse-compiler-or-in-javac

        return result;
    }

    /**
     * Remove and return the "flash" attribute for the given flashHackKey; the key is unique per session and was returned when the
     * attribute was saved.
     */
    @SuppressWarnings("unchecked")
    public static <T> T removeFlashAttribute(String flashHackKey) {
        T result = null;

        if (StringUtils.isNotEmpty(flashHackKey)) {
            FlashHack flashHack = getFlashHack(false);

            if (flashHack != null) {
                result = (T) flashHack.removeAttribute(flashHackKey);
            }
        }

        return result;
    }

    /**
     * Remove and return the "flash" attribute using the value of the "fhk" request parameter as the flash key (e.g., "foo?fhk=312" specifies that
     * "321" be used as the flash key).
     */
    public static <T> T removeFlashAttribute() {
        String fhk = FacesUtils.getRequest().getParameter(FlashUtils.FLASH_HACK_REQUEST_PARAMETER_KEY);

        // type parameters of <T>T cannot be determined; no unique maximal instance exists for type variable T with upper bounds T,java.lang.Object
        // requires java 7 to compile without this fix: FlashUtils.removeFlashAttribute(fhk) => FlashUtils.<T>removeFlashAttribute(fhk).
        T result = FlashUtils.<T>removeFlashAttribute(fhk); // http://stackoverflow.com/questions/314572/bug-in-eclipse-compiler-or-in-javac

        return result;
    }

    /**
     * Save the given "flash" attribute to a unique location in the session; the key of this location is returned by this
     * function and can be used to retrieve the attribute at a later time.
     */
    public static String saveFlashAttribute(Object attribute) {
        String flashHackKey = SimpleIdGenerator.getInstance().getNextIdAsString();
        FlashHack flashHack = getFlashHack(true);

        flashHack.setAttribute(flashHackKey, attribute);

        return flashHackKey;
    }

    public static int getFlashCount() {
        return getFlashHack(true).getTotalCount();
    }

    private static FlashHack getFlashHack(boolean createIfNonExistant) {
        FlashHack result = null;
        HttpSession session = FacesUtils.getSession(createIfNonExistant);

        if (session != null) {
            result = (FlashHack) session.getAttribute(FLASH_HACK_SESSION_KEY);

            if (result == null && createIfNonExistant) {
                result = new FlashHack();

                session.setAttribute(FLASH_HACK_SESSION_KEY, result);
            }
        }

        return result;
    }

}