package jacorb.poa;

/*
 *        JacORB - a free Java ORB
 *
 *   Copyright (C) 1997-98  Gerald Brose.
 *
 *   This library is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU Library General Public
 *   License as published by the Free Software Foundation; either
 *   version 2 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
 *   Library General Public License for more details.
 *
 *   You should have received a copy of the GNU Library General Public
 *   License along with this library; if not, write to the Free
 *   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
import jacorb.poa.util.*;
import jacorb.poa.except.*;
 
import jacorb.util.Environment;
import jacorb.orb.dsi.ServerRequest;

import java.util.Vector;
import java.util.Enumeration;

/**
 * This class will manage a queue of ServerRequest objects.
 *
 * @author Reimo Tiedemann, FU Berlin
 * @version 1.03, 06/09/99, RT
 */
public class RequestQueue 
{
    private RequestQueueListener queueListener;
    private RequestController controller;
    private LogTrace logTrace;
    private Vector queue = new Vector(POAConstants.QUEUE_CAPACITY_INI, POAConstants.QUEUE_CAPACITY_INC);
    private RequestQueue() {
    }
    protected RequestQueue(RequestController _controller, LogTrace _logTrace) {
        controller = _controller;
        logTrace = _logTrace;
    }
    synchronized protected void add(ServerRequest request) throws ResourceLimitReachedException {
        if (queue.size() == Environment.queueMax()) {
            throw new ResourceLimitReachedException();
        }
        queue.addElement(request);
                                
        if (queue.size() == 1) {
            controller.continueToWork();
        }
        logTrace.printLog(3, request, "is queued (queue size: " + queue.size() + ")");
        // notify a queue listener
        if (queueListener != null) queueListener.requestAddedToQueue(request, queue.size());
    }
    protected synchronized void addRequestQueueListener(RequestQueueListener listener) {
        queueListener = EventMulticaster.add(queueListener, listener);
    }
    synchronized protected StringPair[] deliverContent() {
        StringPair[] result = new StringPair[queue.size()];
        Enumeration en = queue.elements();
        ServerRequest sr;
        for (int i=0; i<result.length; i++) {
            sr = (ServerRequest) en.nextElement();
            result[i] = new StringPair(sr.requestId()+"", POAUtil.objectId_to_string(sr.objectId())); 
        }
        return result;
    }
    synchronized protected ServerRequest getElementAndRemove(int rid) {
        if (!queue.isEmpty()) {
            Enumeration en = queue.elements();
            ServerRequest result;
            while (en.hasMoreElements()) {
                result = (ServerRequest) en.nextElement();
                if (result.requestId() == rid) {
                    queue.removeElement(result);
                    // notify a queue listener                                      
                    if (queueListener != null) queueListener.requestRemovedFromQueue(result, queue.size());
                    return result;
                }
            }
        }
        return null;
    }
    synchronized protected ServerRequest getFirst() {
        if (!queue.isEmpty()) {
            return (ServerRequest) queue.firstElement();
        }
        return null;
    }
    protected boolean isEmpty() {
        return queue.isEmpty();
    }
    synchronized protected ServerRequest removeFirst() {
        if (!queue.isEmpty()) {                 
            ServerRequest result = (ServerRequest) queue.elementAt(0);
            queue.removeElementAt(0);
            // notify a queue listener
            if (queueListener != null) queueListener.requestRemovedFromQueue(result, queue.size());
            return result;
        }
        return null;
    }
    synchronized protected ServerRequest removeLast() {
        if (!queue.isEmpty()) {
            ServerRequest result = (ServerRequest) queue.lastElement();
            queue.removeElementAt(queue.size()-1);
            // notify a queue listener                      
            if (queueListener != null) queueListener.requestRemovedFromQueue(result, queue.size());
            return result;
        }
        return null;
    }
    protected synchronized void removeRequestQueueListener(RequestQueueListener listener) {
        queueListener = EventMulticaster.remove(queueListener, listener);
    }
    protected int size() {
        return queue.size();
    }
}

 
