/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/tamino/src/store/org/apache/slide/store/tamino/security/XSecurityStore.java,v 1.3 2004/07/30 06:52:01 ozeigermann Exp $
 * $Revision: 1.3 $
 * $Date: 2004/07/30 06:52:01 $
 *
 * ====================================================================
 *
 * Copyright 1999-2004 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.store.tamino.security;

import com.softwareag.common.instrumentation.logging.Level;
import com.softwareag.common.instrumentation.logging.Logger;
import com.softwareag.common.instrumentation.logging.LoggerFactory;
import com.softwareag.common.instrumentation.logging.LoggerUtil;
import java.util.Enumeration;
import java.util.Hashtable;
import javax.transaction.xa.XAException;
import javax.transaction.xa.Xid;
import org.apache.slide.common.Namespace;
import org.apache.slide.common.NamespaceAccessToken;
import org.apache.slide.common.Scope;
import org.apache.slide.common.ServiceAccessException;
import org.apache.slide.common.ServiceConnectionFailedException;
import org.apache.slide.common.ServiceDisconnectionFailedException;
import org.apache.slide.common.ServiceInitializationFailedException;
import org.apache.slide.common.ServiceParameterErrorException;
import org.apache.slide.common.ServiceParameterMissingException;
import org.apache.slide.common.ServiceResetFailedException;
import org.apache.slide.common.Uri;
import org.apache.slide.content.NodeRevisionContent;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.content.NodeRevisionDescriptors;
import org.apache.slide.content.NodeRevisionNumber;
import org.apache.slide.content.RevisionAlreadyExistException;
import org.apache.slide.content.RevisionDescriptorNotFoundException;
import org.apache.slide.content.RevisionNotFoundException;
import org.apache.slide.lock.LockTokenNotFoundException;
import org.apache.slide.lock.NodeLock;
import org.apache.slide.macro.ForbiddenException;
import org.apache.slide.security.NodePermission;
import org.apache.slide.store.ContentStore;
import org.apache.slide.store.LockStore;
import org.apache.slide.store.NodeStore;
import org.apache.slide.store.RevisionDescriptorStore;
import org.apache.slide.store.RevisionDescriptorsStore;
import org.apache.slide.store.SecurityStore;
import org.apache.slide.store.tamino.common.XForbiddenException;
import org.apache.slide.store.tamino.store.XMemoryStore;
import org.apache.slide.structure.ObjectAlreadyExistsException;
import org.apache.slide.structure.ObjectNode;
import org.apache.slide.structure.ObjectNotFoundException;
import org.apache.slide.util.ClassName;


/**
 ** XSecurity store. This non-persistent store serves as the Security Store.
 **
 ** @author    eckehard.hermann@softwareag.com
 ** @version   $Revision: 1.3 $
 **
 **/
public class XSecurityStore extends XMemoryStore implements ContentStore, LockStore,
NodeStore, RevisionDescriptorsStore, RevisionDescriptorStore, SecurityStore {
    
    private static final String LOGNAME = LoggerUtil.getThisClassName();
    private static final String CLASSNAME = new ClassName(LOGNAME).getPlainName();
    private static Logger logger = LoggerFactory.getLogger(LOGNAME);

    /** True, if this store is initialized. */
    protected boolean initialized = false;

    /** The namespace access token */
    protected NamespaceAccessToken nsaToken = null;

     
    /**
     ** Default constructor.
     **/
    public XSecurityStore() {
        if( logger.isLoggable(Level.FINE) )
            logger.entering( CLASSNAME, "<init>" );
        
        if( logger.isLoggable(Level.FINE) )
            logger.exiting( CLASSNAME, "<init>" );
    }

    /**
     * Return true, if this store is initialized.
     * @return true, if this store is initialized
     */
    public boolean isInitialized() {
        return initialized;
    }
    
    /**
     ** Get the associated namespace.
     **
     ** @return     return the namespace
     **/
    public Namespace getNamespace() {
        return namespace;
    }
    
    /**
     ** Get the associated scope.
     **
     ** @return     return the scope
     **/
    public Scope getScope() {
        return scope;
    }
    
     
    /**
     * Initializes this child store with a set of parameters.
     * These are:
     * <li>not yet defined...
     *
     * @param parameters Hashtable containing the parameters' name
     * and associated value
     *
     * @exception   ServiceParameterErrorException
     * @exception   ServiceParameterMissingException
     */
    public void setParameters(Hashtable parameters)
    throws ServiceParameterErrorException, ServiceParameterMissingException {
        if( logger.isLoggable(Level.FINE) )
            logger.entering( CLASSNAME, "setParameters", new Object[] {parameters} );

        this.parameters = parameters;
            
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME, "setParameters" );
    }
    
    /**
     * Connects to this child store.
     *
     * @exception ServiceConnectionFailedException
     */
    public synchronized void connect() throws ServiceConnectionFailedException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME, "connect" );
        
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME, "connect" );
    }
    
    /**
     * Disconnects from this child store.
     *
     * @exception ServiceDisconnectionFailedException
     */
    public void disconnect() throws ServiceDisconnectionFailedException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME, "disconnect" );
        
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME, "disconnect" );
    }
    
    /**
     * Initializes this child store.
     * @param token token
     * @exception ServiceInitializationFailedException Throws an exception
     * if this child store has already been initialized before
     */
    public synchronized void initialize( NamespaceAccessToken token )
    throws ServiceInitializationFailedException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME, "initialize",
            new Object[] {(token!=null ? token.getName() : null)} );

        if( initialized )
            throw new ServiceInitializationFailedException( this, "Already initialized" );
        
        this.initialized = true;
        this.nsaToken = token;
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME, "initialize" );
    }
    
    /**
     * Deletes content store.
     *
     * @exception ServiceResetFailedException
     */
    public void reset() throws ServiceResetFailedException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME, "reset" );
   
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME, "reset" );
    }
    
    /**
     * This function tells whether or not this child store is connected.
     *
     * @return boolean true if we are connected
     * @exception ServiceAccessException Service access error
     */
    public boolean isConnected() throws ServiceAccessException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME, "isConnected" );
        
        boolean result = true;
        
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME, "isConnected",
            new Boolean(result) );
        return result;
    }
    
    /**
     * Indicates whether or not the objects managed by this service should be
     * cached. Caching is enabled by default.
     *
     * @return boolean True if results should be cached
     */
    public boolean cacheResults() {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME, "cacheResults" );
        
        boolean result = false;
        
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME, "cacheResults",
            new Boolean(result) );
        return result;
    }
    
    /**
     * Commit the global transaction specified by xid.
     * @param xid  transaction id
     * @param onePhase handle in one phase
     * @exception XAException transaction error
     */
    public void commit( Xid xid, boolean onePhase ) throws XAException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME, "commit",
            new Object[] {xid, new Boolean(onePhase)}  );
                
        super.commit( xid, onePhase );
        
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME, "commit" );
    }
    
    /**
     * Inform the resource manager to roll back work done on behalf of a
     * transaction branch.
     * @param xid transaction id
     * @exception XAException transaction error
     */
    public void rollback( Xid xid ) throws XAException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME, "rollback",
            new Object[] {xid}  );
                
        super.rollback( xid );
        
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME, "rollback" );
    }
    
    // ------------------------------------------------------------------------
    // ContentStore interface
    // ------------------------------------------------------------------------
    
    /**
     * Retrieve revision content.
     *
     * @param uri Uri
     * @param revisionDescriptor revision descriptor
     * @return a node revision content
     * @exception ServiceAccessException Error accessing the revision descriptor
     * @exception RevisionNotFoundException Error accessing the revision descriptor
     */
    public NodeRevisionContent retrieveRevisionContent(
    Uri uri, NodeRevisionDescriptor revisionDescriptor)
    throws ServiceAccessException, RevisionNotFoundException {
        if( logger.isLoggable(Level.FINE) )
            logger.entering( CLASSNAME, "retrieveRevisionContent", new Object[] {uri,
            (revisionDescriptor!=null
               ? revisionDescriptor.getRevisionNumber()+"@"+revisionDescriptor.getBranchName()
                 : null) } );

        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
            "NodeRevisionContent" );
        throw new ServiceAccessException( this,
        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }
    
    /**
     * Create a new revision
     *
     * @param uri Uri
     * @param revisionDescriptor Node revision descriptor
     * @param revisionContent Node revision content
     * @exception ServiceAccessException Error accessing the revision descriptor
     * @exception RevisionAlreadyExistException Error accessing the revision descriptor
     */
    public void createRevisionContent( Uri uri, NodeRevisionDescriptor revisionDescriptor,
    NodeRevisionContent revisionContent )
    throws ServiceAccessException, RevisionAlreadyExistException {
        if( logger.isLoggable(Level.FINE) )
            logger.entering( CLASSNAME, "createRevisionContent", new Object[] {uri,
            (revisionDescriptor!=null
                 ? revisionDescriptor.getRevisionNumber()+"@"+revisionDescriptor.getBranchName()
                 : null), revisionContent} );
        
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
                                                           "createRevisionContent" );
        
        throw new ServiceAccessException( this,
        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }

        
    /**
     * Modify the latest revision of an object.
     *
     * @param uri Uri
     * @param revisionDescriptor Node revision descriptor
     * @param revisionContent Node revision content
     * @exception ServiceAccessException Error accessing the revision descriptor
     * @exception RevisionNotFoundException Error accessing the revision descriptor
     */
    public void storeRevisionContent( Uri uri, NodeRevisionDescriptor revisionDescriptor,
    NodeRevisionContent revisionContent)
    throws ServiceAccessException, RevisionNotFoundException {
        if( logger.isLoggable(Level.FINE) )
            logger.entering( CLASSNAME, "storeRevisionContent", new Object[] {uri,
            (revisionDescriptor!=null
                 ? revisionDescriptor.getRevisionNumber()+"@"+revisionDescriptor.getBranchName()
                 : null), revisionContent} );
        
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
          "storeRevisionContent" );
        
        throw new ServiceAccessException( this,
        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }
        
    /**
     * Remove revision.
     *
     * @param uri Uri
     * @param revisionDescriptor revision descriptor
     * @exception ServiceAccessException Error accessing the revision descriptor
     *
     */
    public void removeRevisionContent( Uri uri, NodeRevisionDescriptor revisionDescriptor )
    throws ServiceAccessException {
        if( logger.isLoggable(Level.FINE) )
            logger.entering( CLASSNAME, "removeRevisionContent", new Object[] {uri,
            (revisionDescriptor!=null
                 ? revisionDescriptor.getRevisionNumber()+"@"+revisionDescriptor.getBranchName()
                 : null)} );
        
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
                                                   "removeRevisionContent" );
        
        throw new ServiceAccessException( this,
        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }
    
    // ------------------------------------------------------------------------
    // NodeStore interface
    // ------------------------------------------------------------------------
    
    /**
     * Retrieve an object from the Descriptors Store.
     *
     * @param uri Uri of the object we want to retrieve
     * @return an object node
     * @exception ServiceAccessException Error accessing the Descriptors Store
     * @exception ObjectNotFoundException The object to retrieve was not found
     */
    public ObjectNode retrieveObject(Uri uri)
    throws ServiceAccessException, ObjectNotFoundException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME, "retrieveObject",
            new Object[] {uri} );
        
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
                                                           "retrieveObject" );
        
        throw new ServiceAccessException( this,
        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }
    
    /**
     * Store an object in the Descriptors Store.
     *
     * @param uri Uri of the object we want to update
     * @param object Object to update
     * @exception ServiceAccessException Error accessing the Descriptors Store
     * @exception ObjectNotFoundException The object to update was not found
     */
    public void storeObject(Uri uri, ObjectNode object)
    throws ServiceAccessException, ObjectNotFoundException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME, "storeObject",
            new Object[] {uri, (object!=null ? object.getUri() : null)} );
        
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
                                                           "storeObject" );
        
//        throw new ServiceAccessException( this,
//        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }
    
    /**
     * Create a new object in the Descriptors Store.
     *
     * @param uri Uri of the object we want to create
     * @param object SlideObject
     * @exception ServiceAccessException Error accessing the Descriptors Store
     * @exception ObjectAlreadyExistsException An object already exists
     * at this Uri
     */
    public void createObject(Uri uri, ObjectNode object)
    throws ServiceAccessException, ObjectAlreadyExistsException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME, "createObject",
            new Object[] {uri, (object!=null ? object.getUri() : null)} );
        
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
                                                           "createObject" );
        
        throw new ServiceAccessException( this,
        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }
    
    /**
     * Remove an object from the Descriptors Store.
     *
     * @param uri Uri of the object we want to remove
     * @param object Object to remove **IGNORED**
     * @exception ServiceAccessException Error accessing the Descriptors Store
     * @exception ObjectNotFoundException The object to remove was not found
     */
    public void removeObject(Uri uri, ObjectNode object)
    throws ServiceAccessException, ObjectNotFoundException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME, "removeObject",
            new Object[] {uri, (object!=null ? object.getUri() : null)} );
        
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
                                                           "removeObject" );
        
        throw new ServiceAccessException( this,
        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }
    
    // ------------------------------------------------------------------------
    // SecurityStore interface
    // ------------------------------------------------------------------------
    
    /**
     * Store an object permissions in the Descriptors Store.
     *
     * @param uri Uri of the resource
     * @param permission Permission we want to create
     * @exception ServiceAccessException Error accessing the Descriptors Store
     */
    public void grantPermission(Uri uri, NodePermission permission)
    throws ServiceAccessException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME, "grantPermission",
                                                            new Object[] {uri, permission} );
        
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
                                                           "grantPermission" );
        
        throw new ServiceAccessException( this,
        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }
    
    /**
     * Revoke an object permissions in the Descriptors Store.
     *
     * @param uri Uri of the resource
     * @param permission Permission we want to create
     * @exception ServiceAccessException Error accessing the Descriptors Store
     */
    public void revokePermission(Uri uri, NodePermission permission)
    throws ServiceAccessException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME,
            "revokePermission", new Object[] {uri, permission} );
        
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
                                                           "revokePermission" );
        
        throw new ServiceAccessException( this,
        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }
    
    /**
     * Revoke all the permissions on the object.
     *
     * @param uri Uri of the resource
     * @exception ServiceAccessException Error accessing the Descriptors Store
     */
    public void revokePermissions(Uri uri) throws ServiceAccessException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME,
            "revokePermissions", new Object[] {uri} );
        
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
                                                           "revokePermissions" );
        
        throw new ServiceAccessException( this,
        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }
    
    /**
     * Enumerate permissions on the resource given by uri.
     *
     * @param uri Uri of the resource
     * @return the permissions as enumeration
     * @exception ServiceAccessException Error accessing the Descriptors Store
     */
    public Enumeration enumeratePermissions(Uri uri) throws ServiceAccessException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME,
            "enumeratePermissions", new Object[] {uri} );
        
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
                                                           "enumeratePermissions" );
        
        throw new ServiceAccessException( this,
        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }
    
    // ------------------------------------------------------------------------
    // LockStore interface
    // ------------------------------------------------------------------------
    
    /**
     * Puts a lock on a subject.
     *
     * @param uri Uri of the resource
     * @param lock Lock token
     * @exception ServiceAccessException Service access error
     */
    public void putLock(Uri uri, NodeLock lock) throws ServiceAccessException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME, "putLock",
            new Object[] {uri, (lock!=null ? lock.getLockId() : null)} );
        
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
                                                           "putLock" );
        
        throw new ServiceAccessException( this,
        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }
    
    /**
     * Renews a lock.
     *
     * @param uri Uri of the resource
     * @param lock Token to renew
     * @exception ServiceAccessException Service access error
     * @exception LockTokenNotFoundException Lock token was not found
     */
    public void renewLock(Uri uri, NodeLock lock)
    throws ServiceAccessException, LockTokenNotFoundException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME, "renewLock",
            new Object[] {uri, (lock!=null ? lock.getLockId() : null)} );

        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
                                                           "renewLock" );
        
        throw new ServiceAccessException( this,
        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }
    
    /**
     * Removes (cancels) a lock.
     *
     * @param uri Uri of the resource
     * @param lock Token to remove
     * @exception ServiceAccessException Service access error
     * @exception LockTokenNotFoundException Lock token was not found
     */
    public void removeLock(Uri uri, NodeLock lock)
    throws ServiceAccessException, LockTokenNotFoundException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME, "removeLock",
            new Object[] {uri, (lock!=null ? lock.getLockId() : null)} );

        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
                                                           "removeLock" );
        
        throw new ServiceAccessException( this,
        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }
    
    /**
     * Kills a lock.
     *
     * @param uri Uri of the resource
     * @param lock Token to remove
     * @exception ServiceAccessException Service access error
     * @exception LockTokenNotFoundException Lock token was not found
     */
    public void killLock(Uri uri, NodeLock lock)
    throws ServiceAccessException, LockTokenNotFoundException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME, "killLock",
            new Object[] {uri, (lock!=null ? lock.getLockId() : null)} );
        
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
                                                           "killLock" );
        
        throw new ServiceAccessException( this,
        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }
    
    /**
     * Returns the list of locks put on a subject.
     *
     * @param uri Uri of the resource
     * @return Enumeration List of locks which have been put on the subject
     * @exception ServiceAccessException Service access error
     */
    public Enumeration enumerateLocks(Uri uri) throws ServiceAccessException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME, "enumerateLocks",
            new Object[] {uri} );
        
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
                                                           "enumerateLocks" );
        
        throw new ServiceAccessException( this,
        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }
    
    // ------------------------------------------------------------------------
    // RevisionDescriptorsStore interface
    // ------------------------------------------------------------------------
    
    /**
     * Retrieve a revision descriptors.
     *
     * @param uri Uri
     * @return node revision descriptors
     * @exception ServiceAccessException Service access error
     * @exception RevisionDescriptorNotFoundException Revision descriptor
     * was not found
     */
    public NodeRevisionDescriptors retrieveRevisionDescriptors(Uri uri)
    throws ServiceAccessException, RevisionDescriptorNotFoundException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME,
            "retrieveRevisionDescriptors", new Object[] {uri} );
        
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
                                                           "retrieveRevisionDescriptors" );
        
        throw new ServiceAccessException( this,
        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }
    
    /**
     * Create new revision descriptors.
     *
     * @param uri Uri
     * @param revisionDescriptors Node revision descriptors
     * @exception ServiceAccessException Service access error
     */
    public void createRevisionDescriptors
    (Uri uri, NodeRevisionDescriptors revisionDescriptors)
    throws ServiceAccessException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME,
            "createRevisionDescriptors", new Object[] {uri,
            (revisionDescriptors!=null ? revisionDescriptors.getUri() : null)} );
                
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
                                                           "createRevisionDescriptors" );
        
        throw new ServiceAccessException( this,
        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }
    
    /**
     * Update revision descriptors.
     *
     * @param uri Uri
     * @param revisionDescriptors Node revision descriptors
     * @exception ServiceAccessException Service access error
     * @exception RevisionDescriptorNotFoundException Revision descriptor
     * was not found
     */
    public void storeRevisionDescriptors
    (Uri uri, NodeRevisionDescriptors revisionDescriptors)
    throws ServiceAccessException, RevisionDescriptorNotFoundException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME,
            "storeRevisionDescriptors", new Object[] {uri,
            (revisionDescriptors!=null ? revisionDescriptors.getUri() : null)} );
                
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
                                                           "storeRevisionDescriptors" );
        
        throw new ServiceAccessException( this,
        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }
    
    /**
     * Remove revision descriptors.
     *
     * @param uri uri
     * @exception ServiceAccessException Service access error
     */
    public void removeRevisionDescriptors(Uri uri) throws ServiceAccessException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME,
            "removeRevisionDescriptors", new Object[] {uri} );

        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
                                                           "removeRevisionDescriptors" );
        
        throw new ServiceAccessException( this,
        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }
    
    // ------------------------------------------------------------------------
    // RevisionDescriptorStore interface
    // ------------------------------------------------------------------------
    
    /**
     * Retrieve revision descriptor.
     *
     * @param uri uri
     * @param revisionNumber Node revision number
     * @return a node revision descriptor
     * @exception ServiceAccessException Service access error
     * @exception RevisionDescriptorNotFoundException revision descriptor not found
     */
    public NodeRevisionDescriptor retrieveRevisionDescriptor
    (Uri uri, NodeRevisionNumber revisionNumber)
    throws ServiceAccessException, RevisionDescriptorNotFoundException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME,
            "retrieveRevisionDescriptor", new Object[] {uri, revisionNumber} );

        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
                                                           "retrieveRevisionDescriptor" );
        
        throw new ServiceAccessException( this,
        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }
    
    /**
     * Create new revision descriptor.
     *
     * @param uri Uri
     * @param revisionDescriptor Node revision descriptor
     * @exception ServiceAccessException Service access error
     */
    public void createRevisionDescriptor
    (Uri uri, NodeRevisionDescriptor revisionDescriptor) throws ServiceAccessException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME,
            "createRevisionDescriptor", new Object[] {uri, (revisionDescriptor!=null
            ? revisionDescriptor.getRevisionNumber()+"@"+revisionDescriptor.getBranchName()
            : null)} );

        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
                                                           "createRevisionDescriptor" );
        
        throw new ServiceAccessException( this,
        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }
    
    /**
     * Update revision descriptor.
     *
     * @param uri Uri
     * @param revisionDescriptor Node revision descriptor
     * @exception ServiceAccessException Service access error
     * @exception RevisionDescriptorNotFoundException Revision descriptor
     * was not found
     */
    public void storeRevisionDescriptor
    (Uri uri, NodeRevisionDescriptor revisionDescriptor)
    throws ServiceAccessException, RevisionDescriptorNotFoundException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME,
            "storeRevisionDescriptor", new Object[] {uri, (revisionDescriptor!=null
            ? revisionDescriptor.getRevisionNumber()+"@"+revisionDescriptor.getBranchName()
            : null)} );
                
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
                                                           "storeRevisionDescriptor" );
        
//        throw new ServiceAccessException( this,
//        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }

    
    /**
     * Remove revision descriptor.
     *
     * @param uri Uri
     * @param number Revision number
     * @exception ServiceAccessException Service access error
     */
    public void removeRevisionDescriptor(Uri uri, NodeRevisionNumber number)
    throws ServiceAccessException {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME,
            "removeRevisionDescriptor", new Object[] {uri, number} );

        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME,
                                                           "removeRevisionDescriptor" );
        
        throw new ServiceAccessException( this,
        new ForbiddenException(uri.toString(), new XForbiddenException( "access is forbidden" )) );
    }

    
    
    /**
     * Return true if the given node revision descriptor is a collection.
     * @param nrd node revision descriptor
     * @return true if the given node revision descriptor is a collection
     */
    protected boolean isCollection( NodeRevisionDescriptor nrd ) {
        boolean result = false;
        if (nrd.propertyValueContains(NodeRevisionDescriptor.RESOURCE_TYPE ,"collection")) {
            result = true;
        }
        return result;
    }
}

