Source Code Cross Referenced for CmsLockManager.java in  » Content-Management-System » opencms » org » opencms » lock » 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 » Content Management System » opencms » org.opencms.lock 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * File   : $Source: /usr/local/cvs/opencms/src/org/opencms/lock/CmsLockManager.java,v $
003:         * Date   : $Date: 2008-02-27 12:05:46 $
004:         * Version: $Revision: 1.48 $
005:         *
006:         * This library is part of OpenCms -
007:         * the Open Source Content Management System
008:         *
009:         * Copyright (c) 2002 - 2008 Alkacon Software GmbH (http://www.alkacon.com)
010:         *
011:         * This library is free software; you can redistribute it and/or
012:         * modify it under the terms of the GNU Lesser General Public
013:         * License as published by the Free Software Foundation; either
014:         * version 2.1 of the License, or (at your option) any later version.
015:         *
016:         * This library is distributed in the hope that it will be useful,
017:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
018:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019:         * Lesser General Public License for more details.
020:         *
021:         * For further information about Alkacon Software GmbH, please see the
022:         * company website: http://www.alkacon.com
023:         *
024:         * For further information about OpenCms, please see the
025:         * project website: http://www.opencms.org
026:         * 
027:         * You should have received a copy of the GNU Lesser General Public
028:         * License along with this library; if not, write to the Free Software
029:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
030:         */
031:
032:        package org.opencms.lock;
033:
034:        import org.opencms.db.CmsDbContext;
035:        import org.opencms.db.CmsDriverManager;
036:        import org.opencms.file.CmsProject;
037:        import org.opencms.file.CmsResource;
038:        import org.opencms.file.CmsResourceFilter;
039:        import org.opencms.file.CmsUser;
040:        import org.opencms.file.CmsVfsResourceNotFoundException;
041:        import org.opencms.i18n.CmsMessageContainer;
042:        import org.opencms.main.CmsException;
043:        import org.opencms.main.OpenCms;
044:        import org.opencms.util.CmsUUID;
045:
046:        import java.util.ArrayList;
047:        import java.util.Collections;
048:        import java.util.HashMap;
049:        import java.util.Iterator;
050:        import java.util.List;
051:        import java.util.Map;
052:
053:        /**
054:         * The CmsLockManager is used by the Cms application to detect 
055:         * the lock state of a resource.<p>
056:         * 
057:         * The lock state depends on the path of the resource, and probably 
058:         * locked parent folders. The result of a query to the lock manager
059:         * are instances of CmsLock objects.<p>
060:         * 
061:         * @author Michael Emmerich 
062:         * @author Thomas Weckert  
063:         * @author Andreas Zahner  
064:         * @author Michael Moossen  
065:         * 
066:         * @version $Revision: 1.48 $ 
067:         * 
068:         * @since 6.0.0 
069:         * 
070:         * @see org.opencms.file.CmsObject#getLock(CmsResource)
071:         * @see org.opencms.lock.CmsLock
072:         */
073:        public final class CmsLockManager {
074:
075:            /** The driver manager instance. */
076:            private CmsDriverManager m_driverManager;
077:
078:            /** The flag to indicate if the locks should be written to the db. */
079:            private boolean m_isDirty = false;
080:
081:            /** The flag to indicate if the lock manager has been started in run level 4. */
082:            private boolean m_runningInServlet = false;
083:
084:            /**
085:             * Default constructor, creates a new lock manager.<p>
086:             * 
087:             * @param driverManager the driver manager instance 
088:             */
089:            public CmsLockManager(CmsDriverManager driverManager) {
090:
091:                m_driverManager = driverManager;
092:            }
093:
094:            /**
095:             * Adds a resource to the lock manager.<p>
096:             * 
097:             * @param dbc the current database context
098:             * @param resource the resource
099:             * @param user the user who locked the resource
100:             * @param project the project where the resource is locked
101:             * @param type the lock type
102:             * 
103:             * @throws CmsLockException if the resource is locked
104:             * @throws CmsException if something goes wrong
105:             */
106:            public void addResource(CmsDbContext dbc, CmsResource resource,
107:                    CmsUser user, CmsProject project, CmsLockType type)
108:                    throws CmsLockException, CmsException {
109:
110:                // check the type
111:                if (!type.isSystem() && !type.isExclusive()) {
112:                    // invalid type
113:                    throw new CmsLockException(Messages.get().container(
114:                            Messages.ERR_INVALID_LOCK_TYPE_1, type.toString()));
115:                }
116:
117:                // get the current lock
118:                CmsLock currentLock = getLock(dbc, resource);
119:
120:                // check lockability
121:                checkLockable(dbc, resource, user, project, type, currentLock);
122:
123:                boolean needNewLock = true;
124:                // prevent shared locks get compromised
125:                if ((type.isExclusive())
126:                        && !(type.isTemporary() && currentLock.isInherited())) {
127:                    if (!currentLock.getEditionLock().isUnlocked()) {
128:                        needNewLock = false;
129:                    }
130:                }
131:
132:                CmsLock newLock = CmsLock.getNullLock();
133:                if (needNewLock) {
134:                    // lock the resource
135:                    newLock = new CmsLock(resource.getRootPath(), user.getId(),
136:                            project, type);
137:                    lockResource(newLock);
138:                }
139:
140:                // handle collisions with exclusive locked sub-resources in case of a folder
141:                if (resource.isFolder() && newLock.getSystemLock().isUnlocked()) {
142:                    String resourceName = resource.getRootPath();
143:                    Iterator itLocks = OpenCms.getMemoryMonitor()
144:                            .getAllCachedLocks().iterator();
145:                    while (itLocks.hasNext()) {
146:                        CmsLock lock = (CmsLock) itLocks.next();
147:                        String lockedPath = lock.getResourceName();
148:                        if (lockedPath.startsWith(resourceName)
149:                                && !lockedPath.equals(resourceName)) {
150:                            unlockResource(lockedPath, false);
151:                        }
152:                    }
153:                }
154:            }
155:
156:            /**
157:             * Counts the exclusive locked resources in a project.<p>
158:             * 
159:             * @param project the project
160:             * 
161:             * @return the number of exclusive locked resources in the specified project
162:             */
163:            public int countExclusiveLocksInProject(CmsProject project) {
164:
165:                int count = 0;
166:                Iterator itLocks = OpenCms.getMemoryMonitor()
167:                        .getAllCachedLocks().iterator();
168:                while (itLocks.hasNext()) {
169:                    CmsLock lock = (CmsLock) itLocks.next();
170:                    if (lock.getEditionLock().isInProject(project)) {
171:                        count++;
172:                    }
173:                }
174:                return count;
175:            }
176:
177:            /**
178:             * Returns the lock state of the given resource.<p>
179:             * 
180:             * In case no lock is set, the <code>null lock</code> which can be obtained 
181:             * by {@link CmsLock#getNullLock()} is returned.<p>
182:             * 
183:             * @param dbc the current database context
184:             * @param resource the resource
185:             * 
186:             * @return the lock state of the given resource 
187:
188:             * @throws CmsException if something goes wrong
189:             */
190:            public CmsLock getLock(CmsDbContext dbc, CmsResource resource)
191:                    throws CmsException {
192:
193:                return getLock(dbc, resource, true);
194:            }
195:
196:            /**
197:             * Returns the lock state of the given resource.<p>
198:             * 
199:             * In case no lock is set, the <code>null lock</code> which can be obtained 
200:             * by {@link CmsLock#getNullLock()} is returned.<p>
201:             * 
202:             * @param dbc the current database context
203:             * @param resource the resource
204:             * @param includeSiblings if siblings (shared locks) should be included in the search
205:             * 
206:             * @return the lock state of the given resource 
207:
208:             * @throws CmsException if something goes wrong
209:             */
210:            public CmsLock getLock(CmsDbContext dbc, CmsResource resource,
211:                    boolean includeSiblings) throws CmsException {
212:
213:                // resources are never locked in the online project
214:                // and non-existent resources are never locked
215:                if ((resource == null)
216:                        || (dbc.currentProject().isOnlineProject())) {
217:                    return CmsLock.getNullLock();
218:                }
219:
220:                // check exclusive direct locks first
221:                CmsLock lock = getDirectLock(resource.getRootPath());
222:                if ((lock == null) && includeSiblings) {
223:                    // check if siblings are exclusively locked
224:                    List siblings = internalReadSiblings(dbc, resource);
225:                    lock = getSiblingsLock(siblings, resource.getRootPath());
226:                }
227:                if (lock == null) {
228:                    // if there is no parent lock, this will be the null lock as well
229:                    lock = getParentLock(resource.getRootPath());
230:                }
231:                if (!lock.getSystemLock().isUnlocked()) {
232:                    lock = lock.getSystemLock();
233:                } else {
234:                    lock = lock.getEditionLock();
235:                }
236:                return lock;
237:            }
238:
239:            /**
240:             * Returns all exclusive locked resources matching the given resource name and filter.<p>
241:             * 
242:             * @param dbc the database context
243:             * @param resourceName the resource name
244:             * @param filter the lock filter
245:             * 
246:             * @return a list of root paths
247:             * 
248:             * @throws CmsException if something goes wrong 
249:             */
250:            public List getLocks(CmsDbContext dbc, String resourceName,
251:                    CmsLockFilter filter) throws CmsException {
252:
253:                List locks = new ArrayList();
254:                Iterator itLocks = OpenCms.getMemoryMonitor()
255:                        .getAllCachedLocks().iterator();
256:                while (itLocks.hasNext()) {
257:                    CmsLock lock = (CmsLock) itLocks.next();
258:                    if (filter.isSharedExclusive()) {
259:                        CmsResource resource;
260:                        try {
261:                            resource = m_driverManager.readResource(dbc, lock
262:                                    .getResourceName(), CmsResourceFilter.ALL);
263:                        } catch (CmsVfsResourceNotFoundException e) {
264:                            OpenCms.getMemoryMonitor().uncacheLock(
265:                                    lock.getResourceName());
266:                            continue;
267:                        }
268:                        if (resource.getSiblingCount() > 1) {
269:                            Iterator itSiblings = internalReadSiblings(dbc,
270:                                    resource).iterator();
271:                            while (itSiblings.hasNext()) {
272:                                CmsResource sibling = (CmsResource) itSiblings
273:                                        .next();
274:                                CmsLock siblingLock = internalSiblingLock(lock,
275:                                        sibling.getRootPath());
276:                                if (filter.match(resourceName, siblingLock)) {
277:                                    locks.add(siblingLock);
278:                                }
279:                            }
280:                        }
281:                    }
282:                    if (filter.match(resourceName, lock)) {
283:                        locks.add(lock);
284:                    }
285:                }
286:                return locks;
287:            }
288:
289:            /**
290:             * Returns <code>true</code> if the given resource contains a resource that has a system lock.<p>
291:             * 
292:             * This check is required for certain operations on folders.<p> 
293:             * 
294:             * @param dbc the database context
295:             * @param resource the resource to check the system locks for
296:             * 
297:             * @return <code>true</code> if the given resource contains a resource that has a system lock
298:             * 
299:             * @throws CmsException if something goes wrong 
300:             */
301:            public boolean hasSystemLocks(CmsDbContext dbc, CmsResource resource)
302:                    throws CmsException {
303:
304:                if (resource == null) {
305:                    return false;
306:                }
307:                Iterator itLocks = OpenCms.getMemoryMonitor()
308:                        .getAllCachedLocks().iterator();
309:                while (itLocks.hasNext()) {
310:                    CmsLock lock = (CmsLock) itLocks.next();
311:                    if (lock.getSystemLock().isUnlocked()) {
312:                        // only system locks matter here
313:                        continue;
314:                    }
315:                    if (lock.getResourceName().startsWith(
316:                            resource.getRootPath())) {
317:                        if (lock.getResourceName().startsWith(
318:                                resource.getRootPath())) {
319:                            return true;
320:                        }
321:                        try {
322:                            resource = m_driverManager.readResource(dbc, lock
323:                                    .getResourceName(), CmsResourceFilter.ALL);
324:                        } catch (CmsVfsResourceNotFoundException e) {
325:                            OpenCms.getMemoryMonitor().uncacheLock(
326:                                    lock.getResourceName());
327:                            continue;
328:                        }
329:                        CmsResource lockedResource;
330:                        try {
331:                            lockedResource = m_driverManager.readResource(dbc,
332:                                    lock.getResourceName(),
333:                                    CmsResourceFilter.ALL);
334:                        } catch (CmsVfsResourceNotFoundException e) {
335:                            OpenCms.getMemoryMonitor().uncacheLock(
336:                                    lock.getResourceName());
337:                            continue;
338:                        }
339:                        if (lockedResource.getSiblingCount() > 1) {
340:                            Iterator itSiblings = internalReadSiblings(dbc,
341:                                    lockedResource).iterator();
342:                            while (itSiblings.hasNext()) {
343:                                CmsResource sibling = (CmsResource) itSiblings
344:                                        .next();
345:                                CmsLock siblingLock = internalSiblingLock(lock,
346:                                        sibling.getRootPath());
347:                                if (siblingLock.getResourceName().startsWith(
348:                                        resource.getRootPath())) {
349:                                    return true;
350:                                }
351:                            }
352:                        }
353:                    }
354:                }
355:                return false;
356:            }
357:
358:            /**
359:             * Moves a lock during the move resource operation.<p>
360:             * 
361:             * @param source the source root path 
362:             * @param destination the destination root path
363:             */
364:            public void moveResource(String source, String destination) {
365:
366:                CmsLock lock = OpenCms.getMemoryMonitor().getCachedLock(source);
367:                if (lock != null) {
368:                    OpenCms.getMemoryMonitor().uncacheLock(
369:                            lock.getResourceName());
370:                    CmsLock newLock = new CmsLock(destination,
371:                            lock.getUserId(), lock.getProject(), lock.getType());
372:                    lock = lock.getRelatedLock();
373:                    if ((lock != null) && !lock.isNullLock()) {
374:                        CmsLock relatedLock = new CmsLock(destination, lock
375:                                .getUserId(), lock.getProject(), lock.getType());
376:                        newLock.setRelatedLock(relatedLock);
377:                    }
378:                    OpenCms.getMemoryMonitor().cacheLock(newLock);
379:                }
380:            }
381:
382:            /**
383:             * Reads the latest saved locks from the database and installs them to 
384:             * this lock manager.<p>
385:             * 
386:             *  @param dbc the current database context
387:             *  
388:             *  @throws CmsException if something goes wrong
389:             */
390:            public void readLocks(CmsDbContext dbc) throws CmsException {
391:
392:                if (OpenCms.getRunLevel() > OpenCms.RUNLEVEL_3_SHELL_ACCESS) {
393:                    // read the locks only if the wizard is not enabled
394:                    Map lockCache = new HashMap();
395:                    List locks = m_driverManager.getProjectDriver().readLocks(
396:                            dbc);
397:                    Iterator itLocks = locks.iterator();
398:                    while (itLocks.hasNext()) {
399:                        CmsLock lock = (CmsLock) itLocks.next();
400:                        internalLockResource(lock, lockCache);
401:                    }
402:                    OpenCms.getMemoryMonitor().flushLocks(lockCache);
403:                    m_runningInServlet = true;
404:                }
405:            }
406:
407:            /**
408:             * Removes a resource after it has been deleted by the driver manager.<p>
409:             * 
410:             * @param dbc the current database context
411:             * @param resourceName the root path of the deleted resource
412:             * @throws CmsException if something goes wrong
413:             */
414:            public void removeDeletedResource(CmsDbContext dbc,
415:                    String resourceName) throws CmsException {
416:
417:                try {
418:                    m_driverManager.getVfsDriver()
419:                            .readResource(dbc, dbc.currentProject().getUuid(),
420:                                    resourceName, false);
421:                    throw new CmsLockException(Messages.get().container(
422:                            Messages.ERR_REMOVING_UNDELETED_RESOURCE_1,
423:                            dbc.getRequestContext()
424:                                    .removeSiteRoot(resourceName)));
425:                } catch (CmsVfsResourceNotFoundException e) {
426:                    // ok, ignore
427:                }
428:                unlockResource(resourceName, true);
429:                unlockResource(resourceName, false);
430:            }
431:
432:            /**
433:             * Removes all locks of a user.<p>
434:             * 
435:             * Edition and system locks are removed.<p>
436:             * 
437:             * @param userId the id of the user whose locks should be removed
438:             */
439:            public void removeLocks(CmsUUID userId) {
440:
441:                Iterator itLocks = OpenCms.getMemoryMonitor()
442:                        .getAllCachedLocks().iterator();
443:                while (itLocks.hasNext()) {
444:                    CmsLock currentLock = (CmsLock) itLocks.next();
445:                    boolean editLock = currentLock.getEditionLock().getUserId()
446:                            .equals(userId);
447:                    boolean sysLock = currentLock.getSystemLock().getUserId()
448:                            .equals(userId);
449:                    if (editLock) {
450:                        unlockResource(currentLock.getResourceName(), false);
451:                    }
452:                    if (sysLock) {
453:                        unlockResource(currentLock.getResourceName(), true);
454:                    }
455:                }
456:            }
457:
458:            /**
459:             * Removes a resource from the lock manager.<p>
460:             * 
461:             * The forceUnlock option should be used with caution.<br>
462:             * forceUnlock will remove the lock by ignoring any rules which may cause wrong lock states.<p>
463:             * 
464:             * @param dbc the current database context
465:             * @param resource the resource
466:             * @param forceUnlock <code>true</code>, if a resource is forced to get unlocked (only edition locks), 
467:             *                    no matter by which user and in which project the resource is currently locked
468:             * @param removeSystemLock <code>true</code>, if you also want to remove system locks
469:             * 
470:             * @return the previous {@link CmsLock} object of the resource, 
471:             *          or <code>{@link CmsLock#getNullLock()}</code> if the resource was unlocked
472:             *
473:             * @throws CmsException if something goes wrong
474:             */
475:            public CmsLock removeResource(CmsDbContext dbc,
476:                    CmsResource resource, boolean forceUnlock,
477:                    boolean removeSystemLock) throws CmsException {
478:
479:                String resourcename = resource.getRootPath();
480:                CmsLock lock = getLock(dbc, resource).getEditionLock();
481:
482:                // check some abort conditions first
483:                if (!lock.isNullLock()) {
484:                    // the resource is locked by another user or in other project
485:                    if (!forceUnlock
486:                            && (!lock.isOwnedInProjectBy(dbc.currentUser(), dbc
487:                                    .currentProject()))) {
488:                        throw new CmsLockException(Messages.get().container(
489:                                Messages.ERR_RESOURCE_UNLOCK_1,
490:                                dbc.removeSiteRoot(resourcename)));
491:                    }
492:
493:                    // sub-resources of a locked folder can't be unlocked
494:                    if (!forceUnlock && lock.isInherited()) {
495:                        throw new CmsLockException(Messages.get().container(
496:                                Messages.ERR_UNLOCK_LOCK_INHERITED_1,
497:                                dbc.removeSiteRoot(resourcename)));
498:                    }
499:                }
500:
501:                // remove the lock and clean-up stuff
502:                if (lock.isExclusive()) {
503:                    if (resource.isFolder()) {
504:                        // in case of a folder, remove any exclusive locks on sub-resources that probably have
505:                        // been upgraded from an inherited lock when the user edited a resource                
506:                        Iterator itLocks = OpenCms.getMemoryMonitor()
507:                                .getAllCachedLocks().iterator();
508:                        while (itLocks.hasNext()) {
509:                            String lockedPath = ((CmsLock) itLocks.next())
510:                                    .getResourceName();
511:                            if (lockedPath.startsWith(resourcename)
512:                                    && !lockedPath.equals(resourcename)) {
513:                                // remove the exclusive locked sub-resource
514:                                unlockResource(lockedPath, false);
515:                            }
516:                        }
517:                    }
518:                    if (removeSystemLock) {
519:                        unlockResource(resourcename, true);
520:                    }
521:                    unlockResource(resourcename, false);
522:                    return lock;
523:                }
524:
525:                if (lock.getType().isSharedExclusive()) {
526:                    List locks = OpenCms.getMemoryMonitor()
527:                            .getAllCachedLockPaths();
528:                    // when a resource with a shared lock gets unlocked, fetch all siblings of the resource 
529:                    // to the same content record to identify the exclusive locked sibling
530:                    List siblings = internalReadSiblings(dbc, resource);
531:                    for (int i = 0; i < siblings.size(); i++) {
532:                        CmsResource sibling = (CmsResource) siblings.get(i);
533:                        if (locks.contains(sibling.getRootPath())) {
534:                            // remove the exclusive locked sibling
535:                            if (removeSystemLock) {
536:                                unlockResource(sibling.getRootPath(), true);
537:                            }
538:                            unlockResource(sibling.getRootPath(), false);
539:                            break; // it can only be one!
540:                        }
541:                    }
542:                    return lock;
543:                }
544:
545:                // remove system locks only if explicit required
546:                if (removeSystemLock
547:                        && !getLock(dbc, resource).getSystemLock().isUnlocked()) {
548:                    return unlockResource(resourcename, true);
549:                }
550:                return lock;
551:            }
552:
553:            /**
554:             * Removes all resources locked in a project.<p>
555:             * 
556:             * @param projectId the ID of the project where the resources have been locked
557:             * @param removeSystemLocks if <code>true</code>, also system locks are removed
558:             */
559:            public void removeResourcesInProject(CmsUUID projectId,
560:                    boolean removeSystemLocks) {
561:
562:                Iterator itLocks = OpenCms.getMemoryMonitor()
563:                        .getAllCachedLocks().iterator();
564:                while (itLocks.hasNext()) {
565:                    CmsLock currentLock = (CmsLock) itLocks.next();
566:                    if (removeSystemLocks
567:                            && currentLock.getSystemLock().getProjectId()
568:                                    .equals(projectId)) {
569:                        unlockResource(currentLock.getResourceName(), true);
570:                    }
571:                    if (currentLock.getEditionLock().getProjectId().equals(
572:                            projectId)) {
573:                        unlockResource(currentLock.getResourceName(), false);
574:                    }
575:                }
576:            }
577:
578:            /**
579:             * Removes all exclusive temporary locks of a user.<p>
580:             * 
581:             * Only edition lock can be temporary, so no system locks are removed.<p>
582:             * 
583:             * @param userId the id of the user whose locks has to be removed
584:             */
585:            public void removeTempLocks(CmsUUID userId) {
586:
587:                Iterator itLocks = OpenCms.getMemoryMonitor()
588:                        .getAllCachedLocks().iterator();
589:                while (itLocks.hasNext()) {
590:                    CmsLock currentLock = (CmsLock) itLocks.next();
591:                    if (currentLock.isTemporary()
592:                            && currentLock.getUserId().equals(userId)) {
593:                        unlockResource(currentLock.getResourceName(), false);
594:                    }
595:                }
596:            }
597:
598:            /** 
599:             * @see java.lang.Object#toString()
600:             */
601:            public String toString() {
602:
603:                StringBuffer buf = new StringBuffer();
604:
605:                // bring the list of locked resources into a human readable order first
606:                List lockedResources = OpenCms.getMemoryMonitor()
607:                        .getAllCachedLocks();
608:                Collections.sort(lockedResources);
609:
610:                // iterate all locks
611:                Iterator itLocks = lockedResources.iterator();
612:                while (itLocks.hasNext()) {
613:                    CmsLock lock = (CmsLock) itLocks.next();
614:                    buf.append(lock).append("\n");
615:                }
616:                return buf.toString();
617:            }
618:
619:            /**
620:             * Writes the locks that are currently stored in-memory to the database to allow restoring them in 
621:             * later startups.<p> 
622:             * 
623:             * This overwrites the locks previously stored in the underlying database table.<p>
624:             * 
625:             *  @param dbc the current database context
626:             *  
627:             *  @throws CmsException if something goes wrong
628:             */
629:            public void writeLocks(CmsDbContext dbc) throws CmsException {
630:
631:                if (m_isDirty // only if something changed
632:                        && m_runningInServlet // only if started in run level 4 
633:                        && OpenCms.getMemoryMonitor().requiresPersistency()) { // only if persistency is required
634:
635:                    List locks = OpenCms.getMemoryMonitor().getAllCachedLocks();
636:                    m_driverManager.getProjectDriver().writeLocks(dbc, locks);
637:                    m_isDirty = false;
638:                }
639:            }
640:
641:            /**
642:             * Checks if the given resource is lockable by the given user/project/lock type.<p> 
643:             * 
644:             * @param dbc just to get the site path of the resource
645:             * @param resource the resource to check lockability for
646:             * @param user the user to check
647:             * @param project the project to check
648:             * @param type the lock type to check
649:             * @param currentLock the resource current lock
650:             * 
651:             * @throws CmsLockException if resource is not lockable
652:             */
653:            private void checkLockable(CmsDbContext dbc, CmsResource resource,
654:                    CmsUser user, CmsProject project, CmsLockType type,
655:                    CmsLock currentLock) throws CmsLockException {
656:
657:                if (!currentLock.isLockableBy(user)) {
658:                    // check type, owner and project for system locks
659:                    // this is required if publishing several siblings
660:                    if (currentLock.getSystemLock().isUnlocked()
661:                            || (currentLock.getType() != type)
662:                            || !currentLock.isOwnedInProjectBy(user, project)) {
663:                        // display the right message
664:                        CmsMessageContainer message = null;
665:                        if (currentLock.getSystemLock().isPublish()) {
666:                            message = Messages.get().container(
667:                                    Messages.ERR_RESOURCE_LOCKED_FORPUBLISH_1,
668:                                    dbc.getRequestContext().getSitePath(
669:                                            resource));
670:                        } else if (currentLock.getEditionLock().isInherited()) {
671:                            message = Messages.get().container(
672:                                    Messages.ERR_RESOURCE_LOCKED_INHERITED_1,
673:                                    dbc.getRequestContext().getSitePath(
674:                                            resource));
675:                        } else {
676:                            message = Messages.get().container(
677:                                    Messages.ERR_RESOURCE_LOCKED_BYOTHERUSER_1,
678:                                    dbc.getRequestContext().getSitePath(
679:                                            resource));
680:                        }
681:                        throw new CmsLockException(message);
682:                    }
683:                }
684:            }
685:
686:            /**
687:             * Returns the direct lock of a resource.<p>
688:             * 
689:             * @param resourcename the name of the resource
690:             * 
691:             * @return the direct lock of the resource or <code>null</code> 
692:             */
693:            private CmsLock getDirectLock(String resourcename) {
694:
695:                return OpenCms.getMemoryMonitor().getCachedLock(resourcename);
696:            }
697:
698:            /**
699:             * Returns the lock of a possible locked parent folder of a resource, system locks are ignored.<p>
700:             * 
701:             * @param resourceName the name of the resource
702:             * 
703:             * @return the lock of a parent folder, or {@link CmsLock#getNullLock()} if no parent folders are locked by a non system lock
704:             */
705:            private CmsLock getParentFolderLock(String resourceName) {
706:
707:                Iterator itLocks = OpenCms.getMemoryMonitor()
708:                        .getAllCachedLocks().iterator();
709:                while (itLocks.hasNext()) {
710:                    CmsLock lock = (CmsLock) itLocks.next();
711:                    if (lock.getResourceName().endsWith("/")
712:                            && resourceName.startsWith(lock.getResourceName())
713:                            && !resourceName.equals(lock.getResourceName())) {
714:                        // system locks does not get inherited
715:                        lock = lock.getEditionLock();
716:                        // check the lock
717:                        if (!lock.isUnlocked()) {
718:                            return lock;
719:                        }
720:                    }
721:                }
722:                return CmsLock.getNullLock();
723:            }
724:
725:            /**
726:             * Returns the inherited lock of a resource.<p>
727:             * 
728:             * @param resourcename the name of the resource
729:             * @return the inherited lock or the null lock
730:             */
731:            private CmsLock getParentLock(String resourcename) {
732:
733:                CmsLock parentFolderLock = getParentFolderLock(resourcename);
734:                if (!parentFolderLock.isNullLock()) {
735:                    return new CmsLock(resourcename, parentFolderLock
736:                            .getUserId(), parentFolderLock.getProject(),
737:                            CmsLockType.INHERITED);
738:                }
739:                return CmsLock.getNullLock();
740:            }
741:
742:            /**
743:             * Returns the indirect lock of a resource depending on siblings lock state.<p>
744:             * 
745:             * @param siblings the list of siblings
746:             * @param resourcename the name of the resource
747:             * 
748:             * @return the indirect lock of the resource or the null lock
749:             */
750:            private CmsLock getSiblingsLock(List siblings, String resourcename) {
751:
752:                for (int i = 0; i < siblings.size(); i++) {
753:                    CmsResource sibling = (CmsResource) siblings.get(i);
754:                    CmsLock exclusiveLock = getDirectLock(sibling.getRootPath());
755:                    if (exclusiveLock != null) {
756:                        // a sibling is already locked 
757:                        return internalSiblingLock(exclusiveLock, resourcename);
758:                    }
759:                }
760:                // no locked siblings found
761:                return null;
762:
763:            }
764:
765:            /**
766:             * Finally set the given lock.<p>
767:             * 
768:             * @param lock the lock to set
769:             * @param locks during reading the locks from db we need to operate on an extra map
770:             * 
771:             * @throws CmsLockException if the lock is not compatible with the current lock 
772:             */
773:            private void internalLockResource(CmsLock lock, Map locks)
774:                    throws CmsLockException {
775:
776:                CmsLock currentLock = null;
777:                if (locks == null) {
778:                    currentLock = OpenCms.getMemoryMonitor().getCachedLock(
779:                            lock.getResourceName());
780:                } else {
781:                    currentLock = (CmsLock) locks.get(lock.getResourceName());
782:                }
783:                if (currentLock != null) {
784:                    if (currentLock.getSystemLock().equals(lock)
785:                            || currentLock.getEditionLock().equals(lock)) {
786:                        return;
787:                    }
788:                    if (!currentLock.getSystemLock().isUnlocked()
789:                            && lock.getSystemLock().isUnlocked()) {
790:                        lock.setRelatedLock(currentLock);
791:                        if (locks == null) {
792:                            OpenCms.getMemoryMonitor().cacheLock(lock);
793:                        } else {
794:                            locks.put(lock.getResourceName(), lock);
795:                        }
796:                    } else if (currentLock.getSystemLock().isUnlocked()
797:                            && !lock.getSystemLock().isUnlocked()) {
798:                        currentLock.setRelatedLock(lock);
799:                    } else {
800:                        throw new CmsLockException(Messages.get().container(
801:                                Messages.ERR_LOCK_ILLEGAL_STATE_2, currentLock,
802:                                lock));
803:                    }
804:                } else {
805:                    if (locks == null) {
806:                        OpenCms.getMemoryMonitor().cacheLock(lock);
807:                    } else {
808:                        locks.put(lock.getResourceName(), lock);
809:                    }
810:                }
811:            }
812:
813:            /**
814:             * Reads all siblings from a given resource.<p>
815:             * 
816:             * The result is a list of <code>{@link CmsResource}</code> objects. 
817:             * It does NOT contain the resource itself, only the siblings of the resource.<p>
818:             * 
819:             * @param dbc the current database context
820:             * @param resource the resource to find all siblings from
821:             * 
822:             * @return a list of <code>{@link CmsResource}</code> Objects that 
823:             *          are siblings to the specified resource, 
824:             *          excluding the specified resource itself
825:             * 
826:             * @throws CmsException if something goes wrong
827:             */
828:            private List internalReadSiblings(CmsDbContext dbc,
829:                    CmsResource resource) throws CmsException {
830:
831:                // reading siblings using the DriverManager methods while the lock state is checked would
832:                // result in an infinite loop, therefore we must access the VFS driver directly
833:                List siblings = m_driverManager.getVfsDriver().readSiblings(
834:                        dbc, dbc.currentProject().getUuid(), resource, true);
835:                siblings.remove(resource);
836:                return siblings;
837:            }
838:
839:            /**
840:             * Returns a shared lock for the given excclusive lock and sibling.<p>
841:             * 
842:             * @param exclusiveLock the exclusive lock to use (has to be set on a sibling of siblingName)
843:             * @param siblingName the siblings name
844:             * 
845:             * @return the shared lock
846:             */
847:            private CmsLock internalSiblingLock(CmsLock exclusiveLock,
848:                    String siblingName) {
849:
850:                CmsLock lock = null;
851:                if (!exclusiveLock.getSystemLock().isUnlocked()) {
852:                    lock = new CmsLock(siblingName, exclusiveLock.getUserId(),
853:                            exclusiveLock.getProject(), exclusiveLock
854:                                    .getSystemLock().getType());
855:                }
856:                if ((lock == null)
857:                        || !exclusiveLock.getEditionLock().isNullLock()) {
858:                    CmsLockType type = CmsLockType.SHARED_EXCLUSIVE;
859:                    if (!getParentLock(siblingName).isNullLock()) {
860:                        type = CmsLockType.SHARED_INHERITED;
861:                    }
862:                    if (lock == null) {
863:                        lock = new CmsLock(siblingName, exclusiveLock
864:                                .getUserId(), exclusiveLock.getProject(), type);
865:                    } else {
866:                        CmsLock editionLock = new CmsLock(siblingName,
867:                                exclusiveLock.getUserId(), exclusiveLock
868:                                        .getProject(), type);
869:                        lock.setRelatedLock(editionLock);
870:                    }
871:                }
872:                return lock;
873:            }
874:
875:            /**
876:             * Sets the given lock to the resource.<p>
877:             * 
878:             * @param lock the lock to set
879:             * 
880:             * @throws CmsLockException if the lock is not compatible with the current lock 
881:             */
882:            private void lockResource(CmsLock lock) throws CmsLockException {
883:
884:                m_isDirty = true;
885:                internalLockResource(lock, null);
886:            }
887:
888:            /**
889:             * Unlocks the the resource with the given name.<p>
890:             * 
891:             * @param resourceName the name of the resource to unlock
892:             * @param systemLocks <code>true</code> if only system locks should be removed, 
893:             *              and <code>false</code> if only exclusive locks should be removed
894:             * 
895:             * @return the removed lock object
896:             */
897:            private CmsLock unlockResource(String resourceName,
898:                    boolean systemLocks) {
899:
900:                m_isDirty = true;
901:
902:                // get the current lock
903:                CmsLock lock = OpenCms.getMemoryMonitor().getCachedLock(
904:                        resourceName);
905:                if (lock == null) {
906:                    return CmsLock.getNullLock();
907:                }
908:
909:                // check the lock type (system or user) to remove
910:                if (systemLocks) {
911:                    if (!lock.getSystemLock().isUnlocked()) {
912:                        // if a system lock has to be removed
913:                        // user locks are removed too
914:                        OpenCms.getMemoryMonitor().uncacheLock(resourceName);
915:                        return lock;
916:                    } else {
917:                        // if it is a edition lock, do nothing
918:                        return CmsLock.getNullLock();
919:                    }
920:                } else {
921:                    if (lock.getSystemLock().isUnlocked()) {
922:                        // if it is just an edition lock just remove it
923:                        OpenCms.getMemoryMonitor().uncacheLock(resourceName);
924:                        return lock;
925:                    } else {
926:                        // if it is a system lock check the edition lock
927:                        if (!lock.getEditionLock().isUnlocked()) {
928:                            // remove the edition lock
929:                            CmsLock tmp = lock.getEditionLock();
930:                            CmsLock sysLock = lock.getSystemLock();
931:                            sysLock.setRelatedLock(null);
932:                            if (!sysLock.equals(lock)) {
933:                                // replace the lock entry if needed
934:                                OpenCms.getMemoryMonitor().cacheLock(sysLock);
935:                            }
936:                            return tmp;
937:                        } else {
938:                            // if there is no edition lock, only a system lock, do nothing
939:                            return CmsLock.getNullLock();
940:                        }
941:                    }
942:                }
943:            }
944:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.