/* ======================================================================
The Bodington System Software License, Version 1.0
 
Copyright (c) 2001 The University of Leeds.  All rights reserved.
 
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
 
1.  Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
 
2.  Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
 
3.  The end-user documentation included with the redistribution, if any,
must include the following acknowledgement:  "This product includes
software developed by the University of Leeds
(http://www.bodington.org/)."  Alternately, this acknowledgement may
appear in the software itself, if and wherever such third-party
acknowledgements normally appear.
 
4.  The names "Bodington", "Nathan Bodington", "Bodington System",
"Bodington Open Source Project", and "The University of Leeds" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
d.gardner@leeds.ac.uk.
 
5.  The name "Bodington" may not appear in the name of products derived
from this software without prior written permission of the University of
Leeds.
 
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO,  TITLE,  THE IMPLIED WARRANTIES
OF QUALITY  AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
EVENT SHALL THE UNIVERSITY OF LEEDS OR ITS CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
=========================================================
 
This software was originally created by the University of Leeds and may contain voluntary
contributions from others.  For more information on the Bodington Open Source Project, please
see http://bodington.org/
 
====================================================================== */

package org.bodington.servlet;

import org.bodington.server.NavigationSession;

/**
 * Interface for objects that handle the initialization of sessions. Objects
 * that implement this interface are used by instances of {@link Request} to
 * handle the initialization of sessions associated with incoming requests. The
 * primary motivation for this interface is that the administrator of an
 * installation can specify the (possibly multiple) supported authentication
 * mechanisms by specifying them as ordered links in a session initializer chain
 * (see {@link org.bodington.servlet.SessionInitializerChain}).
 * <p>
 * This interface follows the <em>chain of responsibility</em> pattern from
 * the classic <a href="http://hillside.net/patterns/DPBook/DPBook.html">Gang of
 * Four</a> design patterns book. A given instance attempts to handle the
 * request when its {@link #handleRequest(Request)} method is called. If it can
 * handle the request itself, it does so and then returns. If it can not, then
 * it calls the {@link #handleRequest(Request)} of the next link in the chain
 * (specified to it via its
 * {@link #setNextSessionInitializer(SessionInitializer)} method) or if this is
 * <code>null</code> just returns.
 * <p>
 * Whilst this appears to be a simple interface, actual implementations are
 * tightly-bound to the application as they need to understand the associations
 * between instances of {@link Request}, {@link HttpSession},
 * {@link NavigationSession} and {@link SessionInitializer}. In practice, users
 * would be expected to use the
 * {@link SessionInitializerChain#getSessionInitializer(String)} to obtain an
 * instance configured using the default session initializers. However, it is
 * still possible to supply custom instances, if that is what is required. A key
 * distinction between concrete implementations is that some will call the code
 * that perform the actual authentication themselves. Other implementations will
 * receive requests where the authentication has already happened (prehaps
 * externally) and it is their responsibility to initialize sessions based on
 * the presence of specific tokens in the request.
 * @see Request
 * @see HttpSession
 * @see NavigationSession
 * @see SessionInitializerChain#getSessionInitializer(String)
 * @see SessionInitializerChain
 * @author Alexis O'Connor
 */
public interface SessionInitializer
{
    /**
     * Handle the request. If the object implementing this method can handle the
     * request it should do so and then return an instance of
     * {@link NavigationSession}. If it can not handle the request itself, then
     * it is expected to call the {@link #handleRequest(Request)} of the next
     * link in the chain (that link having been specified to this object via its
     * {@link #setNextSessionInitializer(SessionInitializer)} method). If the
     * current object has been unable to handle the request, but it is the last
     * link in the chain, then this method should ideally return a non-null
     * {@link NavigationSession} instance, albeit one who's
     * {@link NavigationSession#isAuthenticated()} returns <code>false</code>.
     * @param request the request object to be handled.
     * @return a corresponding navigation session instance, or <code>null</code>
     *         if one could not be found.
     * @see #setNextSessionInitializer(SessionInitializer)
     * @see NavigationSession#isAuthenticated()
     */
    NavigationSession handleRequest(Request request);
    
    /**
     * Set the next session initializer. This method is used to specify to the
     * implementing object what is the next link in the chain after this one.
     * @param initializer the next link in the chain after this one.
     */
    void setNextSessionInitializer(SessionInitializer initializer);
}