1 23 24 package org.apache.slide.lock; 25 26 import java.util.Date ; 27 import java.util.Enumeration ; 28 import java.util.Stack ; 29 import java.util.Vector ; 30 31 import org.apache.slide.common.Namespace; 32 import org.apache.slide.common.NamespaceConfig; 33 import org.apache.slide.common.ServiceAccessException; 34 import org.apache.slide.common.SlideException; 35 import org.apache.slide.common.SlideToken; 36 import org.apache.slide.common.Uri; 37 import org.apache.slide.event.EventDispatcher; 38 import org.apache.slide.event.LockEvent; 39 import org.apache.slide.event.VetoException; 40 import org.apache.slide.security.AccessDeniedException; 41 import org.apache.slide.security.Security; 42 import org.apache.slide.structure.ActionNode; 43 import org.apache.slide.structure.ObjectNode; 44 import org.apache.slide.structure.ObjectNotFoundException; 45 import org.apache.slide.structure.SubjectNode; 46 import org.apache.slide.util.Configuration; 47 48 53 public final class LockImpl implements Lock { 54 55 57 58 65 public LockImpl(Namespace namespace, NamespaceConfig namespaceConfig, 66 Security securityHelper) { 67 this.namespace = namespace; 68 this.namespaceConfig = namespaceConfig; 69 this.securityHelper = securityHelper; 70 } 71 72 73 75 76 79 private Namespace namespace; 80 81 82 85 private NamespaceConfig namespaceConfig; 86 87 88 91 private Security securityHelper; 92 93 94 96 109 public void lock(SlideToken slideToken, NodeLock lockToken) 110 throws ServiceAccessException, ObjectIsAlreadyLockedException, 111 AccessDeniedException, ObjectNotFoundException, VetoException { 112 113 ObjectIsAlreadyLockedException nestedException = 114 new ObjectIsAlreadyLockedException(lockToken.getObjectUri()); 115 Uri objectUri = namespace.getUri(slideToken, lockToken.getObjectUri(), true); 116 boolean canLock = 117 !isLockedInternal(slideToken, lockToken, true, nestedException); 118 119 if (canLock) { 124 ObjectNode lockedObject = objectUri.getStore() 125 .retrieveObject(objectUri); 126 securityHelper 127 .checkCredentials(slideToken, lockedObject, 128 namespaceConfig.getLockObjectAction()); 129 objectUri.getStore().putLock(objectUri, lockToken); 130 } else { 131 throw nestedException; 132 } 133 134 if ( LockEvent.LOCK.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(LockEvent.LOCK, new LockEvent(this, slideToken, namespace, objectUri)); 136 } 137 138 139 151 public boolean unlock(SlideToken slideToken, NodeLock lockToken) 152 throws ServiceAccessException, LockTokenNotFoundException, VetoException { 153 154 try { 155 if (!checkLockOwner(slideToken, lockToken)) { 156 return false; 157 } 158 159 if (slideToken.isEnforceLockTokens() && !checkLockToken(slideToken, lockToken)) { 161 return false; 162 } 163 } catch (ObjectNotFoundException e) { 164 return false; 165 } 166 167 Uri lockedUri = namespace.getUri(slideToken, lockToken.getObjectUri(), 169 true); 170 lockedUri.getStore().removeLock(lockedUri, lockToken); 171 172 if ( LockEvent.UNLOCK.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(LockEvent.UNLOCK, new LockEvent(this, slideToken, namespace, lockedUri)); 174 175 return true; 176 } 177 178 179 191 public void unlock(SlideToken slideToken, String objectUri, 192 String lockId) 193 throws ServiceAccessException, LockTokenNotFoundException, 194 ObjectNotFoundException, VetoException { 195 196 Enumeration locksList = enumerateLocks(slideToken, objectUri, false); 197 while (locksList.hasMoreElements()) { 198 NodeLock currentLock = (NodeLock) locksList.nextElement(); 199 if (currentLock.getLockId().equals(lockId)) { 200 if (slideToken.isEnforceLockTokens()) 201 slideToken.addLockToken(lockId); 202 unlock(slideToken, currentLock); 203 } 204 } 205 206 } 207 208 209 219 public void renew(SlideToken slideToken, NodeLock lockToken, 220 Date newExpirationDate) 221 throws ServiceAccessException, LockTokenNotFoundException, VetoException { 222 lockToken.setExpirationDate(newExpirationDate); 223 Uri lockedUri = namespace.getUri(slideToken, lockToken.getObjectUri()); 224 lockedUri.getStore().renewLock(lockedUri, lockToken); 225 226 if ( LockEvent.RENEW.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(LockEvent.RENEW, new LockEvent(this, slideToken, namespace, lockedUri)); 228 } 229 230 231 244 public void renew(SlideToken slideToken, String objectUri, 245 String lockId, Date newExpirationDate) 246 throws ServiceAccessException, LockTokenNotFoundException, 247 ObjectNotFoundException, VetoException { 248 249 Enumeration locksList = enumerateLocks(slideToken, objectUri, false); 250 while (locksList.hasMoreElements()) { 251 NodeLock currentLock = (NodeLock) locksList.nextElement(); 252 if (currentLock.getLockId().equals(lockId)) { 253 renew(slideToken, currentLock, newExpirationDate); 254 } 255 } 256 257 } 258 259 260 273 public void kill(SlideToken slideToken, SubjectNode subject) 274 throws ServiceAccessException, AccessDeniedException, 275 LockTokenNotFoundException, ObjectNotFoundException, VetoException { 276 277 Uri subjectUri = namespace.getUri(slideToken, subject.getUri()); 280 Enumeration locks = subjectUri.getStore() 281 .enumerateLocks(subjectUri); 282 while (locks.hasMoreElements()) { 284 securityHelper 285 .checkCredentials(slideToken, subject, 286 namespaceConfig.getKillLockAction()); 287 subjectUri.getStore() 288 .killLock(subjectUri, (NodeLock) locks.nextElement()); 289 } 290 291 if ( LockEvent.KILL.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(LockEvent.KILL, new LockEvent(this, slideToken, namespace, subjectUri)); 293 } 294 295 public Enumeration enumerateLocks(SlideToken slideToken, String objectUri) 296 throws ServiceAccessException, ObjectNotFoundException, 297 LockTokenNotFoundException { 298 299 return enumerateLocks(slideToken, objectUri, true); 300 } 301 302 public Enumeration enumerateLocks(SlideToken slideToken, String objectUri, 303 boolean inherited) 304 throws ServiceAccessException, ObjectNotFoundException, 305 LockTokenNotFoundException { 306 307 Uri subjectUri = namespace.getUri(slideToken, objectUri); 309 310 Enumeration scopes = null; 311 if (inherited) { 312 scopes = subjectUri.getScopes(); 315 } else { 316 Vector scopeVector = new Vector (); 319 scopeVector.add(subjectUri.toString()); 320 scopes = scopeVector.elements(); 321 } 322 Vector locksVector = new Vector (); 323 while (scopes.hasMoreElements()) { 324 String currentScope = (String ) scopes.nextElement(); 325 Uri currentScopeUri = 326 namespace.getUri(slideToken, currentScope); 327 Enumeration currentLocks = 328 currentScopeUri.getStore().enumerateLocks(currentScopeUri); 329 while (currentLocks.hasMoreElements()) { 330 NodeLock currentLockToken = 331 (NodeLock) currentLocks.nextElement(); 332 if (currentLockToken.hasExpired()) { 333 try { 335 currentScopeUri.getStore() 336 .removeLock(currentScopeUri, currentLockToken); 337 } 338 catch (LockTokenNotFoundException ex) { 339 } 341 } else { 342 locksVector.addElement(currentLockToken); 343 } 344 } 345 } 346 return locksVector.elements(); 347 } 348 349 350 362 public void checkLock(SlideToken token, 363 ObjectNode object, ActionNode action) 364 throws ServiceAccessException, ObjectNotFoundException, 365 ObjectLockedException { 366 367 if (!token.isForceLock()) { 368 return; 369 } 370 371 if (Configuration.useIntegratedLocking()) { 372 373 Boolean locked = token.checkLockCache(object, action); 374 if (locked != null) { 375 if (locked.booleanValue()) { 376 throw new ObjectLockedException(object.getUri()); 377 } 378 else { 379 return; 380 } 381 } 382 383 Uri objectUri = namespace.getUri(token, object.getUri()); 384 ObjectNode realObject = objectUri.getStore() 385 .retrieveObject(objectUri); 386 try { 387 checkLock(token, realObject, (SubjectNode)securityHelper.getPrincipal(token), action); 388 token.cacheLock(object, action, false); 389 } 390 catch (ObjectLockedException e) { 391 token.cacheLock(object, action, true); 392 throw e; 393 } 394 } 395 } 396 397 398 411 public void checkLock(SlideToken slideToken, 412 ObjectNode subject, SubjectNode user, 413 ActionNode action) 414 throws ServiceAccessException, ObjectNotFoundException, 415 ObjectLockedException { 416 417 if (action.equals(ActionNode.DEFAULT)) { 419 return; 420 } 421 422 if (Configuration.useIntegratedLocking()) { 423 if (isLocked(slideToken, subject, user, action, false)) { 424 throw new ObjectLockedException(subject.getUri()); 425 } 426 } 427 } 428 429 430 442 public boolean isLocked(SlideToken slideToken, 443 ObjectNode subject, SubjectNode user, 444 ActionNode action, boolean tryToLock) 445 throws ServiceAccessException, ObjectNotFoundException { 446 NodeLock token = new NodeLock(subject, user, action, 447 new Date (), false); 448 return isLocked(slideToken, token, tryToLock); 449 } 450 451 452 468 public boolean isLocked(SlideToken slideToken, 469 ObjectNode subject, SubjectNode user, 470 ActionNode action, boolean inheritance, 471 boolean tryToLock) 472 throws ServiceAccessException, ObjectNotFoundException { 473 NodeLock token = new NodeLock(subject, user, action, new Date (), 474 inheritance); 475 return isLocked(slideToken, token, tryToLock); 476 } 477 478 479 488 public boolean isLocked(SlideToken slideToken, NodeLock token, 489 boolean tryToLock) 490 throws ServiceAccessException, ObjectNotFoundException { 491 492 return isLockedInternal(slideToken, token, tryToLock, null); 493 494 } 495 496 504 public void clearExpiredLocks( SlideToken slideToken, String objectUri, UnlockListener listener ) throws SlideException { 505 506 Uri uri = 507 namespace.getUri(slideToken, objectUri); 508 Enumeration currentLocks = 509 uri.getStore().enumerateLocks(uri); 510 while (currentLocks.hasMoreElements()) { 511 NodeLock currentLockToken = 512 (NodeLock) currentLocks.nextElement(); 513 if (currentLockToken.hasExpired()) { 514 try { 515 uri.getStore().removeLock(uri, currentLockToken); 516 if( listener != null ) 517 listener.afterUnlock( objectUri ); 518 } 519 catch (LockTokenNotFoundException ex) { 520 } 522 } 523 } 524 } 525 526 533 public boolean checkLockToken(SlideToken slideToken, NodeLock token) { 534 if (!slideToken.isEnforceLockTokens()) 535 return true; 536 537 if (Configuration.usePrincipalIdentifiedLocks()) { 541 SubjectNode principalNode = null; 542 SubjectNode ownerNode = SubjectNode.getSubjectNode(token.getSubjectUri()); 543 try { 544 principalNode = (SubjectNode)securityHelper.getPrincipal(slideToken); 545 } 546 catch (SlideException e) {} 547 548 if (ownerNode != null && 549 !ownerNode.equals(SubjectNode.UNAUTHENTICATED) && 550 ownerNode.equals(principalNode)) 551 { 552 return true; 553 } 554 return (slideToken.checkLockToken(token.getLockId())); 555 } else { 556 return (slideToken.checkLockToken(token.getLockId())); 557 } 558 } 559 560 571 public boolean checkLockOwner(SlideToken slideToken, NodeLock token) throws ObjectNotFoundException, ServiceAccessException { 572 boolean canUnlock = true; 573 SubjectNode principal = (SubjectNode)securityHelper.getPrincipal(slideToken); 574 SubjectNode lockOwner = SubjectNode.getSubjectNode(token.getSubjectUri()); 575 if (!securityHelper.matchPrincipal(slideToken, principal, lockOwner)) { 576 try { 578 securityHelper.checkCredentials(slideToken, 579 SubjectNode.getSubjectNode(token.getObjectUri()), 580 namespaceConfig.getKillLockAction()); 581 } 582 catch (AccessDeniedException e) { 583 canUnlock = false; 584 } 585 } 586 return canUnlock; 587 } 588 589 591 592 601 private boolean isLockedInternal 602 (SlideToken slideToken, NodeLock token, 603 boolean tryToLock, ObjectIsAlreadyLockedException nestedException) 604 throws ServiceAccessException, ObjectNotFoundException { 605 606 Uri objectUri = namespace.getUri(slideToken, token.getObjectUri()); 607 ObjectNode initialObject = objectUri.getStore() 608 .retrieveObject(objectUri); 609 Enumeration scopes = objectUri.getScopes(); 610 611 boolean isLocked = false; 614 615 while (!isLocked && scopes.hasMoreElements()) { 619 String currentScope = (String ) scopes.nextElement(); 620 Uri currentScopeUri = namespace.getUri(slideToken, currentScope); 621 Enumeration locks = currentScopeUri.getStore() 622 .enumerateLocks(currentScopeUri); 623 624 while (locks.hasMoreElements()) { 625 NodeLock currentLockToken = (NodeLock) locks.nextElement(); 626 if (!isCompatible(slideToken, token, currentLockToken, 627 tryToLock)) { 628 isLocked = true; 629 if (nestedException != null) { 630 nestedException.addException 631 (new ObjectLockedException 632 (currentScopeUri.toString())); 633 } 634 } 635 } 636 } 637 638 if (token.isInheritable()) { 642 Stack childrenStack = new Stack (); 643 childrenStack.push(initialObject); 644 while (!isLocked && !childrenStack.empty()) { 645 ObjectNode currentObject = (ObjectNode) childrenStack.pop(); 646 Uri currentObjectUri = 647 namespace.getUri(slideToken, currentObject.getUri()); 648 Enumeration locks = currentObjectUri.getStore() 650 .enumerateLocks(currentObjectUri); 651 652 while (locks.hasMoreElements()) { 653 NodeLock currentLockToken = (NodeLock) locks.nextElement(); 654 if (!isCompatible(slideToken, token, 655 currentLockToken, tryToLock)) { 656 isLocked = true; 657 if (nestedException != null) { 658 nestedException.addException 659 (new ObjectLockedException 660 (currentObjectUri.toString())); 661 } 662 } 663 } 664 665 667 Vector childrenVector = new Vector (); 668 Enumeration childrenUri = currentObject.enumerateChildren(); 669 while (childrenUri.hasMoreElements()) { 670 String childUri = (String ) childrenUri.nextElement(); 671 Uri tempUri = namespace.getUri(slideToken, childUri); 672 ObjectNode child = tempUri.getStore() 673 .retrieveObject(tempUri); 674 childrenVector.addElement(child); 675 } 676 677 Enumeration children = childrenVector.elements(); 678 while (children.hasMoreElements()) { 679 ObjectNode tempObject = 680 (ObjectNode) children.nextElement(); 681 childrenStack.push(tempObject); 682 } 683 } 684 } 685 686 return isLocked; 687 688 } 689 690 691 703 private boolean isCompatible(SlideToken slideToken, 704 NodeLock checkToken, 705 NodeLock matchToken, 706 boolean tryToLock) 707 throws ServiceAccessException { 708 709 boolean compatible = true; 710 711 if (matchToken.hasExpired()) { 712 try { 714 if (slideToken.isForceStoreEnlistment()) { 715 Uri token2Uri = namespace.getUri(slideToken, 716 matchToken.getObjectUri()); 717 token2Uri.getStore().removeLock(token2Uri, matchToken); 718 } 719 } 720 catch (LockTokenNotFoundException e) {} return true; 722 } 723 724 boolean condition0 = matchToken.getObjectUri().equals(checkToken.getObjectUri()) || matchToken.isInheritable(); 726 if (!condition0) { 727 return true; 728 } 729 730 boolean condition1 = matchToken.getTypeUri().equals(checkToken.getTypeUri()); 732 733 SubjectNode checkSubject = SubjectNode.getSubjectNode(checkToken.getSubjectUri()); 735 SubjectNode matchSubject = SubjectNode.getSubjectNode(matchToken.getSubjectUri()); 736 boolean condition2 = 737 securityHelper.matchPrincipal(slideToken, checkSubject, matchSubject); 738 739 ActionNode checkAction = ActionNode.getActionNode(checkToken.getTypeUri()); 741 ActionNode matchAction = ActionNode.getActionNode(matchToken.getTypeUri()); 742 boolean condition3 = 743 securityHelper.matchAction(slideToken, checkAction, matchAction); 744 745 boolean condition4 = checkToken.isExclusive(); 747 748 boolean condition5 = checkLockToken(slideToken, matchToken); 750 751 boolean condition6 = slideToken.isEnforceLockTokens(); 753 754 if ((tryToLock && condition1 && condition4) 755 || (condition3 && !condition2 && !condition6) 756 || (condition3 && !condition5 && condition6) 757 || (condition5 && !condition2) ){ 759 compatible = false; 760 } 761 762 if (checkToken.isShared() && matchToken.isShared() && tryToLock && condition1 ) { 764 compatible = true; 765 } 766 767 795 return compatible; 796 } 797 798 806 private boolean isCompatible_OLD(SlideToken slideToken, 807 NodeLock token1, NodeLock token2, 808 boolean tryToLock) { 809 817 818 boolean compatible = true; 819 820 if (token2.hasExpired()) { 822 try { 824 if (slideToken.isForceStoreEnlistment()) { 825 Uri token2Uri = namespace.getUri(slideToken, 826 token2.getObjectUri()); 827 token2Uri.getStore().removeLock(token2Uri, token2); 828 } 829 } catch (SlideException e) { 830 e.printStackTrace(); 831 } 832 } else { 833 boolean condition1 = token2.getTypeUri().equals(token1.getTypeUri()); 835 boolean condition2 = 837 (token1.getSubjectUri().startsWith(token2.getSubjectUri())); 838 boolean condition3 = token2.getTypeUri() 840 .startsWith(token1.getTypeUri()); 841 boolean condition4 = token1.isExclusive(); 843 boolean condition5 = checkLockToken(slideToken, token2); 845 boolean condition6 = slideToken.isEnforceLockTokens(); 847 boolean condition7 = token2.getObjectUri().equals(token1.getObjectUri()) || token2.isInheritable(); 849 850 if ((tryToLock && condition1 && condition4 && condition7) 851 || (condition3 && !condition2 && !condition6 && condition7) 852 || (condition3 && !condition5 && condition6 && condition7) 853 ){ 854 compatible = false; 855 } 856 857 if (token1.isShared() && token2.isShared() && tryToLock && condition1 ) { 859 compatible = true; 860 } 861 862 890 } 891 return compatible; 892 } 893 } 894 895 896 897 898 | Popular Tags |