package org.jcon.util.service;

import org.jcon.util.msg.Message;
import org.jcon.util.msg.MessageService;
import java.util.Hashtable;

/**
 * This class provides Message services for a container.
 * Its designed to be used by ContainerServices, but may
 * be reused elsewhere. A container hierarchy is supported.
 *
 * @author Jack Harich
 */
public class ContainerMessaging {

//---------- Private Fields ------------------------------
// Properties
private ContainerMessaging parent; // null if root
// Internal
// Key = eventName, Object = MessageService
private Hashtable handlers = new Hashtable();

//------------ Properties --------------------------------
/**
* Sets the parent for this instance. This allows a hierarchy
* of containers. The root has a null parent.
*
* @param parent  the parent of this container service.
*/
public void setParent(ContainerMessaging parent) {
    this.parent = parent;   
}    
/**
* Returns the parent of this instance, which is null if root.
*
* @return the parent container service.
*/
public ContainerMessaging getParent() {
    return parent;   
}    
//---------- Public Methods ------------------------------
/**
* Sets the handler for the messageName. The handler is
* responsible for processing the message, which usually is
* an "acquire" type message. Note there is only one handler
* per messageName.
*
* @param messageName  the message name the handler will process.
* @param handler      the service responsible for handling the message.
*/
public void setMessageHandler(String messageName,
                                MessageService handler) {
    handlers.put(messageName, handler);
}    
/**
* Removes the handler for the messageName. There is no
* effect no handler is found for the messageName.
*
* @param messageName  the message name the handler will process.
*/
public void removeMessageHandler(String messageName) {
    handlers.remove(messageName);
}
/**
* Removes all handlers in this container.
* This method is designed for same instance reuse.
*/
public void removeAllMessageHandlers() {
    handlers.clear();    
}
/**
* Sends the message to the handler for messages with the
* same name as this message. Returns true if a handler is
* found and false if not. This container is searched first
* for a handler. If none is found we search upward until
* the root is reached.
*
* @param   message  the message to send.
* @return  <code>true</code> if a handler was found or
*          <code>false</code> otherwise.
*/
public boolean sendMessage(Message message) {
    MessageService handler = 
        (MessageService)handlers.get(message.getName());    
        
    if (handler != null) {
        //print(".sendMessage() - handler = " + handler);
        handler.serviceMessage(message);
        return true;
        
    } else if (parent != null) { 
        return parent.sendMessage(message);
        
    } else {
        return false;
    }
}
//---------- Private Methods -----------------------------
//--- Std
private static void print(String text) {
    System.out.println("ContainerMessaging" + text);
}

} // End class
