package JACE.netsvcs.Token; import java.io.*; import java.net.*; import java.util.*; import JACE.OS.*; import JACE.Misc.*; import JACE.Connection.*; import JACE.netsvcs.Server; /** * Server for the token service. Launches TokenRequestHandlers as * connections are made. Currently, the activation strategy must be * thread per connection since the operations are allowed to block * during acquires, etc. *
* Two types of locks are supported by default -- Mutex and RWMutex. * New lock types can be added from the command line without changing * any code in the service. To do this, just create a class which * implements the LockHandler interface. *
* When a request for a new lock comes in, a LockHandler of the corresponding * type is created and a mapping is created between the lock name and the * handler. Later requests reuse that mapping. *
* Valid command line arguments: *
* -f (class name):(type) Specify a LockHandler for a type of lock"); * -p (port number) Port to listen on for clients"); * -d Enable debugging messages"); ** *@see JACE.netsvcs.Server *@see TokenRequestHandler *@see LockHandler *@see LockTypes */ public class TokenAcceptor extends Server { protected void addDefaultFactories() throws ClassNotFoundException { addHandlerFactory(LockTypes.MUTEX, Class.forName("JACE.netsvcs.Token.MutexHandler")); addHandlerFactory(LockTypes.RWLOCK, Class.forName("JACE.netsvcs.Token.RWMutexHandler")); } /** * Default constructor. */ public TokenAcceptor() { // Set the name in case we aren't using the service configurator. name ("Token Service"); lockHandlerMap_ = new Hashtable(); handlerFactoryMap_ = new Hashtable(); clientHandlerMap_ = new Hashtable (); } /** * Add a map between a type of lock and the factory which * creates LockHandler instances that handle it. * *@see LockTypes *@param type number representing the type of lock *@param factory Class object for a LockHandler class */ public void addHandlerFactory(Integer type, Class factory) { handlerFactoryMap_.put(type, factory); } /** * Add a map between a type of lock and the factory which * creates LockHandler instances that handle it. * *@see LockTypes *@param type number representing the type of lock *@param factory Class object for a LockHandler class */ public void addHandlerFactory(int type, Class factory) { addHandlerFactory(new Integer(type), factory); } /** * Remove the LockHandler factory which handles locks * of the specified type. * *@param type type of LockHandler to cease supporting *@return the LockHandler instance (or null if not found) */ public Object removeHandlerFactory(Integer type) { return handlerFactoryMap_.remove(type); } /** * Remove the LockHandler factory which handles locks * of the specified type. * *@param type type of LockHandler to cease supporting *@return the LockHandler instance (or null if not found) */ public Object removeHandlerFactory(int type) { return handlerFactoryMap_.remove(new Integer(type)); } /** * Retrieve the LockHandler corresponding to the given name * or create a new one if it doesn't exist. This is called by * TokenRequestHandlers. * *@param lockName name of the lock to retrieve or create a LockHandler for *@param lockType type of the lock *@return LockHandler which handles the lock with that name */ public LockHandler getLockHandler (String lockName, int lockType) { synchronized (lockHandlerMap_) { Object obj = lockHandlerMap_.get(lockName); if (obj != null) return (LockHandler)obj; else { LockHandler handler = newHandler (lockType); lockHandlerMap_.put (lockName, handler); return handler; } } } /** * Create a new LockHandler of the specified type. * *@param type type of LockHandler to create *@return a new LockHandler instance */ protected LockHandler newHandler (int type) { ACE.DEBUG ("Creating new handler of type " + type); Object factoryObj = handlerFactoryMap_.get(new Integer(type)); if (factoryObj == null) return null; Class factory = (Class)factoryObj; LockHandler handler = null; try { handler = (LockHandler)factory.newInstance(); } catch (InstantiationException e) { ACE.ERROR("Can't create a handler of type " + type); } catch (IllegalAccessException e) { ACE.ERROR("Handler of type " + type + " must have a default constructor"); } return handler; } /** * Simple main program. See the class description for more * information about command line arguments. */ public static void main(String args[]) { TokenAcceptor ta = new TokenAcceptor(); ta.init(args); } /** * Create a new TokenRequestHandler instance. */ protected SvcHandler makeSvcHandler() { return new TokenRequestHandler(); } /** * Sets up the default factories so the user can override them on * the command line, then delegates back to Server.init (String[]). * *@see JACE.netsvcs.Server#init *@param args command line arguments *@return -1 on failure, 0 on success */ public int init(String [] args) { try { addDefaultFactories (); } catch (ClassNotFoundException e) { ACE.ERROR ("Can't find default factory " + e.getMessage ()); return -1; } return super.init (args); } /** * Prints out the valid command line arguments. See the class * description for more information. Called by Server.init when * parseArgs returns -1. */ protected void printUsage () { ACE.ERROR ("Valid options:\n"); ACE.ERROR ("-f