/** 
 * 
 * Copyright 2004 Protique Ltd
 * 
 * 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 org.codehaus.activemq.service.impl;

import EDU.oswego.cs.dl.util.concurrent.SynchronizedBoolean;
import org.codehaus.activemq.broker.BrokerClient;
import org.codehaus.activemq.service.Dispatcher;
import org.codehaus.activemq.service.MessageContainerManager;
import org.codehaus.activemq.service.Subscription;

/**
 * A dispatcher of messages to some JMS connection.
 * <p/>
 * Typically this uses either IO or NIO to shovel the messages down
 * a socket as fast as possible - in either a push or pull way.
 *
 * @version $Revision: 1.1 $
 */
public class DispatcherImpl implements Dispatcher {

    private SynchronizedBoolean started = new SynchronizedBoolean(false);
    private DispatchWorker worker = new DispatchWorker(); //this should be pooled
    private MessageContainerManager containerManager;
    private Thread runner;


    /**
     * Register the MessageContainerManager for the Dispatcher
     *
     * @param mcm
     */
    public void register(MessageContainerManager mcm) {
        this.containerManager = mcm;
        worker.register(mcm);
    }

    /**
     * Called to indicate that there is work to do on a Subscription this will wake up a Dispatch Worker if it is
     * waiting for messages to dispatch
     *
     * @param sub the Subscription that now has messages to dispatch
     */
    public void wakeup(Subscription sub) {
        worker.wakeup();
    }

    /**
     * Called to indicate that there is work to do this will wake up a Dispatch Worker if it is
     * waiting for messages to dispatch
     */
    public void wakeup() {
        worker.wakeup();
    }

    /**
     * Add an active subscription
     *
     * @param client
     * @param sub
     */
    public void addActiveSubscription(BrokerClient client, Subscription sub) {
        worker.addActiveSubscription(client, sub);
    }

    /**
     * remove an active subscription
     *
     * @param client
     * @param sub
     */
    public void removeActiveSubscription(BrokerClient client, Subscription sub) {
        worker.removeActiveSubscription(client, sub);
    }

    /**
     * start the DispatchWorker
     *
     * @see org.codehaus.activemq.service.Service#start()
     */
    public void start() {
        if (started.commit(false, true)) {
            worker.start();
            runner = new Thread(worker, "Dispatch Worker");
            runner.setDaemon(true);
            runner.setPriority(Thread.NORM_PRIORITY + 1);
            runner.start();
        }
    }

    /**
     * stop the DispatchWorker
     *
     * @see org.codehaus.activemq.service.Service#stop()
     */
    public void stop() {
        worker.stop();
        started.set(false);
    }
}
