001: /* Copyright 2002 The JA-SIG Collaborative. All rights reserved.
002: * See license distributed with this file and
003: * available online at http://www.uportal.org/license.html
004: */
005:
006: package org.jasig.portal.services;
007:
008: import org.apache.commons.logging.Log;
009: import org.apache.commons.logging.LogFactory;
010: import org.jasig.portal.EntityIdentifier;
011: import org.jasig.portal.concurrency.IEntityLock;
012: import org.jasig.portal.concurrency.IEntityLockService;
013: import org.jasig.portal.concurrency.IEntityLockServiceFactory;
014: import org.jasig.portal.concurrency.LockingException;
015: import org.jasig.portal.properties.PropertiesManager;
016:
017: /**
018: * This is a bootstrap class and facade for the IEntityLockService implementation.
019: * It presents a simple api for acquiring lock objects, <code>IEntityLocks</code>,
020: * that can be used to control concurrent access to portal entities in a
021: * multi-server environment. (See org.jasig.portal.concurrency.IEntityLockService
022: * for a fuller description.)
023: * <p>
024: * Currently supported lock types are IEntityLockService.READ_LOCK and
025: * IEntityLockService.WRITE_LOCK.
026: * <p>
027: * If I want to lock an entity for update, I ask the service for a write lock:
028: * <p>
029: * <code>
030: * Class type = anEntity.getClass(); // maybe hard-coded(?)<br>
031: * String key = anEntity.getKey();<br>
032: * EntityIdentifier ei = new EntityIdentifier(key, type);<br>
033: * String owner = getThePortalUserId();<br>
034: * IEntityLock lock = EntityLockService.instance().newWriteLock(ei, owner);<br>
035: * </code>
036: * <p>
037: * Or maybe:
038: * <p>
039: * <code>
040: * IEntityLock lock = EntityLockService.instance().newWriteLock(ei, owner, duration);<br>
041: * </code>
042: * <p>
043: * If there are no conflicting locks on the entity, the service returns the
044: * requested lock. If I acquire the lock, I know that no other client will be
045: * able to get a conflicting lock, and from then on, I communicate with the
046: * service via the lock:
047: * <p>
048: * <code>
049: * lock.convert(int newType); // See IEntityLockService for types.<br>
050: * lock.isValid();<br>
051: * lock.release();<br>
052: * lock.renew();<br>
053: * </code>
054: * <p>
055: * A READ lock guarantees shared access; other clients can get READ locks
056: * but not WRITE locks. A WRITE lock guarantees exclusive access; no other
057: * clients can get either READ or WRITE locks on the entity.
058: *
059: * @author Dan Ellentuck
060: * @version $Revision: 35551 $
061: */
062:
063: public class EntityLockService {
064:
065: private static final Log log = LogFactory
066: .getLog(EntityLockService.class);
067:
068: // Singleton instance of the bootstrap class:
069: private static EntityLockService instance = null;
070: // The lock service:
071: private IEntityLockService lockService = null;
072:
073: /** Creates new EntityLockService */
074: private EntityLockService() throws LockingException {
075: super ();
076: initialize();
077: }
078:
079: /**
080: * @exception LockingException
081: */
082: private void initialize() throws LockingException {
083: String eMsg = null;
084: String factoryName = PropertiesManager
085: .getProperty(
086: "org.jasig.portal.concurrency.IEntityLockServiceFactory",
087: null);
088:
089: if (factoryName == null) {
090: log
091: .warn("Property org.jasig.portal.concurrency.IEntityLockServiceFactory not configured in PropertiesManager. Defaulting to org.jasig.portal.concurrency.locking.ReferenceEntityLockServiceFactory");
092: factoryName = "org.jasig.portal.concurrency.locking.ReferenceEntityLockServiceFactory";
093: }
094:
095: try {
096: IEntityLockServiceFactory lockServiceFactory = (IEntityLockServiceFactory) Class
097: .forName(factoryName).newInstance();
098: lockService = lockServiceFactory.newLockService();
099: } catch (Exception e) {
100: eMsg = "EntityLockService.initialize(): Problem creating entity lock service...";
101: log.error(eMsg, e);
102: throw new LockingException(eMsg, e);
103: }
104: }
105:
106: public static synchronized EntityLockService instance()
107: throws LockingException {
108: if (instance == null) {
109: instance = new EntityLockService();
110: }
111: return instance;
112: }
113:
114: /**
115: * Returns a read lock for the entity type, entity key and owner.
116: * @return org.jasig.portal.concurrency.locking.IEntityLock
117: * @param entityType Class
118: * @param entityKey String
119: * @param owner String
120: * @exception LockingException
121: */
122: public IEntityLock newReadLock(Class entityType, String entityKey,
123: String owner) throws LockingException {
124: return lockService.newLock(entityType, entityKey,
125: IEntityLockService.READ_LOCK, owner);
126: }
127:
128: /**
129: * Returns a read lock for the entity type, entity key and owner.
130: * @return org.jasig.portal.concurrency.locking.IEntityLock
131: * @param entityType Class
132: * @param entityKey String
133: * @param owner String
134: * @param duration int (in seconds)
135: * @exception LockingException
136: */
137: public IEntityLock newReadLock(Class entityType, String entityKey,
138: String owner, int duration) throws LockingException {
139: return lockService.newLock(entityType, entityKey,
140: IEntityLockService.READ_LOCK, owner, duration);
141: }
142:
143: /**
144: * Returns a read lock for the <code>IBasicEntity</code> and owner.
145: * @return org.jasig.portal.concurrency.locking.IEntityLock
146: * @param entityID EntityIdentifier
147: * @param owner String
148: * @exception LockingException
149: */
150: public IEntityLock newReadLock(EntityIdentifier entityID,
151: String owner) throws LockingException {
152: return lockService.newLock(entityID.getType(), entityID
153: .getKey(), IEntityLockService.READ_LOCK, owner);
154: }
155:
156: /**
157: * Returns a read lock for the <code>IBasicEntity</code>, owner and duration.
158: * @return org.jasig.portal.concurrency.locking.IEntityLock
159: * @param entityID EntityIdentifier
160: * @param owner String
161: * @param durationSecs int
162: * @exception LockingException
163: */
164: public IEntityLock newReadLock(EntityIdentifier entityID,
165: String owner, int durationSecs) throws LockingException {
166: return lockService.newLock(entityID.getType(), entityID
167: .getKey(), IEntityLockService.READ_LOCK, owner,
168: durationSecs);
169: }
170:
171: /**
172: * Returns a write lock for the entity type, entity key and owner.
173: * @return org.jasig.portal.concurrency.locking.IEntityLock
174: * @param entityType Class
175: * @param entityKey String
176: * @param owner String
177: * @exception LockingException
178: */
179: public IEntityLock newWriteLock(Class entityType, String entityKey,
180: String owner) throws LockingException {
181: return lockService.newLock(entityType, entityKey,
182: IEntityLockService.WRITE_LOCK, owner);
183: }
184:
185: /**
186: * Returns a write lock for the entity type, entity key and owner.
187: * @return org.jasig.portal.concurrency.locking.IEntityLock
188: * @param entityType Class
189: * @param entityKey String
190: * @param owner String
191: * @param durationSecs int
192: * @exception LockingException
193: */
194: public IEntityLock newWriteLock(Class entityType, String entityKey,
195: String owner, int durationSecs) throws LockingException {
196: return lockService.newLock(entityType, entityKey,
197: IEntityLockService.WRITE_LOCK, owner, durationSecs);
198: }
199:
200: /**
201: * Returns a write lock for the <code>IBasicEntity</code> and owner.
202: * @return org.jasig.portal.concurrency.locking.IEntityLock
203: * @param entityID EntityIdentifier
204: * @param owner String
205: * @exception LockingException
206: */
207: public IEntityLock newWriteLock(EntityIdentifier entityID,
208: String owner) throws LockingException {
209: return lockService.newLock(entityID.getType(), entityID
210: .getKey(), IEntityLockService.WRITE_LOCK, owner);
211: }
212:
213: /**
214: * Returns a write lock for the <code>IBasicEntity</code>, owner and duration.
215: * @return org.jasig.portal.concurrency.locking.IEntityLock
216: * @param entityID EntityIdentifier
217: * @param owner String
218: * @param durationSecs int
219: * @exception LockingException
220: */
221: public IEntityLock newWriteLock(EntityIdentifier entityID,
222: String owner, int durationSecs) throws LockingException {
223: return lockService.newLock(entityID.getType(), entityID
224: .getKey(), IEntityLockService.WRITE_LOCK, owner,
225: durationSecs);
226: }
227: }
|