1 /***
2 * Redistribution and use of this software and associated documentation
3 * ("Software"), with or without modification, are permitted provided
4 * that the following conditions are met:
5 *
6 * 1. Redistributions of source code must retain copyright
7 * statements and notices. Redistributions must also contain a
8 * copy of this document.
9 *
10 * 2. Redistributions in binary form must reproduce the
11 * above copyright notice, this list of conditions and the
12 * following disclaimer in the documentation and/or other
13 * materials provided with the distribution.
14 *
15 * 3. The name "Exolab" must not be used to endorse or promote
16 * products derived from this Software without prior written
17 * permission of Exoffice Technologies. For written permission,
18 * please contact info@exolab.org.
19 *
20 * 4. Products derived from this Software may not be called "Exolab"
21 * nor may "Exolab" appear in their names without prior written
22 * permission of Exoffice Technologies. Exolab is a registered
23 * trademark of Exoffice Technologies.
24 *
25 * 5. Due credit should be given to the Exolab Project
26 * (http://www.exolab.org/).
27 *
28 * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
32 * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39 * OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Copyright 2001,2003 (C) Exoffice Technologies Inc. All Rights Reserved.
42 *
43 * $Id: IpcServerChannel.java,v 1.8 2003/08/07 13:33:09 tanderson Exp $
44 *
45 * Date Author Changes
46 * 2/14/2001 artw Created
47 */
48
49 package org.exolab.jms.server.mipc;
50
51 import java.io.Serializable;
52 import java.util.HashMap;
53
54 import org.apache.commons.logging.Log;
55 import org.apache.commons.logging.LogFactory;
56
57 import org.exolab.core.ipc.NotifierIfc;
58 import org.exolab.core.mipc.DisconnectionEventListener;
59 import org.exolab.core.mipc.MultiplexConnectionIfc;
60 import org.exolab.core.mipc.ObjectChannel;
61
62
63 /***
64 * An instance of this class represents a client's connection to the server.
65 * It encapsulates the MultiplexConnection and is responsible for listening
66 * to ipc messages and dispatching them to specified NotifierIfc client.
67 *
68 * This object derives from Thread and runs in its own thread. shutdown()
69 * should be used to gracefully stop this thread.
70 *
71 * @version $Revision: 1.8 $
72 * @author <a href="mailto:artw@wfactor.com">Art Whitten</a>
73 * @see org.exolab.core.mipc.MultiplexConnection
74 **/
75 public class IpcServerChannel
76 extends Thread
77 implements DisconnectionEventListener {
78
79 /***
80 * The associated with the client connection
81 */
82 private MultiplexConnectionIfc _connection;
83
84 /***
85 * Object channel used to receive remote ipc commands.
86 */
87 private ObjectChannel _oc;
88
89 /***
90 *The client that wants to be notified whenever a ipc message is received.
91 */
92 private NotifierIfc _client;
93
94 /***
95 * Unique ID for this instance
96 */
97 private String _id;
98
99 /***
100 * Used for stopping the Thread
101 */
102 private volatile boolean _stopRequested = false;
103
104 /***
105 * Used for creating a unique id
106 */
107 private static int _nextID = 0;
108
109 /***
110 * Keeps track of all of the IpcServerChannels. The key is the
111 * _id and the value is the object.
112 */
113 private static HashMap _channels = new HashMap();
114
115 /***
116 * The logger
117 */
118 private static final Log _log = LogFactory.getLog(IpcServerChannel.class);
119
120
121 /***
122 * Creates new IpcServerChannel on the specified connection.
123 *
124 * @param connection The MultiplexConnection to listen for ipc commands on.
125 * @param client This object gets notified of all ipc messages.
126 * @param channel The name of the channel to listen on.
127 */
128 public IpcServerChannel(MultiplexConnectionIfc connection,
129 NotifierIfc client, String channel) {
130 super(channel + "-" + getNextID());
131 _connection = connection;
132 _connection.setDisconnectionEventListener(this);
133 _client = client;
134 _oc = new ObjectChannel(channel, connection);
135
136 // The name that we created for the thread is unique.
137 _id = getName();
138
139 // Keep track of all the active server channels by unique id
140 addServerChannel(this);
141 }
142
143 /***
144 * Return the underlying MultiplexConnection
145 *
146 * @return the underlying connection
147 */
148 public MultiplexConnectionIfc getConnection() {
149 return _connection;
150 }
151
152 /***
153 * This method is called when the thread starts. It sits in a loop
154 * receiving ipc messages. When a message is received, it is passed onto
155 * the client notifier.
156 */
157 public void run() {
158 while (!_stopRequested) {
159 try {
160 Object object = _oc.receive();
161 Serializable returnValue = _client.notify(object, _id);
162 if (returnValue != null) {
163 _oc.send(returnValue);
164 }
165 } catch (Exception exception) {
166 if (!_stopRequested) {
167 _log.debug(exception, exception);
168 }
169 }
170 }
171
172 try {
173 _client.disconnection(_id);
174 _oc.close();
175 } catch (Exception ignore) {
176 // eat exceptions, we don't care here
177 } finally {
178 removeServerChannel(this);
179 _client = null;
180 _connection = null;
181 }
182 }
183
184 /***
185 * Stop execution of this thread.
186 */
187 public void shutdown() {
188 _stopRequested = true;
189 interrupt();
190 }
191
192 // implementation of DisconnectionEventListener.diconnected
193 public void disconnected(MultiplexConnectionIfc connection) {
194 shutdown();
195 new IpcJmsServerConnection().disconnection(_id);
196 }
197
198 /***
199 * Given a IpcServerChannel uniqueID string, return the associated
200 * instance.
201 *
202 * @param id The string ID of the IpcServerChannel we are looking for.
203 * @return IpcServerChannel The found object, null if none.
204 */
205 public static synchronized IpcServerChannel getServerChannel(String id) {
206 return (IpcServerChannel) _channels.get(id);
207 }
208
209 /***
210 * Add a new IpcServerChannel to the list of connections so that clients
211 * can get to it given its uniqueID
212 *
213 * @param newChannel The IpcServerChannel to add.
214 */
215 private synchronized static void addServerChannel(
216 IpcServerChannel newChannel) {
217 _channels.put(newChannel._id, newChannel);
218 }
219
220 /***
221 * Remove a IpcServerChannel from the list of active channels
222 *
223 * @param removeChannel The IpcServerChannel to remove.
224 */
225 private synchronized static void removeServerChannel(
226 IpcServerChannel removeChannel) {
227 _channels.remove(removeChannel._id);
228 }
229
230 private synchronized static int getNextID() {
231 return _nextID++;
232 }
233
234 }
This page was automatically generated by Maven