/**
 * High Availability Service (HA) for JOnAS
 *
 * Copyright (C) 2006 Distributed Systems Lab.
 * Universidad Polit??cnica de Madrid (Spain)
 * Contact: http://lsd.ls.fi.upm.es/lsd
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.objectweb.jonas.ha.interceptor;

import java.util.Stack;

import org.objectweb.carol.cmi.ha.RequestId;
import org.objectweb.carol.cmi.ha.ViewIdWrapper;
import org.objectweb.carol.cmi.ha.interceptor.HACurrentDelegate;

/**
 * This class handles the HAContext/Thread association
 * @author Francisco Perez-Sorrosal (fpsorrosal@no-spam@fi.upm.es)
 * @author Alberto Paz-Jimenez (apaz@no-spam@fi.upm.es)
 */
public class HACurrentDelegateImpl implements HACurrentDelegate {

    /**
     * Local thread
     */
    private static InheritableThreadLocal threadCtx;

    /**
     * Init the thread
     */
    static {
        threadCtx = new InheritableThreadLocal();
    }

    /**
     * Unique instance
     */
    private static HACurrentDelegateImpl currentDelegate = new HACurrentDelegateImpl();

    /**
     * Returns the unique instance
     * @return the current instance
     */
    public static HACurrentDelegateImpl getCurrent() {
        return currentDelegate;
    }

    /**
     * Set the requests stack in the current context
     * @param requests the next request
     */
    public void setRequests(Stack requests) {
        HACurrentContext current = getCurrentContext();
        current.setRequests(requests);
        threadCtx.set(current);
    }
    /**
     * Get the request stack
     * @return the request stack
     */
    public Stack getRequests() {
        return getCurrentContext().getRequests();
    }

    /**
     * Put the request in the request stack
     * @param nextReq the next request
     */
    public void putNextReq(RequestId nextReq) {
        HACurrentContext current = getCurrentContext();
        current.putNextReq(nextReq);
        threadCtx.set(current);
    }

    /**
     * Sets the onFailover variable
     * @param onFailover
     */
    public void setOnFailover(boolean onFailover) {
        HACurrentContext current = getCurrentContext();
        current.setOnFailover(onFailover);
        threadCtx.set(current);
    }

    /**
     * Gets the onFailover variable
     * @return true if on failover
     */
    public boolean isOnFailover() {
        return getCurrentContext().isOnFailover();

    }

    private HACurrentContext getCurrentContext() {
        HACurrentContext current = (HACurrentContext) threadCtx.get();
        if (current == null) {
            current = new HACurrentContext();
        }
        return current;
    }

    /**
     * Set the client view id wrapper
     * @param clientViewIdWrapper view id wrapper
     */
    public void pushClientViewIdWrapper(ViewIdWrapper info) {
        HACurrentContext current = (HACurrentContext) threadCtx.get();
        if (current == null) {
            current = new HACurrentContext();
        }
        current.setClientViewIdWrapper(info);
        threadCtx.set(current);
    }

    /**
     * Get the client view id wrapper
     * @return view id wrapper
     */
    public ViewIdWrapper getClientViewIdWrapper() {
        HACurrentContext current = (HACurrentContext) threadCtx.get();
        if (current == null) {
            current = new HACurrentContext();
        }
        return current.getClientViewIdWrapper();
    }

    /**
     * Set the server view id wrapper
     * @param serverViewIdWrapper view id wrapper
     */
    public void pushServerViewIdWrapper(ViewIdWrapper info) {
        HACurrentContext current = (HACurrentContext) threadCtx.get();
        if (current == null) {
            current = new HACurrentContext();
        }
        current.setServerViewIdWrapper(info);
        threadCtx.set(current);
    }

    /**
     * Get the server view id wrapper
     * @return view id wrapper
     */
    public ViewIdWrapper getServerViewIdWrapper() {
        HACurrentContext current = (HACurrentContext) threadCtx.get();
        if (current == null) {
            current = new HACurrentContext();
        }
        return current.getServerViewIdWrapper();
    }
}
