KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > resource > connectionmanager > BaseConnectionManager2


1 /*
2  * JBoss, Home of Professional Open Source
3  * Copyright 2005, JBoss Inc., and individual contributors as indicated
4  * by the @authors tag. See the copyright.txt in the distribution for a
5  * full listing of individual contributors.
6  *
7  * This is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * This software is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this software; if not, write to the Free
19  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21  */

22 package org.jboss.resource.connectionmanager;
23
24 import java.io.PrintWriter JavaDoc;
25 import java.io.Serializable JavaDoc;
26 import java.security.Principal JavaDoc;
27 import java.security.PrivilegedAction JavaDoc;
28 import java.security.AccessController JavaDoc;
29 import java.util.Collection JavaDoc;
30 import java.util.HashMap JavaDoc;
31 import java.util.HashSet JavaDoc;
32 import java.util.Iterator JavaDoc;
33 import java.util.LinkedList JavaDoc;
34 import java.util.List JavaDoc;
35 import java.util.Map JavaDoc;
36 import java.util.Set JavaDoc;
37
38 import javax.management.MBeanNotificationInfo JavaDoc;
39 import javax.management.MBeanServer JavaDoc;
40 import javax.management.Notification JavaDoc;
41 import javax.management.ObjectName JavaDoc;
42 import javax.naming.InitialContext JavaDoc;
43 import javax.resource.ResourceException JavaDoc;
44 import javax.resource.spi.ConnectionEvent JavaDoc;
45 import javax.resource.spi.ConnectionManager JavaDoc;
46 import javax.resource.spi.ConnectionRequestInfo JavaDoc;
47 import javax.resource.spi.ManagedConnection JavaDoc;
48 import javax.resource.spi.ManagedConnectionFactory JavaDoc;
49 import javax.security.auth.Subject JavaDoc;
50 import javax.transaction.RollbackException JavaDoc;
51 import javax.transaction.SystemException JavaDoc;
52 import javax.transaction.Transaction JavaDoc;
53 import javax.transaction.TransactionManager JavaDoc;
54
55 import org.jboss.deployment.DeploymentException;
56 import org.jboss.logging.Logger;
57 import org.jboss.logging.util.LoggerPluginWriter;
58 import org.jboss.mx.util.JMXExceptionDecoder;
59 import org.jboss.mx.util.MBeanServerLocator;
60 import org.jboss.resource.JBossResourceException;
61 import org.jboss.resource.connectionmanager.JBossManagedConnectionPool.BasePool;
62 import org.jboss.security.SecurityAssociation;
63 import org.jboss.security.SubjectSecurityManager;
64 import org.jboss.system.ServiceMBeanSupport;
65 import org.jboss.tm.TransactionTimeoutConfiguration;
66 import org.jboss.util.NestedRuntimeException;
67 import org.jboss.util.NotImplementedException;
68
69 /**
70  * The BaseConnectionManager2 is an abstract base class for JBoss ConnectionManager
71  * implementations. It includes functionality to obtain managed connections from
72  * a ManagedConnectionPool mbean, find the Subject from a SubjectSecurityDomain,
73  * and interact with the CachedConnectionManager for connections held over
74  * transaction and method boundaries. Important mbean references are to a
75  * ManagedConnectionPool supplier (typically a JBossManagedConnectionPool), and a
76  * RARDeployment representing the ManagedConnectionFactory.
77  *
78  *
79  * @author <a HREF="mailto:d_jencks@users.sourceforge.net">David Jencks</a>
80  * @author <a HREF="mailto:E.Guib@ceyoniq.com">Erwin Guib</a>
81  * @author <a HREF="mailto:adrian@jboss.org">Adrian Brock</a>
82  * @author <a HREF="mailto:weston.price@jboss.com">Weston Price</a>
83  * @version $Revision: 45525 $
84  */

85 public abstract class BaseConnectionManager2 extends ServiceMBeanSupport
86       implements
87          BaseConnectionManager2MBean,
88          ConnectionCacheListener,
89          ConnectionListenerFactory,
90          TransactionTimeoutConfiguration
91 {
92    /**
93     * Note that this copy has a trailing / unlike the original in
94     * JaasSecurityManagerService.
95     */

96    private static final String JavaDoc SECURITY_MGR_PATH = "java:/jaas/";
97
98    /** The STOPPING_NOTIFICATION */
99    public static final String JavaDoc STOPPING_NOTIFICATION = "jboss.jca.connectionmanagerstopping";
100
101    /** The managedConnectionPoolName */
102    protected ObjectName JavaDoc managedConnectionPoolName;
103
104    protected ManagedConnectionPool poolingStrategy;
105
106    protected String JavaDoc jndiName;
107
108    protected String JavaDoc securityDomainJndiName;
109
110    protected SubjectSecurityManager securityDomain;
111
112    protected ObjectName JavaDoc jaasSecurityManagerService;
113
114    protected ObjectName JavaDoc ccmName;
115
116    protected CachedConnectionManager ccm;
117
118    protected boolean trace;
119
120    /**
121     * Rethrow a throwable as resource exception
122     *
123     * @deprecated use JBossResourceException.rethrowAsResourceException
124     */

125    protected static void rethrowAsResourceException(String JavaDoc message, Throwable JavaDoc t) throws ResourceException JavaDoc
126    {
127       JBossResourceException.rethrowAsResourceException(message, t);
128    }
129
130    /**
131     * Default BaseConnectionManager2 managed constructor for use by subclass mbeans.
132     */

133    public BaseConnectionManager2()
134    {
135       super();
136       trace = log.isTraceEnabled();
137    }
138
139    /**
140     * Creates a new <code>BaseConnectionManager2</code> instance.
141     * for TESTING ONLY! not a managed operation.
142     * @param ccm a <code>CachedConnectionManager</code> value
143     * @param poolingStrategy a <code>ManagedConnectionPool</code> value
144     */

145    public BaseConnectionManager2(CachedConnectionManager ccm, ManagedConnectionPool poolingStrategy)
146    {
147       super();
148       this.ccm = ccm;
149       this.poolingStrategy = poolingStrategy;
150       trace = log.isTraceEnabled();
151    }
152
153    /**
154     * For testing
155     */

156    public ManagedConnectionPool getPoolingStrategy()
157    {
158       return poolingStrategy;
159    }
160
161    public String JavaDoc getJndiName()
162    {
163       return jndiName;
164    }
165
166    public void setJndiName(String JavaDoc jndiName)
167    {
168       this.jndiName = jndiName;
169    }
170
171    public ObjectName JavaDoc getManagedConnectionPool()
172    {
173       return managedConnectionPoolName;
174    }
175
176    public void setManagedConnectionPool(ObjectName JavaDoc newManagedConnectionPool)
177    {
178       this.managedConnectionPoolName = newManagedConnectionPool;
179    }
180
181    public void setCachedConnectionManager(ObjectName JavaDoc ccmName)
182    {
183       this.ccmName = ccmName;
184    }
185
186    public ObjectName JavaDoc getCachedConnectionManager()
187    {
188       return ccmName;
189    }
190
191    public void setSecurityDomainJndiName(String JavaDoc securityDomainJndiName)
192    {
193       if (securityDomainJndiName != null && securityDomainJndiName.startsWith(SECURITY_MGR_PATH))
194       {
195          securityDomainJndiName = securityDomainJndiName.substring(SECURITY_MGR_PATH.length());
196          log.warn("WARNING: UPDATE YOUR SecurityDomainJndiName! REMOVE " + SECURITY_MGR_PATH);
197       }
198       this.securityDomainJndiName = securityDomainJndiName;
199    }
200
201    public String JavaDoc getSecurityDomainJndiName()
202    {
203       return securityDomainJndiName;
204    }
205
206    public ObjectName JavaDoc getJaasSecurityManagerService()
207    {
208       return jaasSecurityManagerService;
209    }
210
211    public void setJaasSecurityManagerService(final ObjectName JavaDoc jaasSecurityManagerService)
212    {
213       this.jaasSecurityManagerService = jaasSecurityManagerService;
214    }
215
216    public ManagedConnectionFactory JavaDoc getManagedConnectionFactory()
217    {
218       return poolingStrategy.getManagedConnectionFactory();
219    }
220
221    public BaseConnectionManager2 getInstance()
222    {
223       return this;
224    }
225
226    public long getTimeLeftBeforeTransactionTimeout(boolean errorRollback) throws RollbackException JavaDoc
227    {
228       return -1;
229    }
230
231    public int getTransactionTimeout() throws SystemException JavaDoc
232    {
233       throw new NotImplementedException("NYI: getTransactionTimeout()");
234    }
235
236    //ServiceMBeanSupport
237

238    protected void startService() throws Exception JavaDoc
239    {
240       try
241       {
242          ccm = (CachedConnectionManager) server.getAttribute(ccmName, "Instance");
243       }
244       catch (Exception JavaDoc e)
245       {
246          JMXExceptionDecoder.rethrow(e);
247       }
248
249       if (ccm == null)
250          throw new DeploymentException("cached ConnectionManager not found: " + ccmName);
251
252       if (securityDomainJndiName != null && jaasSecurityManagerService == null)
253          throw new DeploymentException("You must supply both securityDomainJndiName and jaasSecurityManagerService to use container managed security");
254
255       if (securityDomainJndiName != null)
256          securityDomain = (SubjectSecurityManager) new InitialContext JavaDoc().lookup(SECURITY_MGR_PATH
257                + securityDomainJndiName);
258
259       if (managedConnectionPoolName == null)
260          throw new DeploymentException("managedConnectionPool not set!");
261       try
262       {
263          poolingStrategy = (ManagedConnectionPool) server.getAttribute(managedConnectionPoolName,
264                "ManagedConnectionPool");
265       }
266       catch (Exception JavaDoc e)
267       {
268          JMXExceptionDecoder.rethrow(e);
269       }
270
271       poolingStrategy.setConnectionListenerFactory(this);
272
273       // Give it somewhere to tell people things
274
String JavaDoc categoryName = poolingStrategy.getManagedConnectionFactory().getClass().getName() + "." + jndiName;
275       Logger log = Logger.getLogger(categoryName);
276       PrintWriter JavaDoc logWriter = new LoggerPluginWriter(log.getLoggerPlugin());
277       try
278       {
279          poolingStrategy.getManagedConnectionFactory().setLogWriter(logWriter);
280       }
281       catch (ResourceException JavaDoc re)
282       {
283          log.warn("Unable to set log writer '" + logWriter + "' on " + "managed connection factory", re);
284          log.warn("Linked exception:", re.getLinkedException());
285       }
286       if (poolingStrategy instanceof PreFillPoolSupport)
287       {
288                   
289          PreFillPoolSupport prefill = (PreFillPoolSupport) poolingStrategy;
290          
291          if(prefill.shouldPreFill()){
292
293             prefill.prefill();
294             
295          }
296          
297       }
298       
299    }
300
301    protected void stopService() throws Exception JavaDoc
302    {
303       //notify the login modules the mcf is going away, they need to look it up again later.
304
sendNotification(new Notification JavaDoc(STOPPING_NOTIFICATION, getServiceName(), getNextNotificationSequenceNumber()));
305       if (jaasSecurityManagerService != null && securityDomainJndiName != null)
306          server.invoke(jaasSecurityManagerService, "flushAuthenticationCache", new Object JavaDoc[] { securityDomainJndiName }, new String JavaDoc[] { String JavaDoc.class.getName() });
307
308       poolingStrategy.setConnectionListenerFactory(null);
309
310       poolingStrategy = null;
311       securityDomain = null;
312       ccm = null;
313    }
314
315    /**
316     * Public for use in testing pooling functionality by itself.
317     * called by both allocateConnection and reconnect.
318     *
319     * @param subject a <code>Subject</code> value
320     * @param cri a <code>ConnectionRequestInfo</code> value
321     * @return a <code>ManagedConnection</code> value
322     * @exception ResourceException if an error occurs
323     */

324    public ConnectionListener getManagedConnection(Subject JavaDoc subject, ConnectionRequestInfo JavaDoc cri) throws ResourceException JavaDoc
325    {
326       return getManagedConnection(null, subject, cri);
327    }
328
329    /**
330     * Get the managed connection from the pool
331     *
332     * @param transaction the transaction for track by transaction
333     * @param subject the subject
334     * @param cri the ConnectionRequestInfo
335     * @return a managed connection
336     * @exception ResourceException if an error occurs
337     */

338    protected ConnectionListener getManagedConnection(Transaction JavaDoc transaction, Subject JavaDoc subject, ConnectionRequestInfo JavaDoc cri)
339          throws ResourceException JavaDoc
340    {
341       return poolingStrategy.getConnection(transaction, subject, cri);
342    }
343    
344    public void returnManagedConnection(ConnectionListener cl, boolean kill)
345    {
346       ManagedConnectionPool localStrategy = cl.getManagedConnectionPool();
347       if (localStrategy != poolingStrategy)
348          kill = true;
349
350       try
351       {
352          if (kill == false && cl.getState() == ConnectionListener.NORMAL)
353             cl.tidyup();
354       }
355       catch (Throwable JavaDoc t)
356       {
357          log.warn("Error during tidyup " + cl, t);
358          kill = true;
359       }
360       
361       try
362       {
363          localStrategy.returnConnection(cl, kill);
364       }
365       catch (ResourceException JavaDoc re)
366       {
367          // We can receive notification of an error on the connection
368
// before it has been assigned to the pool. Reduce the noise for
369
// these errors
370
if (kill)
371             log.debug("resourceException killing connection (error retrieving from pool?)", re);
372          else
373             log.warn("resourceException returning connection: " + cl.getManagedConnection(), re);
374       }
375    }
376
377    public int getConnectionCount()
378    {
379       return poolingStrategy.getConnectionCount();
380    }
381
382    public Object JavaDoc allocateConnection(ManagedConnectionFactory JavaDoc mcf, ConnectionRequestInfo JavaDoc cri) throws ResourceException JavaDoc
383    {
384       if (poolingStrategy == null)
385          throw new ResourceException JavaDoc(
386                "You are trying to use a connection factory that has been shut down: ManagedConnectionFactory is null.");
387
388       //it is an explicit spec requirement that equals be used for matching rather than ==.
389
if (!poolingStrategy.getManagedConnectionFactory().equals(mcf))
390          throw new ResourceException JavaDoc("Wrong ManagedConnectionFactory sent to allocateConnection!");
391
392       // Pick a managed connection from the pool
393
Subject JavaDoc subject = getSubject();
394       ConnectionListener cl = getManagedConnection(subject, cri);
395
396       // Tell each connection manager the managed connection is active
397
reconnectManagedConnection(cl);
398
399       // Ask the managed connection for a connection
400
Object JavaDoc connection = null;
401       try
402       {
403          connection = cl.getManagedConnection().getConnection(subject, cri);
404       }
405       catch (Throwable JavaDoc t)
406       {
407          managedConnectionDisconnected(cl);
408          JBossResourceException.rethrowAsResourceException(
409                "Unchecked throwable in ManagedConnection.getConnection() cl=" + cl, t);
410       }
411
412       // Associate managed connection with the connection
413
registerAssociation(cl, connection);
414       if (ccm != null)
415          ccm.registerConnection(this, cl, connection, cri);
416       return connection;
417    }
418
419    // ConnectionCacheListener implementation
420

421    public void transactionStarted(Collection JavaDoc conns) throws SystemException JavaDoc
422    {
423       //reimplement in subclasses
424
}
425
426    public void reconnect(Collection JavaDoc conns, Set JavaDoc unsharableResources) throws ResourceException JavaDoc
427    {
428       // if we have an unshareable connection the association was not removed
429
// nothing to do
430
if (unsharableResources.contains(jndiName))
431       {
432          log.trace("reconnect for unshareable connection: nothing to do");
433          return;
434       }
435
436       Map JavaDoc criToCLMap = new HashMap JavaDoc();
437       for (Iterator JavaDoc i = conns.iterator(); i.hasNext();)
438       {
439          ConnectionRecord cr = (ConnectionRecord) i.next();
440          if (cr.cl != null)
441          {
442             //This might well be an error.
443
log.warn("reconnecting a connection handle that still has a managedConnection! "
444                   + cr.cl.getManagedConnection() + " " + cr.connection);
445          }
446          ConnectionListener cl = (ConnectionListener) criToCLMap.get(cr.cri);
447          if (cl == null)
448          {
449             cl = getManagedConnection(getSubject(), cr.cri);
450             criToCLMap.put(cr.cri, cl);
451             //only call once per managed connection, when we get it.
452
reconnectManagedConnection(cl);
453          }
454
455          cl.getManagedConnection().associateConnection(cr.connection);
456          registerAssociation(cl, cr.connection);
457          cr.setConnectionListener(cl);
458       }
459       criToCLMap.clear();//not needed logically, might help the gc.
460
}
461
462    public void disconnect(Collection JavaDoc crs, Set JavaDoc unsharableResources) throws ResourceException JavaDoc
463    {
464       // if we have an unshareable connection do not remove the association
465
// nothing to do
466
if (unsharableResources.contains(jndiName))
467       {
468          log.trace("disconnect for unshareable connection: nothing to do");
469          return;
470       }
471
472       Set JavaDoc cls = new HashSet JavaDoc();
473       for (Iterator JavaDoc i = crs.iterator(); i.hasNext();)
474       {
475          ConnectionRecord cr = (ConnectionRecord) i.next();
476          ConnectionListener cl = cr.cl;
477          cr.setConnectionListener(null);
478          unregisterAssociation(cl, cr.connection);
479          if (!cls.contains(cl))
480          {
481             cls.add(cl);
482          }
483       }
484       for (Iterator JavaDoc i = cls.iterator(); i.hasNext();)
485          disconnectManagedConnection((ConnectionListener) i.next());
486    }
487
488    // implementation of javax.management.NotificationBroadcaster interface
489

490    public MBeanNotificationInfo JavaDoc[] getNotificationInfo()
491    {
492       // TODO: implement this javax.management.NotificationBroadcaster method
493
return super.getNotificationInfo();
494    }
495
496    //protected methods
497

498    //does NOT put the mc back in the pool if no more handles. Doing so would introduce a race condition
499
//whereby the mc got back in the pool while still enlisted in the tx.
500
//The mc could be checked out again and used before the delist occured.
501
protected void unregisterAssociation(ConnectionListener cl, Object JavaDoc c) throws ResourceException JavaDoc
502    {
503       cl.unregisterConnection(c);
504    }
505
506    /**
507     * Invoked to reassociate a managed connection
508     *
509     * @param cl the managed connection
510     */

511    protected void reconnectManagedConnection(ConnectionListener cl) throws ResourceException JavaDoc
512    {
513       try
514       {
515          //WRONG METHOD NAME!!
516
managedConnectionReconnected(cl);
517       }
518       catch (Throwable JavaDoc t)
519       {
520          disconnectManagedConnection(cl);
521          JBossResourceException.rethrowAsResourceException("Unchecked throwable in managedConnectionReconnected() cl="
522                + cl, t);
523       }
524    }
525
526    /**
527     * Invoked when a managed connection is no longer associated
528     *
529     * @param cl the managed connection
530     */

531    protected void disconnectManagedConnection(ConnectionListener cl)
532    {
533       try
534       {
535          managedConnectionDisconnected(cl);
536       }
537       catch (Throwable JavaDoc t)
538       {
539          log.warn("Unchecked throwable in managedConnectionDisconnected() cl=" + cl, t);
540       }
541    }
542
543    protected final CachedConnectionManager getCcm()
544    {
545       return ccm;
546    }
547
548    /**
549     * For polymorphism.<p>
550     *
551     * Do not invoke directly use reconnectManagedConnection
552     * which does the relevent exception handling
553     */

554    protected void managedConnectionReconnected(ConnectionListener cl) throws ResourceException JavaDoc
555    {
556    }
557
558    /**
559     * For polymorphism.<p>
560     *
561     * Do not invoke directly use disconnectManagedConnection
562     * which does the relevent exception handling
563     */

564    protected void managedConnectionDisconnected(ConnectionListener cl) throws ResourceException JavaDoc
565    {
566    }
567
568    private void registerAssociation(ConnectionListener cl, Object JavaDoc c) throws ResourceException JavaDoc
569    {
570       cl.registerConnection(c);
571    }
572
573    private Subject JavaDoc getSubject()
574    {
575       Subject JavaDoc subject = null;
576       if (securityDomain != null)
577       {
578          /* Authenticate using the caller info and obtain a copy of the Subject
579           state for use in establishing a secure connection. A copy must be
580           obtained to avoid problems with multiple threads associated with
581           the same principal changing the state of the resulting Subject.
582           */

583          Principal JavaDoc principal = GetPrincipalAction.getPrincipal();
584          Object JavaDoc credential = GetCredentialAction.getCredential();
585          subject = new Subject JavaDoc();
586          if (securityDomain.isValid(principal, credential, subject) == false)
587             throw new SecurityException JavaDoc("Invalid authentication attempt, principal=" + principal);
588       }
589       if (trace)
590          log.trace("subject: " + subject);
591       return subject;
592    }
593
594    // ConnectionListenerFactory
595

596    public boolean isTransactional()
597    {
598       return false;
599    }
600
601    public TransactionManager JavaDoc getTransactionManagerInstance()
602    {
603       return null;
604    }
605
606    //ConnectionListener
607

608    protected abstract class BaseConnectionEventListener implements ConnectionListener
609    {
610       private final ManagedConnection JavaDoc mc;
611
612       private final ManagedConnectionPool mcp;
613
614       private final Object JavaDoc context;
615
616       private int state = NORMAL;
617
618       private final List JavaDoc handles = new LinkedList JavaDoc();
619
620       private long lastUse;
621
622       private boolean trackByTx = false;
623
624       private boolean permit = false;
625
626       protected Logger log;
627
628       protected boolean trace;
629
630       protected long lastValidated;
631
632       protected BaseConnectionEventListener(ManagedConnection JavaDoc mc, ManagedConnectionPool mcp, Object JavaDoc context, Logger log)
633       {
634          this.mc = mc;
635          this.mcp = mcp;
636          this.context = context;
637          this.log = log;
638          trace = log.isTraceEnabled();
639          lastUse = System.currentTimeMillis();
640       }
641
642       public ManagedConnection JavaDoc getManagedConnection()
643       {
644          return mc;
645       }
646
647       public ManagedConnectionPool getManagedConnectionPool()
648       {
649          return mcp;
650       }
651
652       public Object JavaDoc getContext()
653       {
654          return context;
655       }
656
657       public int getState()
658       {
659          return state;
660       }
661
662       public void setState(int newState)
663       {
664          this.state = newState;
665       }
666
667       public boolean isTimedOut(long timeout)
668       {
669          return lastUse < timeout;
670       }
671
672       public void used()
673       {
674          lastUse = System.currentTimeMillis();
675       }
676
677       public boolean isTrackByTx()
678       {
679          return trackByTx;
680       }
681
682       public void setTrackByTx(boolean trackByTx)
683       {
684          this.trackByTx = trackByTx;
685       }
686
687       public void tidyup() throws ResourceException JavaDoc
688       {
689       }
690
691       public synchronized void registerConnection(Object JavaDoc handle)
692       {
693          handles.add(handle);
694       }
695
696       public synchronized void unregisterConnection(Object JavaDoc handle)
697       {
698          if (!handles.remove(handle))
699          {
700             log.info("Unregistered handle that was not registered! " + handle + " for managedConnection: " + mc);
701          }
702          if (trace)
703             log.trace("unregisterConnection: " + handles.size() + " handles left");
704       }
705
706       public synchronized boolean isManagedConnectionFree()
707       {
708          return handles.isEmpty();
709       }
710
711       protected synchronized void unregisterConnections()
712       {
713          try
714          {
715             for (Iterator JavaDoc i = handles.iterator(); i.hasNext();)
716             {
717                getCcm().unregisterConnection(BaseConnectionManager2.this, i.next());
718             }
719          }
720          finally
721          {
722             handles.clear();
723          }
724       }
725
726       public void connectionErrorOccurred(ConnectionEvent JavaDoc ce)
727       {
728          if (state == NORMAL)
729          {
730             if (ce != null)
731             {
732                Throwable JavaDoc t = ce.getException();
733                if (t == null)
734                   t = new Exception JavaDoc("No exception was reported");
735                log.warn("Connection error occured: " + this, t);
736             }
737             else
738             {
739                Throwable JavaDoc t = new Exception JavaDoc("No exception was reported");
740                log.warn("Unknown Connection error occured: " + this, t);
741             }
742          }
743          try
744          {
745             unregisterConnections();
746          }
747          catch (Throwable JavaDoc t)
748          {
749             //ignore, it wasn't checked out.
750
}
751          if (ce != null && ce.getSource() != getManagedConnection())
752             log.warn("Notified of error on a different managed connection?");
753          returnManagedConnection(this, true);
754       }
755
756       public void enlist() throws SystemException JavaDoc
757       {
758       }
759
760       public void delist() throws ResourceException JavaDoc
761       {
762       }
763
764       public boolean hasPermit()
765       {
766          return permit;
767       }
768
769       public void grantPermit(boolean value)
770       {
771          this.permit = value;
772       }
773
774       public long getLastValidatedTime()
775       {
776          return this.lastValidated;
777       }
778       
779       public void setLastValidatedTime(long lastValidated)
780       {
781          this.lastValidated = lastValidated;
782       }
783       // For debugging
784
public String JavaDoc toString()
785       {
786          StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(100);
787          buffer.append(getClass().getName()).append('@').append(Integer.toHexString(System.identityHashCode(this)));
788          buffer.append("[state=");
789          if (state == ConnectionListener.NORMAL)
790             buffer.append("NORMAL");
791          else if (state == ConnectionListener.DESTROY)
792             buffer.append("DESTROY");
793          else if (state == ConnectionListener.DESTROYED)
794             buffer.append("DESTROYED");
795          else
796             buffer.append("UNKNOWN?");
797          buffer.append(" mc=").append(mc);
798          buffer.append(" handles=").append(handles.size());
799          buffer.append(" lastUse=").append(lastUse);
800          buffer.append(" permit=").append(permit);
801          buffer.append(" trackByTx=").append(trackByTx);
802          buffer.append(" mcp=").append(mcp);
803          buffer.append(" context=").append(context);
804          toString(buffer);
805          buffer.append(']');
806          return buffer.toString();
807       }
808
809       // For debugging
810
protected void toString(StringBuffer JavaDoc buffer)
811       {
812       }
813    }
814
815    public static class ConnectionManagerProxy
816          implements
817             ConnectionManager JavaDoc,
818             Serializable JavaDoc,
819             TransactionTimeoutConfiguration
820    {
821       static final long serialVersionUID = -528322728929261214L;
822
823       private transient BaseConnectionManager2 realCm;
824
825       private final ObjectName JavaDoc cmName;
826
827       ConnectionManagerProxy(final BaseConnectionManager2 realCm, final ObjectName JavaDoc cmName)
828       {
829          this.realCm = realCm;
830          this.cmName = cmName;
831       }
832
833       // implementation of javax.resource.spi.ConnectionManager interface
834

835       public Object JavaDoc allocateConnection(ManagedConnectionFactory JavaDoc mcf, ConnectionRequestInfo JavaDoc cri)
836             throws ResourceException JavaDoc
837       {
838          return getCM().allocateConnection(mcf, cri);
839       }
840
841       public long getTimeLeftBeforeTransactionTimeout(boolean errorRollback) throws RollbackException JavaDoc
842       {
843          try
844          {
845             return getCM().getTimeLeftBeforeTransactionTimeout(errorRollback);
846          }
847          catch (ResourceException JavaDoc e)
848          {
849             throw new NestedRuntimeException("Unable to retrieve connection manager", e);
850          }
851       }
852
853       public int getTransactionTimeout() throws SystemException JavaDoc
854       {
855          try
856          {
857             return getCM().getTransactionTimeout();
858          }
859          catch (ResourceException JavaDoc e)
860          {
861             throw new NestedRuntimeException("Unable to retrieve connection manager", e);
862          }
863       }
864
865       private BaseConnectionManager2 getCM() throws ResourceException JavaDoc
866       {
867          if (realCm == null)
868          {
869             try
870             {
871                MBeanServer JavaDoc server = MBeanServerLocator.locateJBoss();
872                realCm = (BaseConnectionManager2) server.getAttribute(cmName, "Instance");
873             }
874             catch (Throwable JavaDoc t)
875             {
876                Throwable JavaDoc t2 = JMXExceptionDecoder.decode(t);
877                JBossResourceException.rethrowAsResourceException("Problem locating real ConnectionManager: " + cmName,
878                      t2);
879             }
880          }
881          return realCm;
882       }
883    }
884
885    private static class GetPrincipalAction implements PrivilegedAction JavaDoc
886    {
887       static PrivilegedAction JavaDoc ACTION = new GetPrincipalAction();
888
889       public Object JavaDoc run()
890       {
891          Principal JavaDoc principal = SecurityAssociation.getPrincipal();
892          return principal;
893       }
894
895       static Principal JavaDoc getPrincipal()
896       {
897          Principal JavaDoc principal = (Principal JavaDoc) AccessController.doPrivileged(ACTION);
898          return principal;
899       }
900    }
901
902    private static class GetCredentialAction implements PrivilegedAction JavaDoc
903    {
904       static PrivilegedAction JavaDoc ACTION = new GetCredentialAction();
905
906       public Object JavaDoc run()
907       {
908          Object JavaDoc credential = SecurityAssociation.getCredential();
909          return credential;
910       }
911
912       static Object JavaDoc getCredential()
913       {
914          Object JavaDoc credential = AccessController.doPrivileged(ACTION);
915          return credential;
916       }
917    }
918 }
919
Popular Tags