KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > otm > lock > ObjectLock


1 package org.apache.ojb.otm.lock;
2
3 /* Copyright 2003-2005 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * 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
18 import java.util.ArrayList JavaDoc;
19 import java.util.Collection JavaDoc;
20 import java.util.Collections JavaDoc;
21 import java.util.HashMap JavaDoc;
22 import java.util.Iterator JavaDoc;
23
24 import org.apache.ojb.broker.Identity;
25 import org.apache.ojb.otm.OTMKit;
26 import org.apache.ojb.otm.core.Transaction;
27 import org.apache.ojb.otm.lock.wait.LockWaitStrategy;
28
29 /**
30  *
31  * Represents the locks held for an object. The basic assertion is that at any given point
32  * in time, there can be multiple readers, but just one writer.
33  *
34  * @author <a HREF="mailto:rraghuram@hotmail.com">Raghu Rajah</a>
35  *
36  */

37 public class ObjectLock
38 {
39     //////////////////////////////////
40
// IVars
41
//////////////////////////////////
42

43     private Identity _oid;
44     private LockEntry _writer;
45     private HashMap JavaDoc _readers = new HashMap JavaDoc();
46
47
48     ////////////////////////////////////////
49
// Constructor
50
////////////////////////////////////////
51

52     public ObjectLock(Identity oid)
53     {
54         _oid = oid;
55     }
56
57     ////////////////////////////////////////
58
// Operations
59
////////////////////////////////////////
60

61     public Identity getTargetIdentity()
62     {
63         return _oid;
64     }
65
66     public Transaction getWriter()
67     {
68         return (_writer == null)? null: _writer.getTx();
69     }
70
71     public boolean isReader(Transaction tx)
72     {
73         return _readers.containsKey(tx);
74     }
75
76     public boolean doesReaderExists()
77     {
78         return (_readers.size() > 0);
79     }
80
81     public Collection JavaDoc getReaders()
82     {
83         return Collections.unmodifiableCollection(_readers.keySet());
84     }
85
86     public void readLock(Transaction tx)
87     {
88         if (!isReader(tx))
89         {
90             new LockEntry(tx);
91         }
92     }
93
94     public void writeLock(Transaction tx)
95         throws LockingException
96     {
97         if (getWriter() != tx)
98         {
99             LockEntry lock = (LockEntry) _readers.get(tx);
100
101             if (lock == null)
102             {
103                 lock = new LockEntry(tx);
104             }
105             lock.writeLock();
106         }
107     }
108
109     public void releaseLock(Transaction tx)
110     {
111         LockEntry lock = (LockEntry)_readers.get(tx);
112
113         if (lock != null)
114         {
115             lock.release();
116         }
117     }
118
119     public void waitForTx(Transaction tx)
120         throws LockingException
121     {
122         OTMKit kit = tx.getKit();
123         LockWaitStrategy waitStrategy = kit.getLockWaitStrategy();
124         waitStrategy.waitForLock(this, tx);
125     }
126
127     public boolean isFree()
128     {
129         return ((_writer == null) && _readers.isEmpty());
130     }
131
132     /////////////////////////////////////////
133
// Inner classes
134
/////////////////////////////////////////
135

136     private class LockEntry
137     {
138         public Transaction _tx;
139         public ArrayList JavaDoc _listeners;
140
141         public LockEntry(Transaction tx)
142         {
143             _tx = tx;
144             _listeners = null;
145             _readers.put(_tx, LockEntry.this);
146         }
147
148         /**
149          *
150          * Returns the LockListeners for this entry.
151          *
152          * @return ArrayList of LockListeners
153          *
154          */

155         public ArrayList JavaDoc getListeners()
156         {
157             return _listeners;
158         }
159
160         /**
161          *
162          * Returns the transaction held by this LockEntry.
163          *
164          * @return Transaction
165          *
166          */

167         public Transaction getTx()
168         {
169             return _tx;
170         }
171
172         /**
173          *
174          * Add a listener to the list of LockListeners. LockListener is notified, when this
175          * LockEntry is released.
176          *
177          * @param listener the LockListener
178          *
179          */

180         public void addListener(LockListener listener)
181         {
182             if (listener != null)
183             {
184                 if (_listeners == null)
185                 {
186                     _listeners = new ArrayList JavaDoc();
187                 }
188
189                 _listeners.add(listener);
190             }
191         }
192
193         /**
194          *
195          * Make this lock a writer. If a writer is already present, the call will block until
196          * the lock is released by the writer.
197          *
198          */

199         public void writeLock() throws LockingException
200         {
201             while (true)
202             {
203                 if (_writer != null && _writer._tx != _tx)
204                 {
205                     waitForTx(_tx);
206                 }
207
208                 synchronized (ObjectLock.this)
209                 {
210                     if (_writer == null || _writer._tx == _tx)
211                     {
212                         _writer = this;
213                         return;
214                     }
215                 }
216             }
217         }
218
219         public void release()
220         {
221             synchronized (ObjectLock.this)
222             {
223                 if (_writer == this)
224                 {
225                     _writer = null;
226                 }
227             }
228
229             _readers.remove(_tx);
230
231             if (_listeners != null)
232             {
233                 for (Iterator JavaDoc iterator = _listeners.iterator(); iterator.hasNext();)
234                 {
235                   LockListener listener = (LockListener) iterator.next();
236                   listener.lockReleased(_tx, _oid);
237                 }
238             }
239         }
240     }
241 }
242
Popular Tags