/*
 * $Header: /home/cvspublic/jakarta-slide/src/share/org/apache/slide/content/ContentInterceptor.java,v 1.8 2004/07/28 09:37:56 ib Exp $
 * $Revision: 1.8 $
 * $Date: 2004/07/28 09:37:56 $
 *
 * ====================================================================
 *
 * 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.content;

import java.util.Hashtable;
import org.apache.slide.common.NamespaceAccessToken;
import org.apache.slide.common.SlideToken;
import org.apache.slide.common.ServiceAccessException;
import org.apache.slide.lock.ObjectLockedException;
import org.apache.slide.security.AccessDeniedException;
import org.apache.slide.structure.LinkedObjectNotFoundException;
import org.apache.slide.structure.ObjectNotFoundException;

/**
 * An interface that allows custom components to observe and intercept 
 * storage, retrieval and removal of content.
 * 
 * <p>
 *   Multiple <code>ContentInterceptors</code> can be associated with a single 
 *   <code>Namespace</code>. They are typically configured in the 
 *   <code>&lt;configuration&gt;</code> section of the domain configuration 
 *   file like this:
 * </p>
 * <p><code>
 * &nbsp;&lt;content-interceptor class="com.acme.MyContentInterceptor"&gt;
 * <br>
 * &nbsp;&nbsp;&lt;parameter name="myParam1"&gt;someValue&lt;/parameter&gt;
 * <br>
 * &nbsp;&nbsp;&lt;parameter name="myParam2"&gt;anotherValue&lt;/parameter&gt;
 * <br>
 * &nbsp;&lt;/content-interceptor&gt;
 * </code></p>
 * <p>
 *   As you can see, <code>ContentInterceptors</code> can be configured with 
 *   parameters. This is optional, and exactly which parameters are available 
 *   depends on the specific  <code>ContentInterceptor</code> implementation.
 * </p>
 * <p>
 *   <code>ContentInterceptor</code> implementations must provide a public 
 *   constructor without arguments, so that instances of the class can be 
 *   instantiated at startup. In addition, implementors should pay attention 
 *   to this minimal lifecycle definition:
 *   <ul>
 *     <li>When the namespace is being configured, <code>setParameters</code> 
 *     will be called with a <code>java.util.Hashtable</code> containing the 
 *     parameter names and values as specified in the configuration.</li>
 *     <li>When configuration is completed, <code>setNamespace</code> will be 
 *     called, passing in a <code>NamespaceAccessToken</code> than can later 
 *     be used by the <code>ContentInterceptor</code> to perform its deeds 
 *     (like logging to the namespace logger).</li>
 *     <li>After that, any of the <code>preXXX</code> and <code>postXXX</code> 
 *     methods will be called as soon as the associated event occurs.</li>
 *  </ul>
 * </p>
 * <p>
 *   The signatures of the <code>preXXX</code> and <code>postXXX</code> specify
 *   a wide range of exceptions that can be thrown. If such an exception is 
 *   thrown it will be propagated up to the the API client. In the case of the 
 *   <code>preXXX</code> the started operation will be terminated. So be sure 
 *   to handle all exceptions that shouldn't be propagated back into the core 
 *   core API - and thus possibly influence success of the operation - 
 *   yourself.
 * </p>
 * 
 */
public interface ContentInterceptor {
    
    
    // ---------------------------------------------------------------- Methods
    
    
    /**
     * This method will be called just before the content of a node is stored.
     * 
     * @param token                 the SlideToken
     * @param revisionDescriptors   revision tree of the content to be stored
     * @param revisionDescriptor    revision descriptor of the content to be 
     *                              stored
     * @param revisionContent       the actual content to be stored
     * @throws AccessDeniedException            if access to a resource has 
     *                                          been denied
     * @throws ObjectNotFoundException          if an object could not be found
     * @throws LinkedObjectNotFoundException    if an object linked to by 
     *                                          another object could not be 
     *                                          found
     * @throws ObjectLockedException            if an object is locked
     * @throws ServiceAccessException           low-level service failure
     */
    public void preStoreContent
        (SlideToken token, NodeRevisionDescriptors revisionDescriptors,
         NodeRevisionDescriptor revisionDescriptor,
         NodeRevisionContent revisionContent)
        throws AccessDeniedException, ObjectNotFoundException,
               LinkedObjectNotFoundException, ObjectLockedException,
               ServiceAccessException;
    
    
    /**
     * This method will be called just after the content of a node was stored.
     * 
     * @param token                 the SlideToken
     * @param revisionDescriptors   revision tree of the content that has been 
     *                              stored
     * @param revisionDescriptor    revision descriptor of the content that 
     *                              has  been stored
     * @param revisionContent       the actual content that has been stored
     * @throws AccessDeniedException            if access to a resource has 
     *                                          been denied
     * @throws ObjectNotFoundException          if an object could not be found
     * @throws LinkedObjectNotFoundException    if an object linked to by 
     *                                          another object could not be 
     *                                          found
     * @throws ObjectLockedException            if an object is locked
     * @throws ServiceAccessException           low-level service failure
     */
    public void postStoreContent
        (SlideToken token, NodeRevisionDescriptors revisionDescriptors,
         NodeRevisionDescriptor revisionDescriptor,
         NodeRevisionContent revisionContent)
        throws AccessDeniedException, ObjectNotFoundException,
               LinkedObjectNotFoundException, ObjectLockedException,
               ServiceAccessException;
    
    
    /**
     * This method will be called just before content is retrieved, or the 
     * descriptor of a particular revision is retrieved.
     * 
     * @param token                 the SlideToken
     * @param revisionDescriptors   revision tree of the descriptor that 
     *                              should be retrieved, or <code>null</code> 
     *                              if the content should be retrieved
     * @param revisionNumber        revision number of the descriptor that 
     *                              should be retrieved, or <code>null</code> 
     *                              if the content should be retrieved
     * @param revisionDescriptor    revision descriptor of the content that 
     *                              should be retrieved, or <code>null</code> 
     *                              if the descriptor will be retrieved
     * @throws AccessDeniedException            if access to a resource has 
     *                                          been denied
     * @throws ObjectNotFoundException          if an object could not be found
     * @throws LinkedObjectNotFoundException    if an object linked to by 
     *                                          another object could not be 
     *                                          found
     * @throws ObjectLockedException            if an object is locked
     * @throws ServiceAccessException           low-level service failure
     */
    public void preRetrieveContent
        (SlideToken token, NodeRevisionDescriptors revisionDescriptors,
         NodeRevisionNumber revisionNumber,
         NodeRevisionDescriptor revisionDescriptor)
        throws AccessDeniedException, ObjectNotFoundException,
               LinkedObjectNotFoundException, ObjectLockedException,
               ServiceAccessException;
    
    
    /**
     * This method will be called just after retrieving content, or the 
     * descriptor of a particular revision.
     * 
     * @param token                 the SlideToken
     * @param revisionDescriptors   revision tree of the descriptor that has 
     *                              been retrieved, or <code>null</code> when 
     *                              the content has been retrieved
     * @param revisionDescriptor    revision descriptor of the content that has
     *                              been retrieved, or the descriptor itself 
     *                              has been retrieved
     * @param revisionContent       the actual content that has been retrieved,
     *                              or <code>null</code> when the descriptor 
     *                              has been retrieved
     * @throws AccessDeniedException            if access to a resource has 
     *                                          been denied
     * @throws ObjectNotFoundException          if an object could not be found
     * @throws LinkedObjectNotFoundException    if an object linked to by 
     *                                          another object could not be 
     *                                          found
     * @throws ObjectLockedException            if an object is locked
     * @throws ServiceAccessException           low-level service failure
     */
    public void postRetrieveContent
        (SlideToken token, NodeRevisionDescriptors revisionDescriptors,
         NodeRevisionDescriptor revisionDescriptor,
         NodeRevisionContent revisionContent)
        throws AccessDeniedException, ObjectNotFoundException,
               LinkedObjectNotFoundException, ObjectLockedException,
               ServiceAccessException;
    
    
    /**
     * This method will be called just before content will get removed, either 
     * of all revisions of a node, or of only one particular revision.
     * 
     * @param token                 the SlideToken
     * @param revisionDescriptors   revision tree of the content that will be 
     *                              removed, or <code>null</code> if a only a 
     *                              particular revision should be removed
     * @param revisionDescriptor    revision descriptor of the content that 
     *                              will be removed, or <code>null</code> if 
     *                              all revisions of a node should be removed
     * @throws AccessDeniedException            if access to a resource has 
     *                                          been denied
     * @throws ObjectNotFoundException          if an object could not be found
     * @throws LinkedObjectNotFoundException    if an object linked to by 
     *                                          another object could not be 
     *                                          found
     * @throws ObjectLockedException            if an object is locked
     * @throws ServiceAccessException           low-level service failure
     */
    public void preRemoveContent   
        (SlideToken token, NodeRevisionDescriptors revisionDescriptors,
         NodeRevisionDescriptor revisionDescriptor)
        throws AccessDeniedException, ObjectNotFoundException,
               LinkedObjectNotFoundException, ObjectLockedException,
               ServiceAccessException;
    
    
    /**
     * This method will be called just after content has been removed, either 
     * of all revisions of a node, or of only one particular revision.
     * 
     * @param token                 the SlideToken
     * @param revisionDescriptors   revision tree of the content that has been 
     *                              removed, or <code>null</code> if a only a 
     *                              particular revision has been removed
     * @param revisionDescriptor    revision descriptor of the content that 
     *                              has been removed, or <code>null</code> if 
     *                              all revisions of a node have been removed
     * @throws AccessDeniedException            if access to a resource has 
     *                                          been denied
     * @throws ObjectNotFoundException          if an object could not be found
     * @throws LinkedObjectNotFoundException    if an object linked to by 
     *                                          another object could not be 
     *                                          found
     * @throws ObjectLockedException            if an object is locked
     * @throws ServiceAccessException           low-level service failure
     */
    public void postRemoveContent   
        (SlideToken token, NodeRevisionDescriptors revisionDescriptors,
         NodeRevisionDescriptor revisionDescriptor)
        throws AccessDeniedException, ObjectNotFoundException,
               LinkedObjectNotFoundException, ObjectLockedException,
               ServiceAccessException;
    
    
    /**
     * The <code>setNamespace</code> method will be called during 
     * initialization of the ContextInterceptor.
     * 
     * @param nat   the access token to the namespace this ContentInterceptor 
     *              has been associated with
     */
    public void setNamespace
        (NamespaceAccessToken nat);
    
    
    /**
     * This method is called during initialization of the ContentInterceptor 
     * to allow parameterization from the configuration. If no parameters have 
     * been specified, the Hashtable will be empty
     *
     * @param parameters    Hashtable containing the parameters' names as keys 
     *                      and the associated parameter values as values, 
     *                      both of type <code>java.lang.String</code>
     */
    public void setParameters
        (Hashtable parameters);
    
    
}

