/*
* $Header: /home/cvs/jakarta-slide/src/share/org/apache/slide/lock/LockImpl.java,v 1.39.2.2 2004/02/05 16:05:08 mholz Exp $
* $Revision: 1.39.2.2 $
* $Date: 2004/02/05 16:05:08 $
*
* ====================================================================
*
* Copyright 1999-2002 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.slide.lock;
import java.util.Date;
import java.util.Enumeration;
import java.util.Stack;
import java.util.Vector;
import org.apache.slide.common.Namespace;
import org.apache.slide.common.NamespaceConfig;
import org.apache.slide.common.ServiceAccessException;
import org.apache.slide.common.SlideException;
import org.apache.slide.common.SlideToken;
import org.apache.slide.common.SlideTokenWrapper;
import org.apache.slide.common.Uri;
import org.apache.slide.security.AccessDeniedException;
import org.apache.slide.security.Security;
import org.apache.slide.structure.ActionNode;
import org.apache.slide.structure.ObjectNode;
import org.apache.slide.structure.ObjectNotFoundException;
import org.apache.slide.structure.SubjectNode;
import org.apache.slide.util.Configuration;
/**
* Lock helper class.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
* @version $Revision: 1.39.2.2 $
*/
public final class LockImpl implements Lock {
// ----------------------------------------------------------- Constructors
/**
* Constructor.
*
* @param namespace Associated namespace
* @param namespaceConfig Namespace configuration
* @param securityHelper Security helper
*/
public LockImpl(Namespace namespace, NamespaceConfig namespaceConfig,
Security securityHelper) {
this.namespace = namespace;
this.namespaceConfig = namespaceConfig;
this.securityHelper = securityHelper;
}
// ----------------------------------------------------- Instance Variables
/**
* Namespace.
*/
private Namespace namespace;
/**
* Namespace configuration.
*/
private NamespaceConfig namespaceConfig;
/**
* Security helper.
*/
private Security securityHelper;
// ----------------------------------------------------------- Lock Methods
/**
* Put a lock on a subject.
*
* @param slideToken The token to access slide.
* @param lockToken Object containing all the lock information
* @exception ServiceAccessException Low level service access exception
* @exception ObjectNotFoundException One of the objects referenced
* in the lock token were not found
* @exception ObjectIsAlreadyLockedException Object is already locked
* with an incompatible lock token
* @exception AccessDeniedException Insufficient credentials to allow
* object locking
*/
public void lock(SlideToken slideToken, NodeLock lockToken)
throws ServiceAccessException, ObjectIsAlreadyLockedException,
AccessDeniedException, ObjectNotFoundException {
ObjectIsAlreadyLockedException nestedException =
new ObjectIsAlreadyLockedException(lockToken.getObjectUri());
Uri objectUri = namespace.getUri(slideToken, lockToken.getObjectUri(), true);
boolean canLock =
!isLockedInternal(slideToken, lockToken, true, nestedException);
// Then we try to lock the subject.
// If the User doesn't have enough priviledges to accomplish this
// action, we will get a SecurityException which will in turn be
// thrown by this function.
if (canLock) {
ObjectNode lockedObject = objectUri.getStore()
.retrieveObject(objectUri);
securityHelper
.checkCredentials(slideToken, lockedObject,
namespaceConfig.getLockObjectAction());
objectUri.getStore().putLock(objectUri, lockToken);
} else {
throw nestedException;
}
}
/**
* Removes a lock.
*
* @param slideToken The token to access slide.
* @param lockToken Object containing all the lock information
*
* @return <code>true</code> if the lock could be removed
*
* @exception ServiceAccessException Low level service access exception
* @exception LockTokenNotFoundException Cannot find the Lock in the
* Lock Store service
*/
public boolean unlock(SlideToken slideToken, NodeLock lockToken)
throws ServiceAccessException, LockTokenNotFoundException {
try {
if (!checkLockOwner(slideToken, lockToken)) {
return false;
}
// check the lockId
if (slideToken.isEnforceLockTokens() && !checkLockToken(slideToken, lockToken)) {
return false;
}
} catch (ObjectNotFoundException e) {
return false;
}
// all checks successful, so try to actually remove the lock
Uri lockedUri = namespace.getUri(slideToken, lockToken.getObjectUri(),
true);
lockedUri.getStore().removeLock(lockedUri, lockToken);
return true;
}
/**
* Removes a set of linked locks.
*
* @param slideToken Slide token
* @param objectUri Uri of the locked object.
* @param lockId The id of the locks, which will be removed.
* @exception ServiceAccessException Low level service access exception
* @exception LockTokenNotFoundException Cannot find the Lock in the
* Lock Store service
* @exception ObjectNotFoundException One of the objects referenced
* in the lock token were not found
*/
public void unlock(SlideToken slideToken, String objectUri,
String lockId)
throws ServiceAccessException, LockTokenNotFoundException,
ObjectNotFoundException {
Enumeration locksList = enumerateLocks(slideToken, objectUri, false);
while (locksList.hasMoreElements()) {
NodeLock currentLock = (NodeLock) locksList.nextElement();
if (currentLock.getLockId().equals(lockId)) {
if (slideToken.isEnforceLockTokens())
slideToken.addLockToken(lockId);
unlock(slideToken, currentLock);
}
}
}
/**
* Renew a lock.
*
* @param slideToken Slide token
* @param lockToken Token containing the lock info.
* @param newExpirationDate the desired expiration date
* @exception ServiceAccessException Low level service access exception
* @exception LockTokenNotFoundException Cannot find the Lock in
* the Lock Store service
*/
public void renew(SlideToken slideToken, NodeLock lockToken,
Date newExpirationDate)
throws ServiceAccessException, LockTokenNotFoundException {
lockToken.setExpirationDate(newExpirationDate);
Uri lockedUri = namespace.getUri(slideToken, lockToken.getObjectUri());
lockedUri.getStore().renewLock(lockedUri, lockToken);
}
/**
* Renew a set of linked locks.
*
* @param slideToken Slide token
* @param objectUri Uri of the locked object
* @param lockId Id of the locks, which will be renewed.
* @param newExpirationDate The new expiration date of the locks
* @exception ServiceAccessException Low level service access exception
* @exception LockTokenNotFoundException Cannot find the Lock in the
* Lock Store service
* @exception ObjectNotFoundException One of the objects referenced
* in the lock token were not found
*/
public void renew(SlideToken slideToken, String objectUri,
String lockId, Date newExpirationDate)
throws ServiceAccessException, LockTokenNotFoundException,
ObjectNotFoundException {
Enumeration locksList = enumerateLocks(slideToken, objectUri, false);
while (locksList.hasMoreElements()) {
NodeLock currentLock = (NodeLock) locksList.nextElement();
if (currentLock.getLockId().equals(lockId)) {
renew(slideToken, currentLock, newExpirationDate);
}
}
}
/**
* Kills locks.
*
* @param slideToken Slide token
* @param subject Subject on which locks are to be removed
* @exception ServiceAccessException Low level service access exception
* @exception ObjectNotFoundException One of the objects referenced in
* the lock token were not found
* @exception LockTokenNotFoundException Cannot find the Lock in the
* Lock Store service
* @exception AccessDeniedException Insufficient credentials to allow
* forced removal of locks
*/
public void kill(SlideToken slideToken, SubjectNode subject)
throws ServiceAccessException, AccessDeniedException,
LockTokenNotFoundException, ObjectNotFoundException {
// We retrieve the enumeration of locks which have been put on the
// subject.
Uri subjectUri = namespace.getUri(slideToken, subject.getUri());
Enumeration locks = subjectUri.getStore()
.enumerateLocks(subjectUri);
// Then, try to kill each individual lock.
while (locks.hasMoreElements()) {
securityHelper
.checkCredentials(slideToken, subject,
namespaceConfig.getKillLockAction());
subjectUri.getStore()
.killLock(subjectUri, (NodeLock) locks.nextElement());
}
}
public Enumeration enumerateLocks(SlideToken slideToken, String objectUri)
throws ServiceAccessException, ObjectNotFoundException,
LockTokenNotFoundException {
return enumerateLocks(slideToken, objectUri, true);
}
public Enumeration enumerateLocks(SlideToken slideToken, String objectUri,
boolean inherited)
throws ServiceAccessException, ObjectNotFoundException,
LockTokenNotFoundException {
// We retrieve the LockStore service from the namespace.
Uri subjectUri = namespace.getUri(slideToken, objectUri);
Enumeration scopes = null;
if (inherited) {
// traverse the namespace up to the root node, and add any locks
// found in the process
scopes = subjectUri.getScopes();
} else {
// only return the locks that explicitly and directly lock the
// given subject
Vector scopeVector = new Vector();
scopeVector.add(subjectUri.toString());
scopes = scopeVector.elements();
}
Vector locksVector = new Vector();
while (scopes.hasMoreElements()) {
String currentScope = (String) scopes.nextElement();
Uri currentScopeUri =
namespace.getUri(slideToken, currentScope);
Enumeration currentLocks =
currentScopeUri.getStore().enumerateLocks(currentScopeUri);
while (currentLocks.hasMoreElements()) {
NodeLock currentLockToken =
(NodeLock) currentLocks.nextElement();
if (currentLockToken.hasExpired()) {
// FIXME: do cleanup of locks someplace else
try {
currentScopeUri.getStore()
.removeLock(currentScopeUri, currentLockToken);
}
catch (LockTokenNotFoundException ex) {
// ignore
}
} else {
locksVector.addElement(currentLockToken);
}
}
}
return locksVector.elements();
}
/**
* Utility function for lock checking. Mirrors Security.checkCredentials.
*
* @param token Slide token
* @param object Object on which the action is performed
* @param action Action to test
* @exception ObjectLockedException Can't perform specified action
* on object
* @exception ServiceAccessException Low level service access exception
* @exception ObjectNotFoundException One of the objects referenced
* in the lock token were not found
*/
public void checkLock(SlideToken token,
ObjectNode object, ActionNode action)
throws ServiceAccessException, ObjectNotFoundException,
ObjectLockedException {
if (!token.isForceLock()) {
return;
}
if (!token.isForceStoreEnlistment()) {
token = new SlideTokenWrapper(token, false);
}
if (Configuration.useIntegratedLocking()) {
Boolean locked = token.checkLockCache(object, action);
if (locked != null) {
if (locked.booleanValue()) {
throw new ObjectLockedException(object.getUri());
}
else {
return;
}
}
Uri objectUri = namespace.getUri(token, object.getUri());
ObjectNode realObject = objectUri.getStore()
.retrieveObject(objectUri);
try {
checkLock(token, realObject, (SubjectNode)securityHelper.getPrincipal(token), action);
token.cacheLock(object, action, false);
}
catch (ObjectLockedException e) {
token.cacheLock(object, action, true);
throw e;
}
}
}
/**
* Check locking for a specific action and credential.
*
* @param slideToken Credetials token
* @param subject Subject to test
* @param user User to test
* @param action Action to test
* @exception ObjectLockedException Can't perform specified action
* on object
* @exception ServiceAccessException Low level service access exception
* @exception ObjectNotFoundException One of the objects referenced
* in the lock token were not found
*/
public void checkLock(SlideToken slideToken,
ObjectNode subject, SubjectNode user,
ActionNode action)
throws ServiceAccessException, ObjectNotFoundException,
ObjectLockedException {
// no check for default action (server intitialization)
if (action == ActionNode.DEFAULT) {
return;
}
if (Configuration.useIntegratedLocking()) {
if (isLocked(slideToken, subject, user, action, false)) {
throw new ObjectLockedException(subject.getUri());
}
}
}
/**
* Tests if an element is locked.
*
* @param slideToken Slide token
* @param subject Subject to test
* @param user User to test
* @param action Locked for action
* @return boolean True if the subject is locked
* @exception ServiceAccessException Low level service access exception
* @exception ObjectNotFoundException One of the objects referenced
* in the lock token were not found
*/
public boolean isLocked(SlideToken slideToken,
ObjectNode subject, SubjectNode user,
ActionNode action, boolean tryToLock)
throws ServiceAccessException, ObjectNotFoundException {
NodeLock token = new NodeLock(subject, user, action,
new Date(), false);
return isLocked(slideToken, token, tryToLock);
}
/**
* Tests if an element is locked.
*
* @param slideToken Slide token
* @param subject Subject to test
* @param user User to test
* @param action Locked for action
* @param inheritance Set to true if we want to check if any children
* is locked with an incompatible lock
* @param tryToLock True if the check is intended to check whether
* or not we can put a new lock
* @return boolean True if the subject is locked
* @exception ServiceAccessException Low level service access exception
* @exception ObjectNotFoundException One of the objects referenced
* in the lock token were not found
*/
public boolean isLocked(SlideToken slideToken,
ObjectNode subject, SubjectNode user,
ActionNode action, boolean inheritance,
boolean tryToLock)
throws ServiceAccessException, ObjectNotFoundException {
NodeLock token = new NodeLock(subject, user, action, new Date(),
inheritance);
return isLocked(slideToken, token, tryToLock);
}
/**
* Tests if an element is locked.
*
* @param token Lock token to test
* @return boolean True if locked
* @exception ServiceAccessException Low level service access exception
* @exception ObjectNotFoundException One of the objects referenced
* in the lock token were not found
*/
public boolean isLocked(SlideToken slideToken, NodeLock token,
boolean tryToLock)
throws ServiceAccessException, ObjectNotFoundException {
return isLockedInternal(slideToken, token, tryToLock, null);
}
/**
* Clears the expired locks from the specified resource.
*
* @param slideToken a SlideToken
* @param objectUri a String
* @param listener an UnlockListener
* @throws SlideException
*/
public void clearExpiredLocks( SlideToken slideToken, String objectUri, UnlockListener listener ) throws SlideException {
Uri uri =
namespace.getUri(slideToken, objectUri);
Enumeration currentLocks =
uri.getStore().enumerateLocks(uri);
while (currentLocks.hasMoreElements()) {
NodeLock currentLockToken =
(NodeLock) currentLocks.nextElement();
if (currentLockToken.hasExpired()) {
try {
uri.getStore().removeLock(uri, currentLockToken);
if( listener != null )
listener.afterUnlock( objectUri );
}
catch (LockTokenNotFoundException ex) {
// ignore
}
}
}
}
/**
* Return true if a lock token for this lock has been given in the
* credentials token.
*
* @param slideToken Current credentials token
* @param token Lock token
*/
public boolean checkLockToken(SlideToken slideToken, NodeLock token) {
if (!slideToken.isEnforceLockTokens())
return true;
SubjectNode principalNode = null;
SubjectNode ownerNode = SubjectNode.getSubjectNode(token.getSubjectUri());
try {
principalNode = (SubjectNode)securityHelper.getPrincipal(slideToken);
}
catch (SlideException e) {}
if (Configuration.usePrincipalIdentifiedLocks() &&
ownerNode != null &&
ownerNode != SubjectNode.UNAUTHENTICATED &&
ownerNode.equals(principalNode)) {
return true;
}
else {
return (slideToken.checkLockToken(token.getLockId()));
}
}
/**
* Returns true, if the principal from the credentials token is either the
* lock-owner of has kill-lock privileges
*
* @param slideToken a SlideToken
* @param token a NodeLock
* @return a boolean
*
* @throws ObjectNotFoundException
* @throws ServiceAccessException
*/
public boolean checkLockOwner(SlideToken slideToken, NodeLock token) throws ObjectNotFoundException, ServiceAccessException {
boolean canUnlock = true;
SubjectNode principal = (SubjectNode)securityHelper.getPrincipal(slideToken);
SubjectNode lockOwner = SubjectNode.getSubjectNode(token.getSubjectUri());
if (!securityHelper.matchPrincipal(slideToken, principal, lockOwner)) {
// it is not the lock owner ... now check the kill-lock privilege
try {
securityHelper.checkCredentials(slideToken,
SubjectNode.getSubjectNode(token.getObjectUri()),
namespaceConfig.getKillLockAction());
}
catch (AccessDeniedException e) {
canUnlock = false;
}
}
return canUnlock;
}
// -------------------------------------------------------- Private Methods
/**
* Tests if an element is locked.
*
* @param token Lock token to test
* @return boolean True if locked
* @exception ServiceAccessException Low level service access exception
* @exception ObjectNotFoundException One of the objects referenced
* in the lock token were not found
*/
private boolean isLockedInternal
(SlideToken slideToken, NodeLock token,
boolean tryToLock, ObjectIsAlreadyLockedException nestedException)
throws ServiceAccessException, ObjectNotFoundException {
Uri objectUri = namespace.getUri(slideToken, token.getObjectUri(), false);
ObjectNode initialObject = objectUri.getStore()
.retrieveObject(objectUri);
Enumeration scopes = objectUri.getScopes();
// At the end of the test, this boolean's value is true if we can
// actually put the lock on the desired subject.
boolean isLocked = false;
// We parse all of the scopes which encompass the subject we want
// to lock.
// First, we parse all the parents of the subject.
while (!isLocked && scopes.hasMoreElements()) {
String currentScope = (String) scopes.nextElement();
Uri currentScopeUri = namespace.getUri(slideToken, currentScope, false);
Enumeration locks = currentScopeUri.getStore()
.enumerateLocks(currentScopeUri);
while (locks.hasMoreElements()) {
NodeLock currentLockToken = (NodeLock) locks.nextElement();
if (!isCompatible(slideToken, token, currentLockToken,
tryToLock)) {
isLocked = true;
if (nestedException != null) {
nestedException.addException
(new ObjectLockedException
(currentScopeUri.toString()));
}
}
}
}
// Then, if the desired scope is inheritable, we parse the
// locked subject's children to see if any of them has been
// locked with an incompatible lock.
if (token.isInheritable()) {
Stack childrenStack = new Stack();
childrenStack.push(initialObject);
while (!isLocked && !childrenStack.empty()) {
ObjectNode currentObject = (ObjectNode) childrenStack.pop();
Uri currentObjectUri =
namespace.getUri(slideToken, currentObject.getUri(), false);
// We test the compatibility of the child
Enumeration locks = currentObjectUri.getStore()
.enumerateLocks(currentObjectUri);
while (locks.hasMoreElements()) {
NodeLock currentLockToken = (NodeLock) locks.nextElement();
if (!isCompatible(slideToken, token,
currentLockToken, tryToLock)) {
isLocked = true;
if (nestedException != null) {
nestedException.addException
(new ObjectLockedException
(currentObjectUri.toString()));
}
}
}
// We get the children and add them to the Stack.
Vector childrenVector = new Vector();
Enumeration childrenUri = currentObject.enumerateChildren();
while (childrenUri.hasMoreElements()) {
String childUri = (String) childrenUri.nextElement();
Uri tempUri = namespace.getUri(slideToken, childUri, false);
ObjectNode child = tempUri.getStore()
.retrieveObject(tempUri);
childrenVector.addElement(child);
}
Enumeration children = childrenVector.elements();
while (children.hasMoreElements()) {
ObjectNode tempObject =
(ObjectNode) children.nextElement();
childrenStack.push(tempObject);
}
}
}
return isLocked;
}
/**
* Method isCompatibe
*
* @param slideToken a SlideToken
* @param checkToken the "current" token
* @param matchToken the token to check against
* (from a resource)
* @param tryToLock a boolean
*
* @return a boolean
*
*/
private boolean isCompatible(SlideToken slideToken,
NodeLock checkToken,
NodeLock matchToken,
boolean tryToLock)
throws ServiceAccessException {
boolean compatible = true;
if (matchToken.hasExpired()) {
// Since the lock has expired, it is removed
try {
if (slideToken.isForceStoreEnlistment()) {
Uri token2Uri = namespace.getUri(slideToken,
matchToken.getObjectUri());
token2Uri.getStore().removeLock(token2Uri, matchToken);
}
}
catch (LockTokenNotFoundException e) {} // ignore silently
return true;
}
// same-object-uri-OR-matchToken-is-inheritable
boolean condition0 = matchToken.getObjectUri().equals(checkToken.getObjectUri()) || matchToken.isInheritable();
if (!condition0) {
return true;
}
// lock-types-are-equal
boolean condition1 = matchToken.getTypeUri().equals(checkToken.getTypeUri());
// user-of-tokens-are-equal OR user-of-matchToken-is-parent
SubjectNode checkSubject = SubjectNode.getSubjectNode(checkToken.getSubjectUri());
SubjectNode matchSubject = SubjectNode.getSubjectNode(matchToken.getSubjectUri());
boolean condition2 =
securityHelper.matchPrincipal(slideToken, checkSubject, matchSubject);
// lock-types-are-equal OR lock-type-of-matchToken-is-parent
ActionNode checkAction = ActionNode.getActionNode(checkToken.getTypeUri());
ActionNode matchAction = ActionNode.getActionNode(matchToken.getTypeUri());
boolean condition3 =
securityHelper.matchAction(slideToken, checkAction, matchAction);
// checkToken-is-exclusive
boolean condition4 = checkToken.isExclusive();
// check-matchToken-against-slidetoken
boolean condition5 = checkLockToken(slideToken, matchToken);
// enforced-locktokens
boolean condition6 = slideToken.isEnforceLockTokens();
if ((tryToLock && condition1 && condition4)
|| (condition3 && !condition2 && !condition6)
|| (condition3 && !condition5 && condition6)
){
compatible = false;
}
// sharing the lock is OK
if (checkToken.isShared() && matchToken.isShared() && tryToLock && condition1 ) {
compatible = true;
}
// System.out.println();
// System.out.println("SlideToken:");
// System.out.println(" .showLockTokens = " + slideToken.showLockTokens());
// System.out.println(" .isEnforceLockTokens = " + slideToken.isEnforceLockTokens());
// System.out.println("Token1 = " + checkToken);
// System.out.println(" .getLockId = " + checkToken.getLockId());
// System.out.println(" .getTypeUri = " + checkToken.getTypeUri());
// System.out.println(" .getSubjectUri = " + checkToken.getSubjectUri());
// System.out.println(" .getObjectUri = " + checkToken.getObjectUri());
// System.out.println(" .isExclusive = " + checkToken.isExclusive());
// System.out.println(" .isInheritable() = " + checkToken.isInheritable());
// System.out.println("Token2 = " + matchToken);
// System.out.println(" .getLockId = " + matchToken.getLockId());
// System.out.println(" .getTypeUri = " + matchToken.getTypeUri());
// System.out.println(" .getSubjectUri = " + matchToken.getSubjectUri());
// System.out.println(" .getObjectUri = " + matchToken.getObjectUri());
// System.out.println(" .isExclusive = " + matchToken.isExclusive());
// System.out.println(" .isInheritable() = " + matchToken.isInheritable());
// System.out.println("Parameter tryToLock: "+tryToLock);
// System.out.println("C1 (lock-types-are-equal).................................: " + condition1);
// System.out.println("C2 (user-of-tokens-are-equal OR user-of-matchToken-is-parent).: " + condition2);
// System.out.println("C3 (lock-types-are-equal OR lock-type-of-checkToken-is-parent): " + condition3);
// System.out.println("C4 (checkToken-is-exclusive)..................................: " + condition4);
// System.out.println("C5 (check-matchToken-against-slidetoken)......................: " + condition5);
// System.out.println("C6 (enforced-locktokens)..................................: " + condition6);
// System.out.println("C7 (same-object-uri-OR-matchToken-is-inheritable).............: " + condition7);
// System.out.println("Compatible (tryToLock && C1 && C4 && C7 || C3 && !C2 && !C6 && C7 || C3 && !C5 && C6 && C7): " + compatible);
return compatible;
}
/**
* Tells whether or not two locks are compatible.
*
* @param token1 First token
* @param token2 Second token : object's lock
* @param tryToLock True if we want to check for a lock creation
* @return boolean True if the locks are compatible
*/
private boolean isCompatible_OLD(SlideToken slideToken,
NodeLock token1, NodeLock token2,
boolean tryToLock) {
/*
System.out.println("**** Check lock ****");
System.out.println("Lock 1 : " + token1.getSubjectUri() + " action "
+ token1.getTypeUri());
System.out.println("Lock 2 : " + token2.getSubjectUri() + " on "
+ token2.getObjectUri() + " action "
+ token2.getTypeUri());
*/
boolean compatible = true;
// We first check whether or not the lock is still valid
if (token2.hasExpired()) {
// Since the lock has expired, it is removed
try {
if (slideToken.isForceStoreEnlistment()) {
Uri token2Uri = namespace.getUri(slideToken,
token2.getObjectUri());
token2Uri.getStore().removeLock(token2Uri, token2);
}
} catch (SlideException e) {
e.printStackTrace();
}
} else {
// lock-types-are-equal
boolean condition1 = token2.getTypeUri().equals(token1.getTypeUri());
// user-of-tokens-are-equal OR user-of-token2-is-parent
boolean condition2 =
(token1.getSubjectUri().startsWith(token2.getSubjectUri()));
// lock-types-are-equal OR lock-type-of-token1-is-parent
boolean condition3 = token2.getTypeUri()
.startsWith(token1.getTypeUri());
// token1-is-exclusive
boolean condition4 = token1.isExclusive();
// check-token2-against-slidetoken
boolean condition5 = checkLockToken(slideToken, token2);
// enforced-locktokens
boolean condition6 = slideToken.isEnforceLockTokens();
// same-object-uri-OR-token2-is-inheritable
boolean condition7 = token2.getObjectUri().equals(token1.getObjectUri()) || token2.isInheritable();
if ((tryToLock && condition1 && condition4 && condition7)
|| (condition3 && !condition2 && !condition6 && condition7)
|| (condition3 && !condition5 && condition6 && condition7)
){
compatible = false;
}
// sharing the lock is OK
if (token1.isShared() && token2.isShared() && tryToLock && condition1 ) {
compatible = true;
}
// System.out.println();
// System.out.println("SlideToken:");
// System.out.println(" .showLockTokens = " + slideToken.showLockTokens());
// System.out.println(" .isEnforceLockTokens = " + slideToken.isEnforceLockTokens());
// System.out.println("Token1 = " + token1);
// System.out.println(" .getLockId = " + token1.getLockId());
// System.out.println(" .getTypeUri = " + token1.getTypeUri());
// System.out.println(" .getSubjectUri = " + token1.getSubjectUri());
// System.out.println(" .getObjectUri = " + token1.getObjectUri());
// System.out.println(" .isExclusive = " + token1.isExclusive());
// System.out.println(" .isInheritable() = " + token1.isInheritable());
// System.out.println("Token2 = " + token2);
// System.out.println(" .getLockId = " + token2.getLockId());
// System.out.println(" .getTypeUri = " + token2.getTypeUri());
// System.out.println(" .getSubjectUri = " + token2.getSubjectUri());
// System.out.println(" .getObjectUri = " + token2.getObjectUri());
// System.out.println(" .isExclusive = " + token2.isExclusive());
// System.out.println(" .isInheritable() = " + token2.isInheritable());
// System.out.println("Parameter tryToLock: "+tryToLock);
// System.out.println("C1 (lock-types-are-equal).................................: " + condition1);
// System.out.println("C2 (user-of-tokens-are-equal OR user-of-token2-is-parent).: " + condition2);
// System.out.println("C3 (lock-types-are-equal OR lock-type-of-token1-is-parent): " + condition3);
// System.out.println("C4 (token1-is-exclusive)..................................: " + condition4);
// System.out.println("C5 (check-token2-against-slidetoken)......................: " + condition5);
// System.out.println("C6 (enforced-locktokens)..................................: " + condition6);
// System.out.println("C7 (same-object-uri-OR-token2-is-inheritable).............: " + condition7);
// System.out.println("Compatible (tryToLock && C1 && C4 && C7 || C3 && !C2 && !C6 && C7 || C3 && !C5 && C6 && C7): " + compatible);
}
return compatible;
}
}