1 package org.apache.ojb.otm.lock; 2 3 17 18 import java.util.ArrayList ; 19 import java.util.Collection ; 20 import java.util.Collections ; 21 import java.util.HashMap ; 22 import java.util.Iterator ; 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 37 public class ObjectLock 38 { 39 43 private Identity _oid; 44 private LockEntry _writer; 45 private HashMap _readers = new HashMap (); 46 47 48 52 public ObjectLock(Identity oid) 53 { 54 _oid = oid; 55 } 56 57 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 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 136 private class LockEntry 137 { 138 public Transaction _tx; 139 public ArrayList _listeners; 140 141 public LockEntry(Transaction tx) 142 { 143 _tx = tx; 144 _listeners = null; 145 _readers.put(_tx, LockEntry.this); 146 } 147 148 155 public ArrayList getListeners() 156 { 157 return _listeners; 158 } 159 160 167 public Transaction getTx() 168 { 169 return _tx; 170 } 171 172 180 public void addListener(LockListener listener) 181 { 182 if (listener != null) 183 { 184 if (_listeners == null) 185 { 186 _listeners = new ArrayList (); 187 } 188 189 _listeners.add(listener); 190 } 191 } 192 193 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 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 |