summaryrefslogtreecommitdiff
path: root/java/src/Acceptor.java
blob: 1db6e01f7b5f156a0a94ea9ab84282c88d006d3c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
/*************************************************
 *
 * = 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.*;

/**
 * <hr>
 * <p><h2>SYNOPSIS</h2>
 *
 * <blockquote>Abstract factory for creating a service handler
 * (<a href="ACE.Connection.SvcHandler.html"><tt>SvcHandler</tt></a>),
 * accepting into the
 * <a href="ACE.Connection.SvcHandler.html"><tt>SvcHandler</tt></a>, and activating the
 * <a href="ACE.Connection.SvcHandler.html"><tt>SvcHandler</tt></a>.</blockquote>
 *
 * <p><h2>DESCRIPTION</h2>
 *
 * <blockquote>Implements the basic strategy for passively establishing
 * connections with applications.  The <tt>Acceptor</tt>
 * is a factory for <tt>SvcHandler</tt> instances, and, by default
 * generates a new <tt>SvcHandler</tt> instance for each connection
 * esablished.</blockquote>
 *
 * <p>
 *
 * <blockquote> The user of this class <em>must</em> provide a
 * reference to a handler factory prior to calling <a
 * href="#accept()"><tt>accept</tt></a>, or an exception will be
 * thrown.  The handler factory is identified by the meta-class for
 * the <tt>SvcHandler</tt>, and is typically obtained by calling <a
 * href="java.lang.Class#classForName(java.lang.String)"><tt>Class.classForName("SvcHandler")</tt></a>.
 * </blockquote>
 *
 * <p>
 *
 * <blockquote> TCP is the transport mechanism used, via
 * <a href="ACE.SOCK_SAP.SOCKAcceptor.html#_top_"><tt>SOCKAcceptor</tt></a>,
 * <em>et.al.</em> The SvcHandler is instantiated with a concrete type
 * that performs the application-specific service. </blockquote>
 *
 * <h2>NOTES</h2>
 *
 * <blockquote> This class is not directly related to the
 * <tt>AcceptorStrategy</tt> class.</blockquote>
 *
 *
 * @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, <tt>setHandlerFactory</tt>
   * must be called prior to using <tt>accept</tt>.
   *
   * @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 <tt>Class.classForName</tt>).
   *
   *@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 <tt>Class.classForName</tt>).
   *
   *@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:
   * <ul>
   * <li><tt>makeSvcHandler</tt></li>
   * <li><tt>acceptSvcHandler</tt></li>
   * <li><tt>activateSvcHandler</tt></li>
   * </ul>
   *
   * <p>
   *
   * The method first obtains a <tt>SvcHandler</tt> via
   * <tt>makeSvcHandler</tt>, accepts the connection <q>into</q> the
   * handler using <tt>acceptSvcHandler</tt>, and finally turns over
   * control to the handler with <tt>activateSvcHandler</tt>.
   *
   *@exception SocketException socket level error
   *@exception InstantiationException <tt>makeSvcHandler</tt> failure
   *@exception IllegalAccessException <tt>makeSvcHandler</tt> 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 <tt>SvcHandler</tt>. The default is to
   * create a new <SvcHandler>.  However, subclasses can override this
   * policy to perform <SvcHandler> creation in any way that they like
   * (such as creating subclass instances of <SvcHandler>, 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
   * <tt>SvcHandler</tt>.  The default behavior delegates the work to
   * <tt>SOCKAcceptor.accept</tt>. 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 <tt>SvcHandler</tt>.  The default
   * behavior of this method is to activate the <tt>SvcHandler</tt> by
   * calling its open() method (which allows the <tt>SvcHandler</tt> 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_;
}