1 31 32 package org.opencms.lock; 33 34 import org.opencms.db.CmsDbContext; 35 import org.opencms.db.CmsDriverManager; 36 import org.opencms.file.CmsProject; 37 import org.opencms.file.CmsResource; 38 import org.opencms.file.CmsVfsResourceNotFoundException; 39 import org.opencms.main.CmsException; 40 import org.opencms.util.CmsUUID; 41 42 import java.util.ArrayList ; 43 import java.util.Collections ; 44 import java.util.HashMap ; 45 import java.util.Iterator ; 46 import java.util.List ; 47 import java.util.Map ; 48 49 68 public final class CmsLockManager { 69 70 71 private static CmsLockManager sharedInstance; 72 73 74 private Map m_exclusiveLocks; 75 76 79 private CmsLockManager() { 80 81 super(); 82 m_exclusiveLocks = Collections.synchronizedMap(new HashMap ()); 83 } 84 85 90 public static CmsLockManager getInstance() { 91 92 if (sharedInstance == null) { 93 sharedInstance = new CmsLockManager(); 95 } 96 return sharedInstance; 97 } 98 99 112 public void addResource( 113 CmsDriverManager driverManager, 114 CmsDbContext dbc, 115 CmsResource resource, 116 CmsUUID userId, 117 int projectId, 118 int mode) throws CmsLockException, CmsException { 119 120 CmsLock lock = getLock(driverManager, dbc, resource); 121 String resourceName = resource.getRootPath(); 122 123 if (!lock.isNullLock() && !lock.getUserId().equals(dbc.currentUser().getId())) { 124 throw new CmsLockException(Messages.get().container( 125 Messages.ERR_RESOURCE_LOCKED_1, 126 dbc.getRequestContext().getSitePath(resource))); 127 } 128 129 if (lock.isNullLock()) { 130 CmsLock newLock = new CmsLock(resourceName, userId, projectId, CmsLock.TYPE_EXCLUSIVE, mode); 133 m_exclusiveLocks.put(resourceName, newLock); 134 } 135 136 if (CmsResource.isFolder(resourceName)) { 138 Iterator i = m_exclusiveLocks.keySet().iterator(); 139 String lockedPath = null; 140 141 while (i.hasNext()) { 142 lockedPath = (String )i.next(); 143 144 if (lockedPath.startsWith(resourceName) && !lockedPath.equals(resourceName)) { 145 i.remove(); 146 } 147 } 148 } 149 } 150 151 158 public int countExclusiveLocksInFolder(String foldername) { 159 160 Iterator i = m_exclusiveLocks.values().iterator(); 161 CmsLock lock = null; 162 int count = 0; 163 164 while (i.hasNext()) { 165 lock = (CmsLock)i.next(); 166 if (lock.getResourceName().startsWith(foldername)) { 167 count++; 168 } 169 } 170 171 return count; 172 } 173 174 181 public int countExclusiveLocksInProject(CmsProject project) { 182 183 Iterator i = m_exclusiveLocks.values().iterator(); 184 CmsLock lock = null; 185 int count = 0; 186 187 while (i.hasNext()) { 188 lock = (CmsLock)i.next(); 189 if (lock.getProjectId() == project.getId()) { 190 count++; 191 } 192 } 193 194 return count; 195 } 196 197 207 public CmsLock getLock(CmsDriverManager driverManager, CmsDbContext dbc, CmsResource resource) throws CmsException { 208 209 String resourcename = resource.getRootPath(); 210 211 213 if (dbc.currentProject().getId() == CmsProject.ONLINE_PROJECT_ID) { 214 return CmsLock.getNullLock(); 216 } 217 218 if (resource == null) { 219 return CmsLock.getNullLock(); 221 } 222 223 225 if (m_exclusiveLocks.containsKey(resourcename)) { 226 return (CmsLock)m_exclusiveLocks.get(resourcename); 228 } 229 230 232 List siblings = internalReadSiblings(driverManager, dbc, resource); 234 235 CmsLock siblingLock; 236 CmsResource sibling; 237 238 CmsLock parentFolderLock = getParentFolderLock(resourcename); 239 if (parentFolderLock == null) { 240 242 for (int i = 0; i < siblings.size(); i++) { 243 sibling = (CmsResource)siblings.get(i); 244 siblingLock = (CmsLock)m_exclusiveLocks.get(sibling.getRootPath()); 245 246 if (siblingLock != null) { 247 return new CmsLock( 249 resourcename, 250 siblingLock.getUserId(), 251 siblingLock.getProjectId(), 252 CmsLock.TYPE_SHARED_EXCLUSIVE); 253 } 254 } 255 256 return CmsLock.getNullLock(); 258 } else { 259 261 for (int i = 0; i < siblings.size(); i++) { 262 sibling = (CmsResource)siblings.get(i); 263 264 if (m_exclusiveLocks.containsKey(sibling.getRootPath())) { 265 return new CmsLock( 267 resourcename, 268 parentFolderLock.getUserId(), 269 parentFolderLock.getProjectId(), 270 CmsLock.TYPE_SHARED_INHERITED); 271 } 272 } 273 274 return new CmsLock( 276 resourcename, 277 parentFolderLock.getUserId(), 278 parentFolderLock.getProjectId(), 279 CmsLock.TYPE_INHERITED); 280 } 281 } 282 283 297 public boolean isLocked(CmsDriverManager driverManager, CmsDbContext dbc, CmsResource resource) throws CmsException { 298 299 CmsLock lock = getLock(driverManager, dbc, resource); 300 return !lock.isNullLock(); 301 } 302 303 311 public void removeDeletedResource(CmsDriverManager driverManager, CmsDbContext dbc, String resourceName) 312 throws CmsException { 313 314 boolean resourceExists; 315 try { 316 driverManager.getVfsDriver().readResource(dbc, dbc.currentProject().getId(), resourceName, false); 317 resourceExists = true; 318 } catch (CmsVfsResourceNotFoundException e) { 319 resourceExists = false; 320 } 321 322 if (resourceExists) { 323 throw new CmsLockException(Messages.get().container( 324 Messages.ERR_REMOVING_UNDELETED_RESOURCE_1, 325 dbc.getRequestContext().removeSiteRoot(resourceName))); 326 } 327 328 m_exclusiveLocks.remove(resourceName); 329 } 330 331 346 public CmsLock removeResource( 347 CmsDriverManager driverManager, 348 CmsDbContext dbc, 349 CmsResource resource, 350 boolean forceUnlock) throws CmsException { 351 352 String resourcename = resource.getRootPath(); 353 CmsLock lock = getLock(driverManager, dbc, resource); 354 CmsResource sibling = null; 355 356 358 if (lock.isNullLock()) { 359 return null; 361 } 362 363 if (!forceUnlock 364 && (!lock.getUserId().equals(dbc.currentUser().getId()) || lock.getProjectId() != dbc.currentProject().getId())) { 365 throw new CmsLockException(Messages.get().container( 367 Messages.ERR_RESOURCE_UNLOCK_1, 368 dbc.removeSiteRoot(resourcename))); 369 } 370 371 if (!forceUnlock 372 && (lock.getType() == CmsLock.TYPE_INHERITED || lock.getType() == CmsLock.TYPE_SHARED_INHERITED || (getParentFolderLock(resourcename) != null))) { 373 throw new CmsLockException(Messages.get().container( 375 Messages.ERR_UNLOCK_LOCK_INHERITED_1, 376 dbc.removeSiteRoot(resourcename))); 377 } 378 379 if (lock.getType() == CmsLock.TYPE_EXCLUSIVE) { 381 if (resource.isFolder()) { 382 Iterator i = m_exclusiveLocks.keySet().iterator(); 385 String lockedPath = null; 386 387 while (i.hasNext()) { 388 lockedPath = (String )i.next(); 389 if (lockedPath.startsWith(resourcename) && !lockedPath.equals(resourcename)) { 390 i.remove(); 392 } 393 } 394 } 395 396 return (CmsLock)m_exclusiveLocks.remove(resourcename); 397 } 398 399 if (lock.getType() == CmsLock.TYPE_SHARED_EXCLUSIVE) { 400 List siblings = internalReadSiblings(driverManager, dbc, resource); 403 404 for (int i = 0; i < siblings.size(); i++) { 405 sibling = (CmsResource)siblings.get(i); 406 407 if (m_exclusiveLocks.containsKey(sibling.getRootPath())) { 408 m_exclusiveLocks.remove(sibling.getRootPath()); 410 break; 411 } 412 } 413 414 return lock; 415 } 416 417 return lock; 418 } 419 420 425 public void removeResourcesInProject(int projectId) { 426 427 Iterator i = m_exclusiveLocks.keySet().iterator(); 428 CmsLock currentLock = null; 429 430 while (i.hasNext()) { 431 currentLock = (CmsLock)m_exclusiveLocks.get(i.next()); 432 433 if (currentLock.getProjectId() == projectId) { 434 i.remove(); 436 } 437 } 438 } 439 440 445 public void removeTempLocks(CmsUUID userId) { 446 447 Iterator i = m_exclusiveLocks.keySet().iterator(); 448 CmsLock currentLock = null; 449 450 while (i.hasNext()) { 451 currentLock = (CmsLock)m_exclusiveLocks.get(i.next()); 452 453 if (currentLock.getUserId().equals(userId) && currentLock.getMode() == CmsLock.TEMPORARY) { 454 i.remove(); 456 } 457 } 458 } 459 460 465 public int size() { 466 467 return m_exclusiveLocks.size(); 468 } 469 470 473 public String toString() { 474 475 List lockedResources = new ArrayList (m_exclusiveLocks.keySet()); 477 Collections.sort(lockedResources); 478 479 Iterator i = lockedResources.iterator(); 480 StringBuffer buf = new StringBuffer (); 481 String lockedPath = null; 482 CmsLock currentLock = null; 483 484 while (i.hasNext()) { 485 lockedPath = (String )i.next(); 486 currentLock = (CmsLock)m_exclusiveLocks.get(lockedPath); 487 buf.append(currentLock.toString()).append("\n"); 488 } 489 490 return buf.toString(); 491 } 492 493 496 protected void finalize() throws Throwable { 497 498 try { 499 if (m_exclusiveLocks != null) { 500 m_exclusiveLocks.clear(); 501 502 m_exclusiveLocks = null; 503 sharedInstance = null; 504 } 505 } catch (Throwable t) { 506 } 508 super.finalize(); 509 } 510 511 517 private CmsLock getParentFolderLock(String resourcename) { 518 519 String lockedPath = null; 520 List keys = new ArrayList (m_exclusiveLocks.keySet()); 521 522 for (int i = 0; i < keys.size(); i++) { 523 lockedPath = (String )keys.get(i); 524 525 if (resourcename.startsWith(lockedPath) && !resourcename.equals(lockedPath) && lockedPath.endsWith("/")) { 526 return (CmsLock)m_exclusiveLocks.get(lockedPath); 527 } 528 529 } 530 531 return null; 532 } 533 534 550 private List internalReadSiblings(CmsDriverManager driverManager, CmsDbContext dbc, CmsResource resource) 551 throws CmsException { 552 553 556 List siblings = driverManager.getVfsDriver().readSiblings(dbc, dbc.currentProject(), resource, true); 557 siblings.remove(resource); 558 559 return siblings; 560 } 561 } | Popular Tags |