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: import org.apache.ojb.odmg.TransactionImpl;
019:
020: import java.util.Collection;
021:
022: /**
023: * The implementation of the Serializable Locking strategy.
024: *
025: * @author Thomas Mahler & David Dixon-Peugh
026: */
027: public class SerializableStrategy extends AbstractLockStrategy {
028: /**
029: * acquire a read lock on Object obj for Transaction tx.
030: * @param tx the transaction requesting the lock
031: * @param obj the Object to be locked
032: * @return true if successful, else false
033: *
034: */
035: public boolean readLock(TransactionImpl tx, Object obj) {
036: LockEntry writer = getWriter(obj);
037: Collection readers = getReaders(obj);
038: if (writer == null) {
039: // only one reader at a time
040: if (readers.size() == 0) {
041: if (addReader(tx, obj)) {
042: readers = getReaders(obj);
043: if (readers.size() == 1) {
044: return true;
045: } else {
046: removeReader(tx, obj);
047: return readLock(tx, obj);
048: }
049: } else
050: return readLock(tx, obj);
051: } else if ((readers.size() == 1)
052: && (((LockEntry) readers.iterator().next())
053: .isOwnedBy(tx))) {
054: // I'm the reader, thus I am allowed to read even more !
055: return true;
056: }
057: } else if (writer.isOwnedBy(tx)) {
058: return true; // If I'm the writer, I can read.
059: }
060:
061: return false;
062: }
063:
064: /**
065: * acquire a write lock on Object obj for Transaction tx.
066: * @param tx the transaction requesting the lock
067: * @param obj the Object to be locked
068: * @return true if successful, else false
069: *
070: */
071: public boolean writeLock(TransactionImpl tx, Object obj) {
072: LockEntry writer = getWriter(obj);
073: Collection readers = getReaders(obj);
074: if (writer == null) {
075: if (readers.size() == 0) {
076: if (setWriter(tx, obj))
077: return true;
078: else
079: return writeLock(tx, obj);
080: }
081:
082: else if (readers.size() == 1) {
083: if (((LockEntry) readers.iterator().next())
084: .isOwnedBy(tx))
085: return upgradeLock(tx, obj);
086: }
087: } else if (writer.isOwnedBy(tx)) {
088: return true; // If I'm the writer, then I can write.
089: }
090: return false;
091: }
092:
093: /**
094: * acquire a lock upgrade (from read to write) lock on Object obj for Transaction tx.
095: * @param tx the transaction requesting the lock
096: * @param obj the Object to be locked
097: * @return true if successful, else false
098: *
099: */
100: public boolean upgradeLock(TransactionImpl tx, Object obj) {
101: LockEntry writer = getWriter(obj);
102: if (writer == null) {
103: Collection readers = getReaders(obj);
104: if (readers.size() == 1) {
105: LockEntry reader = (LockEntry) readers.iterator()
106: .next();
107: if (reader.isOwnedBy(tx)) {
108: if (upgradeLock(reader))
109: return true;
110: else
111: return upgradeLock(tx, obj);
112: }
113: } else {
114: if (readers.size() == 0) {
115: if (setWriter(tx, obj))
116: return true;
117: else
118: return upgradeLock(tx, obj);
119: }
120: }
121: } else if (writer.isOwnedBy(tx)) {
122: return true; // If I already have Write, then I've upgraded.
123: }
124:
125: return false;
126: }
127:
128: /**
129: * release a lock on Object obj for Transaction tx.
130: * @param tx the transaction releasing the lock
131: * @param obj the Object to be unlocked
132: * @return true if successful, else false
133: *
134: */
135: public boolean releaseLock(TransactionImpl tx, Object obj) {
136: LockEntry writer = getWriter(obj);
137: if (writer != null && writer.isOwnedBy(tx)) {
138: removeWriter(writer);
139: return true;
140: }
141:
142: if (hasReadLock(tx, obj)) {
143: removeReader(tx, obj);
144: return true;
145: } else
146: return false;
147:
148: }
149:
150: /**
151: * checks whether the specified Object obj is read-locked by Transaction tx.
152: * @param tx the transaction
153: * @param obj the Object to be checked
154: * @return true if lock exists, else false
155: */
156: public boolean checkRead(TransactionImpl tx, Object obj) {
157: if (hasReadLock(tx, obj)) {
158: return true;
159: }
160: LockEntry writer = getWriter(obj);
161: if (writer != null && writer.isOwnedBy(tx)) {
162: return true;
163: } else
164: return false;
165: }
166:
167: /**
168: * checks whether the specified Object obj is write-locked by Transaction tx.
169: * @param tx the transaction
170: * @param obj the Object to be checked
171: * @return true if lock exists, else false
172: */
173: public boolean checkWrite(TransactionImpl tx, Object obj) {
174: LockEntry writer = getWriter(obj);
175: return (writer != null && writer.isOwnedBy(tx));
176: }
177: }
|