/*
Copyright (c) 2002, Matthias Bauer, LIVINGLOGIC AG, BAYREUTH
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 acknowlegement:
       "This product includes software developed by 
        Matthias Bauer, LIVINGLOGIC AG, BAYREUTH 
        (http://www.livinglogic.de/)."
       Alternately, this acknowlegement may appear in the software itself,
       if and wherever such third-party acknowlegements normally appear.
    4. Neither the name of Matthias Bauer, nor the LIVINGLOGIC AG nor the 
       names of the other contributors may be used to endorse or promote 
       products derived from this software without specific prior written
       permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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.
 */

package es.ejie.frmk.presentacion.base;


import java.io.Serializable;
import java.util.Hashtable;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;


/**
 * Class that provides access by label to Q70Workflow objects stored in a
 * user's session. An instance of this class is maintained in every user 
 * session.
 *
 * @author A. Lamm, M. Bauer, D. White
 * @version 1.0
 */

public class Q70WorkflowContainer implements Serializable
{
	/**
	 * The attribute key under which the Q70WorkflowContainer object is
	 * stored in a user's session.
	 */
	public final static String WORKFLOW_CONTAINER_KEY = "es.ejie.frmk.presentacion.base.Q70WorkflowContainer.container";

	/**
	 * A Map object, which maps label Strings to all Q70Workflow objects
	 * of the user session this Q70WorkflowContainer object belongs to.
	 */
	private Hashtable workflows = new Hashtable();

	/**
	 * The label of the workflow that is the current primary one.
	 */
	private String primaryLabel;

	/**
	 * @return The names of the workflow objects known for this user's session.
	 */
	public Set getWorkflowLabels() 
	{
		return workflows.keySet();
	}
	
	/**
	 * Retrieves the Q70Workflow object for the specified label.
	 * If it doesn't exist, null is returned.
	 * @param label the label of the requested Q70Workflow object
	 * @return the requested Q70Workflow object or null, if the workflow does not exist.
	 */
	public Q70Workflow get(String label) 
	{
		return (Q70Workflow) workflows.get(label);
	}
	
	/**
	 * Retrieves the primary Q70Workflow object, if any is known at this time.
	 * @return the primary Q70Workflow object or null, if no primary workflow
	 *     exists.
	 */
	public Q70Workflow getPrimary() 
	{
		return null == primaryLabel ? null : (Q70Workflow) workflows.get(primaryLabel);
	}

	/**
	 * Retrieves the primary Q70Workflow label, if any is defined at this time.
	 * @return the primary Q70Workflow label or null, if no primary workflow
	 *     exists.
	 */
	public String getPrimaryLabel() 
	{
		return primaryLabel;
	}

	/**
	 * Sets the workflow with the specified label as the primary workflow. The
	 * null value is allowed and indicates that no primary workflow is defined
	 * for this action
	 */
	public void setPrimaryLabel(String label)
	{
		primaryLabel = label;
	}

	/**
	 * Retrieves the Q70Workflow object for the specified label.
	 * If it doesn't exist yet, a new Q70Workflow object is created and
	 * stored under the specified label.
	 * @param label the label of the requested Q70Workflow object
	 * @return the requested Q70Workflow object 
	 */
	public Q70Workflow getOrCreate(String label)
	{
		Q70Workflow retVal;

		// Try to retrieve the requested Q70Workflow from the map of stored Workflows
		retVal = (Q70Workflow)workflows.get(label);
			
		// if no workflow was found under the given label,
		// create a new Q70Workflow and store it under its label 
		if (null == retVal)
		{
			retVal = new Q70Workflow();
			workflows.put(label, retVal);
		}
		return retVal;
	}

	/**
	 * Removes the Q70Workflow object stored under the specified label.
	 * If no object is stored under this label, this method does nothing.
	 * @param request The servlet request we are processing
	 * @param label the label of the Q70Workflow object to remove
	 */
	public void remove(HttpServletRequest request, String label)
	{
		Q70Workflow theWorkflow = (Q70Workflow) workflows.get(label);
		if(null != theWorkflow) 
		{
			// reset the primaryLabel if necessary
			if (label.equals(primaryLabel))
			{
				primaryLabel = null;
			}
			theWorkflow.performCleanup(request);
			workflows.remove(label);
		}
	}

	/**
	 * Retrieves the Q70WorkflowContainer object for a specified user session.
	 * If it doesn't exist yet, a new one is created and stored in the session.
	 * @param session the user's session object
	 * @return a Q70WorkflowContainer object, possibly newly created
	 */
	public static Q70WorkflowContainer get(HttpSession session)
	{
		Q70WorkflowContainer retVal = (Q70WorkflowContainer)session.getAttribute(WORKFLOW_CONTAINER_KEY);
		if (null == retVal)
		{
			retVal = new Q70WorkflowContainer();
			session.setAttribute(WORKFLOW_CONTAINER_KEY, retVal);
		}
		return retVal;
	}
}
