1
16 package net.sf.ehcache.transaction.manager;
17
18 import java.util.ArrayList;
19 import java.util.HashSet;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.Properties;
23 import java.util.Set;
24 import java.util.concurrent.locks.Lock;
25 import java.util.concurrent.locks.ReentrantLock;
26
27 import javax.transaction.TransactionManager;
28
29 import net.sf.ehcache.CacheException;
30 import net.sf.ehcache.transaction.manager.selector.AtomikosSelector;
31 import net.sf.ehcache.transaction.manager.selector.BitronixSelector;
32 import net.sf.ehcache.transaction.manager.selector.GenericJndiSelector;
33 import net.sf.ehcache.transaction.manager.selector.GlassfishSelector;
34 import net.sf.ehcache.transaction.manager.selector.JndiSelector;
35 import net.sf.ehcache.transaction.manager.selector.NullSelector;
36 import net.sf.ehcache.transaction.manager.selector.Selector;
37 import net.sf.ehcache.transaction.manager.selector.WeblogicSelector;
38 import net.sf.ehcache.transaction.xa.EhcacheXAResource;
39
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43
63 public class DefaultTransactionManagerLookup implements TransactionManagerLookup {
64
65 private static final Logger LOG = LoggerFactory.getLogger(DefaultTransactionManagerLookup.class.getName());
66
67 private final Lock lock = new ReentrantLock();
68 private final List<EhcacheXAResource> uninitializedEhcacheXAResources = new ArrayList<EhcacheXAResource>();
69 private volatile boolean initialized = false;
70 private volatile Selector selector;
71
72 private final JndiSelector defaultJndiSelector = new GenericJndiSelector();
73
74 private final Selector[] transactionManagerSelectors = new Selector[] {defaultJndiSelector,
75 new GlassfishSelector(),
76 new WeblogicSelector(),
77 new BitronixSelector(),
78 new AtomikosSelector()
79 };
80
81
84 public void init() {
85 if (!initialized) {
86 lock.lock();
87 try {
88 Iterator<EhcacheXAResource> iterator = uninitializedEhcacheXAResources.iterator();
89 while (iterator.hasNext()) {
90 if (getTransactionManager() == null) {
91 throw new CacheException("No Transaction Manager could be located, cannot initialize DefaultTransactionManagerLookup." +
92 " Caches which registered an XAResource: " + getUninitializedXAResourceCacheNames());
93 }
94 EhcacheXAResource resource = iterator.next();
95 selector.registerResource(resource, true);
96 iterator.remove();
97 }
98 } finally {
99 lock.unlock();
100 }
101 initialized = true;
102 }
103 }
104
105 private Set<String> getUninitializedXAResourceCacheNames() {
106 Set<String> names = new HashSet<String>();
107 for (EhcacheXAResource xar : uninitializedEhcacheXAResources) {
108 names.add(xar.getCacheName());
109 }
110 return names;
111 }
112
113
118 public TransactionManager getTransactionManager() {
119 if (selector == null) {
120 lock.lock();
121 try {
122 if (selector == null) {
123 lookupTransactionManager();
124 }
125 } finally {
126 lock.unlock();
127 }
128 }
129 return selector.getTransactionManager();
130 }
131
132 private void lookupTransactionManager() {
133 for (Selector s : transactionManagerSelectors) {
134 TransactionManager transactionManager = s.getTransactionManager();
135 if (transactionManager != null) {
136 this.selector = s;
137 LOG.debug("Found TransactionManager for {}", s.getVendor());
138 return;
139 }
140 }
141 this.selector = new NullSelector();
142 LOG.debug("Found no TransactionManager");
143 }
144
145
148 public void register(EhcacheXAResource resource, boolean forRecovery) {
149 if (initialized) {
150 selector.registerResource(resource, forRecovery);
151 } else {
152 lock.lock();
153 try {
154 uninitializedEhcacheXAResources.add(resource);
155 } finally {
156 lock.unlock();
157 }
158 }
159 }
160
161
164 public void unregister(EhcacheXAResource resource, boolean forRecovery) {
165 if (initialized) {
166 selector.unregisterResource(resource, forRecovery);
167 } else {
168 lock.lock();
169 try {
170 Iterator<EhcacheXAResource> iterator = uninitializedEhcacheXAResources.iterator();
171 while (iterator.hasNext()) {
172 EhcacheXAResource uninitializedEhcacheXAResource = iterator.next();
173 if (uninitializedEhcacheXAResource == resource) {
174 iterator.remove();
175 break;
176 }
177 }
178 } finally {
179 lock.unlock();
180 }
181 }
182 }
183
184
187 public void setProperties(Properties properties) {
188 if (properties != null) {
189 String jndiName = properties.getProperty("jndiName");
190 if (jndiName != null) {
191 defaultJndiSelector.setJndiName(jndiName);
192 }
193 }
194 }
195
196 }
197