KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > rift > coad > daemon > messageservice > IDLock


1 /*
2  * MessageService: The message service daemon
3  * Copyright (C) 2006-2007 Rift IT Contracting
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  *
19  * IDLock.java
20  */

21
22 // the package path
23
package com.rift.coad.daemon.messageservice;
24
25 // java imports
26
import java.util.Iterator JavaDoc;
27 import java.util.Map JavaDoc;
28 import java.util.LinkedHashMap JavaDoc;
29 import java.util.HashMap JavaDoc;
30 import java.util.concurrent.ConcurrentHashMap JavaDoc;
31 import javax.naming.Context JavaDoc;
32 import javax.naming.InitialContext JavaDoc;
33 import javax.transaction.xa.XAException JavaDoc;
34 import javax.transaction.xa.XAResource JavaDoc;
35 import javax.transaction.xa.Xid JavaDoc;
36
37 // logging import
38
import org.apache.log4j.Logger;
39
40 // coadunation imports
41
import com.rift.coad.util.transaction.TransactionManager;
42
43
44 /**
45  * This object is responsible for creating a lock based on the string id passed
46  * in.
47  *
48  * @author Bret Chaldecott
49  */

50 public class IDLock implements XAResource JavaDoc {
51     
52     /**
53      * This class is responsible for representing a lock based on an id.
54      */

55     public class Lock {
56         
57         // private member variables
58
private String JavaDoc id = null;
59         private Xid JavaDoc owner = null;
60         private int referenceCount = 0;
61         
62         /**
63          * The constructor of the lock object.
64          */

65         public Lock(String JavaDoc id) {
66             this.id = id;
67         }
68         
69         
70         /**
71          * The getter for the id value.
72          *
73          * @return The value of the id for this object.
74          */

75         public String JavaDoc getId() {
76             return id;
77         }
78         
79         
80         /**
81          * This method increments the reference count.
82          *
83          * @return The integer reference count.
84          */

85         public synchronized int incrementReferenceCount() {
86             return ++referenceCount;
87         }
88         
89         
90         /**
91          * This method decrements the reference count to this object and returns
92          * the result of this.
93          *
94          * @return The integer reference count.
95          */

96         public synchronized int decrementReferenceCount() {
97             return --referenceCount;
98         }
99         
100         
101         /**
102          * This method attempts to lock this object based on the owner id
103          * passed in
104          *
105          * @param owner The owner of this lock.
106          * @exception IDLockException
107          */

108         public synchronized void lock(Xid JavaDoc owner) throws IDLockException {
109             while (this.owner != null) {
110                 try {
111                     wait();
112                 } catch (Exception JavaDoc ex) {
113                     log.error("Failed to lock this object : " + ex.getMessage(),
114                             ex);
115                     throw new IDLockException(
116                             "Failed to lock this object : " + ex.getMessage(),
117                             ex);
118                 }
119             }
120             this.owner = owner;
121         }
122         
123         
124         /**
125          * This method unlocks the object.
126          */

127         public synchronized void unlock() {
128             this.owner = null;
129             notify();
130         }
131     }
132
133     // singletons
134
private static IDLock singleton = null;
135     
136     // log object
137
private Logger log = Logger.getLogger(IDLock.class.getName());
138     
139     // private member variables
140
private Map JavaDoc transactionMap = new ConcurrentHashMap JavaDoc();
141     private Map JavaDoc lockMap = new HashMap JavaDoc();
142     private ThreadLocal JavaDoc currentLock = new ThreadLocal JavaDoc();
143     
144     
145     /**
146      * Creates a new instance of IDLock
147      */

148     private IDLock() {
149     }
150     
151     
152     /**
153      * This method returns an instance of the IDLock object.
154      *
155      * @return A reference to the id lock singleton.
156      */

157     public synchronized static IDLock getInstance() {
158         if (singleton == null) {
159             singleton = new IDLock();
160         }
161         return singleton;
162     }
163     
164     
165     /**
166      * This method creates a lock based on the supplied id.
167      *
168      * @param id The id of the key to lock
169      * @exception IDLockException
170      */

171     public void lock(String JavaDoc id) throws IDLockException {
172         try {
173             Lock lock = null;
174             synchronized(lockMap) {
175                 lock = (Lock)lockMap.get(id);
176                 if (lock == null) {
177                     lock = new Lock(id);
178                     lockMap.put(id,lock);
179                 }
180                 lock.incrementReferenceCount();
181             }
182             currentLock.set(lock);
183             TransactionManager.getInstance().bindResource(this,false);
184         } catch (Exception JavaDoc ex) {
185             log.error("Failed to lock the id [" + id + "] : " +
186                     ex.getMessage(),ex);
187             throw new IDLockException("Failed to lock the id [" + id + "] : " +
188                     ex.getMessage(),ex);
189         }
190     }
191
192     
193     /**
194      * This method is responsible for handling the committing of a transaction
195      * identified by the xid.
196      *
197      * @param xid The id of the transaction to commit.
198      * @param onePhase If true a one phase commit should be used.
199      * @exception XAException
200      */

201     public void commit(Xid JavaDoc xid, boolean b) throws XAException JavaDoc {
202         try {
203             Lock lock = (Lock)transactionMap.remove(xid);
204             lock.unlock();
205             synchronized(lockMap) {
206                 if (lock.decrementReferenceCount() <= 0) {
207                     lockMap.remove(lock.getId());
208                 }
209             }
210         } catch (Exception JavaDoc ex) {
211             log.error("Failed to roll back the changes : " +
212                     ex.getMessage(),ex);
213             throw new XAException JavaDoc("Failed to roll back the changes : " +
214                     ex.getMessage());
215         }
216     }
217     
218     
219     /**
220      * The resource manager has dissociated this object from the transaction.
221      *
222      * @param xid The id of the transaction that is getting ended.
223      * @param flags The flags associated with this operation.
224      * @exception XAException
225      */

226     public void end(Xid JavaDoc xid, int i) throws XAException JavaDoc {
227     }
228     
229     
230     /**
231      * The transaction has been completed and must be forgotten.
232      *
233      * @param xid The id of the transaction to forget.
234      * @exception XAException
235      */

236     public void forget(Xid JavaDoc xid) throws XAException JavaDoc {
237         try {
238             Lock lock = (Lock)transactionMap.remove(xid);
239             lock.unlock();
240             synchronized(lockMap) {
241                 if (lock.decrementReferenceCount() <= 0) {
242                     lockMap.remove(lock.getId());
243                 }
244             }
245         } catch (Exception JavaDoc ex) {
246             log.error("Failed to roll back the changes : " +
247                     ex.getMessage(),ex);
248             throw new XAException JavaDoc("Failed to roll back the changes : " +
249                     ex.getMessage());
250         }
251     }
252     
253     
254     /**
255      * This method returns the transaction timeout for this object.
256      *
257      * @return The int containing the transaction timeout.
258      * @exception XAException
259      */

260     public int getTransactionTimeout() throws XAException JavaDoc {
261         return -1;
262     }
263     
264     
265     /**
266      * This method returns true if this object is the resource manager getting
267      * queried.
268      *
269      * @return TRUE if this is the resource manager, FALSE if not.
270      * @param xaResource The resource to perform the check against.
271      * @exception XAException
272      */

273     public boolean isSameRM(XAResource JavaDoc xAResource) throws XAException JavaDoc {
274         return this == xAResource;
275     }
276     
277     
278     /**
279      * This is called before a transaction is committed.
280      *
281      * @return The results of the transaction.
282      * @param xid The id of the transaction to check against.
283      * @exception XAException
284      */

285     public int prepare(Xid JavaDoc xid) throws XAException JavaDoc {
286         return XAResource.XA_OK;
287     }
288     
289     
290     /**
291      * This method returns the list of transaction branches for this resource
292      * manager.
293      *
294      * @return The list of resource branches.
295      * @param flags The flags
296      * @exception XAException
297      */

298     public Xid JavaDoc[] recover(int i) throws XAException JavaDoc {
299         return null;
300     }
301     
302     
303     /**
304      * This method is called to roll back the specified transaction.
305      *
306      * @param xid The id of the transaction to roll back.
307      * @exception XAException
308      */

309     public void rollback(Xid JavaDoc xid) throws XAException JavaDoc {
310         try {
311             Lock lock = (Lock)transactionMap.remove(xid);
312             lock.unlock();
313             synchronized(lockMap) {
314                 if (lock.decrementReferenceCount() <= 0) {
315                     lockMap.remove(lock.getId());
316                 }
317             }
318         } catch (Exception JavaDoc ex) {
319             log.error("Failed to roll back the changes : " +
320                     ex.getMessage(),ex);
321             throw new XAException JavaDoc("Failed to roll back the changes : " +
322                     ex.getMessage());
323         }
324     }
325     
326     
327     /**
328      * This method sets the transaction timeout for this resource manager.
329      *
330      * @return TRUE if the transaction timeout can be set successfully.
331      * @param transactionTimeout The new transaction timeout value.
332      * @exception XAException
333      */

334     public boolean setTransactionTimeout(int i) throws XAException JavaDoc {
335         return true;
336     }
337     
338     
339     /**
340      * This method is called to start a transaction on a resource manager.
341      *
342      * @param xid The id of the new transaction.
343      * @param flags The flags associated with the transaction.
344      * @exception XAException
345      */

346     public void start(Xid JavaDoc xid, int i) throws XAException JavaDoc {
347         try {
348             Lock lock = (Lock)currentLock.get();
349             lock.lock(xid);
350             transactionMap.put(xid,lock);
351         } catch (Exception JavaDoc ex) {
352             log.error("Failed to start the transaction : " +
353                     ex.getMessage(),ex);
354             throw new XAException JavaDoc("Failed to start the transaction : " +
355                     ex.getMessage());
356         }
357     }
358     
359     
360     
361 }
362
Popular Tags