/*
 * $Header: /home/cvspublic/jakarta-slide/src/share/org/apache/slide/lock/Lock.java,v 1.20 2004/07/28 09:35:44 ib Exp $
 * $Revision: 1.20 $
 * $Date: 2004/07/28 09:35:44 $
 *
 * ====================================================================
 *
 * 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 org.apache.slide.common.ServiceAccessException;
import org.apache.slide.common.SlideException;
import org.apache.slide.common.SlideToken;
import org.apache.slide.security.AccessDeniedException;
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.event.VetoException;

/**
 * Lock helper class.
 * 
 * @version $Revision: 1.20 $
 */
public interface Lock {
    
    
    // ------------------------------------------------------ Interface 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
     */
    void lock(SlideToken slideToken, NodeLock lockToken)
        throws ServiceAccessException, ObjectIsAlreadyLockedException, 
        AccessDeniedException, ObjectNotFoundException, VetoException;
    
    
    /**
     * 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 was successfully removed
     * 
     * @exception ServiceAccessException Low level service access exception
     * @exception LockTokenNotFoundException Cannot find the Lock in the 
     * Lock Store service
     */
    boolean unlock(SlideToken slideToken, NodeLock lockToken)
        throws ServiceAccessException, LockTokenNotFoundException, VetoException;
    
    /**
     * 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
     */
    void unlock(SlideToken slideToken, String objectUri, 
                String lockId)
        throws ServiceAccessException, LockTokenNotFoundException, 
        ObjectNotFoundException, VetoException;
    
    
    /**
     * 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
     */
    void renew(SlideToken slideToken, NodeLock lockToken, 
               Date newExpirationDate)
        throws ServiceAccessException, LockTokenNotFoundException, VetoException;
    
    
   /**
     * 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
     */
    void renew(SlideToken slideToken, String objectUri, 
               String lockId, Date newExpirationDate)
        throws ServiceAccessException, LockTokenNotFoundException, 
        ObjectNotFoundException, VetoException;
    
    
    /**
     * 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
     */
    void kill(SlideToken slideToken, SubjectNode subject)
        throws ServiceAccessException, AccessDeniedException, 
        LockTokenNotFoundException, ObjectNotFoundException, VetoException;
    
    
    /**
     * Enumerate locks on a subject, including any locks inherited from parent
     * subjects.
     * 
     * @param slideToken the slide token
     * @param objectUri the URI of the object of which we want to enumerate 
     *        active locks
     * 
     * @return an Enumeration of NodeLock objects
     * 
     * @exception ServiceAccessException low level service access exception
     * @exception ObjectNotFoundException one of the objects referenced in 
     *            the lock token were not found
     */
    Enumeration enumerateLocks(SlideToken slideToken, 
                               String objectUri)
        throws ServiceAccessException, ObjectNotFoundException, 
        LockTokenNotFoundException;
    
    
    /**
     * Enumerate locks on a subject, optionally excluding locks inherited 
     * from parent subjects.
     * 
     * @param slideToken the slide token
     * @param objectUri the URI of the object of which we want to enumerate 
     *        active locks
     * @param inherited if true, locks inherited from parent objects will be 
     *                  included in the result, otherwise, only locks that
     *                  explicitly lock the object will be returned
     * 
     * @return an Enumeration of NodeLock objects
     * 
     * @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
     */
    Enumeration enumerateLocks(SlideToken slideToken, String objectUri,
                               boolean inherited)
        throws ServiceAccessException, ObjectNotFoundException, 
        LockTokenNotFoundException;
    
    
    /**
     * Utility function for lock checking. Mirrors Security.checkCredentials.
     * 
     * @param slideToken Credetials 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
     */
    void checkLock(SlideToken slideToken, ObjectNode object, 
                   ActionNode action)
        throws ServiceAccessException, ObjectNotFoundException, 
        ObjectLockedException;
    
    
    /**
     * 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
     */
    void checkLock(SlideToken slideToken, ObjectNode subject, 
                   SubjectNode user, ActionNode action)
        throws ServiceAccessException, ObjectNotFoundException, 
        ObjectLockedException;
    
    
    /**
     * 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
     */
    boolean isLocked(SlideToken slideToken, ObjectNode subject, 
                     SubjectNode user, ActionNode action, boolean tryToLock)
        throws ServiceAccessException, ObjectNotFoundException;
    
    
    /**
     * 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
     */
    boolean isLocked(SlideToken slideToken, ObjectNode subject, 
                     SubjectNode user, ActionNode action, boolean inheritance,
                     boolean tryToLock)
        throws ServiceAccessException, ObjectNotFoundException;
    
    
    /**
     * 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
     */
    boolean isLocked(SlideToken slideToken, NodeLock token, 
                     boolean tryToLock)
        throws ServiceAccessException, ObjectNotFoundException;
    
    /**
     * 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;
    
    /**
     * 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);

    /**
     * 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;
}
