KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > connector > ConnectorTransactionContext


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

17 package org.apache.geronimo.connector;
18
19 import java.util.Map JavaDoc;
20 import java.util.HashMap JavaDoc;
21 import java.util.Iterator JavaDoc;
22
23 import javax.transaction.Transaction JavaDoc;
24 import javax.transaction.Synchronization JavaDoc;
25 import javax.transaction.RollbackException JavaDoc;
26 import javax.transaction.SystemException JavaDoc;
27 import javax.transaction.Status JavaDoc;
28
29 import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
30 import org.apache.geronimo.connector.outbound.TransactionCachingInterceptor;
31
32 /**
33  * @version $Rev: 476049 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $
34  */

35 public class ConnectorTransactionContext {
36     private static final ConcurrentHashMap DATA_INDEX = new ConcurrentHashMap();
37
38     public static ConnectorTransactionContext get(Transaction JavaDoc transaction) {
39         if (transaction == null) {
40             throw new NullPointerException JavaDoc("transaction is null");
41         }
42
43         ConnectorTransactionContext ctx = (ConnectorTransactionContext) DATA_INDEX.get(transaction);
44         if (ctx == null) {
45             ctx = new ConnectorTransactionContext();
46
47             try {
48                 if (transaction.getStatus() == Status.STATUS_ACTIVE) {
49                     transaction.registerSynchronization(new ConnectorSynchronization(ctx, transaction));
50                     // Note: no synchronization is necessary here. Since a transaction can only be associated with a single
51
// thread at a time, it should not be possible for someone else to have snuck in and created a
52
// ConnectorTransactionContext for this transaction. We still protect against that with the putIfAbsent
53
// call below, and we simply have an extra transaction synchronization registered that won't do anything
54
DATA_INDEX.putIfAbsent(transaction, ctx);
55                 }
56             } catch (RollbackException JavaDoc e) {
57                 throw (IllegalStateException JavaDoc) new IllegalStateException JavaDoc("Transaction is already rolled back").initCause(e);
58             } catch (SystemException JavaDoc e) {
59                 throw new RuntimeException JavaDoc("Unable to register ejb transaction synchronization callback", e);
60             }
61
62         }
63         return ctx;
64     }
65
66     public static TransactionCachingInterceptor.ManagedConnectionInfos get(Transaction JavaDoc transaction, ConnectionReleaser key) {
67         ConnectorTransactionContext ctx = get(transaction);
68         TransactionCachingInterceptor.ManagedConnectionInfos infos = ctx.getManagedConnectionInfo(key);
69         if (infos == null) {
70             infos = new TransactionCachingInterceptor.ManagedConnectionInfos();
71             ctx.setManagedConnectionInfo(key, infos);
72         }
73         return infos;
74     }
75
76     private static void remove(Transaction JavaDoc transaction) {
77         DATA_INDEX.remove(transaction);
78     }
79
80     private Map JavaDoc managedConnections;
81
82     private synchronized TransactionCachingInterceptor.ManagedConnectionInfos getManagedConnectionInfo(ConnectionReleaser key) {
83         if (managedConnections == null) {
84             return null;
85         }
86         return (TransactionCachingInterceptor.ManagedConnectionInfos) managedConnections.get(key);
87     }
88
89     private synchronized void setManagedConnectionInfo(ConnectionReleaser key, TransactionCachingInterceptor.ManagedConnectionInfos info) {
90         if (managedConnections == null) {
91             managedConnections = new HashMap JavaDoc();
92         }
93         managedConnections.put(key, info);
94     }
95
96     private static class ConnectorSynchronization implements Synchronization JavaDoc {
97         private final ConnectorTransactionContext ctx;
98         private final Transaction JavaDoc transaction;
99
100         public ConnectorSynchronization(ConnectorTransactionContext ctx, Transaction JavaDoc transaction) {
101             this.ctx = ctx;
102             this.transaction = transaction;
103         }
104
105         public void beforeCompletion() {
106         }
107
108         public void afterCompletion(int status) {
109             try {
110                 synchronized (ctx) {
111                     if (ctx.managedConnections != null) {
112                         for (Iterator JavaDoc entries = ctx.managedConnections.entrySet().iterator(); entries.hasNext();) {
113                             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) entries.next();
114                             ConnectionReleaser key = (ConnectionReleaser) entry.getKey();
115                             key.afterCompletion(entry.getValue());
116                         }
117                         //If BeanTransactionContext never reuses the same instance for sequential BMT, this
118
//clearing is unnecessary.
119
ctx.managedConnections.clear();
120                     }
121                 }
122             } finally {
123                 remove(transaction);
124             }
125         }
126     }
127 }
128
Popular Tags