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-2005 (C) Exoffice Technologies Inc. All Rights Reserved.
42   *
43   * $Id: ServerConnectionImpl.java,v 1.2 2005/08/30 14:24:26 tanderson Exp $
44   */
45  package org.exolab.jms.server;
46  
47  import java.util.HashSet;
48  import java.util.Iterator;
49  import javax.jms.InvalidClientIDException;
50  import javax.jms.JMSException;
51  
52  import org.apache.commons.logging.Log;
53  import org.apache.commons.logging.LogFactory;
54  
55  import org.exolab.jms.messagemgr.ConsumerManager;
56  import org.exolab.jms.messagemgr.MessageManager;
57  import org.exolab.jms.messagemgr.ResourceManager;
58  import org.exolab.jms.persistence.DatabaseService;
59  import org.exolab.jms.scheduler.Scheduler;
60  
61  /***
62   * Server implementation of the <code>javax.jms.Connection</code> interface.
63   *
64   * @author <a href="mailto:jima@comware.com.au">Jim Alateras</a>
65   * @author <a href="mailto:tma@netspace.net.au">Tim Anderson</a>
66   * @version $Revision: 1.2 $ $Date: 2005/08/30 14:24:26 $
67   * @see ServerConnectionManagerImpl
68   */
69  public class ServerConnectionImpl implements ServerConnection {
70  
71      /***
72       * The connection manager responsible for this.
73       */
74      private final ServerConnectionManagerImpl _manager;
75  
76      /***
77       * The connection identifier.
78       */
79      private final long _connectionId;
80  
81      /***
82       * The client identifier. May be <code>null</code>.
83       */
84      private String _clientId;
85  
86      /***
87       * The sessions associated with the connection.
88       */
89      private HashSet _sessions = new HashSet();
90  
91      /***
92       * Indicates if message delivery has been stopped for this connection.
93       */
94      private boolean _stopped = true;
95  
96      /***
97       * The message manager.
98       */
99      private final MessageManager _messages;
100 
101     /***
102      * The consumer manager.
103      */
104     private final ConsumerManager _consumers;
105 
106     /***
107      * The resource manager.
108      */
109     private final ResourceManager _resources;
110 
111     /***
112      * The database service.
113      */
114     private final DatabaseService _database;
115 
116     /***
117      * The scheduler.
118      */
119     private final Scheduler _scheduler;
120 
121     /***
122      * The logger.
123      */
124     private static final Log _log =
125             LogFactory.getLog(ServerConnectionImpl.class);
126 
127     /***
128      * Construct a new <code>ServerConnectionImpl</code>.
129      *
130      * @param manager      the connection manager
131      * @param connectionId the identifier for this connection
132      * @param clientId     the client identifier. May be <code>null</code>
133      * @param messages     the message manager
134      * @param consumers    the consumer manager
135      * @param resources    the resource manager
136      */
137     protected ServerConnectionImpl(ServerConnectionManagerImpl manager,
138                                   long connectionId, String clientId,
139                                   MessageManager messages,
140                                   ConsumerManager consumers,
141                                   ResourceManager resources,
142                                   DatabaseService database,
143                                   Scheduler scheduler) {
144         if (manager == null) {
145             throw new IllegalArgumentException("Argument 'manager' is null");
146         }
147         if (messages == null) {
148             throw new IllegalArgumentException("Argument 'messages' is null");
149         }
150         if (consumers == null) {
151             throw new IllegalArgumentException("Argument 'consumers' is null");
152         }
153         if (resources == null) {
154             throw new IllegalArgumentException("Argument 'resources' is null");
155         }
156         if (database == null) {
157             throw new IllegalArgumentException("Argument 'database' is null");
158         }
159         if (scheduler == null) {
160             throw new IllegalArgumentException("Argument 'scheduler' is null");
161         }
162         _manager = manager;
163         _connectionId = connectionId;
164         _clientId = clientId;
165         _messages = messages;
166         _consumers = consumers;
167         _resources = resources;
168         _database = database;
169         _scheduler = scheduler;
170     }
171 
172     /***
173      * Returns the connection identifier.
174      *
175      * @return the connection identifier
176      */
177     public long getConnectionId() {
178         return _connectionId;
179     }
180 
181     /***
182      * Returns the client identifier.
183      *
184      * @return the client identifier
185      */
186     public String getClientID() {
187         return _clientId;
188     }
189 
190     /***
191      * Sets the client identifier for this connection.
192      *
193      * @param clientID the unique client identifier
194      * @throws JMSException             if the JMS provider fails to set the
195      *                                  client ID for this connection due to
196      *                                  some internal error.
197      * @throws InvalidClientIDException if the JMS client specifies an invalid
198      *                                  or duplicate client ID.
199      * @throws IllegalStateException    if the JMS client attempts to set a
200      *                                  connection's client ID at the wrong time
201      *                                  or when it has been administratively
202      *                                  configured.
203      */
204     public void setClientID(String clientID) throws JMSException {
205         if (clientID == null) {
206             throw new InvalidClientIDException("Invalid clientID: " + clientID);
207         }
208         _manager.addClientID(clientID);
209         _clientId = clientID;
210     }
211 
212     /***
213      * Create a new session
214      *
215      * @param acknowledgeMode indicates whether the consumer or the client will
216      *                        acknowledge any messages it receives; ignored if
217      *                        the session is transacted. Legal values are
218      *                        <code>Session.AUTO_ACKNOWLEDGE</code>,
219      *                        <code>Session.CLIENT_ACKNOWLEDGE</code>, and
220      *                        <code>Session.DUPS_OK_ACKNOWLEDGE</code>.
221      * @param transacted      indicates whether the session is transacted
222      * @return a newly created session
223      * @throws JMSException for any JMS error
224      */
225     public synchronized ServerSession createSession(int acknowledgeMode,
226                                                     boolean transacted)
227             throws JMSException {
228         ServerSessionImpl session = new ServerSessionImpl(
229                 this, acknowledgeMode, transacted, _messages, _consumers,
230                 _resources, _database, _scheduler);
231         _sessions.add(session);
232         if (!_stopped) {
233             session.start();
234         }
235 
236         return session;
237     }
238 
239     /***
240      * Closes the connection.
241      */
242     public synchronized void close() {
243         Iterator iterator = _sessions.iterator();
244         while (iterator.hasNext()) {
245             ServerSessionImpl session = (ServerSessionImpl) iterator.next();
246             try {
247                 session.close();
248             } catch (JMSException exception) {
249                 _log.debug("Failed to close session", exception);
250             }
251         }
252         _sessions.clear();
253         _manager.closed(this);
254     }
255 
256     /***
257      * Notify closure of a session
258      *
259      * @param session the closed session
260      */
261     public synchronized void closed(ServerSessionImpl session) {
262         _sessions.remove(session);
263     }
264 
265 }