/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2000-2001 The Apache Software Foundation.  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 acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" and
 *     "Apache Jetspeed" must not be used to endorse or promote products
 *    derived from this software without prior written permission. For
 *    written permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache" or
 *    "Apache Jetspeed", nor may "Apache" appear in their name, without
 *    prior written permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION 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 consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

package org.apache.jetspeed.portlet;

import java.io.IOException;

import java.util.Locale;

/**
 * The <CODE>Portlet</CODE> interface is used by the portlet container to
 * invoke the portlet. However, a portlet cannot directly implement the
 * <CODE>Portlet</CODE> interface directly. Instead, it has to extend
 * one of the abstract portlet implementations, which indicates to the
 * the portlet container the type of content (eg. content stream or
 * SAX events) that the portlet will generate.
 * 
 * <P>
 * A portlet is a small Java program that runs within a portlet container.
 * Portlets receive and respond to requests from the portlet container.
 * There is ever only object instance of each portlet class, yet each
 * user should be able to a have personalized view of that portlet instance.
 * Therefore, the portlet session carries vital information for the
 * portlet to create a personalized user experience. Portlet instance
 * plus session create a <EM>virtual instance</EM> of the portlet. This
 * is similar to the way a servlet relates to its servlet container.
 * As a consequence, the portlet should not attempt to store the portlet
 * session or any other user-related information as instance or class
 * variabled. In fact, instance variables of a portlet can be considered
 * to have similar behaviour as class variables, because there is ever
 * only one instance which is shared by multiple threads. Therefore,
 * any instance information has to be either read-only (as is the case
 * for the portlet configuration), or carefully protected by the
 * <CODE>synchronized</CODE> keyword.
 * </P>
 * 
 * <P>
 * As part of running within the portlet container each portlet has a
 * life-cycle. The corresponding methods are called in the following
 * sequence:
 * </P>
 * <OL>
 * <LI>The portlet is constructed, then initialized with the
 *     <CODE>init()</CODE> method.
 * <LI>Any calls from the portlet container to the <CODE>service()</CODE>
 *     method are handled.
 * <LI>The portlet is taken out of service, then destroyed with the
 *     <CODE>destroy()</CODE> method, then garbage collected and finalized.
 * </OL>
 * 
 * <P>
 * The virtual instance is created and destroyed with the
 * <CODE>login()</CODE> and <CODE>logout()</CODE> methods,
 * respectively. If a portlet provides personalized views these methods
 * should be implemented.
 * </P>
 *
 * <P>
 * The portlet container loads and instantiates the portlet class. This
 * can happen during startup of the portal server or later, but no later
 * then when the first request to the portlet has to be serviced.
 * Also, if a portlet is taken temporarily out of service, for example
 * while administrating it, the portlet container may finish the life-cycle
 * before taking the portlet out of service. When the administration
 * is done, the portlet will be newly initialized.
 * </P>
 * 
 * @author <A HREF="mailto:tboehme@us.ibm.com">Thomas F. Boehme</A>
 */
public interface Portlet
{
    /**
     ** The <CODE>Mode</CODE> class is a finite enumeration of
     ** the possible modes that a portlet can assume.
     **/

    public static class Mode implements java.io.Serializable
    {
        /**
         ** The standard "one-of many" portlet view on a page.
         **/

        public final static Mode VIEW     = new Mode ("View", 0);

        /**
         ** This mode allows the portlet to capture user-specific
         ** parameterization, which leads to a personalized view of the
         ** portlet.
         **/

        public final static Mode PERSONALIZE = new Mode ("Personalize", 1);

        /**
         ** A portlet should provide useful online help in this mode.
         ** This may be a short description or a multi-page instruction on
         ** how to use the portlet.
         **/

        public final static Mode HELP        = new Mode ("Help", 2);

        /**
         ** Allows the portlet to bring its own configuration screen if
         ** required. Only a user with administrator privileges should
         ** be able to call a portlet in this mode.
         **/

        public final static Mode CONFIGURE   = new Mode ("Configure", 3);

        private String identifier;

        private int value;

        private Mode (String identifier, int value)
        {
            this.identifier = identifier;
            this.value = value;
        }

        public int getId()
        {
            return value;
        }

        public String toString ()
        {
            return (identifier);
        }
    }

    /**
     ** Called by the portlet container to indicate to this portlet
     ** that it is put into service.
     **
     ** <P>
     ** The portlet container calls the <CODE>init()</CODE> method
     ** for the whole life-cycle of the portlet. The
     ** <CODE>init()</CODE> method must complete successfully before
     ** virtual instances are created through the
     ** <CODE>beginSession()</CODE> method.
     **
     ** <P>
     ** The portlet container cannot place the portlet into service
     ** if the <CODE>init()</CODE> method
     **
     ** <OL>
     ** <LI>Throws a <CODE>PortletException</CODE>
     ** <LI>Does not return within a time period defined by the portlet
     **     container.
     ** </OL>
     **
     ** @param   config
     **          the portlet configuration
     **
     ** @exception   UnavailableException
     **              if an exception has occurrred that interferes
     **              with the portlet's normal initialization
     **/

    public void init (PortletConfig config) throws UnavailableException;

    /**
     ** Called by the portlet container to indicate to this portlet
     ** that it is taken out of service. This method is only called
     ** once all threads within the portlet's <CODE>service()</CODE>
     ** method have exited or after a timeout period has passed. After
     ** the portlet container calls this method, it will not call the
     ** <CODE>service()</CODE> method again on this portlet.
     **
     ** <P>
     ** This method gives the portlet an opportunity to clean up any
     ** resources that are being held (for example, memory, file
     ** handles, threads).
     **/

    public void destroy ();

    /**
     ** Called by the portlet container to ask the portlet to
     ** initialize the given portlet for a user.
     **
     ** <P>
     ** In addition to initializing the session this method allows the
     ** portlet to initialize the virtual instance, for example, to
     ** store attributes in the session. 
     ** </P>
     **
     ** @param   request
     **          the portlet request
     **
     ** @exception   PortletException
     **              if the portlet has trouble fulfilling the
     **              request
     **/

    public void login (PortletRequest request) throws PortletException;

    /**
     ** Called by the portlet container to indicate that a virtual
     ** instance of the portlet is being removed.
     **
     ** <P>
     ** This method gives the virtual instance of the portlet an
     ** opportunity to clean up any resources (for example, memory,
     ** file handles, threads), before it is removed. This happens
     ** if the user logs off, or decides to remove this portlet from
     ** a page.
     ** </P>
     **
     ** @param   request
     **          the portlet request
     **
     ** @exception   PortletException
     **              if the portlet has trouble fulfilling the
     **              request
     **/

    public void logout (PortletRequest request) throws PortletException;

    /**
     ** Called by the portlet container to ask this portlet to generate
     ** its markup using the given request/response pair. Depending
     ** on the mode of the portlet and the requesting client device,
     ** the markup will be different. Also, the portlet can take language
     ** preferences and/or personalized settings into account.
     **
     ** @param   request
     **          the portlet request
     ** @param   response
     **          the portlet response
     **
     ** @exception   PortletException
     **              if the portlet has trouble fulfilling the
     **              rendering request
     ** @exception   IOException
     **              if the streaming causes an I/O problem
     **/

    public void service (PortletRequest request,
                         PortletResponse response) throws PortletException,
                                                          IOException;

}
