/*
 * $Header: /home/cvspublic/jakarta-slide/src/share/org/apache/slide/common/SlideTokenWrapper.java,v 1.15 2004/09/02 12:41:11 luetzkendorf Exp $
 * $Revision: 1.15 $
 * $Date: 2004/09/02 12:41:11 $
 *
 * ====================================================================
 *
 * 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.common;

import java.util.Enumeration;
import java.util.List;
import org.apache.slide.authenticate.CredentialsToken;
import org.apache.slide.store.ResourceId;
import org.apache.slide.structure.ActionNode;
import org.apache.slide.structure.ObjectNode;
import org.apache.slide.structure.SubjectNode;

/**
 * The SlideTokenWrapper wraps around an existing token.
 * It delegated all work to that token, except that it
 * may have a different policy for store enlistment, 
 * security and locking.
 *
 */
public final class SlideTokenWrapper implements SlideToken{
    
    
    // ------------------------------------------------------------ Constructor
    
    
    /**
     * Constructor.
     * @param token The token to wrap.
     */
    public SlideTokenWrapper(SlideToken token) {
        this.wrappedToken = token;
        this.forceStoreEnlistment = token.isForceStoreEnlistment();
        this.forceSecurity = token.isForceSecurity();
        this.forceLock = token.isForceLock();
        this.isExternalTransaction = token.isExternalTransaction();
    }
    
    
    
    // ----------------------------------------------------- Instance Variables
    
    
    /**
     * Credentials.
     */
    private SlideToken wrappedToken;
    
    private boolean forceStoreEnlistment = false;
    private boolean forceSecurity = true;
    private boolean forceLock = true;
    private boolean isExternalTransaction = false;
    
    // ------------------------------------------------------------- Properties
    
    
    /**
     * Returns the credentials token.
     *
     * @return String
     */
    public CredentialsToken getCredentialsToken() {
        return wrappedToken.getCredentialsToken();
    }
    
    
    /**
     * Credentials token mutator.
     */
    public void setCredentialsToken(CredentialsToken credentialsToken) {
        wrappedToken.setCredentialsToken(credentialsToken);
    }
    
    
    /**
     * Returns the CacheInfo token.
     *
     * @return CacheInfoToken
     */
    public CacheInfoToken getCacheInfoToken() {
        return wrappedToken.getCacheInfoToken();
    }
    
    
    /**
     * CacheInfo token mutator.
     */
    public void setCacheInfoToken(CacheInfoToken cacheInfoToken) {
        wrappedToken.setCacheInfoToken(cacheInfoToken);
    }
    
    
    /**
     * Use lock tokens in lock resolution ?
     *
     * @return boolean
     */
    public boolean isEnforceLockTokens() {
        return wrappedToken.isEnforceLockTokens();
    }
    
    
    /**
     * Enforce lock tokens flag mutator.
     *
     * @param enforceLockTokens New flag value
     */
    public void setEnforceLockTokens(boolean enforceLockTokens) {
        wrappedToken.setEnforceLockTokens(enforceLockTokens);
    }
    
    
    /**
     * Force store enlistment flag accessor. If true, that will cause Slide to
     * enlist the store in the current transaction for all operations,
     * to be able to prevent dirty reads when doing complex updates.
     *
     * @return boolean
     */
    public boolean isForceStoreEnlistment() {
        return forceStoreEnlistment;
    }
    
    
    /**
     * Force store enlistment flag mutator. If set to true, that will cause
     * Slide to enlist the store in the current transaction for all
     * operations, to be able to prevent dirty reads when doing complex
     * updates. That value should be set to true only in some very specific
     * critical sections of the code, as this would greatly decrease the
     * ability of Slide to handle multiple concurrent requests.
     *
     * @param forceStoreEnlistment New flag value
     */
    public void setForceStoreEnlistment(boolean forceStoreEnlistment) {
        this.forceStoreEnlistment = forceStoreEnlistment;
    }
    
    
    /**
     * Add a new lock token to the lock token list.
     *
     * @param lockId Lock token to add
     */
    public void addLockToken(String lockId) {
        wrappedToken.addLockToken(lockId);
    }
    
    
    /**
     * Removes a lock token from the lock token list.
     *
     * @param lockId Lock token to remove
     */
    public void removeLockToken(String lockId) {
        wrappedToken.removeLockToken(lockId);
    }
    
    
    /**
     * Clears the lock token list.
     */
    public void clearLockTokens() {
        wrappedToken.clearLockTokens();
    }
    
    
    /**
     * Checks if the given lock token is present.
     *
     * @param lockToken Lock token to check
     * @return boolean True if the given lock token is present
     */
    public boolean checkLockToken(String lockToken) {
        return wrappedToken.checkLockToken(lockToken);
    }
    
    
    public List showLockTokens() {
        return wrappedToken.showLockTokens();
    }
    
    /**
     * Add a new parameter to the parameter list.
     *
     * @param parameterName Parameter to add
     * @param parameterValue Parameter value
     */
    public void addParameter(String parameterName, Object parameterValue) {
        wrappedToken.addParameter(parameterName, parameterValue);
    }
    
    
    /**
     * Removes a parameter from the parameter list.
     *
     * @param parameterName Parameter to remove
     */
    public void removeParameter(String parameterName) {
        wrappedToken.removeParameter(parameterName);
    }
    
    
    /**
     * Clears the parameter list.
     */
    public void clearParameters() {
        wrappedToken.clearParameters();
    }
    
    /**
     * Returns a named parameter. 
     */
    public Object getParameter(String name) {
        return wrappedToken.getParameter(name);
    }
    
    /**
     * Return parameter list.
     */
    public Enumeration getParameterNames() {
        return wrappedToken.getParameterNames();
    }
    
    /**
     * allows to cache the result of a permission check
     *
     * @return true if successful added to cache, false else
     */
    public void cachePermission(ObjectNode object, ActionNode action, boolean permission){
        wrappedToken.cachePermission(object, action, permission);
    }
    
    /**
     * checks if the permission cache contains an entry for the ObjectNode and
     * ActionNode combination.
     *
     * @return true if granted, false if denied, null if nothing in the cache.
     */
    public Boolean checkPermissionCache(ObjectNode object, ActionNode action){
        return wrappedToken.checkPermissionCache(object, action);
    }
    
    /**
     * Force security check. If false, checkCredentials of SecurityImpl will
     * return immediately.
     *
     * @return   a boolean
     */
    public boolean isForceSecurity() {
        return forceSecurity;
    }
    
    public void setForceSecurity(boolean forceSecurity) {
        this.forceSecurity = forceSecurity;
    }

    /**
     * Force lock check. If false, checkLock of LockImpl will
     * return immediately.
     *
     * @return   a boolean
     */
    public boolean isForceLock() {
        return forceLock;
    }
        
    public void setForceLock(boolean forceLock) {
        this.forceLock = forceLock;
    }
    
    /**
     * allows to cache the result of a lock check
     */
    public void cacheLock(ObjectNode object, ActionNode action, boolean lock) {
        wrappedToken.cacheLock(object, action, lock);
    }
    
    /**
     * checks if the lock cache contains an entry for the ObjectNode and
     * ActionNode combination.
     *
     * @return true if locked, false otherwise
     */
    public Boolean checkLockCache(ObjectNode object, ActionNode action) {
        // TODO ??
        return wrappedToken.checkLockCache(object, action);
    }
    
    /**
     * Allows to cache the result of a resolve operation
     */
    public void cacheResolve(Uri uri, ResourceId resourceId) {
        wrappedToken.cacheResolve(uri, resourceId);
    }
    
    /**
     * Checks if the resolve cache contains an entry for the specified uri.
     * @return the cached resourceId or null
     */
    public ResourceId checkResolveCache(Uri uri) {
        return wrappedToken.checkResolveCache(uri);
    }
    
    /**
     * Allows to cache the result of a matchPrincipal operation
     */
    public void cacheMatchPrincipal(SubjectNode checkSubject, SubjectNode matchSubject, boolean match) {
        wrappedToken.cacheMatchPrincipal(checkSubject, matchSubject, match);
    }
    
    /**
     * Checks if the matchPrincipal cache
     * @return the cached Boolean or null
     */
    public Boolean checkMatchPrincipalCache(SubjectNode checkSubject, SubjectNode matchSubject) {
        return wrappedToken.checkMatchPrincipalCache(checkSubject, matchSubject);
    }

    /**
     * Checks if this request is part of an externally controlled transaction. 
     */
    public boolean isExternalTransaction() {
        return isExternalTransaction;
    }

    /**
     * Sets if this request is part of an externally controlled transaction. 
     */
    public void setExternalTx() {
        isExternalTransaction = true;
    }
}
