//----------------------------BEGIN LICENSE----------------------------
/* 
 * Willow : the Open Source WorkFlow Project
 * Distributable under GNU LGPL license by gun.org
 *
 * Copyright (C) 2004-2010 huihoo.org 
 * Copyright (C) 2004-2010  ZosaTapo <dertyang@hotmail.com> 
 * 
 * ====================================================================
 * Project Homepage : http://www.huihoo.org/willow
 * Source Forge     : http://sourceforge.net/projects/huihoo
 * Mailing list     : willow@lists.sourceforge.net 
 */
//----------------------------END  LICENSE----------------------------
package org.huihoo.willow.desktop;

import java.rmi.RemoteException;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Vector;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.huihoo.willow.Manager;
import org.huihoo.willow.RealmDatabase;
import org.huihoo.willow.Server;
import org.huihoo.willow.ServerFactory;
import org.huihoo.willow.Service;
import org.huihoo.workflow.WorkflowException;
import org.huihoo.workflow.desktop.WorkflowDesktop;
import org.huihoo.workflow.desktop.WorkflowImplementation;
import org.huihoo.workflow.server.WorkflowXPDL;
import org.huihoo.workflow.server.WorkflowSession;
import org.huihoo.workflow.server.WorkflowXPDLRepository;

public class WorkflowDesktopImpl implements WorkflowDesktop
{
	private static Log log = LogFactory.getLog(WorkflowDesktopImpl.class);

	protected WorkflowSession session;

	/**
	 * The environment associated with this WorkflowDesktop.
	 * It is initialized to null and is updated by the constructor
	 * that accepts an environment or by the <tt>init()</tt> method.
	 * @see #addToEnvironment
	 * @see #removeFromEnvironment
	 * @see #getEnvironment
	 */
	protected Hashtable myProps = null;

	public WorkflowDesktopImpl(Hashtable environment) throws WorkflowException
	{
		if (environment == null)
		{
			environment = new Hashtable();
		}
		this.myProps = (Hashtable) environment.clone();

		String serviceName = DesktopImplUtils.getURLService((String) myProps.get(WorkflowDesktop.PROVIDER_URL));

		Service service = null;
		Server server = ServerFactory.getServer();
		if (serviceName != null)
		{
			service = server.findService(serviceName);
		}

		if (service == null)
		{
			service = server.findServices()[0];
		}

		if (service == null)
		{
			throw new WorkflowException("no service found in willow server");
		}

		RealmDatabase realmDatabase = service.getRealmDatabase();
		Manager manager = service.getManager();
		String username = (String) myProps.get(WorkflowDesktop.SECURITY_PRINCIPAL);
		String password = (String) myProps.get(WorkflowDesktop.SECURITY_CREDENTIALS);

		try
		{
			this.session = DesktopImplUtils.authenticate(manager, realmDatabase, username, password);
		}
		catch (RemoteException e)
		{
			throw new WorkflowException(e.toString());
		}
	}

	public WorkflowSession getSession()
	{
		return this.session;
	}

	public WorkflowImplementation findImplementation(String xpdlid) throws WorkflowException
	{
		WorkflowXPDL workflowTemplate = WorkflowXPDLRepository.getInstance().findWorkflowXPDL(xpdlid);
		if (workflowTemplate != null)
		{
			try
			{
				return new WorkflowRealization(this, workflowTemplate);
			}
			catch (RemoteException e)
			{
				throw new WorkflowException(e);
			}
		}
		return null;
	}

	public WorkflowImplementation[] findImplementations() throws WorkflowException
	{
		Vector vector = new Vector(0);
		Iterator iterator = WorkflowXPDLRepository.getInstance().findWorkflowXPDLs();
		while (iterator.hasNext())
		{
			vector.addElement(WorkflowXPDLRepository.getInstance().findWorkflowXPDL((String) iterator.next()));
		}

		int size = vector.size();
		WorkflowImplementation[] result = new WorkflowImplementation[size];
		for (int i = 0; i < size; ++i)
		{
			try
			{
				result[i] = new WorkflowRealization(this, (WorkflowXPDL) vector.elementAt(i));
			}
			catch (RemoteException e)
			{
				throw new WorkflowException(e);
			}
		}
		return result;
	}

	public Object addToEnvironment(String propName, Object propVal) throws WorkflowException
	{
		return myProps.put(propName, propVal);
	}

	public Object removeFromEnvironment(String propName) throws WorkflowException
	{
		return myProps.remove(propName);
	}

	public Hashtable getEnvironment() throws WorkflowException
	{
		return (Hashtable) myProps.clone();
	}

	public void close() throws WorkflowException
	{
		if (session != null)
		{
			try
			{
				session.invalidate();
				session = null;
			}
			catch (RemoteException e)
			{
				throw new RuntimeException();
			}
		}
	}
}
