package org.jcon.util.msg;

import java.util.Hashtable;

/**
* This class contains a collection of MessageRouters.
* It's purpose is to make inter system collaboration
* easier by using the reusable mechanism of passing
* Messages between systems through routers.
* <p>
* For normal use, call getSingleton() then getRouter()
* first. After that, use the router as usual. This class
* should not be used for work within an ItemSystem, or
* much of the architecture's advantages will be lost.
*
* @author Jack Harich
*/
public class MessageRouterRegistry {

//---------- Private Fields ------------------------------
// Internal
private static MessageRouterRegistry singleton =
    new MessageRouterRegistry();
private static final String DEFAULT = new String("Default");

// Key = String name, Object = MessageRouter
private Hashtable routers = new Hashtable();

//---------- Public Methods ------------------------------
/**
* Returns the single "master" registry. This is what most
* clients will use, for simplicity.
*/
public static MessageRouterRegistry getSingleton() {
    return singleton;
}
/**
* This convenience method returns the singleton's default
* router. This is what most simple uses will need. It's the
* same as: <code>getSingleton().getRouter(null, true)</code>.
*/
public static MessageRouter getSingletonDefaultRouter() {
    return singleton.getRouter(null, true);
}
/**
* Returns the named router, for use in sending Messages
* to listeners or adding/removing listeners. For simple
* work the name is null.
* 
* @param name the unique router name. If null an internal
*    default router is used. This is a standard
*    MessageRouter, and is only good for inter system work
*    in the same JVM process.
* @param isAutoAdd if true and the router is not found it
*    is automatically added. This makes it much easier for
*    two systems to start up, since it doesn't matter 
*    which makes the first call to this method.
*    This argument is automatically true if the name
*    argument is null.
* @return    the requested router.
* @exception throws an IllegalArgumentException of the
*    router is not found and isAutoAdd is false, since
*    this indicates a programming error.
*/
public synchronized MessageRouter getRouter(String name,
                                     boolean isAutoAdd) {
    
    if (name == null) name = DEFAULT;
    MessageRouter router = (MessageRouter)routers.get(name);
    if (router ==  null) {
        if (isAutoAdd || name == DEFAULT) {
            router = new MessageRouter();
            routers.put(name, router);
        } else {
            throw new IllegalArgumentException
            ("Router name '" + name + "' not found.");
        }
    }
    //print(".getRouter() - Returning " + router);
    return router;
}
/**
* Adds the named router, which must not alread be there.
*
* @exception throws an IllegalArgumentException if the
* name is already in use, to prevent accidental overwrites.
*/
public synchronized void addRouter(String name, MessageRouter router) {
     print(".addRouter() - Not yet implemented");
}
/**
* Removes the named router. There is no effect if not found.
*/
public synchronized void removeRouter(String name) {
     print(".removeRouter() - Not yet implemented");
}
//---------- Private Methods -----------------------------
//--- Std
private static void print(String text) {
    System.out.println("MessageRouterRegistry" + text);
}

} // End class
