001 package org.apache.ojb.odmg.locking;
002
003 /* Copyright 2002-2005 The Apache Software Foundation
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018
019 import org.apache.ojb.odmg.TransactionImpl;
020
021 import java.util.Collection;
022
023 /**
024 * The implementation of the Serializable Locking strategy.
025 *
026 * @author Thomas Mahler & David Dixon-Peugh
027 */
028 public class SerializableStrategy extends AbstractLockStrategy
029 {
030 /**
031 * acquire a read lock on Object obj for Transaction tx.
032 * @param tx the transaction requesting the lock
033 * @param obj the Object to be locked
034 * @return true if successful, else false
035 *
036 */
037 public boolean readLock(TransactionImpl tx, Object obj)
038 {
039 LockEntry writer = getWriter(obj);
040 Collection readers = getReaders(obj);
041 if (writer == null)
042 {
043 // only one reader at a time
044 if (readers.size() == 0)
045 {
046 if (addReader(tx, obj))
047 {
048 readers = getReaders(obj);
049 if (readers.size() == 1)
050 {
051 return true;
052 }
053 else
054 {
055 removeReader(tx, obj);
056 return readLock(tx, obj);
057 }
058 }
059 else
060 return readLock(tx, obj);
061 }
062 else if ((readers.size() == 1) && (((LockEntry) readers.iterator().next()).isOwnedBy(tx)))
063 {
064 // I'm the reader, thus I am allowed to read even more !
065 return true;
066 }
067 }
068 else if (writer.isOwnedBy(tx))
069 {
070 return true; // If I'm the writer, I can read.
071 }
072
073 return false;
074 }
075
076 /**
077 * acquire a write lock on Object obj for Transaction tx.
078 * @param tx the transaction requesting the lock
079 * @param obj the Object to be locked
080 * @return true if successful, else false
081 *
082 */
083 public boolean writeLock(TransactionImpl tx, Object obj)
084 {
085 LockEntry writer = getWriter(obj);
086 Collection readers = getReaders(obj);
087 if (writer == null)
088 {
089 if (readers.size() == 0)
090 {
091 if (setWriter(tx, obj))
092 return true;
093 else
094 return writeLock(tx, obj);
095 }
096
097 else if (readers.size() == 1)
098 {
099 if (((LockEntry) readers.iterator().next()).isOwnedBy(tx))
100 return upgradeLock(tx, obj);
101 }
102 }
103 else if (writer.isOwnedBy(tx))
104 {
105 return true; // If I'm the writer, then I can write.
106 }
107 return false;
108 }
109
110 /**
111 * acquire a lock upgrade (from read to write) lock on Object obj for Transaction tx.
112 * @param tx the transaction requesting the lock
113 * @param obj the Object to be locked
114 * @return true if successful, else false
115 *
116 */
117 public boolean upgradeLock(TransactionImpl tx, Object obj)
118 {
119 LockEntry writer = getWriter(obj);
120 if (writer == null)
121 {
122 Collection readers = getReaders(obj);
123 if (readers.size() == 1)
124 {
125 LockEntry reader = (LockEntry) readers.iterator().next();
126 if (reader.isOwnedBy(tx))
127 {
128 if (upgradeLock(reader))
129 return true;
130 else
131 return upgradeLock(tx, obj);
132 }
133 }
134 else
135 {
136 if (readers.size() == 0)
137 {
138 if (setWriter(tx, obj))
139 return true;
140 else
141 return upgradeLock(tx, obj);
142 }
143 }
144 }
145 else if (writer.isOwnedBy(tx))
146 {
147 return true; // If I already have Write, then I've upgraded.
148 }
149
150 return false;
151 }
152
153 /**
154 * release a lock on Object obj for Transaction tx.
155 * @param tx the transaction releasing the lock
156 * @param obj the Object to be unlocked
157 * @return true if successful, else false
158 *
159 */
160 public boolean releaseLock(TransactionImpl tx, Object obj)
161 {
162 LockEntry writer = getWriter(obj);
163 if (writer != null && writer.isOwnedBy(tx))
164 {
165 removeWriter(writer);
166 return true;
167 }
168
169 if (hasReadLock(tx, obj))
170 {
171 removeReader(tx, obj);
172 return true;
173 }
174 else
175 return false;
176
177 }
178
179 /**
180 * checks whether the specified Object obj is read-locked by Transaction tx.
181 * @param tx the transaction
182 * @param obj the Object to be checked
183 * @return true if lock exists, else false
184 */
185 public boolean checkRead(TransactionImpl tx, Object obj)
186 {
187 if (hasReadLock(tx, obj))
188 {
189 return true;
190 }
191 LockEntry writer = getWriter(obj);
192 if (writer != null && writer.isOwnedBy(tx))
193 {
194 return true;
195 }
196 else
197 return false;
198 }
199
200 /**
201 * checks whether the specified Object obj is write-locked by Transaction tx.
202 * @param tx the transaction
203 * @param obj the Object to be checked
204 * @return true if lock exists, else false
205 */
206 public boolean checkWrite(TransactionImpl tx, Object obj)
207 {
208 LockEntry writer = getWriter(obj);
209 return (writer != null && writer.isOwnedBy(tx));
210 }
211 }