KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mr > ra > ManagedConnectionImpl


1 /*
2  * Copyright 2002 by
3  * <a HREF="http://www.coridan.com">Coridan</a>
4  * <a HREF="mailto: support@coridan.com ">support@coridan.com</a>
5  *
6  * The contents of this file are subject to the Mozilla Public License Version
7  * 1.1 (the "License"); you may not use this file except in compliance with the
8  * License. You may obtain a copy of the License at
9  * http://www.mozilla.org/MPL/
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the
14  * License.
15  *
16  * The Original Code is "MantaRay" (TM).
17  *
18  * The Initial Developer of the Original Code is Coridan.
19  * Portions created by the Initial Developer are Copyright (C) 2006
20  * Coridan Inc. All Rights Reserved.
21  *
22  * Contributor(s): all the names of the contributors are added in the source
23  * code where applicable.
24  *
25  * Alternatively, the contents of this file may be used under the terms of the
26  * LGPL license (the "GNU LESSER GENERAL PUBLIC LICENSE"), in which case the
27  * provisions of LGPL are applicable instead of those above. If you wish to
28  * allow use of your version of this file only under the terms of the LGPL
29  * License and not to allow others to use your version of this file under
30  * the MPL, indicate your decision by deleting the provisions above and
31  * replace them with the notice and other provisions required by the LGPL.
32  * If you do not delete the provisions above, a recipient may use your version
33  * of this file under either the MPL or the GNU LESSER GENERAL PUBLIC LICENSE.
34  
35  *
36  * This library is free software; you can redistribute it and/or modify it
37  * under the terms of the MPL as stated above or under the terms of the GNU
38  * Lesser General Public License as published by the Free Software Foundation;
39  * either version 2.1 of the License, or any later version.
40  *
41  * This library is distributed in the hope that it will be useful, but WITHOUT
42  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
43  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
44  * License for more details.
45  */

46
47 package org.mr.ra;
48
49 import java.io.PrintWriter JavaDoc;
50 import java.util.ArrayList JavaDoc;
51 import java.util.Iterator JavaDoc;
52
53 import javax.jms.Connection JavaDoc;
54 import javax.jms.ExceptionListener JavaDoc;
55 import javax.jms.JMSException JavaDoc;
56 import javax.resource.ResourceException JavaDoc;
57 import javax.resource.spi.ConnectionEvent JavaDoc;
58 import javax.resource.spi.ConnectionEventListener JavaDoc;
59 import javax.resource.spi.ConnectionRequestInfo JavaDoc;
60 import javax.resource.spi.LocalTransaction JavaDoc;
61 import javax.resource.spi.ManagedConnection JavaDoc;
62 import javax.resource.spi.ManagedConnectionMetaData JavaDoc;
63 import javax.security.auth.Subject JavaDoc;
64 import javax.transaction.xa.XAResource JavaDoc;
65
66 import org.apache.commons.logging.Log;
67 import org.apache.commons.logging.LogFactory;
68 import org.mr.api.jms.LocalTransactionEventListener;
69 import org.mr.api.jms.MantaConnection;
70 import org.mr.api.jms.TransactionContext;
71 //import org.activemq.LocalTransactionEventListener;
72
//import org.activemq.TransactionContext;
73

74 /**
75  * ActiveMQManagedConnection maps to real physical connection to the
76  * server. Since a ManagedConnection has to provide a transaction
77  * managment interface to the physical connection, and sessions
78  * are the objects implement transaction managment interfaces in
79  * the JMS API, this object also maps to a singe physical JMS session.
80  * <p/>
81  * The side-effect is that JMS connection the application gets
82  * will allways create the same session object. This is good if
83  * running in an app server since the sessions are elisted in the
84  * context transaction. This is bad if used outside of an app
85  * server since the user may be trying to create 2 different
86  * sessions to coordinate 2 different uow.
87  *
88  * @version $Revision: 1.1.1.1 $
89  */

90 public class ManagedConnectionImpl implements ManagedConnection JavaDoc, ExceptionListener JavaDoc { // TODO: , DissociatableManagedConnection {
91

92     private static final Log log = LogFactory.getLog(ManagedConnectionImpl.class);
93
94     private PrintWriter JavaDoc logWriter;
95
96     private final MantaConnection physicalConnection;
97     private final TransactionContext transactionContext;
98     private final ArrayList JavaDoc proxyConnections = new ArrayList JavaDoc();
99     private final ArrayList JavaDoc listeners = new ArrayList JavaDoc();
100     private final LocalAndXATransaction localAndXATransaction;
101     
102     private Subject JavaDoc subject;
103     private ConnectionRequestInfoImpl info;
104     private boolean destoryed;
105
106     public ManagedConnectionImpl(Subject JavaDoc subject,
107                                  MantaConnection physicalConnection,
108                                  ConnectionRequestInfoImpl info)
109                                                 throws ResourceException JavaDoc {
110         try {
111             this.subject = subject;
112             this.info = info;
113             this.physicalConnection = physicalConnection;
114             //this.transactionContext = new TransactionContext("ManagedConnection");
115
this.transactionContext = new TransactionContext();
116             
117             this.localAndXATransaction = new LocalAndXATransaction(transactionContext) {
118                 public void setInManagedTx(boolean inManagedTx) throws JMSException JavaDoc {
119                     super.setInManagedTx(inManagedTx);
120                     Iterator JavaDoc iterator = proxyConnections.iterator();
121                     while (iterator.hasNext()) {
122                         JMSConnectionProxy proxy = (JMSConnectionProxy) iterator.next();
123                         proxy.setUseSharedTxContext(inManagedTx);
124                     }
125                 }
126             };
127             
128             this.transactionContext.setLocalTransactionEventListener(new LocalTransactionEventListener() {
129                 public void beginEvent(String JavaDoc arg0) {
130                     fireBeginEvent();
131                 }
132                 public void commitEvent(String JavaDoc arg0) {
133                     fireCommitEvent();
134                 }
135                 public void rollbackEvent(String JavaDoc arg0) {
136                     fireRollbackEvent();
137                 }
138             });
139                         
140             physicalConnection.setExceptionListener(this);
141         } catch (JMSException JavaDoc e) {
142             throw new ResourceException JavaDoc("Could not create a new connection: "+e.getMessage(), e);
143         }
144     }
145     
146     public boolean isInManagedTx() {
147         return localAndXATransaction.isInManagedTx();
148     }
149     
150     // a utility method
151
private boolean matches(Object JavaDoc x, Object JavaDoc y) {
152         if (x == null ^ y == null) {
153             return false;
154         }
155         if (x != null && !x.equals(y)) {
156             return false;
157         }
158         return true;
159     }
160
161     /*public void associate(Subject subject, ConnectionRequestInfoImpl info) throws JMSException {
162
163         // Do we need to change the associated userid/password
164         if( !matches(info.getUserName(), this.info.getUserName()) || !matches(info.getPassword(), this.info.getPassword()) ) {
165             ((MantaConnection)physicalConnection).changeUserInfo(info.getUserName(), info.getPassword());
166         }
167         
168         // Do we need to set the clientId?
169         if( info.getClientid()!=null && info.getClientid().length()>0 )
170             physicalConnection.setClientID(info.getClientid());
171
172         this.subject = subject;
173         this.info = info;
174     }*/

175
176     public Connection JavaDoc getPhysicalConnection() {
177         return physicalConnection;
178     }
179     
180     
181
182     /**
183      * @see javax.resource.spi.ManagedConnection#getConnection(javax.security.auth.Subject,
184      * javax.resource.spi.ConnectionRequestInfo)
185      */

186     public Object JavaDoc getConnection(Subject JavaDoc subject, ConnectionRequestInfo JavaDoc info)
187             throws ResourceException JavaDoc {
188         JMSConnectionProxy proxy = new JMSConnectionProxy(this);
189         proxyConnections.add(proxy);
190         return proxy;
191     }
192
193     private boolean isDestroyed() {
194         return destoryed;
195     }
196     
197     /**
198      * Close down the physical connection to the server.
199      *
200      * @see javax.resource.spi.ManagedConnection#destroy()
201      */

202     public void destroy() throws ResourceException JavaDoc {
203         // Have we allready been destroyed??
204
if (isDestroyed()) {
205             return;
206         }
207
208         cleanup();
209
210         try {
211             physicalConnection.close();
212             destoryed = true;
213         } catch (JMSException JavaDoc e) {
214             log.info("Error occured during close of a JMS connection.", e);
215         }
216     }
217
218     /**
219      * Cleans up all proxy handles attached to this physical connection so that
220      * they cannot be used anymore.
221      *
222      * @see javax.resource.spi.ManagedConnection#cleanup()
223      */

224     public void cleanup() throws ResourceException JavaDoc {
225         // Have we allready been destroyed??
226
if (isDestroyed()) {
227             return;
228         }
229
230         Iterator JavaDoc iterator = proxyConnections.iterator();
231         while (iterator.hasNext()) {
232             JMSConnectionProxy proxy = (JMSConnectionProxy) iterator.next();
233             proxy.cleanup();
234         }
235         proxyConnections.clear();
236
237         try {
238             ((MantaConnection)physicalConnection).cleanup();
239         } catch (JMSException JavaDoc e) {
240             throw new ResourceException JavaDoc("Could cleanup the Manta connection: "+e, e);
241         }
242             
243     }
244
245     /**
246      * @see javax.resource.spi.ManagedConnection#associateConnection(java.lang.Object)
247      */

248     public void associateConnection(Object JavaDoc connection) throws ResourceException JavaDoc {
249         throw new ResourceException JavaDoc("No support for connection association");
250     }
251
252     /**
253      * @see javax.resource.spi.ManagedConnection#addConnectionEventListener(javax.resource.spi.ConnectionEventListener)
254      */

255     public void addConnectionEventListener(ConnectionEventListener JavaDoc listener) {
256         listeners.add(listener);
257     }
258
259     /**
260      * @see javax.resource.spi.ManagedConnection#removeConnectionEventListener(javax.resource.spi.ConnectionEventListener)
261      */

262     public void removeConnectionEventListener(ConnectionEventListener JavaDoc listener) {
263         listeners.remove(listener);
264     }
265
266     /**
267      * @see javax.resource.spi.ManagedConnection#getXAResource()
268      */

269     public XAResource JavaDoc getXAResource() throws ResourceException JavaDoc {
270         return localAndXATransaction;
271         //throw new ResourceException("Not supporting XA transactions.");
272
}
273
274     /**
275      * @see javax.resource.spi.ManagedConnection#getLocalTransaction()
276      */

277     public LocalTransaction JavaDoc getLocalTransaction() throws ResourceException JavaDoc {
278         return localAndXATransaction;
279         //throw new ResourceException("Not supporting Local transactions.");
280
}
281
282     /**
283      * @see javax.resource.spi.ManagedConnection#getMetaData()
284      */

285     public ManagedConnectionMetaData JavaDoc getMetaData() throws ResourceException JavaDoc {
286         return new ManagedConnectionMetaData JavaDoc() {
287
288             public String JavaDoc getEISProductName() throws ResourceException JavaDoc {
289                 if (physicalConnection == null) {
290                     throw new ResourceException JavaDoc("Not connected.");
291                 }
292                 try {
293                     return physicalConnection.getMetaData().getJMSProviderName();
294                 }
295                 catch (JMSException JavaDoc e) {
296                     throw new ResourceException JavaDoc("Error accessing provider.", e);
297                 }
298             }
299
300             public String JavaDoc getEISProductVersion() throws ResourceException JavaDoc {
301                 if (physicalConnection == null) {
302                     throw new ResourceException JavaDoc("Not connected.");
303                 }
304                 try {
305                     return physicalConnection.getMetaData().getProviderVersion();
306                 }
307                 catch (JMSException JavaDoc e) {
308                     throw new ResourceException JavaDoc("Error accessing provider.", e);
309                 }
310             }
311
312             public int getMaxConnections() throws ResourceException JavaDoc {
313                 if (physicalConnection == null) {
314                     throw new ResourceException JavaDoc("Not connected.");
315                 }
316                 return Integer.MAX_VALUE;
317             }
318
319             public String JavaDoc getUserName() throws ResourceException JavaDoc {
320                 if (physicalConnection == null) {
321                     throw new ResourceException JavaDoc("Not connected.");
322                 }
323                 try {
324                     return physicalConnection.getClientID();
325                 }
326                 catch (JMSException JavaDoc e) {
327                     throw new ResourceException JavaDoc("Error accessing provider.", e);
328                 }
329             }
330         };
331     }
332
333     /**
334      * @see javax.resource.spi.ManagedConnection#setLogWriter(java.io.PrintWriter)
335      */

336     public void setLogWriter(PrintWriter JavaDoc logWriter) throws ResourceException JavaDoc {
337         this.logWriter = logWriter;
338     }
339
340     /**
341      * @see javax.resource.spi.ManagedConnection#getLogWriter()
342      */

343     public PrintWriter JavaDoc getLogWriter() throws ResourceException JavaDoc {
344         return logWriter;
345     }
346
347     /**
348      * @param subject
349      * @param info
350      * @return
351      */

352     public boolean matches(Subject JavaDoc subject, ConnectionRequestInfo JavaDoc info) {
353         // Check to see if it is our info class
354
if (info == null) {
355             return false;
356         }
357         if (info.getClass() != ConnectionRequestInfoImpl.class) {
358             return false;
359         }
360
361         // Do the subjects match?
362
if (subject == null ^ this.subject == null) {
363             return false;
364         }
365         if (subject != null && !subject.equals(this.subject)) {
366             return false;
367         }
368
369         // Does the info match?
370
return info.equals(this.info);
371     }
372
373     /**
374      * When a proxy is closed this cleans up the proxy and notifys the
375      * ConnectionEventListeners that a connection closed.
376      *
377      * @param proxy
378      */

379     public void proxyClosedEvent(JMSConnectionProxy proxy) {
380         proxyConnections.remove(proxy);
381         proxy.cleanup();
382         fireCloseEvent(proxy);
383     }
384
385     public void onException(JMSException JavaDoc e) {
386         log.warn("Connection failed: "+e);
387         log.debug("Cause: ", e);
388         
389         // Let any active proxy connections know that exception occured.
390
for (Iterator JavaDoc iter = proxyConnections.iterator(); iter.hasNext();) {
391             JMSConnectionProxy proxy = (JMSConnectionProxy) iter.next();
392             proxy.onException(e);
393         }
394         // Let the container know that the error occured.
395
fireErrorOccurredEvent(e);
396     }
397
398     /**
399      * @return Returns the transactionContext.
400      */

401     TransactionContext getTransactionContext() {
402         return transactionContext;
403     }
404     
405     
406     
407     /////////////////////////////
408
//
409
// Firing Connection Events
410
//
411
/////////////////////////////
412

413     private void fireBeginEvent() {
414         ConnectionEvent JavaDoc event = new ConnectionEvent JavaDoc(ManagedConnectionImpl.this,
415                 ConnectionEvent.LOCAL_TRANSACTION_STARTED);
416         Iterator JavaDoc iterator = listeners.iterator();
417         while (iterator.hasNext()) {
418             ConnectionEventListener JavaDoc l = (ConnectionEventListener JavaDoc) iterator.next();
419             l.localTransactionStarted(event);
420         }
421     }
422
423     private void fireCommitEvent() {
424         ConnectionEvent JavaDoc event = new ConnectionEvent JavaDoc(ManagedConnectionImpl.this,
425                 ConnectionEvent.LOCAL_TRANSACTION_COMMITTED);
426         Iterator JavaDoc iterator = listeners.iterator();
427         while (iterator.hasNext()) {
428             ConnectionEventListener JavaDoc l = (ConnectionEventListener JavaDoc) iterator.next();
429             l.localTransactionCommitted(event);
430         }
431     }
432
433     private void fireRollbackEvent() {
434         ConnectionEvent JavaDoc event = new ConnectionEvent JavaDoc(ManagedConnectionImpl.this,
435                 ConnectionEvent.LOCAL_TRANSACTION_ROLLEDBACK);
436         Iterator JavaDoc iterator = listeners.iterator();
437         while (iterator.hasNext()) {
438             ConnectionEventListener JavaDoc l = (ConnectionEventListener JavaDoc) iterator.next();
439             l.localTransactionRolledback(event);
440         }
441     }
442
443     private void fireCloseEvent(JMSConnectionProxy proxy) {
444         ConnectionEvent JavaDoc event = new ConnectionEvent JavaDoc(ManagedConnectionImpl.this,
445                 ConnectionEvent.CONNECTION_CLOSED);
446         event.setConnectionHandle(proxy);
447         
448         Iterator JavaDoc iterator = listeners.iterator();
449         while (iterator.hasNext()) {
450             ConnectionEventListener JavaDoc l = (ConnectionEventListener JavaDoc) iterator.next();
451             l.connectionClosed(event);
452         }
453     }
454
455     private void fireErrorOccurredEvent(Exception JavaDoc error) {
456         ConnectionEvent JavaDoc event = new ConnectionEvent JavaDoc(ManagedConnectionImpl.this,
457                 ConnectionEvent.CONNECTION_ERROR_OCCURRED, error);
458         Iterator JavaDoc iterator = listeners.iterator();
459         while (iterator.hasNext()) {
460             ConnectionEventListener JavaDoc l = (ConnectionEventListener JavaDoc) iterator.next();
461             l.connectionErrorOccurred(event);
462         }
463     }
464
465 }
466
Popular Tags