/* $Id: ProcessManager.java,v 1.2 2007/11/05 09:50:54 nito Exp $
 *
 * Copyright (c)ARGO 21, Corporation. 2005, 2006.  All rights reserved.
 * 
 * This file is part of Nautica Workflow Core.
 * 
 *  Nautica Workflow Core is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2.1 of the License, or
 *  (at your option) any later version.
 * 
 *  Nautica Workflow Core is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 * 
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with Nautica Workflow Core; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *  
 */
package jp.co.argo21.nautica.workflow.engine;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import jp.co.argo21.nautica.workflow.dataaccess.ActivityBean;
import jp.co.argo21.nautica.workflow.dataaccess.ActivityDAO;
import jp.co.argo21.nautica.workflow.dataaccess.ProcessBean;
import jp.co.argo21.nautica.workflow.dataaccess.ProcessDAO;
import jp.co.argo21.nautica.workflow.dataaccess.VariableBean;
import jp.co.argo21.nautica.workflow.dataaccess.VariableDAO;
import jp.co.argo21.nautica.workflow.dataaccess.WorkflowDAOFactory;
import jp.co.argo21.nautica.workflow.definition.PackageDefinition;
import jp.co.argo21.nautica.workflow.definition.ParameterDefinition;
import jp.co.argo21.nautica.workflow.definition.ProcessDefinition;
import jp.co.argo21.nautica.workflow.definition.VariableDefinition;
import jp.co.argo21.nautica.workflow.omg.InvalidRequesterException;
import jp.co.argo21.nautica.workflow.omg.NotEnabledException;
import jp.co.argo21.nautica.workflow.omg.RequesterRequiredException;
import jp.co.argo21.nautica.workflow.omg.WfActivity;
import jp.co.argo21.nautica.workflow.omg.WfNameValue;
import jp.co.argo21.nautica.workflow.omg.WfProcess;
import jp.co.argo21.nautica.workflow.omg.WfProcessManager;
import jp.co.argo21.nautica.workflow.omg.WfRequester;
import jp.co.argo21.nautica.workflow.omg.WfState;
import jp.co.argo21.nautica.workflow.omg.WorkflowException;
import jp.co.argo21.nautica.workflow.util.DurationHelper;
import jp.co.argo21.nautica.workflow.util.StringManager;
import jp.co.argo21.nautica.workflow.util.UniqueKeyGenerator;
import jp.co.argo21.nautica.workflow.wfmc.Activity;
import jp.co.argo21.nautica.workflow.wfmc.ActivityState;
import jp.co.argo21.nautica.workflow.wfmc.Attribute;
import jp.co.argo21.nautica.workflow.wfmc.Filter;
import jp.co.argo21.nautica.workflow.wfmc.FormalParameter;
import jp.co.argo21.nautica.workflow.wfmc.InvalidActivityInstanceException;
import jp.co.argo21.nautica.workflow.wfmc.InvalidActivityNameException;
import jp.co.argo21.nautica.workflow.wfmc.InvalidAttributeException;
import jp.co.argo21.nautica.workflow.wfmc.InvalidFilterException;
import jp.co.argo21.nautica.workflow.wfmc.InvalidProcessDefinitionException;
import jp.co.argo21.nautica.workflow.wfmc.InvalidSessionException;
import jp.co.argo21.nautica.workflow.wfmc.InvalidStateException;
import jp.co.argo21.nautica.workflow.wfmc.Process;
import jp.co.argo21.nautica.workflow.wfmc.ProcessDefinitionState;
import jp.co.argo21.nautica.workflow.wfmc.ProcessState;
import jp.co.argo21.nautica.workflow.wfmc.TransitionNotAllowedException;

/**
 * ひとつのプロセス定義に相当するプロセスインスタンスの生成と
 * 管理を行う。
 *
 * @author  nito(Argo 21, Corp.)
 * @version $Revision: 1.2 $
 * @since   Nautica Workflow 1.0
 */
class ProcessManager implements WfProcessManager
{
    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/** エンジンログ */
	@SuppressWarnings("unused")
	private static Logger eLog = LogManager.getEngineLogger();
	
	private String definitionID;
	private PackageDefinition packageDefifinition;
	private ProcessDefinition processDefinition;
	
	/**
	 * プロセスマネージャを生成する。
	 */
	public ProcessManager(String pdid) throws InvalidProcessDefinitionException
	{
		this.definitionID = pdid;
		try {
			WorkflowEngine engine = WorkflowEngine.getInstance();
			DefinitionRepositoryImpl rep = engine.getDefinitionRepository();
			packageDefifinition = rep.getPackageDefinition(pdid);
			processDefinition = rep.getProcessDefinition(pdid);
			
			init();
		} catch (Exception ex) {
			// プロセスマネージャの生成に失敗しました。
			String E0149 = StringManager.get("E0149") + "(ProcessDefinitionID = " + pdid + ")";
			throw new InvalidProcessDefinitionException(E0149, ex);
		}
	}
	
	private void init()
	{
	}

	/**
	 * 管理しているプロセスの個数を返す。
	 *
	 * @return プロセスの個数
	 * @throws WorkflowException　ワークフロー関連で例外が発生した場合
	 * @see jp.co.argo21.nautica.workflow.omg.WfProcessManager#getProcessCount()
	 */
	public int getProcessCount() throws WorkflowException
	{
		try {
			WorkflowDAOFactory daoFactory = DataAccessManager.getDAOFactory();
			ProcessDAO procDAO = daoFactory.getProcessDAO();

			return procDAO.findCountByPDID(definitionID);
		} catch (WorkflowException ex) {
			throw ex;
		} catch (Exception ex) {
			// プロセス数の取得に失敗しました。
			String E0150 = StringManager.get("E0150");
			throw new WorkflowException(E0150, ex);
		}
	}

	/**
	 * IDで指定されたプロセスを返す。
	 *
	 * @param pid プロセスID
	 * @return プロセス
	 * @throws WorkflowException　ワークフロー関連で例外が発生した場合
	 * @see jp.co.argo21.nautica.workflow.omg.WfProcessManager#getProcess(java.lang.String)
	 */
	public WfProcess getProcess(String pid) throws WorkflowException
	{
		try {
			WorkflowDAOFactory daoFactory = DataAccessManager.getDAOFactory();
			ProcessDAO procDAO = daoFactory.getProcessDAO();

			ProcessBean bean = procDAO.findByPDIDandPID(definitionID, pid);
			FormalParameter[] params = (FormalParameter[])getResultSignature();
			WfProcess proc = new ProcessInternal(bean, params);
			//リクエスタをどうするか
			return proc;
		} catch (WorkflowException ex) {
			throw ex;
		} catch (Exception ex) {
			// プロセスの取得に失敗しました。
			String E0151 = StringManager.get("E0151") + "(ProcessID = " + pid + ")" ;
			throw new WorkflowException(E0151, ex);
		}
	}

	/**
	 * 管理下のすべてのプロセスを返す。
	 *
	 * @return プロセス
	 * @throws WorkflowException　ワークフロー関連で例外が発生した場合
	 * @see jp.co.argo21.nautica.workflow.omg.WfProcessManager#getAllProcesses()
	 */
	public WfProcess[] getAllProcesses() throws WorkflowException
	{
		try {
			WorkflowDAOFactory daoFactory = DataAccessManager.getDAOFactory();
			ProcessDAO procDAO = daoFactory.getProcessDAO();

			ProcessBean[] beans = procDAO.findByPDID(definitionID);
			ProcessInternal[] procs = new ProcessInternal[beans.length];
			
			for (int i = 0; i < beans.length; i++) {
				FormalParameter[] params = (FormalParameter[])getResultSignature();
				procs[i] = new ProcessInternal(beans[i], params);
				//リクエスタをどうするか
			}
			return procs;
		} catch (WorkflowException ex) {
			throw ex;
		} catch (Exception ex) {
			// 管理下の全プロセスの取得に失敗しました。
			String E0159 = StringManager.get("E0159");
			throw new WorkflowException(E0159, ex);
		}
	}

	/**
	 * 引数で指定されたプロセスが、管理下にあるかどうかを返す。
	 *
	 * @param member プロセスID
	 * @return 管理下にある場合は、True
	 * @throws WorkflowException　ワークフロー関連で例外が発生した場合
	 * @see jp.co.argo21.nautica.workflow.omg.WfProcessManager#isMemberOfProcess(java.lang.String)
	 */
	public boolean isMemberOfProcess(String member) throws WorkflowException
	{
		try {
			WorkflowDAOFactory daoFactory
			= DataAccessManager.getDAOFactory();
			ProcessDAO procDAO = daoFactory.getProcessDAO();

			Process proc = procDAO.findByPDIDandPID(definitionID, member);
			return (proc != null);
		} catch (WorkflowException ex) {
			throw ex;
		} catch (Exception ex) {
			// プロセスの判定に失敗しました。
			String E0152 = StringManager.get("E0152");
			throw new WorkflowException(E0152, ex);
		}
	}

	/**
	 * カテゴリーを返す。
	 *
	 * @return カテゴリ
	 * @throws WorkflowException　ワークフロー関連で例外が発生した場合
	 * @see jp.co.argo21.nautica.workflow.omg.WfProcessManager#getCategory()
	 */
	public String getCategory() throws WorkflowException
	{
		return packageDefifinition.getName();
	}

	/**
	 * 名称を返す。
	 *
	 * @return 名称
	 * @throws WorkflowException　ワークフロー関連で例外が発生した場合
	 * @see jp.co.argo21.nautica.workflow.omg.WfProcessManager#getName()
	 */
	public String getName() throws WorkflowException
	{
		return processDefinition.getName();
	}

	/**
	 * バージョンを返す。
	 *
	 * @return バージョン
	 * @throws WorkflowException　ワークフロー関連で例外が発生した場合
	 * @see jp.co.argo21.nautica.workflow.omg.WfProcessManager#getVersion()
	 */
	public String getVersion() throws WorkflowException
	{
		return packageDefifinition.getVersion();
	}

	/**
	 * 詳細情報を返す。
	 *
	 * @return 詳細情報
	 * @throws WorkflowException　ワークフロー関連で例外が発生した場合
	 * @see jp.co.argo21.nautica.workflow.omg.WfProcessManager#getDescription()
	 */
	public String getDescription() throws WorkflowException
	{
		return processDefinition.getDescription();
	}

	/**
	 * 状態を返す。新規のプロセス生成の可否を返す。
	 *
	 * @return 状態
	 * @throws WorkflowException　ワークフロー関連で例外が発生した場合
	 * @see jp.co.argo21.nautica.workflow.omg.WfProcessManager#getState()
	 */
	public WfState getState() throws WorkflowException
	{
		try {
			WorkflowEngine engine = WorkflowEngine.getInstance();
			DefinitionRepositoryImpl rep = engine.getDefinitionRepository();
			return rep.getProcessDefinitionState(definitionID);
		} catch (WorkflowException ex) {
			throw ex;
		} catch (Exception ex) {
			// プロセス状態の取得に失敗しました。
			String E0154 = StringManager.get("E0154");
			throw new WorkflowException(E0154, ex);
		}
	}

	/**
	 * 状態を設定する。
	 *
	 * @param state 状態
	 * @throws TransitionNotAllowedException その状態に遷移できない場合
	 * @throws WorkflowException　ワークフロー関連で例外が発生した場合
	 * @see jp.co.argo21.nautica.workflow.omg.WfProcessManager#setState(jp.co.argo21.nautica.workflow.omg.WfState)
	 */
	public void setState(WfState state) throws TransitionNotAllowedException,
			WorkflowException
	{
		try {
			WorkflowEngine engine = WorkflowEngine.getInstance();
			DefinitionRepositoryImpl rep = engine.getDefinitionRepository();
			rep.setProcessDefinitionState(definitionID,
				(ProcessDefinitionState)state);
		} catch (WorkflowException ex) {
			throw ex;
		} catch (Exception ex) {
			// プロセス状態の設定に失敗しました。
			String E0155 = StringManager.get("E0155");
			throw new WorkflowException(E0155, ex);
		}
	}

	/**
	 * インスタンスのコンテキストの設定方法を定義するメタ情報を返す。
	 * ただしこれらから返される値はAttribute型とし、
	 * ID、プロセスID、更新日については初期化されていないものとする。
	 * これらの項目の初期化は、このメソッドを利用した側で責任を負うものとする。
	 *
	 * @return コンテキストシグニチャ
	 * @throws WorkflowException　ワークフロー関連で例外が発生した場合
	 * @see jp.co.argo21.nautica.workflow.omg.WfProcessManager#getContextSignature()
	 */
	public WfNameValue[] getContextSignature() throws WorkflowException
	{
		List<VariableDefinition> varDefs = packageDefifinition.getVariables();
		List<VariableBean> vars = new ArrayList<VariableBean>();
		for (VariableDefinition varDef : varDefs) {
			VariableBean bean = new VariableBean();
			bean.setVariableDefinitionID(varDef.getID());
			bean.setName(varDef.getName());
			bean.setType(varDef.getType());
			bean.setValue(varDef.getInitialValue());
			vars.add(bean);
		}
		return (VariableBean[])vars.toArray(new VariableBean[vars.size()]);
	}

	/**
	 * インスタンスが結果を返す方法を指定するメタ情報を返す。
	 * ただしこれらから返される値はFormalParameter型とし、
	 * 値については初期化されていないものとする。
	 * この項目の初期化は、このメソッドを利用した側で責任を負うものとする。
	 *
	 * @return プロセス変数
	 * @throws WorkflowException　ワークフロー関連で例外が発生した場合
	 * @see jp.co.argo21.nautica.workflow.omg.WfProcessManager#getResultSignature()
	 */
	public WfNameValue[] getResultSignature() throws WorkflowException
	{
		List<ParameterDefinition> paramDefs = processDefinition.getParameters();
		List<FormalParameterBean> params = new ArrayList<FormalParameterBean>();
		for (ParameterDefinition paramDef : paramDefs) {
			FormalParameterBean bean = new FormalParameterBean();
			bean.setID(paramDef.getID());
			bean.setName(paramDef.getName());
			bean.setType(paramDef.getType());
			bean.setMode(paramDef.getMode());
			bean.setDescription(paramDef.getDescription());
			params.add(bean);
		}
		return (FormalParameterBean[])params.toArray(new FormalParameterBean[params.size()]);
	}

	/**
	 * プロセスのインスタンスを生成し、リクエスタに結合する。
	 * プロセスが生成されると、not_running.not_startedの状態に設定される。
	 *
	 * @param requester プロセスリクエスタ
	 * @param name 人が識別可能なプロセス名
	 * @return 生成されたプロセス
	 * @throws NotEnabledException プロセス生成ができない場合
	 * @throws InvalidRequesterException リクエスタが正しくない場合
	 * @throws RequesterRequiredException リクエスタが指定されていない場合
	 * @throws WorkflowException　ワークフロー関連で例外が発生した場合
	 * @see jp.co.argo21.nautica.workflow.omg.WfProcessManager#createProcess(jp.co.argo21.nautica.workflow.omg.WfRequester, java.lang.String)
	 */
	public WfProcess createProcess(WfRequester requester, String name)
			throws NotEnabledException, InvalidRequesterException,
			RequesterRequiredException, WorkflowException
	{
		try {
			WorkflowDAOFactory daoFactory
				= DataAccessManager.getDAOFactory();
			ProcessDAO processDAO = daoFactory.getProcessDAO();
			VariableDAO variableDAO = daoFactory.getVariableDAO();

			long now = System.currentTimeMillis();
			
			ProcessBean processBean = insertProcess(processDAO, requester, name, now);

			VariableBean[] vars = (VariableBean[])getContextSignature();
			for (int i = 0; i < vars.length; i++) {
				VariableBean variableBean = vars[i];
				insertVariable(variableDAO, processBean, variableBean, now);
			}
			
			FormalParameter[] params = (FormalParameter[])getResultSignature();
			WfProcess proc = new ProcessInternal(processBean, params);
			proc.setRequester(requester);
			return proc;
		} catch (WorkflowException ex) {
			throw ex;
		} catch (Exception ex) {
			// プロセスの生成に失敗しました。
			String E0153 = StringManager.get("E0153");
			throw new WorkflowException(E0153, ex);
		}		
	}

	/**
	 * 指定されたプロセス定義に属するプロセスインスタンスを
	 * フィルターで絞り込み、状態の変更を行う。
	 * 指定可能なフィルターはStateFilterとする。
	 *
	 * @param filter 検索用フィルター
	 * @param state 新しいプロセスインスタンス状態
	 * @throws InvalidFilterException 指定されたフィルターが有効でない場合
	 * @throws InvalidStateException 指定された状態が有効でない場合
	 * @throws TransitionNotAllowedException 状態の変更が許可されていない場合
	 */
	void changeProcessesState(Filter filter, ProcessState state)
	throws InvalidFilterException, InvalidStateException,
		TransitionNotAllowedException
	{
		try {
			Process[] procs = getProcesses(filter);
			
			for (int i = 0; i < procs.length; i++) {
				String pid = procs[i].getID();
				ProcessInternal process = (ProcessInternal)getProcess(pid);
				process.changeState(state);
			}
		} catch (InvalidFilterException ex) {
			throw ex;
		} catch (InvalidStateException ex) {
			throw ex;
		} catch (TransitionNotAllowedException ex) {
			throw ex;
		} catch (Exception ex) {
			// プロセス状態の変更に失敗しました。
			String E0156 = StringManager.get("E0156");
			throw new TransitionNotAllowedException(E0156, ex);
		}
	}

	/**
	 * 指定されたプロセス定義とアクティビティ定義に属する
	 * アクティビティインスタンスをフィルターで絞り込み、状態の変更を行う。
	 * 指定可能なフィルターはStateFilterとする。
	 *
	 * @param adid アクティビティ定義ID
	 * @param filter 検索用フィルター
	 * @param state 新しいアクティビティインスタンス状態
	 * @throws InvalidActivityNameException 指定されたアクティビティ定義IDが有効でない場合
	 * @throws InvalidFilterException 指定されたフィルターが有効でない場合
	 * @throws InvalidStateException 指定された状態が有効でない場合
	 * @throws TransitionNotAllowedException 状態の変更が許可されていない場合
	 */
	void changeActivitiesState(String adid, Filter filter, ActivityState state)
	throws InvalidActivityNameException, InvalidFilterException,
		InvalidStateException, TransitionNotAllowedException
	{
		try {
			Activity[] acts = getActivities(adid, filter);
			
			for (int i = 0; i < acts.length; i++) {
				String pid = acts[i].getProcessID();
				String aid = acts[i].getActivityID();
				ProcessInternal process = (ProcessInternal)getProcess(pid);
				WfActivity activity = process.getStep(aid);
				if (activity == null) {
					// 該当するアクティビティが存在しません。
					String msg = StringManager.get("E0069");
					throw new InvalidActivityInstanceException(msg);
				}
				activity.changeState(state);
			}
		} catch (InvalidActivityNameException ex) {
			throw ex;
		} catch (InvalidFilterException ex) {
			throw ex;
		} catch (InvalidStateException ex) {
			throw ex;
		} catch (TransitionNotAllowedException ex) {
			throw ex;
		} catch (Exception ex) {
			// アクティビティ状態の変更に失敗しました。
			String E0157 = StringManager.get("E0157");
			throw new TransitionNotAllowedException(E0157, ex);
		}
	}

	/**
	 * 指定されたプロセス定義に属するプロセスインスタンスを
	 * フィルターで絞り込み、停止を行う。
	 *
	 * @param filter 検索用フィルター
	 * @throws InvalidFilterException 指定されたフィルターが有効でない場合
	 */
	void terminateProcesses(Filter filter)
	throws InvalidProcessDefinitionException, InvalidFilterException
	{
		try {
			Process[] procs = getProcesses(filter);
			
			for (int i = 0; i < procs.length; i++) {
				String pid = procs[i].getID();
				ProcessInternal process = (ProcessInternal)getProcess(pid);
				process.terminate();
			}
		} catch (InvalidProcessDefinitionException ex) {
			throw ex;
		} catch (InvalidFilterException ex) {
			throw ex;
		} catch (Exception ex) {
			// プロセスの停止に失敗しました。
			String E0136 = StringManager.get("E0136");
			throw new InvalidProcessDefinitionException(E0136, ex);
		}
	}

	/**
	 * 指定されたプロセス定義に属するプロセスインスタンスを
	 * フィルターで絞り込み、属性の割り当てを行う。
	 *
	 * @param attr 属性
	 * @throws InvalidFilterException 指定されたフィルターが有効でない場合
	 * @throws InvalidAttributeException 属性が有効でない場合
	 */
	void assignProcessesAttribute(Filter filter, Attribute attr)
	throws InvalidFilterException, InvalidAttributeException
	{
		try {
			Process[] procs = getProcesses(filter);
			
			for (int i = 0; i < procs.length; i++) {
				String pid = procs[i].getID();
				VariableBean bean = new VariableBean();
				bean.setName(attr.getName());
				bean.setType(attr.getType());
				bean.setValue(attr.getValue());
				bean.setProcessID(pid);
				ProcessInternal process = (ProcessInternal)getProcess(pid);
				process.setContext(bean);
			}
		} catch (InvalidFilterException ex) {
			throw ex;
		} catch (InvalidAttributeException ex) {
			throw ex;
		} catch (Exception ex) {
			// プロセス変数の設定に失敗しました。
			String E0080 = StringManager.get("E0080");
			throw new InvalidAttributeException(E0080, ex);
		}
	}

	/**
	 * 指定されたプロセス定義とアクティビティ定義に属する
	 * アクティビティインスタンスをフィルターで絞り込み、
	 * 属性の割り当てを行う。
	 *
	 * @param adid アクティビティ定義ID
	 * @param filter 検索用フィルター
	 * @param attr 属性
	 * @throws InvalidActivityNameException 指定されたアクティビティ定義IDが有効でない場合
	 * @throws InvalidFilterException 指定されたフィルターが有効でない場合
	 * @throws InvalidAttributeException 属性が有効でない場合
	 */
	void assignActivitiesAttribute(String adid, Filter filter, Attribute attr)
	throws InvalidActivityNameException, InvalidFilterException,
		InvalidAttributeException
	{
		try {
			Activity[] acts = getActivities(adid, filter);
			
			for (int i = 0; i < acts.length; i++) {
				String pid = acts[i].getProcessID();
				String aid = acts[i].getActivityID();
				VariableBean bean = new VariableBean();
				bean.setName(attr.getName());
				bean.setType(attr.getType());
				bean.setValue(attr.getValue());
				bean.setProcessID(pid);
				ProcessInternal process = (ProcessInternal)getProcess(pid);
				WfActivity activity = process.getStep(aid);
				if (activity == null) {
					// 該当するアクティビティが存在しません。
					String msg = StringManager.get("E0069");
					throw new InvalidActivityInstanceException(msg);
				}
				activity.setContext(bean);
			}
		} catch (InvalidActivityNameException ex) {
			throw ex;
		} catch (InvalidFilterException ex) {
			throw ex;
		} catch (InvalidAttributeException ex) {
			throw ex;
		} catch (Exception ex) {
			// アクティビティ指定のプロセス変数の設定に失敗しました。
			String E0158 = StringManager.get("E0158");
			throw new InvalidAttributeException(E0158, ex);
		}
	}

	/**
	 * 指定されたプロセス定義に属するプロセスインスタンスを
	 * フィルターで絞り込み、中断を行う。
	 *
	 * @param filter 検索用フィルター
	 * @throws InvalidSessionException 指定されたセッションが無効の場合
	 * @throws InvalidFilterException 指定されたフィルターが有効でない場合
	 */
	void abortProcesses(Filter filter)
	throws InvalidFilterException
	{
		try {
			Process[] procs = getProcesses(filter);
			
			for (int i = 0; i < procs.length; i++) {
				String pid = procs[i].getID();
				ProcessInternal process = (ProcessInternal)getProcess(pid);
				process.abort();
			}
		} catch (InvalidFilterException ex) {
			throw ex;
		} catch (Exception ex) {
			// プロセスの中止に失敗しました。
			String E0137 = StringManager.get("E0137");
			throw new InvalidFilterException(E0137, ex);
		}
	}

	/**
	 * フィルターで特定されるプロセスを返す。
	 *
	 * @param filter フィルター
	 * @return プロセス
	 * @throws InvalidFilterException 無効なフィルターが指定された場合
	 */
	Process[] getProcesses(Filter filter)
	throws InvalidFilterException
	{
		try {
			WorkflowDAOFactory daoFactory = DataAccessManager.getDAOFactory();
			ProcessDAO procDAO = daoFactory.getProcessDAO();

			ProcessBean[] beans = procDAO.findByFilter(definitionID, filter);
			return beans;
		} catch (InvalidFilterException ex) {
			throw ex;
		} catch (Exception ex) {
			// プロセスの取得に失敗しました。
			String E0151 = StringManager.get("E0151");
			throw new InvalidFilterException(E0151, ex);
		}
	}

	/**
	 * フィルターで特定されるアクティビティを返す。
	 *
	 * @param adid アクティビティ定義ID
	 * @param filter フィルター
	 * @return アクティビティ
	 * @throws InvalidFilterException 無効なフィルターが指定された場合
	 */
	Activity[] getActivities(String adid, Filter filter)
	throws InvalidFilterException
	{
		try {
			WorkflowDAOFactory daoFactory = DataAccessManager.getDAOFactory();
			ActivityDAO actDAO = daoFactory.getActivityDAO();

			ActivityBean[] beans = actDAO.findByFilter(definitionID, adid, filter);
			return beans;
		} catch (InvalidFilterException ex) {
			throw ex;
		} catch (Exception ex) {
			// アクティビティの取得に失敗しました。
			String E0124 = StringManager.get("E0124");
			throw new InvalidFilterException(E0124, ex);
		}
	}
	
	/**
	 * 新規プロセスを挿入する。
	 *
	 * @param processDAO プロセスDAO
	 * @param requester リクエスタ
	 * @param name プロセス名
	 * @param now 作成時間
	 * @return プロセス
	 * @throws Exception 任意の例外
	 */
	private ProcessBean insertProcess(ProcessDAO processDAO, WfRequester requester,
		String name, long now)
	throws Exception
	{
		Timestamp ts = DataAccessManager.getAccessTime();
		int du = processDefinition.getDurationUnit();
		int limit = processDefinition.getLimit();
		long durationLimit = now + DurationHelper.calculateDuration(du, limit);
		Timestamp limitTs = new Timestamp(durationLimit);
		String procName = name;
		if (procName == null) procName = "";
		
		ProcessBean processBean = new ProcessBean();
		processBean.setID(UniqueKeyGenerator.generate(ProcessBean.ID_PREFIX));
		processBean.setName(name);
		processBean.setPackageID(packageDefifinition.getID());
		processBean.setProcDefinitionID(definitionID);
		processBean.setProcessState(ProcessState.OPEN_NOT_RUNNING_NOT_STARTED.toInt());
		processBean.setStartDate(ts);
		processBean.setStarterID(requester.getReqesterResource().getID());
		processBean.setDurationLimit(limitTs);
		processBean.setUpdateDate(ts);

		processDAO.insert(processBean);
		
		return processBean;
	}
	
	/**
	 * 新規プロセス変数を挿入する。
	 *
	 * @param variableDAO プロセス変数DAO
	 * @param processBean プロセス
	 * @param variableBean プロセス変数
	 * @param now 作成時間
	 * @throws Exception 任意の例外
	 */
	private void insertVariable(VariableDAO variableDAO,
		ProcessBean processBean, VariableBean variableBean, long now)
	throws Exception
	{
		Timestamp ts = DataAccessManager.getAccessTime();

		variableBean.setID(UniqueKeyGenerator.generate(VariableBean.ID_PREFIX));
		variableBean.setProcessID(processBean.getID());
		variableBean.setUpdateDate(ts);

		variableDAO.insert(variableBean, null);
	}
}
