KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jonas_jms > JConnection


1 /*
2  * JOnAS: Java(TM) Open Application Server
3  * Copyright (C) 1999 Bull S.A.
4  * Contact: jonas-team@objectweb.org
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  *
21  * --------------------------------------------------------------------------
22  * $Id: JConnection.java,v 1.11 2004/04/28 15:31:20 durieuxp Exp $
23  * --------------------------------------------------------------------------
24  */

25
26 package org.objectweb.jonas_jms;
27
28 import java.util.LinkedList JavaDoc;
29
30 import javax.jms.Connection JavaDoc;
31 import javax.jms.ConnectionConsumer JavaDoc;
32 import javax.jms.ConnectionMetaData JavaDoc;
33 import javax.jms.Destination JavaDoc;
34 import javax.jms.ExceptionListener JavaDoc;
35 import javax.jms.JMSException JavaDoc;
36 import javax.jms.ServerSessionPool JavaDoc;
37 import javax.jms.Session JavaDoc;
38 import javax.jms.Topic JavaDoc;
39 import javax.jms.XAConnection JavaDoc;
40 import javax.jms.XAConnectionFactory JavaDoc;
41
42 import org.objectweb.transaction.jta.TransactionManager;
43 import org.objectweb.util.monolog.api.BasicLevel;
44
45 /**
46  * Common methods used in JQueueConnection and JTopicConnection.
47  *
48  * @author Laurent Chauvirey, Frederic Maistre, Nicolas Tachker
49  * Contributor(s):
50  * Philippe Durieux
51  * Jeff Mesnil connection anonymous
52  * Philippe Coq JMS 1.1 integration
53  */

54
55 public class JConnection implements Connection JavaDoc {
56
57     // The XAConnection used in the MOM
58
protected XAConnection JavaDoc xac;
59
60     protected boolean closed;
61     protected String JavaDoc user;
62     protected boolean globaltx = false;
63     protected static TransactionManager tm;
64     protected JConnectionFactory jcf;
65     protected LinkedList JavaDoc sessionlist = new LinkedList JavaDoc();
66
67     // This constant is used to determine connection
68
// with an anonymous user in the pool of JConnection.
69
protected static final String JavaDoc INTERNAL_USER_NAME = "anInternalNameUsedOnlyByJOnAS";
70
71     /**
72      * Prepares the construction of a JConnection.
73      */

74     protected JConnection(JConnectionFactory jcf, String JavaDoc user) throws JMSException JavaDoc {
75         this.user = user;
76         this.jcf = jcf;
77         closed = false;
78         if (tm == null) {
79             tm = JmsManagerImpl.getTransactionManager();
80         }
81         // Remember if we are inside a global transaction
82
// This is to handle a case that is not expected in JMS specs.
83
try {
84             globaltx = (tm.getTransaction() != null);
85         } catch (Exception JavaDoc e) {
86         }
87     }
88
89
90     /**
91      * Constructor of a JConnection for a specified user.
92      *
93      * @param user user's name
94      * @param passwd user's password
95      */

96     public JConnection(JConnectionFactory jcf, XAConnectionFactory JavaDoc xacf, String JavaDoc user, String JavaDoc passwd)
97         throws JMSException JavaDoc {
98         this(jcf, user);
99         // Create the underlaying XAConnection
100
xac = xacf.createXAConnection(user, passwd);
101     }
102
103     /**
104      * Constructor of a JConnection for an anonymous user.
105      */

106     public JConnection(JConnectionFactory jcf, XAConnectionFactory JavaDoc xacf) throws JMSException JavaDoc {
107         this(jcf, INTERNAL_USER_NAME);
108         // Create the underlaying XAConnection
109
xac = xacf.createXAConnection();
110     }
111
112     // -----------------------------------------------------------------------
113
// internal methods
114
// -----------------------------------------------------------------------
115

116     /**
117      * A new non transacted session has been opened
118      */

119     protected synchronized boolean sessionOpen(Session JavaDoc s) {
120         if (!closed) {
121             sessionlist.add(s);
122             return true;
123         } else {
124             return false;
125         }
126     }
127
128     /**
129      * A non transacted session has beem closed
130      */

131     protected synchronized void sessionClose(Session JavaDoc s) {
132         sessionlist.remove(s);
133         if (sessionlist.size() == 0 && closed) {
134             notify();
135         }
136     }
137
138     /**
139      * Return the user associated to this connection
140      */

141     public String JavaDoc getUser() {
142         return user;
143     }
144
145     // -----------------------------------------------------------------------
146
// Connection implementation
147
// -----------------------------------------------------------------------
148

149     /**
150      * When this method is invoked it should not return until message processing
151      * has been orderly shut down. This means that all message listeners that may
152      * have been running have returned and that all pending receives have returned.
153      * A close terminates all pending message receives on the connection's sessions'
154      * consumers.
155      * @throws JMSException - if JMS implementation fails to return the client ID for this
156      * Connection due to some internal
157      */

158     public void close() throws JMSException JavaDoc {
159         TraceJms.logger.log(BasicLevel.DEBUG, "");
160         if (globaltx) {
161             // Connection that was open inside a global transaction.
162
// Don't wait (to avoid deadlocks) and don't close it now
163
// Since this situation is not expected by the specs, we just
164
// pool this connection for now, waiting better...
165
jcf.freeJConnection(this);
166         } else {
167             // Wait for all NON transacted sessions to be finished.
168
// LATER: Should rollback first all transacted sessions still running.
169
synchronized(this) {
170                 while (sessionlist.size() > 0) {
171                     try {
172                         wait();
173                     } catch (InterruptedException JavaDoc e) {
174                         TraceJms.logger.log(BasicLevel.ERROR, "interrupted");
175                     }
176                 }
177             }
178             closed = true;
179             xac.close();
180         }
181     }
182     public void finalClose() throws JMSException JavaDoc {
183         if (!closed) {
184             xac.close();
185         }
186     }
187         
188     /**
189      * Creates a connection consumer for this connection (optional operation)
190      * @param destination - the destination to access
191      * @param messageSelector - only messages with properties matching
192      * the message selector expression are delivered.
193      * A value of null or an empty string indicates that
194      * there is no message selector for the message consumer.
195      * @param sessionPool - the server session pool to associate with this connection consumer
196      * @param maxMessages - the maximum number of messages that can be assigned to a server
197      * session at one time
198      * @return the connection consumer
199      */

200
201     public ConnectionConsumer JavaDoc createConnectionConsumer(Destination JavaDoc destination,
202                                                        java.lang.String JavaDoc messageSelector,
203                                                        ServerSessionPool JavaDoc sessionPool,
204                                                        int maxMessages)
205         throws JMSException JavaDoc {
206         TraceJms.logger.log(BasicLevel.DEBUG, "");
207         return xac.createConnectionConsumer(destination,
208                                             messageSelector,
209                                             sessionPool,
210                                             maxMessages);
211     }
212
213     /**
214      * Creates a connection consumer for this connection (optional operation)
215      * @param topic - the topic to access
216      * @param subscriptionName - durable subscription name
217      * @param messageSelector - only messages with properties matching
218      * the message selector expression are delivered.
219      * A value of null or an empty string indicates that
220      * there is no message selector for the message consumer.
221      * @param sessionPool - the server session pool to associate with this connection consumer
222      * @param maxMessages - the maximum number of messages that can be assigned to a server
223      * session at one time
224      * @return the durable connection consumer
225      */

226     public ConnectionConsumer JavaDoc createDurableConnectionConsumer(Topic JavaDoc topic,
227                                                           java.lang.String JavaDoc subscriptionName,
228                                                           java.lang.String JavaDoc messageSelector,
229                                                           ServerSessionPool JavaDoc sessionPool,
230                                                           int maxMessages)
231         throws JMSException JavaDoc {
232         TraceJms.logger.log(BasicLevel.DEBUG, "");
233         return xac.createDurableConnectionConsumer(topic,
234                                                    subscriptionName,
235                                                    messageSelector,
236                                                    sessionPool,
237                                                    maxMessages);
238     }
239
240
241     /**
242      * Creates a Session object.
243      * @param transacted - indicates whether the session is transacted
244      * @param acknowledgeMode indicates whether the consumer or the client
245      * will acknowledge any messages it receives;
246      * ignored if the session is transacted.
247      * Legal values are Session.AUTO_ACKNOWLEDGE, Session.CLIENT_ACKNOWLEDGE,
248      * and Session.DUPS_OK_ACKNOWLEDGE.
249      */

250
251     public Session JavaDoc createSession(boolean transacted,int acknowledgeMode) throws JMSException JavaDoc {
252         TraceJms.logger.log(BasicLevel.DEBUG, "");
253         return new JSession(this, xac);
254     }
255
256
257     /**
258      * Get the client identifier for this connection. This value is JMS Provider specific.
259      * Either pre-configured by an administrator in a ConnectionFactory or assigned dynamically
260      * by the application by calling setClientID method.
261      * @return the unique client identifier.
262      * @throws JMSException - if JMS implementation fails to return the client ID for this
263      * Connection due to some internal
264      */

265     public String JavaDoc getClientID() throws JMSException JavaDoc {
266     TraceJms.logger.log(BasicLevel.DEBUG, "");
267     return xac.getClientID();
268     }
269
270     /**
271      * Set the client identifier for this connection.
272      * If another connection with clientID is already running when this method is called,
273      * the JMS Provider should detect the duplicate id and throw InvalidClientIDException.
274      * @param clientID - the unique client identifier
275      * @throws JMSException - general exception if JMS implementation fails to set the client
276      * ID for this Connection due to some internal error.
277      * @throws InvalidClientIDException - if JMS client specifies an invalid or duplicate client id.
278      * @throws IllegalStateException - if attempting to set a connection's client identifier at
279      * the wrong time or when it has been administratively configured.
280      */

281     public void setClientID(String JavaDoc clientID) throws JMSException JavaDoc {
282     TraceJms.logger.log(BasicLevel.DEBUG, "");
283     xac.setClientID(clientID);
284     }
285
286     /**
287      * Get the meta data for this connection.
288      * @return the connection meta data.
289      * @throws JMSException - general exception if JMS implementation fails to get the Connection
290      * meta-data for this Connection.
291      */

292     public ConnectionMetaData JavaDoc getMetaData() throws JMSException JavaDoc {
293     TraceJms.logger.log(BasicLevel.DEBUG, "");
294     return xac.getMetaData();
295     }
296
297     /**
298      * Get the ExceptionListener for this Connection.
299      * @return the ExceptionListener for this Connection.
300      * @throws JMSException - general exception if JMS implementation fails to get
301      * the Exception listener for this Connection.
302      */

303     public ExceptionListener JavaDoc getExceptionListener() throws JMSException JavaDoc {
304     TraceJms.logger.log(BasicLevel.DEBUG, "");
305     return xac.getExceptionListener();
306     }
307
308     /**
309      * Set an exception listener for this connection.
310      * @param listener - the exception listener.
311      * @throws JMSException - general exception if JMS implementation fails to set
312      * the Exception listener for this Connection.
313      */

314     public void setExceptionListener(ExceptionListener JavaDoc listener) throws JMSException JavaDoc {
315     TraceJms.logger.log(BasicLevel.DEBUG, "");
316     xac.setExceptionListener(listener);
317     }
318
319     /**
320      * Start (or restart) a Connection's delivery of incoming messages.
321      * @throws JMSException - if JMS implementation fails to start the message
322      * delivery due to some internal error.
323      */

324     public void start() throws JMSException JavaDoc {
325     TraceJms.logger.log(BasicLevel.DEBUG, "");
326     xac.start();
327     }
328
329     /**
330      * Used to temporarily stop a Connection's delivery of incoming messages.
331      * It can be restarted using its start method.
332      * When stopped, delivery to all the Connection's message consumers is inhibited:
333      * synchronous receive's block and messages are not delivered to message listeners.
334      * @throws JMSException - if JMS implementation fails to start the message
335      * delivery due to some internal error.
336      */

337     public void stop() throws JMSException JavaDoc {
338     TraceJms.logger.log(BasicLevel.DEBUG, "");
339     xac.stop();
340     }
341 }
342
Popular Tags