1 17 package org.alfresco.repo.lock; 18 19 import java.io.Serializable ; 20 import java.util.ArrayList ; 21 import java.util.Calendar ; 22 import java.util.Collection ; 23 import java.util.Date ; 24 import java.util.HashSet ; 25 import java.util.List ; 26 import java.util.Map ; 27 import java.util.Set ; 28 29 import org.alfresco.model.ContentModel; 30 import org.alfresco.repo.policy.JavaBehaviour; 31 import org.alfresco.repo.policy.PolicyComponent; 32 import org.alfresco.repo.policy.PolicyScope; 33 import org.alfresco.service.cmr.lock.LockService; 34 import org.alfresco.service.cmr.lock.LockStatus; 35 import org.alfresco.service.cmr.lock.LockType; 36 import org.alfresco.service.cmr.lock.NodeLockedException; 37 import org.alfresco.service.cmr.lock.UnableToAquireLockException; 38 import org.alfresco.service.cmr.lock.UnableToReleaseLockException; 39 import org.alfresco.service.cmr.repository.AspectMissingException; 40 import org.alfresco.service.cmr.repository.ChildAssociationRef; 41 import org.alfresco.service.cmr.repository.NodeRef; 42 import org.alfresco.service.cmr.repository.NodeService; 43 import org.alfresco.service.cmr.repository.StoreRef; 44 import org.alfresco.service.cmr.search.ResultSet; 45 import org.alfresco.service.cmr.search.SearchService; 46 import org.alfresco.service.cmr.security.AuthenticationService; 47 import org.alfresco.service.cmr.security.OwnableService; 48 import org.alfresco.service.namespace.NamespaceService; 49 import org.alfresco.service.namespace.QName; 50 51 56 public class LockServiceImpl implements LockService 57 { 58 61 private NodeService nodeService; 62 63 66 private PolicyComponent policyComponent; 67 68 71 private Set <NodeRef> ignoreNodeRefs = new HashSet <NodeRef>(); 72 73 76 private AuthenticationService authenticationService; 77 78 82 private OwnableService ownableService; 83 84 87 private SearchService searchService; 88 89 95 public void setNodeService(NodeService nodeService) 96 { 97 this.nodeService = nodeService; 98 } 99 100 106 public void setPolicyComponent(PolicyComponent policyComponent) 107 { 108 this.policyComponent = policyComponent; 109 } 110 111 117 public void setAuthenticationService(AuthenticationService authenticationService) 118 { 119 this.authenticationService = authenticationService; 120 } 121 122 128 public void setOwnableService(OwnableService ownableService) 129 { 130 this.ownableService = ownableService; 131 } 132 133 138 public void setSearchService(SearchService searchService) 139 { 140 this.searchService = searchService; 141 } 142 143 146 public void initialise() 147 { 148 this.policyComponent.bindClassBehaviour( 150 QName.createQName(NamespaceService.ALFRESCO_URI, "beforeCreateVersion"), ContentModel.ASPECT_LOCKABLE, 151 new JavaBehaviour(this, "checkForLock")); 152 this.policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "beforeUpdateNode"), 153 ContentModel.ASPECT_LOCKABLE, new JavaBehaviour(this, "checkForLock")); 154 this.policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteNode"), 155 ContentModel.ASPECT_LOCKABLE, new JavaBehaviour(this, "checkForLock")); 156 157 this.policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onCopyNode"), 159 ContentModel.ASPECT_LOCKABLE, new JavaBehaviour(this, "onCopy")); 160 161 this.policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateVersion"), 163 ContentModel.ASPECT_LOCKABLE, new JavaBehaviour(this, "onCreateVersion")); 164 } 165 166 169 public synchronized void lock(NodeRef nodeRef, LockType lockType) 170 { 171 lock(nodeRef, lockType, 0); 173 } 174 175 178 public synchronized void lock(NodeRef nodeRef, LockType lockType, int timeToExpire) 179 { 180 checkForLockApsect(nodeRef); 182 183 String userName = getUserName(); 185 186 if (lockType == null) 188 { 189 lockType = LockType.WRITE_LOCK; 190 } 191 192 LockStatus currentLockStatus = getLockStatus(nodeRef, userName); 193 if (LockStatus.LOCKED.equals(currentLockStatus) == true) 194 { 195 throw new UnableToAquireLockException(nodeRef); 197 } 198 else if (LockStatus.NO_LOCK.equals(currentLockStatus) == true || 199 LockStatus.LOCK_EXPIRED.equals(currentLockStatus) == true || 200 LockStatus.LOCK_OWNER.equals(currentLockStatus) == true) 201 { 202 this.ignoreNodeRefs.add(nodeRef); 203 try 204 { 205 this.nodeService.setProperty(nodeRef, ContentModel.PROP_LOCK_OWNER, userName); 207 this.nodeService.setProperty(nodeRef, ContentModel.PROP_LOCK_TYPE, lockType.toString()); 208 setExpiryDate(nodeRef, timeToExpire); 209 } 210 finally 211 { 212 this.ignoreNodeRefs.remove(nodeRef); 213 } 214 } 215 } 216 217 223 private void setExpiryDate(NodeRef nodeRef, int timeToExpire) 224 { 225 Date expiryDate = null; 227 if (timeToExpire > 0) 228 { 229 expiryDate = new Date (); 230 Calendar calendar = Calendar.getInstance(); 231 calendar.setTime(expiryDate); 232 calendar.add(Calendar.SECOND, timeToExpire); 233 expiryDate = calendar.getTime(); 234 } 235 236 this.nodeService.setProperty(nodeRef, ContentModel.PROP_EXPIRY_DATE, expiryDate); 237 } 238 239 242 public synchronized void lock(NodeRef nodeRef, LockType lockType, int timeToExpire, boolean lockChildren) 243 throws UnableToAquireLockException 244 { 245 lock(nodeRef, lockType, timeToExpire); 246 247 if (lockChildren == true) 248 { 249 Collection <ChildAssociationRef> childAssocRefs = this.nodeService.getChildAssocs(nodeRef); 250 for (ChildAssociationRef childAssocRef : childAssocRefs) 251 { 252 lock(childAssocRef.getChildRef(), lockType, timeToExpire, lockChildren); 253 } 254 } 255 } 256 257 260 public synchronized void lock(Collection <NodeRef> nodeRefs, LockType lockType, int timeToExpire) 261 throws UnableToAquireLockException 262 { 263 for (NodeRef nodeRef : nodeRefs) 265 { 266 lock(nodeRef, lockType, timeToExpire); 267 } 268 } 269 270 273 public synchronized void unlock(NodeRef nodeRef) throws UnableToReleaseLockException 274 { 275 checkForLockApsect(nodeRef); 277 278 281 this.ignoreNodeRefs.add(nodeRef); 290 try 291 { 292 this.nodeService.setProperty(nodeRef, ContentModel.PROP_LOCK_OWNER, null); 294 this.nodeService.setProperty(nodeRef, ContentModel.PROP_LOCK_TYPE, null); 295 } finally 296 { 297 this.ignoreNodeRefs.remove(nodeRef); 298 } 299 } 301 302 306 public synchronized void unlock(NodeRef nodeRef, boolean unlockChildren) 307 throws UnableToReleaseLockException 308 { 309 unlock(nodeRef); 311 312 if (unlockChildren == true) 313 { 314 Collection <ChildAssociationRef> childAssocRefs = this.nodeService.getChildAssocs(nodeRef); 316 for (ChildAssociationRef childAssocRef : childAssocRefs) 317 { 318 unlock(childAssocRef.getChildRef(), unlockChildren); 319 } 320 } 321 } 322 323 327 public synchronized void unlock(Collection <NodeRef> nodeRefs) throws UnableToReleaseLockException 328 { 329 for (NodeRef nodeRef : nodeRefs) 330 { 331 unlock(nodeRef); 332 } 333 } 334 335 338 public LockStatus getLockStatus(NodeRef nodeRef) 339 { 340 return getLockStatus(nodeRef, getUserName()); 341 } 342 343 350 private LockStatus getLockStatus(NodeRef nodeRef, String userName) 351 { 352 LockStatus result = LockStatus.NO_LOCK; 353 354 if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_LOCKABLE) == true) 355 356 { 357 String currentUserRef = (String ) this.nodeService.getProperty(nodeRef, ContentModel.PROP_LOCK_OWNER); 359 String owner = ownableService.getOwner(nodeRef); 360 if (currentUserRef != null) 361 { 362 Date expiryDate = (Date )this.nodeService.getProperty(nodeRef, ContentModel.PROP_EXPIRY_DATE); 363 if (expiryDate != null && expiryDate.before(new Date ()) == true) 364 { 365 result = LockStatus.LOCK_EXPIRED; 367 } 368 else 369 { 370 if (currentUserRef.equals(userName) == true) 371 { 372 result = LockStatus.LOCK_OWNER; 373 } 374 else if ((owner != null) && owner.equals(userName)) 375 { 376 result = LockStatus.LOCK_OWNER; 377 } 378 else 379 { 380 result = LockStatus.LOCKED; 381 } 382 } 383 } 384 385 } 386 return result; 387 388 } 389 390 393 public LockType getLockType(NodeRef nodeRef) 394 { 395 LockType result = null; 396 397 if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_LOCKABLE) == true) 398 { 399 String lockTypeString = (String ) this.nodeService.getProperty(nodeRef, ContentModel.PROP_LOCK_TYPE); 400 if (lockTypeString != null) 401 { 402 result = LockType.valueOf(lockTypeString); 403 } 404 } 405 406 return result; 407 } 408 409 415 private void checkForLockApsect(NodeRef nodeRef) 416 { 417 if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_LOCKABLE) == false) 418 { 419 this.nodeService.addAspect(nodeRef, ContentModel.ASPECT_LOCKABLE, null); 420 } 421 } 422 423 426 public void checkForLock(NodeRef nodeRef) throws NodeLockedException 427 { 428 String userName = getUserName(); 429 430 if (nodeRef != null && userName != null) 432 { 433 if (this.ignoreNodeRefs.contains(nodeRef) == false) 435 { 436 try 437 { 438 LockStatus currentLockStatus = getLockStatus(nodeRef, userName); 440 441 LockType lockType = getLockType(nodeRef); 442 if (LockType.WRITE_LOCK.equals(lockType) == true && 443 LockStatus.LOCKED.equals(currentLockStatus) == true) 444 { 445 throw new NodeLockedException(nodeRef); 448 } 449 else if (LockType.READ_ONLY_LOCK.equals(lockType) == true && 450 (LockStatus.LOCKED.equals(currentLockStatus) == true || LockStatus.LOCK_OWNER.equals(currentLockStatus) == true)) 451 { 452 throw new NodeLockedException(nodeRef); 456 } 457 } 458 catch (AspectMissingException exception) 459 { 460 } 464 } 465 } 466 } 467 468 477 public void onCopy(QName sourceClassRef, NodeRef sourceNodeRef, StoreRef destinationStoreRef, 478 boolean copyToNewNode, PolicyScope copyDetails) 479 { 480 copyDetails.addAspect(ContentModel.ASPECT_LOCKABLE); 482 } 483 484 499 public void onCreateVersion(QName classRef, NodeRef versionableNode, Map <String , Serializable > versionProperties, 500 PolicyScope nodeDetails) 501 { 502 nodeDetails.addAspect(ContentModel.ASPECT_LOCKABLE); 504 } 505 506 511 private String getUserName() 512 { 513 return this.authenticationService.getCurrentUserName(); 514 } 515 516 519 public List <NodeRef> getLocks(StoreRef storeRef) 520 { 521 return getLocks( 522 storeRef, 523 "ASPECT:\"" + ContentModel.ASPECT_LOCKABLE.toString() + 524 "\" +@\\{http\\://www.alfresco.org/model/content/1.0\\}" + ContentModel.PROP_LOCK_OWNER.getLocalName() + ":\"" + getUserName() + "\""); 525 } 526 527 534 private List <NodeRef> getLocks(StoreRef storeRef, String query) 535 { 536 List <NodeRef> result = new ArrayList <NodeRef>(); 537 ResultSet resultSet = null; 538 try 539 { 540 resultSet = this.searchService.query( 541 storeRef, 542 SearchService.LANGUAGE_LUCENE, 543 query); 544 result = resultSet.getNodeRefs(); 545 } 546 finally 547 { 548 if (resultSet != null) 549 { 550 resultSet.close(); 551 } 552 } 553 return result; 554 } 555 556 559 public List <NodeRef> getLocks(StoreRef storeRef, LockType lockType) 560 { 561 return getLocks( 562 storeRef, 563 "ASPECT:\"" + ContentModel.ASPECT_LOCKABLE.toString() + 564 "\" +@\\{http\\://www.alfresco.org/model/content/1.0\\}" + ContentModel.PROP_LOCK_OWNER.getLocalName() + ":\"" + getUserName() + "\"" + 565 " +@\\{http\\://www.alfresco.org/model/content/1.0\\}" + ContentModel.PROP_LOCK_TYPE.getLocalName() + ":\"" + lockType.toString() + "\""); 566 } 567 } 568 | Popular Tags |