/*
 ************************************************************************
 *
 * Copyright (c) 2003-2004, C&C Research Laboratories, NEC Europe Ltd.
 *
 * Copyright in this software belongs to C&C Research Laboratories,
 * Rathausallee 10, 53757 Sankt Augustin, Germany.
 *
 * This software may not be used, sold, licensed, transferred, copied
 * or reproduced in whole or in part in any manner or form or in or
 * on any media by any person other than in accordance with the terms
 * of the Licence Agreement supplied with the software, or otherwise
 * without the prior written consent of the copyright owners.
 *
 * This software is distributed WITHOUT ANY WARRANTY, without even the
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE, except where stated in the Licence Agreement supplied with
 * the software.
 *
 *  Created By :           G.A. Kohring
 *  Created for Project :  GEMSS (IST-2001-37153)
 *
 ************************************************************************
 */

package de.nece.ccrle.organizer;

import java.security.AccessController;
import java.util.Iterator;
import java.util.HashSet;
import java.util.Set;

import eu.gemss.signals.Signal;
import eu.gemss.signals.SignalHandler;
import eu.gemss.signals.SignalPermission;

import de.nece.ccrle.util.HashCatalog;
import de.nece.ccrle.util.Catalog;


/**
 * A framework for transmitting signals from one component to another
 *
 * @author Greg Kohring
 */
public class Transmitter {

    private Catalog signalRegistry = null;

    /**
     * The default constructor.
     *
     */
    public Transmitter() {
        signalRegistry = new HashCatalog();
    }

    /**
     * Regigisters the specified signal handler for the specified signal type.
     * When a signal of the specified type is emitted by any component, the
     * the specified handler will be called.
     *
     * @param sh the <tt>SignalHandler</tt> which will process the given
     *      signal.
     * @param signalType a <tt>String</tt> indicating the signal type.
     *
     */
    public synchronized void registerSignalHandler( SignalHandler sh, 
                                            String signalType){
        signalRegistry.addItem( signalType, sh );
    }

    /**
     * Send a signal to the registered signal handlers, if any.
     *
     * @param signal the <tt>Signal</tt> to be sent to the handlers.
     * @return an array of processed signals. If there are no handlers
     *      registered for the given signal, then the array will be empty.
     *
     */
    public synchronized Signal[] generateSignal( Signal signal ){

        // Make sure we have permission to generate a signal

        SecurityManager sm = System.getSecurityManager();
        if ( sm != null ){
            SignalPermission perm = new SignalPermission( "generate");
            AccessController.checkPermission( perm );
        }


        Set handlerSet = signalRegistry.getItems( signal.getSignalType() );
        if ( handlerSet == null ){
            return new Signal[0];
        }
        Signal[] signals = new Signal[handlerSet.size()];
        int s = 0;
        Iterator handlers = handlerSet.iterator();
        while( handlers.hasNext() ){
            SignalHandler handler = (SignalHandler) handlers.next();
            Signal sent = (Signal) signal.clone();
            handler.process( sent );
            sent.processed();
            signals[s] = sent;
            s++;
        }

        return signals;
    }

}
