/************************************************* * * = PACKAGE * JACE.Connection * * = FILENAME * Acceptor.java * *@author Prashant Jain * *************************************************/ package JACE.Connection; import java.io.*; import java.net.*; import JACE.OS.*; import JACE.SOCK_SAP.*; import JACE.ServiceConfigurator.*; /** *
*

SYNOPSIS

* *
Abstract factory for creating a service handler * (SvcHandler), * accepting into the * SvcHandler, and activating the * SvcHandler.
* *

DESCRIPTION

* *
Implements the basic strategy for passively establishing * connections with applications. The Acceptor * is a factory for SvcHandler instances, and, by default * generates a new SvcHandler instance for each connection * esablished.
* *

* *

The user of this class must provide a * reference to a handler factory prior to calling accept, or an exception will be * thrown. The handler factory is identified by the meta-class for * the SvcHandler, and is typically obtained by calling Class.classForName("SvcHandler"). *
* *

* *

TCP is the transport mechanism used, via * SOCKAcceptor, * et.al. The SvcHandler is instantiated with a concrete type * that performs the application-specific service.
* *

NOTES

* *
This class is not directly related to the * AcceptorStrategy class.
* * * @see java.lang.Class,ACE.Connection.SvcHandler,ACE.SOCK_SAP.SOCKAcceptor */ public class Acceptor extends ServiceObject { /** * Create an instance of Acceptor. Default constructor. Note that if * an instance is created via this method, setHandlerFactory * must be called prior to using accept. * * @see ACE.Connection.Acceptor.setHandlerFactory */ public Acceptor () { } /** * Create an instance of Acceptor. *@param handlerFactory meta-class reference used to create * an instance of a SvcHandler when a connection is accepted * (typically obtained by calling Class.classForName). * *@see java.lang.Class.classForName */ public Acceptor (Class handlerFactory) { this.handlerFactory_ = handlerFactory; } /** * Set the handler factory. This is provided to aid the default * no-arg constructor. *@param handlerFactory meta-class reference used to create * an instance of a SvcHandler when a connection is accepted * (typically obtained by calling Class.classForName). * *@see java.lang.Class.classForName */ public void setHandlerFactory (Class handlerFactory) { this.handlerFactory_ = handlerFactory; } /** * Initialize the Acceptor. *@param port TCP port number where the Acceptor will listen for connections *@exception IOException socket level exception */ public void open (int port) throws IOException { this.sockAcceptor_ = new SOCKAcceptor (port); } /** * Template method for accepting connections. Delegates operational * activities to the following bridge methods: * * *

* * The method first obtains a SvcHandler via * makeSvcHandler, accepts the connection into the * handler using acceptSvcHandler, and finally turns over * control to the handler with activateSvcHandler. * *@exception SocketException socket level error *@exception InstantiationException makeSvcHandler failure *@exception IllegalAccessException makeSvcHandler failure *@exception IOException socket level error */ public void accept () throws SocketException, InstantiationException, IllegalAccessException, IOException { // Create a Svc_Handler using the appropriate Creation_Strategy SvcHandler sh = this.makeSvcHandler (); // Accept a connection into the SvcHandler using the appropriate // Accept_Strategy this.acceptSvcHandler (sh); // Activate the SvcHandler using the appropriate ActivationStrategy this.activateSvcHandler (sh); } /** * Bridge method for creating a SvcHandler. The default is to * create a new . However, subclasses can override this * policy to perform creation in any way that they like * (such as creating subclass instances of , using a * singleton, etc.) *@return a new instance of the SvcHandler *@exception InstantiationException could not create new SvcHandler *@exception IllegalAccessException no SvcHandler factory provided */ protected SvcHandler makeSvcHandler () throws InstantiationException, IllegalAccessException { // Create a new handler for the connection return (SvcHandler) handlerFactory_.newInstance (); } /** * Bridge method for accepting the new connection into the * SvcHandler. The default behavior delegates the work to * SOCKAcceptor.accept. However, subclasses can override this * strategy. *@param sh SvcHandler in which to accept the connection *@return 0 *@exception SocketException socket level error *@exception IOException socket level error */ protected int acceptSvcHandler (SvcHandler sh) throws SocketException, IOException { // Create a new stream SOCKStream sockStream = new SOCKStream (); // Block in accept. Returns when a connection shows up this.sockAcceptor_.accept (sockStream); // Set the streams for the new handler sh.setHandle (sockStream); return 0; } /** * Bridge method for activating a SvcHandler. The default * behavior of this method is to activate the SvcHandler by * calling its open() method (which allows the SvcHandler to * define its own concurrency strategy). However, subclasses can * override this strategy to do more sophisticated concurrency * activations. *@param sh SvcHandler to activate *@return 0 */ protected int activateSvcHandler (SvcHandler sh) { sh.open (null); return 0; } // Handler class that should be instantiated when a connection is // made with a client private Class handlerFactory_; // Our connection acceptance factory protected SOCKAcceptor sockAcceptor_; }