/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2009 France Telecom R&D
 * Contact: jonas-team@ow2.org
 *
 * 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 (at your option) 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.objectweb.jonas.jndi.checker.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.Iterator;

import org.objectweb.jonas.jndi.checker.IResourceCheckerManager;
import org.objectweb.jonas.jndi.checker.IResourceChecker;
import org.objectweb.jonas.jndi.checker.IResourceCheckerInfo;

/**
 * Manager of all the resources that need to be checked.
 * This kind of interceptors are called
 */
public class ResourceCheckerManager implements IResourceCheckerManager {

    /**
     * Build a new Resource checker manager by using a thread local providing a list of enlisted resources.
     */
    private static ThreadLocal/*<Stack<List<IResourceChecker>>>*/ resourcesThread = new ThreadLocal/*<Stack<List<IResourceChecker>>>*/() {
        protected Object/*Stack<List<IResourceChecker>>*/ initialValue() {
            Stack/*<List<IResourceChecker>>*/ stack = new Stack/*<List<IResourceChecker>>*/();
            List/*<IResourceChecker>*/ list = new ArrayList/*<IResourceChecker>*/();
            stack.push(list);
            return stack;
        }
    };

    /**
     * Push a new list on the stack.
     */
    public void push() {
        ((Stack) resourcesThread.get()).push(new ArrayList/*<IResourceChecker>*/());
    }

    /**
     * Pop the list on the stacK.
     */
    public void pop() {
        ((Stack) resourcesThread.get()).pop();
    }

    /**
     * Enlist a new resource.
     * @param resource the given resource that can be checked.
     */
    public void enlistResource(final IResourceChecker resource) {
        if (!getResources().contains(resource)) {
            getResources().add(resource);
        }
    }

    /**
     * Delist a resource.
     * @param resource the given resource.
     */
    public void delistResource(final IResourceChecker resource) {
        getResources().remove(resource);
    }

    /**
     * Delist all resources that are enlisted.
     */
    public void delistAll() {
        getResources().clear();
    }

    /**
     * Call detect method on each enlisted resource.
     * @param resourceCheckerInfo some data for the resource checker
     */
    public void detect(final IResourceCheckerInfo resourceCheckerInfo) {
        for (Iterator i = getResources().iterator(); i.hasNext();) {
            IResourceChecker resourceChecker = (IResourceChecker) i.next();
            resourceChecker.detect(resourceCheckerInfo);
        }
    }

    /**
     * @return list of resources enlisted on the current thread.
     */
    public List/*<IResourceChecker>*/ getResources() {
        return (List) ((Stack) resourcesThread.get()).peek();
    }
}