KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > activemq > ra > ActiveMQManagedConnection


1 /**
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one or more
4  * contributor license agreements. See the NOTICE file distributed with
5  * this work for additional information regarding copyright ownership.
6  * The ASF licenses this file to You under the Apache License, Version 2.0
7  * (the "License"); you may not use this file except in compliance with
8  * the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18 package org.apache.activemq.ra;
19
20 import java.io.PrintWriter JavaDoc;
21 import java.util.ArrayList JavaDoc;
22 import java.util.Iterator JavaDoc;
23
24 import javax.jms.Connection JavaDoc;
25 import javax.jms.ExceptionListener JavaDoc;
26 import javax.jms.JMSException JavaDoc;
27 import javax.resource.ResourceException JavaDoc;
28 import javax.resource.spi.ConnectionEvent JavaDoc;
29 import javax.resource.spi.ConnectionEventListener JavaDoc;
30 import javax.resource.spi.ConnectionRequestInfo JavaDoc;
31 import javax.resource.spi.LocalTransaction JavaDoc;
32 import javax.resource.spi.ManagedConnection JavaDoc;
33 import javax.resource.spi.ManagedConnectionMetaData JavaDoc;
34 import javax.security.auth.Subject JavaDoc;
35 import javax.transaction.xa.XAResource JavaDoc;
36
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39 import org.apache.activemq.ActiveMQConnection;
40 import org.apache.activemq.LocalTransactionEventListener;
41 import org.apache.activemq.TransactionContext;
42
43 /**
44  * ActiveMQManagedConnection maps to real physical connection to the
45  * server. Since a ManagedConnection has to provide a transaction
46  * managment interface to the physical connection, and sessions
47  * are the objects implement transaction managment interfaces in
48  * the JMS API, this object also maps to a singe physical JMS session.
49  * <p/>
50  * The side-effect is that JMS connection the application gets
51  * will allways create the same session object. This is good if
52  * running in an app server since the sessions are elisted in the
53  * context transaction. This is bad if used outside of an app
54  * server since the user may be trying to create 2 different
55  * sessions to coordinate 2 different uow.
56  *
57  * @version $Revision$
58  */

59 public class ActiveMQManagedConnection implements ManagedConnection JavaDoc, ExceptionListener JavaDoc { // TODO: , DissociatableManagedConnection {
60

61     private static final Log log = LogFactory.getLog(ActiveMQManagedConnection.class);
62
63     private PrintWriter JavaDoc logWriter;
64
65     private final ActiveMQConnection physicalConnection;
66     private final TransactionContext transactionContext;
67     private final ArrayList JavaDoc proxyConnections = new ArrayList JavaDoc();
68     private final ArrayList JavaDoc listeners = new ArrayList JavaDoc();
69     private final LocalAndXATransaction localAndXATransaction;
70     
71     private Subject JavaDoc subject;
72     private ActiveMQConnectionRequestInfo info;
73     private boolean destoryed;
74
75     public ActiveMQManagedConnection(Subject JavaDoc subject, ActiveMQConnection physicalConnection, ActiveMQConnectionRequestInfo info) throws ResourceException JavaDoc {
76         try {
77             this.subject = subject;
78             this.info = info;
79             this.physicalConnection = physicalConnection;
80             this.transactionContext = new TransactionContext(physicalConnection);
81             
82             this.localAndXATransaction = new LocalAndXATransaction(transactionContext) {
83                 public void setInManagedTx(boolean inManagedTx) throws JMSException JavaDoc {
84                     super.setInManagedTx(inManagedTx);
85                     Iterator JavaDoc iterator = proxyConnections.iterator();
86                     while (iterator.hasNext()) {
87                         ManagedConnectionProxy proxy = (ManagedConnectionProxy) iterator.next();
88                         proxy.setUseSharedTxContext(inManagedTx);
89                     }
90                 }
91             };
92             
93             this.transactionContext.setLocalTransactionEventListener( new LocalTransactionEventListener() {
94                 public void beginEvent() {
95                     fireBeginEvent();
96                 }
97                 public void commitEvent() {
98                     fireCommitEvent();
99                 }
100                 public void rollbackEvent() {
101                     fireRollbackEvent();
102                 }
103             });
104                         
105             physicalConnection.setExceptionListener(this);
106         } catch (JMSException JavaDoc e) {
107             throw new ResourceException JavaDoc("Could not create a new connection: "+e.getMessage(), e);
108         }
109     }
110     
111     public boolean isInManagedTx() {
112         return localAndXATransaction.isInManagedTx();
113     }
114     
115     static public boolean matches(Object JavaDoc x, Object JavaDoc y) {
116         if (x == null ^ y == null) {
117             return false;
118         }
119         if (x != null && !x.equals(y)) {
120             return false;
121         }
122         return true;
123     }
124
125     public void associate(Subject JavaDoc subject, ActiveMQConnectionRequestInfo info) throws JMSException JavaDoc {
126
127         // Do we need to change the associated userid/password
128
if( !matches(info.getUserName(), this.info.getUserName()) || !matches(info.getPassword(), this.info.getPassword()) ) {
129             ((ActiveMQConnection)physicalConnection).changeUserInfo(info.getUserName(), info.getPassword());
130         }
131         
132         // Do we need to set the clientId?
133
if( info.getClientid()!=null && info.getClientid().length()>0 )
134             physicalConnection.setClientID(info.getClientid());
135
136         this.subject = subject;
137         this.info = info;
138     }
139
140     public Connection JavaDoc getPhysicalConnection() {
141         return physicalConnection;
142     }
143     
144     private void fireBeginEvent() {
145         ConnectionEvent JavaDoc event = new ConnectionEvent JavaDoc(ActiveMQManagedConnection.this,
146                 ConnectionEvent.LOCAL_TRANSACTION_STARTED);
147         Iterator JavaDoc iterator = listeners.iterator();
148         while (iterator.hasNext()) {
149             ConnectionEventListener JavaDoc l = (ConnectionEventListener JavaDoc) iterator.next();
150             l.localTransactionStarted(event);
151         }
152     }
153
154     private void fireCommitEvent() {
155         ConnectionEvent JavaDoc event = new ConnectionEvent JavaDoc(ActiveMQManagedConnection.this,
156                 ConnectionEvent.LOCAL_TRANSACTION_COMMITTED);
157         Iterator JavaDoc iterator = listeners.iterator();
158         while (iterator.hasNext()) {
159             ConnectionEventListener JavaDoc l = (ConnectionEventListener JavaDoc) iterator.next();
160             l.localTransactionCommitted(event);
161         }
162     }
163
164     private void fireRollbackEvent() {
165         ConnectionEvent JavaDoc event = new ConnectionEvent JavaDoc(ActiveMQManagedConnection.this,
166                 ConnectionEvent.LOCAL_TRANSACTION_ROLLEDBACK);
167         Iterator JavaDoc iterator = listeners.iterator();
168         while (iterator.hasNext()) {
169             ConnectionEventListener JavaDoc l = (ConnectionEventListener JavaDoc) iterator.next();
170             l.localTransactionRolledback(event);
171         }
172     }
173
174     private void fireCloseEvent(ManagedConnectionProxy proxy) {
175         ConnectionEvent JavaDoc event = new ConnectionEvent JavaDoc(ActiveMQManagedConnection.this,
176                 ConnectionEvent.CONNECTION_CLOSED);
177         event.setConnectionHandle(proxy);
178         
179         Iterator JavaDoc iterator = listeners.iterator();
180         while (iterator.hasNext()) {
181             ConnectionEventListener JavaDoc l = (ConnectionEventListener JavaDoc) iterator.next();
182             l.connectionClosed(event);
183         }
184     }
185
186     private void fireErrorOccurredEvent(Exception JavaDoc error) {
187         ConnectionEvent JavaDoc event = new ConnectionEvent JavaDoc(ActiveMQManagedConnection.this,
188                 ConnectionEvent.CONNECTION_ERROR_OCCURRED, error);
189         Iterator JavaDoc iterator = listeners.iterator();
190         while (iterator.hasNext()) {
191             ConnectionEventListener JavaDoc l = (ConnectionEventListener JavaDoc) iterator.next();
192             l.connectionErrorOccurred(event);
193         }
194     }
195
196     /**
197      * @see javax.resource.spi.ManagedConnection#getConnection(javax.security.auth.Subject,
198      * javax.resource.spi.ConnectionRequestInfo)
199      */

200     public Object JavaDoc getConnection(Subject JavaDoc subject, ConnectionRequestInfo JavaDoc info)
201             throws ResourceException JavaDoc {
202         ManagedConnectionProxy proxy = new ManagedConnectionProxy(this);
203         proxyConnections.add(proxy);
204         return proxy;
205     }
206
207     private boolean isDestroyed() {
208         return destoryed;
209     }
210     
211     /**
212      * Close down the physical connection to the server.
213      *
214      * @see javax.resource.spi.ManagedConnection#destroy()
215      */

216     public void destroy() throws ResourceException JavaDoc {
217         // Have we allready been destroyed??
218
if (isDestroyed()) {
219             return;
220         }
221
222         cleanup();
223
224         try {
225             physicalConnection.close();
226             destoryed = true;
227         } catch (JMSException JavaDoc e) {
228             log.info("Error occured during close of a JMS connection.", e);
229         }
230     }
231
232     /**
233      * Cleans up all proxy handles attached to this physical connection so that
234      * they cannot be used anymore.
235      *
236      * @see javax.resource.spi.ManagedConnection#cleanup()
237      */

238     public void cleanup() throws ResourceException JavaDoc {
239         
240         // Have we allready been destroyed??
241
if (isDestroyed()) {
242             return;
243         }
244
245         Iterator JavaDoc iterator = proxyConnections.iterator();
246         while (iterator.hasNext()) {
247             ManagedConnectionProxy proxy = (ManagedConnectionProxy) iterator.next();
248             proxy.cleanup();
249         }
250         proxyConnections.clear();
251         localAndXATransaction.cleanup();
252         
253         try {
254             ((ActiveMQConnection)physicalConnection).cleanup();
255         } catch (JMSException JavaDoc e) {
256             throw new ResourceException JavaDoc("Could cleanup the ActiveMQ connection: "+e, e);
257         }
258             
259     }
260
261     /**
262      * @see javax.resource.spi.ManagedConnection#associateConnection(java.lang.Object)
263      */

264     public void associateConnection(Object JavaDoc connection) throws ResourceException JavaDoc {
265         if (connection instanceof ManagedConnectionProxy) {
266             ManagedConnectionProxy proxy = (ManagedConnectionProxy) connection;
267             proxyConnections.add(proxy);
268         }
269         else {
270             throw new ResourceException JavaDoc("Not supported : associating connection instance of " + connection.getClass().getName());
271         }
272     }
273
274     /**
275      * @see javax.resource.spi.ManagedConnection#addConnectionEventListener(javax.resource.spi.ConnectionEventListener)
276      */

277     public void addConnectionEventListener(ConnectionEventListener JavaDoc listener) {
278         listeners.add(listener);
279     }
280
281     /**
282      * @see javax.resource.spi.ManagedConnection#removeConnectionEventListener(javax.resource.spi.ConnectionEventListener)
283      */

284     public void removeConnectionEventListener(ConnectionEventListener JavaDoc listener) {
285         listeners.remove(listener);
286     }
287
288     /**
289      * @see javax.resource.spi.ManagedConnection#getXAResource()
290      */

291     public XAResource JavaDoc getXAResource() throws ResourceException JavaDoc {
292         return localAndXATransaction;
293     }
294
295     /**
296      * @see javax.resource.spi.ManagedConnection#getLocalTransaction()
297      */

298     public LocalTransaction JavaDoc getLocalTransaction() throws ResourceException JavaDoc {
299         return localAndXATransaction;
300     }
301
302     /**
303      * @see javax.resource.spi.ManagedConnection#getMetaData()
304      */

305     public ManagedConnectionMetaData JavaDoc getMetaData() throws ResourceException JavaDoc {
306         return new ManagedConnectionMetaData JavaDoc() {
307
308             public String JavaDoc getEISProductName() throws ResourceException JavaDoc {
309                 if (physicalConnection == null) {
310                     throw new ResourceException JavaDoc("Not connected.");
311                 }
312                 try {
313                     return physicalConnection.getMetaData().getJMSProviderName();
314                 }
315                 catch (JMSException JavaDoc e) {
316                     throw new ResourceException JavaDoc("Error accessing provider.", e);
317                 }
318             }
319
320             public String JavaDoc getEISProductVersion() throws ResourceException JavaDoc {
321                 if (physicalConnection == null) {
322                     throw new ResourceException JavaDoc("Not connected.");
323                 }
324                 try {
325                     return physicalConnection.getMetaData().getProviderVersion();
326                 }
327                 catch (JMSException JavaDoc e) {
328                     throw new ResourceException JavaDoc("Error accessing provider.", e);
329                 }
330             }
331
332             public int getMaxConnections() throws ResourceException JavaDoc {
333                 if (physicalConnection == null) {
334                     throw new ResourceException JavaDoc("Not connected.");
335                 }
336                 return Integer.MAX_VALUE;
337             }
338
339             public String JavaDoc getUserName() throws ResourceException JavaDoc {
340                 if (physicalConnection == null) {
341                     throw new ResourceException JavaDoc("Not connected.");
342                 }
343                 try {
344                     return physicalConnection.getClientID();
345                 }
346                 catch (JMSException JavaDoc e) {
347                     throw new ResourceException JavaDoc("Error accessing provider.", e);
348                 }
349             }
350         };
351     }
352
353     /**
354      * @see javax.resource.spi.ManagedConnection#setLogWriter(java.io.PrintWriter)
355      */

356     public void setLogWriter(PrintWriter JavaDoc logWriter) throws ResourceException JavaDoc {
357         this.logWriter = logWriter;
358     }
359
360     /**
361      * @see javax.resource.spi.ManagedConnection#getLogWriter()
362      */

363     public PrintWriter JavaDoc getLogWriter() throws ResourceException JavaDoc {
364         return logWriter;
365     }
366
367     /**
368      * @param subject
369      * @param info
370      * @return
371      */

372     public boolean matches(Subject JavaDoc subject, ConnectionRequestInfo JavaDoc info) {
373
374         // Check to see if it is our info class
375
if (info == null) {
376             return false;
377         }
378         if (info.getClass() != ActiveMQConnectionRequestInfo.class) {
379             return false;
380         }
381
382         // Do the subjects match?
383
if (subject == null ^ this.subject == null) {
384             return false;
385         }
386         if (subject != null && !subject.equals(this.subject)) {
387             return false;
388         }
389
390         // Does the info match?
391
return info.equals(this.info);
392     }
393
394     /**
395      * When a proxy is closed this cleans up the proxy and notifys the
396      * ConnectionEventListeners that a connection closed.
397      *
398      * @param proxy
399      */

400     public void proxyClosedEvent(ManagedConnectionProxy proxy) {
401         proxyConnections.remove(proxy);
402         proxy.cleanup();
403         fireCloseEvent(proxy);
404     }
405
406     public void onException(JMSException JavaDoc e) {
407         log.warn("Connection failed: "+e);
408         log.debug("Cause: ", e);
409         
410         // Let any active proxy connections know that exception occured.
411
for (Iterator JavaDoc iter = proxyConnections.iterator(); iter.hasNext();) {
412             ManagedConnectionProxy proxy = (ManagedConnectionProxy) iter.next();
413             proxy.onException(e);
414         }
415         // Let the container know that the error occured.
416
fireErrorOccurredEvent(e);
417     }
418
419     /**
420      * @return Returns the transactionContext.
421      */

422     public TransactionContext getTransactionContext() {
423         return transactionContext;
424     }
425
426 }
427
Popular Tags