/*
 * Created on 2004-8-16
 *
 * To change the template for this generated file go to
 * Window - Preferences - Java - Code Generation - Code and Comments
 */
package workflow.util;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import workflow.WorkflowException;
import workflow.services.WorkflowService;
import workflow.store.UserDatabase;
import workflow.wfmc.pm.Department;
import workflow.wfmc.pm.Group;
import workflow.wfmc.pm.Participant;
import workflow.wfmc.pm.Role;
import workflow.wfmc.rtm.PerformerSelector;
import workflow.wfmc.rtm.WorkflowWork;
import workflow.wfmc.xpdl.WorkflowActivity;
import workflow.wfmc.xpdl.WorkflowProcess;
import workflow.wfmc.xpdl.WorkflowTransition;
import workflow.wfmc.xpdl.XPDLGlobals;
import workflow.wfmc.xpdl.activity.PerformerType;
import workflow.wfmc.xpdl.ext.ExtendedAttribute;
/**
 * @author reic
 *
 * To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Generation - Code and Comments
 */
public class WorkflowUtils
{
	/**
	 *  获取需要人员交互的活动的参与者列表
	 * 
	 *  @param  workflowWork         等待派发的工作项
	 *  @param  workflowTransition   工作项的派发流转路径
	 **/
	public static List getParticipants(
		WorkflowService workflowService,
		WorkflowProcess workflowProcess,
		WorkflowWork workflowWork,
		WorkflowTransition workflowTransition)
		throws WorkflowException
	{
		WorkflowActivity workflowActivity = workflowTransition.getToWorkflowActivity();
		PerformerType performerType = workflowActivity.getPerformerType();
		UserDatabase userDatabase =workflowService.getUserDatabase();

		List users =null;

		if (PerformerType.PERFORMER_PARTICIPANT_BASED.equals(performerType))
		{
			users=WorkflowUtils.getParticipantsByParicipant(userDatabase,workflowActivity);
		}
		else if (PerformerType.PERFORMER_GROUP_BASED.equals(performerType))
		{
			users=WorkflowUtils.getParticipantsByGroup(userDatabase,workflowActivity);
		}
		else if (PerformerType.PERFORMER_ROLE_BASED.equals(performerType))
		{
			users=WorkflowUtils.getParticipantsByRole(userDatabase,workflowActivity);
		}
		else if (PerformerType.PERFORMER_DEPARTMENT_BASED.equals(performerType))
		{
			users=WorkflowUtils.getParticipantsByDepartment(userDatabase,workflowActivity);
		}
		else if (PerformerType.PERFORMER_CATEGORY_BASED.equals(performerType))
		{
			users=WorkflowUtils.getParticipantsByCategory(userDatabase,workflowActivity);
		}
		else if (PerformerType.PERFORMER_RANK_BASED.equals(performerType))
		{
			users=WorkflowUtils.getParticipantsByRank(userDatabase,workflowActivity);
		}
		else if (PerformerType.PERFORMER_SELECTOR_BASED.equals(performerType))
		{
			users=WorkflowUtils.getParticipantsBySelector(workflowWork,workflowTransition);
		}

		return users;
	}

	//------------------------------------------------------------------------------
	//	private function blocks
	//------------------------------------------------------------------------------
	private static List getParticipantsByParicipant(UserDatabase userDatabase,WorkflowActivity workflowActivity)
		throws WorkflowException
	{
		List users = new ArrayList();
		List userIds = workflowActivity.getPerformers();
		
		int sizeUser = userIds.size();
		for (int i = 0; i < sizeUser; ++i)
		{
			add2List(users, userDatabase.findParticipant((String) userIds.get(i)));
		}
		return users;
	}

	private static List getParticipantsByGroup(UserDatabase userDatabase,WorkflowActivity workflowActivity)
		throws WorkflowException
	{
		List users = new ArrayList();
		List groupIds = workflowActivity.getPerformers();
		int sizeGroup = groupIds.size();
		for (int i = 0; i < sizeGroup; ++i)
		{
			Group group = (Group) userDatabase.findGroup((String) groupIds.get(i));
			Iterator userInterator = group.getParticipants();
			while (userInterator.hasNext())
			{
				Participant user = (Participant) userInterator.next();
				add2List(users, user);
			}
		}
		return users;
	}

	private static List getParticipantsByRole(UserDatabase userDatabase,WorkflowActivity workflowActivity)
		throws WorkflowException
	{
		List users = new ArrayList();
		List roleIds = workflowActivity.getPerformers();
		int sizeRole = roleIds.size();
		for (int i = 0; i < sizeRole; ++i)
		{
			Role role = (Role) userDatabase.findRole((String) roleIds.get(i));
			Iterator userInterator = role.getParticipants();
			while (userInterator.hasNext())
			{
				Participant user = (Participant) userInterator.next();
				add2List(users, user);
			}
		}
		return users;
	}

	private static List getParticipantsByDepartment(UserDatabase userDatabase,WorkflowActivity workflowActivity)
		throws WorkflowException
	{
		List users = new ArrayList();
		List deptIds = workflowActivity.getPerformers();
			int sizeDept = deptIds.size();
			for (int i = 0; i < sizeDept; ++i)
			{
				Department dept = (Department) userDatabase.findDepartment((String) deptIds.get(i));
				Iterator userInterator = dept.getParticipants();
				while (userInterator.hasNext())
				{
					Participant user = (Participant) userInterator.next();
					add2List(users, user);
				}
			}
		return users;
	}


	private static List getParticipantsByCategory(UserDatabase userDatabase,WorkflowActivity workflowActivity)
		throws WorkflowException
	{
		List users = new ArrayList();
		List catIds = workflowActivity.getPerformers();
		int sizeCat = catIds.size();
		for (int i = 0; i < sizeCat; ++i)
		{
			String catId = (String) catIds.get(i);
			Iterator depts = userDatabase.getDepartments();
			while (depts.hasNext())
			{
				Department dept = (Department) userDatabase.findDepartment((String) depts.next());

				if (dept.getCategory() != null && catId.equals(dept.getCategory().getUUID()))
				{
					Iterator userInterator = dept.getParticipants();
					while (userInterator.hasNext())
					{
						Participant user = (Participant) userInterator.next();
						add2List(users, user);
					}
				}
			}
		}
		return users;
	}
	
	private static List getParticipantsByRank(UserDatabase userDatabase,WorkflowActivity workflowActivity)
		throws WorkflowException
	{
		List users = new ArrayList();
		List rankIds = workflowActivity.getPerformers();
		int sizeRank = rankIds.size();
		for (int i = 0; i < sizeRank; ++i)
		{
			String rankId = (String) rankIds.get(i);
			Iterator userInterator = userDatabase.getParticipants();
			while (userInterator.hasNext())
			{
				Participant user = (Participant) userInterator.next();
				if (user.getRank() != null && rankId.equals(user.getRank().getUUID()))
				{
					add2List(users, user);
				}
			}
		}
		return users;
	}

	private static List getParticipantsBySelector(
		WorkflowWork workflowWork,
		WorkflowTransition workflowTransition)
		throws WorkflowException
	{
		List users = new ArrayList();
		WorkflowActivity workflowActivity = workflowTransition.getToWorkflowActivity();
		ExtendedAttribute attribute =
			(ExtendedAttribute) workflowActivity.getExtendedAttributes().get(
				XPDLGlobals.SELECTOR_QUALIFIED_CLASS_NAME);

		String implClassName = attribute.getValue();
		Class implClass = null;
		PerformerSelector selector = null;
		try
		{
			implClass = Class.forName(implClassName);
			selector = (PerformerSelector) implClass.newInstance();
		}
		catch (Exception e)
		{
			throw new WorkflowException(e);
		}

		users = selector.select(workflowWork, workflowTransition);

		return users;
	}

	private static void add2List(List users, Participant user)
	{
		int sizeUsers = users.size();
		boolean found = false;
		Participant temp = null;
		for (int i = 0; i < sizeUsers; ++i)
		{
			temp = (Participant) users.get(i);
			if (user.getUUID().equals(temp.getUUID()))
			{
				found = true;
				break;
			}
		}
		if (!found)
		{
			users.add(user);
		}
	}
}
