Source Code Cross Referenced for ReferenceEntityLockService.java in  » Portal » uPortal_rel-2-6-1-GA » org » jasig » portal » concurrency » locking » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Portal » uPortal_rel 2 6 1 GA » org.jasig.portal.concurrency.locking 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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.concurrency.locking;
007:
008:        import java.util.Date;
009:
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.LockingException;
014:        import org.jasig.portal.properties.PropertiesManager;
015:        import org.apache.commons.logging.Log;
016:        import org.apache.commons.logging.LogFactory;
017:
018:        /**
019:         * @author Dan Ellentuck
020:         * @version $Revision: 35550 $
021:         */
022:        public class ReferenceEntityLockService implements  IEntityLockService {
023:            private static final Log log = LogFactory
024:                    .getLog(ReferenceEntityLockService.class);
025:
026:            // Singleton instance:
027:            private static IEntityLockService singleton = null;
028:
029:            // Store for IEntityLocks:
030:            private IEntityLockStore lockStore = null;
031:
032:            // Locking properties, initialized with default values, are settable
033:            // via portal.properties:
034:
035:            // Are we running in a multi-server environment?  If so, the lock store
036:            // will be in persistent storage.
037:            private boolean multiServer = false;
038:
039:            // Lifetime of a lock in seconds, defaults to 5 minutes.
040:            private int defaultLockPeriod = 300;
041:
042:            /* Fudge factor in milliseconds, extends the apparent expiration times
043:             * of potentially conflicting locks beyond their actual expirations.
044:             * We only use it when checking for locking conflicts and then only if
045:             * inMemory == false.  Defaults to 5000.
046:             */
047:            private int lockToleranceMillis = 5000;
048:
049:            /**
050:             * ReferenceEntityLockingService constructor comment.
051:             */
052:            public ReferenceEntityLockService() throws LockingException {
053:                super ();
054:                initialize();
055:            }
056:
057:            /**
058:             * Attempts to change the lock's <code>lockType</code> to <code>newType</code>.
059:             * @param lock IEntityLock
060:             * @param newType int
061:             * @exception org.jasig.portal.concurrency.LockingException
062:             */
063:            public void convert(IEntityLock lock, int newType)
064:                    throws LockingException {
065:                convert(lock, newType, defaultLockPeriod);
066:            }
067:
068:            /**
069:             * Attempts to change the lock's <code>lockType</code> to <code>newType</code>.
070:             * @param lock IEntityLock
071:             * @param newType int
072:             * @param newDuration int
073:             * @exception org.jasig.portal.concurrency.LockingException
074:             */
075:            public void convert(IEntityLock lock, int newType, int newDuration)
076:                    throws LockingException {
077:                if (lock.getLockType() == newType) {
078:                    throw new LockingException("Could not convert " + lock
079:                            + " : old and new lock TYPEs are the same.");
080:                }
081:
082:                if (!isValidLockType(newType)) {
083:                    throw new LockingException("Could not convert " + lock
084:                            + " : lock TYPE " + newType + " is invalid.");
085:                }
086:
087:                if (!isValid(lock)) {
088:                    throw new LockingException("Could not convert " + lock
089:                            + " : lock is invalid.");
090:                }
091:
092:                if (newType == WRITE_LOCK
093:                        && retrieveLocks(lock.getEntityType(), lock
094:                                .getEntityKey(), null).length > 1) {
095:                    throw new LockingException("Could not convert " + lock
096:                            + " : another lock already exists.");
097:                }
098:
099:                if (newType == READ_LOCK) { /* Can always convert to READ */
100:                }
101:
102:                Date newExpiration = getNewExpiration(newDuration);
103:                getLockStore()
104:                        .update(lock, newExpiration, new Integer(newType));
105:                ((EntityLockImpl) lock).setLockType(newType);
106:                ((EntityLockImpl) lock).setExpirationTime(newExpiration);
107:            }
108:
109:            /**
110:             * Answer if this <code>IEntityLock</code> exists in the store.
111:             * @param lock
112:             * @return boolean
113:             */
114:            public boolean existsInStore(IEntityLock lock)
115:                    throws LockingException {
116:                Class entityType = lock.getEntityType();
117:                String key = lock.getEntityKey();
118:                Integer lockType = new Integer(lock.getLockType());
119:                Date expiration = lock.getExpirationTime();
120:                String owner = lock.getLockOwner();
121:                IEntityLock[] lockArray = getLockStore().find(entityType, key,
122:                        lockType, expiration, owner);
123:
124:                return (lockArray.length > 0);
125:            }
126:
127:            /**
128:             * @return int
129:             */
130:            private int getDefaultLockPeriod() {
131:                return defaultLockPeriod;
132:            }
133:
134:            /**
135:             * @return org.jasig.portal.concurrency.locking.IEntityLockStore
136:             */
137:            private IEntityLockStore getLockStore() {
138:                return lockStore;
139:            }
140:
141:            /**
142:             * @return int
143:             */
144:            private int getLockToleranceMillis() {
145:                return lockToleranceMillis;
146:            }
147:
148:            /**
149:             * @return java.util.Date
150:             */
151:            private Date getNewExpiration(int durationSecs) {
152:                return new Date(System.currentTimeMillis()
153:                        + (durationSecs * 1000));
154:            }
155:
156:            /**
157:             * @exception LockingException
158:             */
159:            private void initialize() throws LockingException {
160:                String eMsg = null;
161:
162:                try {
163:                    multiServer = PropertiesManager.getPropertyAsBoolean(
164:                            "org.jasig.portal.concurrency.multiServer", false);
165:
166:                    lockStore = (multiServer) ? RDBMEntityLockStore.singleton()
167:                            : MemoryEntityLockStore.singleton();
168:                } catch (Exception e) {
169:                    eMsg = "ReferenceEntityLockingService.initialize(): Failed to instantiate entity lock store. "
170:                            + e;
171:                    log.error(eMsg);
172:                    throw new LockingException(eMsg);
173:                }
174:
175:                try {
176:                    int lockDuration = PropertiesManager
177:                            .getPropertyAsInt("org.jasig.portal.concurrency.IEntityLockService.defaultLockDuration");
178:                    setDefaultLockPeriod(lockDuration);
179:                } catch (Exception ex) { /* defaults to 5 minutes. */
180:                }
181:
182:                if (multiServer) {
183:                    try {
184:                        int lockTolerance = PropertiesManager
185:                                .getPropertyAsInt("org.jasig.portal.concurrency.clockTolerance");
186:                        setLockToleranceMillis(lockTolerance);
187:                    } catch (Exception ex) { /* defaults to 0. */
188:                    }
189:                }
190:            }
191:
192:            /**
193:             * Answers if the entity represented by the entityType and entityKey already
194:             * has a lock of some type.
195:             * 
196:             * @param entityType
197:             * @param entityKey
198:             * @exception org.jasig.portal.concurrency.LockingException
199:             */
200:            private boolean isLocked(Class entityType, String entityKey)
201:                    throws LockingException {
202:                return isLocked(entityType, entityKey, null);
203:            }
204:
205:            /**
206:             * Answers if the entity represented by entityType and entityKey has one
207:             * or more locks.  Param <code>lockType</code> can be null.
208:             *
209:             * @param entityType
210:             * @param entityKey
211:             * @param lockType (optional)
212:             * @exception org.jasig.portal.concurrency.LockingException
213:             */
214:            private boolean isLocked(Class entityType, String entityKey,
215:                    Integer lockType) throws LockingException {
216:                IEntityLock[] locks = retrieveLocks(entityType, entityKey,
217:                        lockType);
218:                return locks.length > 0;
219:            }
220:
221:            /**
222:             * @return boolean
223:             */
224:            private boolean isMultiServer() {
225:                return multiServer;
226:            }
227:
228:            /**
229:             * @param lock IEntityLock
230:             * @return boolean
231:             */
232:            private boolean isUnexpired(IEntityLock lock) {
233:                return lock.getExpirationTime().getTime() > System
234:                        .currentTimeMillis();
235:            }
236:
237:            /**
238:             * Answers if this <code>IEntityLock</code> represents a lock that is still
239:             * good.  To be valid, a lock must exist in the underlying store and be
240:             * unexpired.
241:             *
242:             * @param lock IEntityLock
243:             * @exception org.jasig.portal.concurrency.LockingException
244:             */
245:            public boolean isValid(IEntityLock lock) throws LockingException {
246:                return isUnexpired(lock) && existsInStore(lock);
247:            }
248:
249:            /**
250:             *
251:             */
252:            private boolean isValidLockType(int lockType) {
253:                return ((lockType == READ_LOCK) || (lockType == WRITE_LOCK));
254:            }
255:
256:            /**
257:             * Returns a lock for the entity, lock type and owner if no conflicting locks exist.
258:             * @param entityType
259:             * @param entityKey
260:             * @param lockType
261:             * @param owner
262:             * @return org.jasig.portal.groups.IEntityLock
263:             * @exception LockingException
264:             */
265:            public IEntityLock newLock(Class entityType, String entityKey,
266:                    int lockType, String owner) throws LockingException {
267:                return newLock(entityType, entityKey, lockType, owner,
268:                        defaultLockPeriod);
269:            }
270:
271:            /**
272:             * Returns a lock for the entity, lock type and owner if no conflicting locks exist.
273:             * @param entityType
274:             * @param entityKey
275:             * @param lockType
276:             * @param owner
277:             * @param durationSecs
278:             * @return org.jasig.portal.groups.IEntityLock
279:             * @exception LockingException
280:             * 
281:             * Retrieves potentially conflicting locks and checks them before adding
282:             * the new lock to the store.  The add of a write lock will fail if any 
283:             * other lock exists for the entity.  The add of a read lock will fail if 
284:             * a write lock exists for the entity.  After we add a write lock we 
285:             * check the store a second time and roll back if any other lock has snuck
286:             * in.  I think this is slightly safer than depending on the db isolation
287:             * level for transactional integrity.  
288:             */
289:            public IEntityLock newLock(Class entityType, String entityKey,
290:                    int lockType, String owner, int durationSecs)
291:                    throws LockingException {
292:                int expirationSecs = durationSecs;
293:                Date expires = getNewExpiration(expirationSecs);
294:                IEntityLock newLock = new EntityLockImpl(entityType, entityKey,
295:                        lockType, expires, owner, this );
296:
297:                // retrieve potentially conflicting locks:
298:                IEntityLock[] locks = retrieveLocks(entityType, entityKey, null);
299:
300:                if (lockType == WRITE_LOCK) {
301:                    if (locks.length > 0) {
302:                        throw new LockingException(
303:                                "Could not create lock: entity already locked.");
304:                    }
305:
306:                    getLockStore().add(newLock);
307:
308:                    locks = retrieveLocks(entityType, entityKey, null);
309:                    if (locks.length > 1) // another lock snuck in
310:                    {
311:                        release(newLock);
312:                        throw new LockingException(
313:                                "Could not create lock: entity already locked.");
314:                    }
315:                }
316:
317:                else // ( lockType == READ_LOCK )
318:                {
319:                    for (int i = 0; i < locks.length; i++) {
320:                        if (locks[i].getLockType() == WRITE_LOCK) {
321:                            throw new LockingException(
322:                                    "Could not create lock: entity already write locked.");
323:                        } else {
324:                            if (locks[i].equals(newLock)) {
325:                                // another read lock from the same owner; bump the expiration time.
326:                                expirationSecs++;
327:                                expires = getNewExpiration(expirationSecs);
328:                                newLock = new EntityLockImpl(entityType,
329:                                        entityKey, lockType, expires, owner,
330:                                        this );
331:                            }
332:                        }
333:                    }
334:                    getLockStore().add(newLock);
335:                }
336:                return newLock;
337:            }
338:
339:            /**
340:             * Returns a lock for the entity, lock type and owner if no conflicting locks exist.
341:             * @return org.jasig.portal.groups.IEntityLock
342:             * @param entityID org.jasig.portal.EntityIdentifier
343:             * @param lockType int
344:             * @param owner String
345:             * @exception LockingException
346:             */
347:            public IEntityLock newLock(EntityIdentifier entityID, int lockType,
348:                    String owner) throws LockingException {
349:                return newLock(entityID.getType(), entityID.getKey(), lockType,
350:                        owner, defaultLockPeriod);
351:            }
352:
353:            /**
354:             * Returns a lock for the entity, lock type and owner if no conflicting locks exist.
355:             * @return org.jasig.portal.groups.IEntityLock
356:             * @param entityID org.jasig.portal.EntityIdentifier
357:             * @param lockType int
358:             * @param owner String
359:             * @param durationSecs int
360:             * @exception LockingException
361:             */
362:            public IEntityLock newLock(EntityIdentifier entityID, int lockType,
363:                    String owner, int durationSecs) throws LockingException {
364:                return newLock(entityID.getType(), entityID.getKey(), lockType,
365:                        owner, durationSecs);
366:            }
367:
368:            /**
369:             * Releases the <code>IEntityLock</code>.
370:             * @param lock IEntityLock
371:             * @exception LockingException
372:             */
373:            public void release(IEntityLock lock) throws LockingException {
374:                getLockStore().delete(lock);
375:                ((EntityLockImpl) lock).setExpirationTime(new Date(0));
376:            }
377:
378:            /**
379:             * Extends the expiration time of the lock by some service-defined increment.
380:             * @param lock IEntityLock
381:             * @exception LockingException
382:             */
383:            public void renew(IEntityLock lock) throws LockingException {
384:                renew(lock, defaultLockPeriod);
385:            }
386:
387:            /**
388:             * Extends the expiration time of the lock by some service-defined increment.
389:             * @param lock IEntityLock
390:             * @exception LockingException
391:             */
392:            public void renew(IEntityLock lock, int duration)
393:                    throws LockingException {
394:                if (isValid(lock)) {
395:                    Date newExpiration = getNewExpiration(duration);
396:                    getLockStore().update(lock, newExpiration);
397:                    ((EntityLockImpl) lock).setExpirationTime(newExpiration);
398:                } else {
399:                    throw new LockingException("Could not renew " + lock
400:                            + " : lock is invalid.");
401:                }
402:            }
403:
404:            /**
405:             * Returns an IEntityLock[] containing unexpired locks for the entityType, entityKey
406:             * and lockType.  Param <code>lockType</code> can be null.
407:             *
408:             * @param entityType
409:             * @param entityKey
410:             * @param lockType (optional)
411:             * @exception LockingException
412:             */
413:            private IEntityLock[] retrieveLocks(Class entityType,
414:                    String entityKey, Integer lockType) throws LockingException {
415:                Date expiration = (multiServer) ? new Date(System
416:                        .currentTimeMillis()
417:                        - getLockToleranceMillis()) : new Date();
418:
419:                return getLockStore().findUnexpired(expiration, entityType,
420:                        entityKey, lockType, null);
421:            }
422:
423:            /**
424:             * @param newDefaultLockPeriod int
425:             */
426:            private void setDefaultLockPeriod(int newDefaultLockPeriod) {
427:                defaultLockPeriod = newDefaultLockPeriod;
428:            }
429:
430:            /**
431:             * @param newLockToleranceMillis int
432:             */
433:            private void setLockToleranceMillis(int newLockToleranceMillis) {
434:                lockToleranceMillis = newLockToleranceMillis;
435:            }
436:
437:            /**
438:             * @param newMultiServer boolean
439:             */
440:            private void setMultiServer(boolean newMultiServer) {
441:                multiServer = newMultiServer;
442:            }
443:
444:            /**
445:             * @return org.jasig.portal.concurrency.locking.ReferenceEntityLockService
446:             */
447:            public static synchronized IEntityLockService singleton()
448:                    throws LockingException {
449:                if (singleton == null) {
450:                    singleton = new ReferenceEntityLockService();
451:                }
452:                return singleton;
453:            }
454:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.