zweb/src/main/java/org/zkoss/web/servlet/xel/RequestContexts.java

Summary

Maintainability
A
0 mins
Test Coverage
/* RequestContexts.java

    Purpose:
        
    Description:
        
    History:
        Fri Apr  8 12:16:23     2005, Created by tomyeh

Copyright (C) 2005 Potix Corporation. All Rights Reserved.

{{IS_RIGHT
    This program is distributed under LGPL Version 2.1 in the hope that
    it will be useful, but WITHOUT ANY WARRANTY.
}}IS_RIGHT
*/
package org.zkoss.web.servlet.xel;

import java.util.LinkedList;
import java.util.List;

/**
 * RequestContexts maintains a stack of {@link RequestContext} to simplify
 * the signatures of the XEL function.
 *
 * <p>It is designed to make the signature of XEL functions
 * (see {@link org.zkoss.web.fn.ServletFns}) simpler.
 * For example, {@link org.zkoss.web.fn.ServletFns#getCurrentContext} requires
 * no argument, since it assumes the current context can be retrieved
 * from {@link #getCurrent}.
 *
 * <p>Spec Issue:<br/>
 * It is controversial whether the introduction of {@link RequestContext} and
 * {@link RequestContexts} is worth. However, we have to maintain the backward
 * compatibility of the XEL/EL function signatures.
 *
 * @author tomyeh
 * @since 3.0.0
 */
public class RequestContexts {
    protected RequestContexts() {
    } //prevent from instantiated

    /** A list of RequestContext. */
    private static final ThreadLocal<List<RequestContext>> _elCtxs = new ThreadLocal<>();

    /** Returns the current page context if this thread is evaluating a page,
     * or null if not.
     */
    public static final RequestContext getCurrent() {
        final List<RequestContext> jcs = _elCtxs.get();
        return jcs != null && !jcs.isEmpty() ? jcs.get(0) : null;
    }

    /** Pushes the context as the current context, such that it will
     * be returned by {@link #getCurrent}. The reason this method exists is
     * many functions ({@link org.zkoss.web.fn.ServletFns}) counts on it.
     *
     * <p>However, you don't need to invoke this method if you are using
     * DSP.
     * <ol>
     * <li>If go thru DSP, it is done automatically
     * (by {@link org.zkoss.web.servlet.dsp.Interpreter}</li>
     * </ol>
     *
     * <p>Note: you must use try/finally as follows:
     * <pre><code>RequestContexts.push(jc);
     *try {
     *  ...
     *} finally {
     *  RequestContexts.pop();
     *}</code></pre>
     */
    public static final void push(RequestContext jc) {
        if (jc == null)
            throw new IllegalArgumentException("null");

        List<RequestContext> jcs = _elCtxs.get();
        if (jcs == null)
            _elCtxs.set(jcs = new LinkedList<>());
        jcs.add(0, jc);
    }

    /** Pops the context out and use the previous one as the current context.
     *
     * <p>However, you don't need to invoke this method if you are using
     * DSP.
     *
     * @see #push
     */
    public static final void pop() {
        final List<RequestContext> l = _elCtxs.get();
        if (l.size() == 1)
            _elCtxs.remove();
        else
            l.remove(0);
    }
}