View Javadoc

1   package org.csc.phynixx.xa;
2   
3   /*
4    * #%L
5    * phynixx-xa
6    * %%
7    * Copyright (C) 2014 csc
8    * %%
9    * Licensed under the Apache License, Version 2.0 (the "License");
10   * you may not use this file except in compliance with the License.
11   * You may obtain a copy of the License at
12   * 
13   *      http://www.apache.org/licenses/LICENSE-2.0
14   * 
15   * Unless required by applicable law or agreed to in writing, software
16   * distributed under the License is distributed on an "AS IS" BASIS,
17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18   * See the License for the specific language governing permissions and
19   * limitations under the License.
20   * #L%
21   */
22  
23  
24  import org.csc.phynixx.connection.IPhynixxConnection;
25  import org.csc.phynixx.connection.IPhynixxConnectionFactory;
26  import org.csc.phynixx.connection.IPhynixxManagedConnectionFactory;
27  import org.csc.phynixx.watchdog.IWatchdog;
28  import org.csc.phynixx.watchdog.IWatchedCondition;
29  import org.csc.phynixx.watchdog.WatchdogRegistry;
30  
31  import javax.transaction.TransactionManager;
32  import javax.transaction.xa.Xid;
33  
34  import java.util.Collections;
35  import java.util.HashSet;
36  import java.util.Iterator;
37  import java.util.Set;
38  
39  
40  /**
41   * @param <T>
42   */
43  public class PhynixxXAResourceFactory<T extends IPhynixxConnection> implements IPhynixxXAResourceFactory<T>, IPhynixxXAResourceListener<T> {
44  
45      private static final long CHECK_INTERVAL = 100; // msecs
46  
47      private static IResourceIDGenerator ID_GENERATOR = new IDGenerator();
48  
49  
50      /**
51       * this XAResources represents the Resources of this factory
52       */
53      PhynixxXAResource<T> xaResource;
54  
55  
56      private final IXATransactionalBranchRepository<T> xaTransactionalBranchRepository;
57  
58  
59      //  private PhynixxConnectionTray<T> connectionTray = null;
60  
61  
62      /**
63       * set of active xaresources
64       */
65      private Set<PhynixxXAResource<T>> xaresources = Collections.synchronizedSet(new HashSet());
66  
67      private Object resourceFactoryId = null;
68  
69      /**
70       * factory instaciating the underlying connections
71       */
72      private IPhynixxManagedConnectionFactory<T> managedConnectionFactory;
73  
74      private TransactionManager transactionManager = null;
75  
76      private boolean supportsTimeOut= false;
77  
78      public boolean isSupportsTimeOut() {
79          return supportsTimeOut;
80      }
81  
82      public void setSupportsTimeOut(boolean supportsTimeOut) {
83          this.supportsTimeOut = supportsTimeOut;
84      }
85  
86      /**
87       * checks timeouts
88       */
89      private IWatchdog xaresourrceWatchdog = null;
90  
91      public PhynixxXAResourceFactory(
92              IPhynixxManagedConnectionFactory<T> connectionFactory,
93              TransactionManager transactionManager) {
94          this("RF", connectionFactory, transactionManager);
95      }
96  
97      public PhynixxXAResourceFactory(
98              Object id,
99              IPhynixxManagedConnectionFactory<T> connectionFactory,
100             TransactionManager transactionManager) {
101         this.resourceFactoryId = id;
102 
103         //  this.connectionTray = new PhynixxConnectionTray(connectionFactory);
104 
105         this.managedConnectionFactory = connectionFactory;
106 
107         xaTransactionalBranchRepository = new XATransactionalBranchRepository();
108 
109         this.transactionManager = transactionManager;
110         //this.xaresourrceWatchdog = WatchdogRegistry.getTheRegistry().createWatchdog(CHECK_INTERVAL);
111 
112 
113         this.xaResource= instanciateXAResource();
114     }
115 
116 
117     public String getId() {
118         return resourceFactoryId.toString();
119     }
120 
121     public IPhynixxManagedConnectionFactory<T> getManagedConnectionFactory() {
122 
123         return managedConnectionFactory;
124     }
125 
126     IXATransactionalBranchRepository<T> getXATransactionalBranchRepository() {
127         return xaTransactionalBranchRepository;
128     }
129 
130     public TransactionManager getTransactionManager() {
131         return transactionManager;
132     }
133 
134 
135     protected IResourceIDGenerator getIdGenerator() {
136         return ID_GENERATOR;
137     }
138 
139     protected static void setIdGenerator(IResourceIDGenerator idGenerator) {
140         ID_GENERATOR = idGenerator;
141     }
142 
143 
144     private PhynixxXAResource<T> instanciateXAResource() {
145         PhynixxXAResource<T> xares = new PhynixxXAResource<T>(createXAResourceId(), this.transactionManager, this);
146         xares.addXAResourceListener(this);
147         this.xaresources.add(xares);
148         return xares;
149     }
150 
151     public IPhynixxXAConnection<T> getXAConnection() {
152         return this.xaResource.getXAConnection();
153     }
154 
155 
156     /**
157      * XAResourceProgressState id helps debugging a xa resource.
158      * It's unique for all xa resources of a resource factory
159      *
160      * @return
161      */
162     private String createXAResourceId() {
163         return this.resourceFactoryId + "_" + this.ID_GENERATOR.generate();
164     }
165 
166     /**
167      * erzeugt eine neue XAResource ...
168      *
169      * @return
170      */
171     @Override
172     public IPhynixxXAResource<T> getXAResource() {
173         return this.xaResource;
174     }
175 
176 
177     public void closed(IPhynixxXAResourceEvent event) {
178         this.xaresources.remove(event.getXAResource());
179     }
180 
181     /**
182      * resource factory represents the persistence management system and is responsible
183      * to implements system recovery
184      * Subclasses have to implement die recovery
185      *
186      * @return recovered TX
187      *
188      * TODO recover still to be implemented
189      */
190     @Override
191     public synchronized Xid[] recover() {
192         return new Xid[]{};
193     }
194 
195     /**
196      * Closes all pending XAResources and all reopen but unused connections
197      */
198     @Override
199     public synchronized void close() {
200         if (this.xaresources.size() > 0) {
201             // copy all resources as the close of a resource modifies the xaresources ...
202             Set<PhynixxXAResource<T>> tmpXAResources = new HashSet(this.xaresources);
203             // close all reopen XAResources ....
204             for (Iterator<PhynixxXAResource<T>> iterator = tmpXAResources.iterator(); iterator.hasNext(); ) {
205                 PhynixxXAResource<T> xaresource = iterator.next();
206                 xaresource.close();
207             }
208         }
209 
210         this.getXATransactionalBranchRepository().close();
211     }
212 
213 
214     synchronized void registerWatchCondition(IWatchedCondition cond) {
215         this.xaresourrceWatchdog.registerCondition(cond);
216     }
217 
218     synchronized void unregisterWatchCondition(IWatchedCondition cond) {
219         this.xaresourrceWatchdog.unregisterCondition(cond);
220     }
221 
222 	@Override
223 	public T getConnection() {
224 		return this.getXAResource().getXAConnection().getConnection();
225 	}
226 
227 	@Override
228 	public Class<T> getConnectionInterface() {
229 		return this.managedConnectionFactory.getConnectionInterface();
230 	}
231 
232 
233 }