View Javadoc

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 2000-2003 (C) Exoffice Technologies Inc. All Rights Reserved.
42   *
43   * $Id: IpcJmsServerConnection.java,v 1.8 2003/08/17 01:32:26 tanderson Exp $
44   *
45   * Date         Author  Changes
46   * $Date	    jimm    Created
47   */
48  package org.exolab.jms.server.mipc;
49  
50  import java.io.Serializable;
51  import java.util.Hashtable;
52  import java.util.Vector;
53  
54  import javax.jms.JMSException;
55  
56  import org.exolab.core.ipc.NotifierIfc;
57  import org.exolab.jms.server.JmsServerConnection;
58  import org.exolab.jms.server.JmsServerConnectionManager;
59  import org.exolab.jms.server.JmsServerSession;
60  
61  
62  /***
63   * This class is responsible for interpreting server connection requests and
64   * delegating them to the server. And passing back any necessary replies.
65   *
66   * @version     $Revision: 1.8 $ $Date: 2003/08/17 01:32:26 $
67   * @author      <a href="mailto:mourikis@exolab.org">Jim Mourikis</a>
68   * @see	        org.exolab.jms.server.mipc.IpcJmsReceiver
69   * @see	        org.exolab.jms.server.JmsServerConnection
70   * @see	        org.exolab.jms.server.JmsServerConnectionManager
71   * @see	        org.exolab.core.ipc.NotifierIfc
72   */
73  public class IpcJmsServerConnection implements NotifierIfc {
74  
75      /***
76       * A hashtable of Vectors. Each node containing the list of Connection Id's
77       * for a particular IPC connection.
78       */
79      private static Hashtable _connections = new Hashtable();
80  
81      /***
82       * Default constructor
83       */
84      public IpcJmsServerConnection() {
85      }
86  
87      /***
88       * A new request has been received.
89       * Carry out the request, and pass back any relevent data.
90       *
91       * @param ob The data received,
92       * @return Object Return any requested result. This must never be null.
93       *
94       */
95      public Serializable notify(Object ob, String id) {
96          Vector v = (Vector) ob;
97          String func = (String) v.get(1);
98          Serializable result = null;
99  
100         if (func.equals("createConnection")) {
101             // Use the unique Ipc id for every new connection.
102             result = createConnection(id, (String) v.get(2), (String) v.get(3),
103                 (String) v.get(4));
104         } else if (func.equals("createSession")) {
105             result = createSession(id, (String) v.get(2), (String) v.get(3),
106                 (Integer) v.get(4), (Boolean) v.get(5));
107         } else if (func.equals("close")) {
108             result = close(id, (String) v.get(2), (String) v.get(3));
109         } else {
110             String st = ("Unknown request received: " + func);
111             System.err.println(st);
112             result = pack(new Boolean(false), st);
113         }
114 
115         return result;
116     }
117 
118 
119     /***
120      * The connection has been broken.
121      *
122      * @param The unique IPC identifier of this connection.
123      *
124      */
125     public void disconnection(String id) {
126         Vector v;
127         synchronized (_connections) {
128             v = (Vector) _connections.remove(id);
129         }
130 
131         if (v != null) {
132             Object[] ob = v.toArray();
133             JmsServerConnection con = null;
134 
135             for (int i = 0, j = v.size(); i < j; i++) {
136                 con = JmsServerConnectionManager.instance().getConnection
137                     ((String) ob[i]);
138                 if (con != null) {
139                     con.close();
140                 }
141             }
142             // help clean up.
143             v.clear();
144             v = null;
145         }
146     }
147 
148     /***
149      * Add all the client id's for this IPC connection into the connections
150      * list. Use the IPC id as the key, so all client connections from
151      * a single physical client are on the same key.
152      *
153      * @param ipc The IPC client id if this connection
154      * @param id The unique clientId of this client
155      */
156     private void addConnection(String ipc, String id) {
157         synchronized (_connections) {
158             Vector v = (Vector) _connections.get(ipc);
159 
160             if (v == null) {
161                 v = new Vector();
162                 _connections.put(ipc, v);
163             }
164             v.add(id);
165         }
166     }
167 
168     /***
169      * A new connection request has been made.
170      * Pass on the request to the JmsServerConnectionMgr. If the request
171      * succeeds return the connectionId to the client.
172      *
173      * @param ipcId The unique IPC id of this connection.
174      * @param clientId The unique id of the client.
175      * @param username the client's username
176      * @param password the client's password
177      * @return Vector The result of the request.
178      */
179     private Vector createConnection(String ipcId,
180                                     String clientId, String username,
181                                     String password) {
182         Vector result;
183         try {
184             JmsServerConnection connection =
185                 JmsServerConnectionManager.instance().createConnection(
186                     clientId, username, password);
187 
188             addConnection(ipcId, clientId);
189             result = pack(new Boolean(true), connection.getConnectionId());
190         } catch (JMSException exception) {
191             result = pack(new Boolean(false), exception);
192         }
193         return result;
194     }
195 
196     /***
197      * A create session request has been received. Get the JmsServerConnection
198      * object from the manager and create a new session. If the request
199      * succeeds return the unique session id of the session, and the flow
200      * control notification limit.
201      *
202      * @param ipcId The unique IPC id of this connection.
203      * @param clientId The unique id of the client.
204      * @param connectionId The unique connection id of the client.
205      * @return Vector The result of the request.
206      *
207      */
208     private Vector createSession(String ipcId, String clientId,
209                                  String connectionId, Integer ackMode,
210                                  Boolean transacted) {
211         Vector result = null;
212 
213         JmsServerConnection connection =
214             JmsServerConnectionManager.instance().getConnection(clientId);
215         JmsServerSession session = null;
216 
217         if (connection != null) {
218             session = connection.createSession(ackMode.intValue(),
219                 transacted.booleanValue());
220         }
221         if (session != null) {
222             Vector state = new Vector(2);
223             state.add(session.getSessionId());
224             result = pack(new Boolean(true), state);
225         } else {
226             result = pack(new Boolean(false),
227                 "Failed to create session");
228         }
229         return result;
230     }
231 
232     /***
233      * A close connection request has been received. Get the
234      * JmsServerConnection object from the manager and close the connection.
235      *
236      * @param ipcId The unique IPC id of this connection.
237      * @param clientId The unique id of the client.
238      * @param connectionId The unique connection id of the client.
239      * @return Vector The result of the request.
240      */
241     private Vector close(String ipcId, String clientId, String connectionId) {
242         synchronized (_connections) {
243             Vector connections = (Vector) _connections.get(ipcId);
244             if (connections != null) {
245                 connections.remove(clientId);
246                 if (connections.isEmpty()) {
247                     _connections.remove(ipcId);
248                 }
249             }
250         }
251         JmsServerConnectionManager.instance().closeConnection(clientId);
252 
253         return pack(new Boolean(true), null);
254     }
255 
256     /***
257      * Pack all the data that is required by the server in a vector.
258      * Set the size of the vector to be exactly the right size for efficiency.
259      *
260      * @param success Boolean indicating success or failure of request.
261      * @param ob The Object being returned.
262      * @return Vector The vector containing all the data.
263      *
264      */
265     private Vector pack(Boolean success, Object ob) {
266         Vector v = new Vector(2);
267         v.add(success);
268         v.add(ob);
269         return v;
270     }
271 
272 } // End IpcJmsServerConnection