/* $Id: WorkflowAdminHandlerImpl.java,v 1.2 2007/11/26 08:51:40 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 org.apache.log4j.Logger;

import jp.co.argo21.nautica.workflow.security.SessionManager;
import jp.co.argo21.nautica.workflow.security.User;
import jp.co.argo21.nautica.workflow.util.StringManager;
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.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.InvalidProcessInstanceException;
import jp.co.argo21.nautica.workflow.wfmc.InvalidSessionException;
import jp.co.argo21.nautica.workflow.wfmc.InvalidStateException;
import jp.co.argo21.nautica.workflow.wfmc.ProcessState;
import jp.co.argo21.nautica.workflow.wfmc.TransitionNotAllowedException;
import jp.co.argo21.nautica.workflow.wfmc.WorkflowAdminHandler;

/**
 * ワークフロー管理ハンドラは、ワークフローに対する
 * 管理クライアントである。
 *
 * @author  nito(Argo 21, Corp.)
 * @version $Revision: 1.2 $
 * @since   Nautica Workflow 1.0
 */
public class WorkflowAdminHandlerImpl implements WorkflowAdminHandler
{
	/** エンジンログ */
	private static Logger eLog = LogManager.getEngineLogger();
	
	/** 監査ログ */
	private static Logger audit = LogManager.getAuditLogger();

	/**
	 * WorkflowAdminHandlerImplを生成する。
	 */
	WorkflowAdminHandlerImpl()
	{
	}

	/**
	 * 指定されたプロセス定義に属するプロセスインスタンスを
	 * フィルターで絞り込み、状態の変更を行う。
	 * 指定可能なフィルターはStateFilterとする。
	 *
	 * @param session セッションID
	 * @param pdid プロセス定義ID
	 * @param filter 検索用フィルター
	 * @param state 新しいプロセスインスタンス状態
	 * @throws InvalidSessionException 指定されたセッションが無効の場合
	 * @throws InvalidProcessDefinitionException 指定されたプロセス定義IDが有効でない場合
	 * @throws InvalidFilterException 指定されたフィルターが有効でない場合
	 * @throws InvalidStateException 指定された状態が有効でない場合
	 * @throws TransitionNotAllowedException 状態の変更が許可されていない場合
	 * @see jp.co.argo21.nautica.workflow.wfmc.WorkflowAdminHandler#changeProcessesState(java.lang.String, java.lang.String, jp.co.argo21.nautica.workflow.wfmc.Filter, jp.co.argo21.nautica.workflow.wfmc.ProcessState)
	 */
	public void changeProcessesState(String session,
		String pdid, Filter filter, ProcessState state)
	throws InvalidSessionException, InvalidProcessDefinitionException,
		InvalidFilterException, InvalidStateException,
		TransitionNotAllowedException
	{
		String argInfo = "(NAUTICA API = changeProcessesState,"
			 + "session = [" + session + "],"
			 + "pdid = [" + pdid + "],"
			 + "filter = [" + filter + "],"
			 + "state = [" + state + "])";
	
		try {
			checkProcessDefinitionID(pdid);
			
			if (filter == null)
			{
				// フィルターが設定されていません。この呼び出しには、少なくとも状態フィルターが必要です。
				String msg = StringManager.get("E0060");
				throw new InvalidFilterException(msg);
			}
		
			if (state == null) {
				// プロセスの状態が設定されていません。
				String msg = StringManager.get("E0063");
				throw new InvalidStateException(msg);
			} else if (ProcessState.OPEN_NOT_RUNNING_NOT_STARTED.equals(state)) {
				// プロセスの状態を未開始にすることはできません。
				String msg = StringManager.get("E0064");
				throw new InvalidStateException(msg);
			} else if (ProcessState.CLOSED_COMPLETED.equals(state)) {
				// プロセスの状態を強制的に正常終了させることはできません。
				String msg = StringManager.get("E0065");
				throw new InvalidStateException(msg);
			}

			DataAccessManager.begin(false);
				
			validateSession(session);
			ProcessManagerFactory pmf = ProcessManagerFactory.getInstance();
			ProcessManager pm = pmf.getProcessManager(pdid);
			pm.changeProcessesState(filter, state);
				
			DataAccessManager.commit();
			
			// 監査ログ出力
		    AuditDataRecord data = new AuditDataRecord(
		            new AuditPrefix("", "WMChangedProcessInstanceState", session),
		            new AuditSuffix());
		    data.setDataElement("NewProcessState", state);
		    audit.info(data);
	
		} catch (InvalidSessionException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (InvalidProcessDefinitionException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (InvalidFilterException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (InvalidStateException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (TransitionNotAllowedException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (Exception ex) {
			try { DataAccessManager.rollback(); } catch (Exception ex2) { /* Ignore */ }
			// プロセス状態の変更に失敗しました。
			String E0156 = StringManager.get("E0156") + argInfo;
			eLog.error(E0156, ex);
			throw new TransitionNotAllowedException(E0156, ex);
		} finally {
			try { DataAccessManager.close(); } catch (Exception ex) { /* Ignore */ }
		}
	}

	/**
	 * 指定されたプロセス定義とアクティビティ定義に属する
	 * アクティビティインスタンスをフィルターで絞り込み、状態の変更を行う。
	 * 指定可能なフィルターはStateFilterとする。
	 *
	 * @param session セッションID
	 * @param pdid プロセス定義ID
	 * @param adid アクティビティ定義ID
	 * @param filter 検索用フィルター
	 * @param state 新しいアクティビティインスタンス状態
	 * @throws InvalidSessionException 指定されたセッションが無効の場合
	 * @throws InvalidProcessDefinitionException 指定されたプロセス定義IDが有効でない場合
	 * @throws InvalidActivityNameException 指定されたアクティビティ定義IDが有効でない場合
	 * @throws InvalidFilterException 指定されたフィルターが有効でない場合
	 * @throws InvalidStateException 指定された状態が有効でない場合
	 * @throws TransitionNotAllowedException 状態の変更が許可されていない場合
	 * @see jp.co.argo21.nautica.workflow.wfmc.WorkflowAdminHandler#changeActivitiesState(java.lang.String, java.lang.String, java.lang.String, jp.co.argo21.nautica.workflow.wfmc.Filter, jp.co.argo21.nautica.workflow.wfmc.ActivityState)
	 */
	public void changeActivitiesState(String session,
		String pdid, String adid, Filter filter, ActivityState state)
	throws InvalidSessionException, InvalidProcessDefinitionException,
		InvalidActivityNameException, InvalidFilterException,
		InvalidStateException, TransitionNotAllowedException
	{
		String argInfo = "(NAUTICA API = changeActivitiesState,"
			 + "session = [" + session + "],"
			 + "pdid = [" + pdid + "],"
			 + "adid = [" + adid + "],"
			 + "filter = [" + filter + "],"
			 + "state = [" + state + "])";
	
		try {
			checkProcessDefinitionID(pdid);
			checkActivityDefinitionID(adid);

			if (filter == null)
			{
				// フィルターが設定されていません。この呼び出しには、少なくとも状態フィルターが必要です。
				String msg = StringManager.get("E0060");
				throw new InvalidFilterException(msg);
			}
		
			if (state == null) {
				// アクティビティの状態が設定されていません。
				String msg = StringManager.get("E0066");
				throw new InvalidStateException(msg);
			} else if (ActivityState.OPEN_NOT_RUNNING_NOT_STARTED.equals(state)) {
				// アクティビティの状態を未開始にすることはできません。
				String msg = StringManager.get("E0067");
				throw new InvalidStateException(msg);
			} else if (ActivityState.CLOSED_COMPLETED.equals(state)) {
				// アクティビティの状態を強制的に正常終了させることはできません。
				String msg = StringManager.get("E0068");
				throw new InvalidStateException(msg);
			}
		
			DataAccessManager.begin(false);
				
			validateSession(session);

			ProcessManagerFactory pmf = ProcessManagerFactory.getInstance();
			ProcessManager pm = pmf.getProcessManager(pdid);
			pm.changeActivitiesState(adid, filter, state);
			
			DataAccessManager.commit();
			
			// 監査ログ出力
		    AuditDataRecord data = new AuditDataRecord(
		            new AuditPrefix("", "WMChangedActivityInstanceState", session),
		            new AuditSuffix());
		    data.setDataElement("NewActivityState", state);
		    audit.info(data);
	
		} catch (InvalidSessionException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (InvalidProcessDefinitionException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (InvalidActivityNameException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (InvalidFilterException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (InvalidStateException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (TransitionNotAllowedException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (Exception ex) {
			try { DataAccessManager.rollback(); } catch (Exception ex2) { /* Ignore */ }
			// アクティビティ状態の変更に失敗しました。
			String E0157 = StringManager.get("E0157") + argInfo;
			eLog.error(E0157, ex);
			throw new TransitionNotAllowedException(E0157, ex);
		} finally {
			try { DataAccessManager.close(); } catch (Exception ex) { /* Ignore */ }
		}
	}

	/**
	 * 指定されたプロセス定義に属するプロセスインスタンスを
	 * フィルターで絞り込み、停止を行う。
	 *
	 * @param session セッションID
	 * @param pdid プロセス定義ID
	 * @param filter 検索用フィルター
	 * @throws InvalidSessionException 指定されたセッションが無効の場合
	 * @throws InvalidProcessDefinitionException 指定されたプロセス定義IDが有効でない場合
	 * @throws InvalidFilterException 指定されたフィルターが有効でない場合
	 * @see jp.co.argo21.nautica.workflow.wfmc.WorkflowAdminHandler#terminateProcesses(java.lang.String, java.lang.String, jp.co.argo21.nautica.workflow.wfmc.Filter)
	 */
	public void terminateProcesses(String session,
		String pdid, Filter filter)
	throws InvalidSessionException, InvalidProcessDefinitionException,
		InvalidFilterException
	{
		String argInfo = "(NAUTICA API = terminateProcesses,"
			 + "session = [" + session + "],"
			 + "pdid = [" + pdid + "],"
			 + "filter = [" + filter + "])";
	
		try {
			checkProcessDefinitionID(pdid);
			
			if (filter == null)
			{
				// フィルターが設定されていません。この呼び出しには、少なくとも状態フィルターが必要です。
				String msg = StringManager.get("E0060");
				throw new InvalidFilterException(msg);
			}
			
			DataAccessManager.begin(false);
				
			validateSession(session);
	
			ProcessManagerFactory pmf = ProcessManagerFactory.getInstance();
			ProcessManager pm = pmf.getProcessManager(pdid);
			pm.terminateProcesses(filter);
				
			DataAccessManager.commit();
			
			// 監査ログ出力
		    AuditDataRecord data = new AuditDataRecord(
		            new AuditPrefix("", "WMTerminatedProcessInstance", session),
		            new AuditSuffix());
		    data.setDataElement("NewProcessState", ProcessState.CLOSED_TERMINATED);
		    audit.info(data);
	
		} catch (InvalidSessionException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (InvalidProcessDefinitionException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (InvalidFilterException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (Exception ex) {
			try { DataAccessManager.rollback(); } catch (Exception ex2) { /* Ignore */ }
			// プロセスの停止に失敗しました。
			String E0136 = StringManager.get("E0136") + argInfo;
			eLog.error(E0136, ex);
			throw new InvalidFilterException(E0136, ex);
		} finally {
			try { DataAccessManager.close(); } catch (Exception ex) { /* Ignore */ }
		}
	}

	/**
	 * 指定されたプロセス定義に属するプロセスインスタンスを
	 * フィルターで絞り込み、属性の割り当てを行う。
	 *
	 * @param session セッションID
	 * @param pdid プロセス定義ID
	 * @param filter 検索用フィルター
	 * @param attr 属性
	 * @throws InvalidSessionException 指定されたセッションが無効の場合
	 * @throws InvalidProcessDefinitionException 指定されたプロセス定義IDが有効でない場合
	 * @throws InvalidFilterException 指定されたフィルターが有効でない場合
	 * @throws InvalidAttributeException 属性が有効でない場合
	 * @see jp.co.argo21.nautica.workflow.wfmc.WorkflowAdminHandler#assignProcessesAttribute(java.lang.String, java.lang.String, jp.co.argo21.nautica.workflow.wfmc.Filter, jp.co.argo21.nautica.workflow.wfmc.Attribute)
	 */
	public void assignProcessesAttribute(String session,
		String pdid, Filter filter, Attribute attr)
	throws InvalidSessionException, InvalidProcessDefinitionException,
		InvalidFilterException, InvalidAttributeException
	{
		String argInfo = "(NAUTICA API = assignProcessesAttribute,"
			 + "session = [" + session + "],"
			 + "pdid = [" + pdid + "],"
			 + "filter = [" + filter + "],"
			 + "attr = [" + attr + "])";
	
		try {
			checkProcessDefinitionID(pdid);
			
			if (filter == null)
			{
				// フィルターが設定されていません。この呼び出しには、少なくとも状態フィルターが必要です。
				String E0060 = StringManager.get("E0060");
				throw new InvalidFilterException(E0060);
			}
		
			if (attr == null) {
				// プロセス変数が未設定です。
				String E0131 = StringManager.get("E0131");
				throw new InvalidAttributeException(E0131);
			}
			
			DataAccessManager.begin(false);
				
			validateSession(session);
	
			ProcessManagerFactory pmf = ProcessManagerFactory.getInstance();
			ProcessManager pm = pmf.getProcessManager(pdid);
			pm.assignProcessesAttribute(filter, attr);
				
			DataAccessManager.commit();
				
			// 監査ログ出力
		    AuditDataRecord data = new AuditDataRecord(
		            new AuditPrefix("", "WMAssignedProcessInstanceAttributes", session),
		            new AuditSuffix());
		    data.setDataElement("AttributeName", attr.getName());
		    data.setDataElement("AttributeType", attr.getType());
		    data.setDataElement("NewAttributeValue", attr.getValue());
		    audit.info(data);

		} catch (InvalidSessionException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (InvalidProcessDefinitionException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (InvalidFilterException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (InvalidAttributeException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (Exception ex) {
			try { DataAccessManager.rollback(); } catch (Exception ex2) { /* Ignore */ }
			// プロセス変数の設定に失敗しました。
			String E0080 = StringManager.get("E0080") + argInfo;
			eLog.error(E0080, ex);
			throw new InvalidFilterException(E0080, ex);
		} finally {
			try { DataAccessManager.close(); } catch (Exception ex) { /* Ignore */ }
		}
	}

	/**
	 * 指定されたプロセス定義とアクティビティ定義に属する
	 * アクティビティインスタンスをフィルターで絞り込み、
	 * 属性の割り当てを行う。
	 *
	 * @param session セッションID
	 * @param pdid プロセス定義ID
	 * @param adid アクティビティ定義ID
	 * @param filter 検索用フィルター
	 * @param attr 属性
	 * @throws InvalidSessionException 指定されたセッションが無効の場合
	 * @throws InvalidProcessDefinitionException 指定されたプロセス定義IDが有効でない場合
	 * @throws InvalidActivityNameException 指定されたアクティビティ定義IDが有効でない場合
	 * @throws InvalidFilterException 指定されたフィルターが有効でない場合
	 * @throws InvalidAttributeException 属性が有効でない場合
	 * @see jp.co.argo21.nautica.workflow.wfmc.WorkflowAdminHandler#assignActivitiesAttribute(java.lang.String, java.lang.String, java.lang.String, jp.co.argo21.nautica.workflow.wfmc.Filter, jp.co.argo21.nautica.workflow.wfmc.Attribute)
	 */
	public void assignActivitiesAttribute(String session,
		String pdid, String adid, Filter filter, Attribute attr)
	throws InvalidSessionException, InvalidProcessDefinitionException,
		InvalidActivityNameException, InvalidFilterException,
		InvalidAttributeException
	{
		String argInfo = "(NAUTICA API = assignActivitiesAttribute,"
			 + "session = [" + session + "],"
			 + "pdid = [" + pdid + "],"
			 + "adid = [" + adid + "],"
			 + "filter = [" + filter + "],"
			 + "attr = [" + attr + "])";
	
		try {
			checkProcessDefinitionID(pdid);
			checkActivityDefinitionID(adid);
		
			if (filter == null)
			{
				// フィルターが設定されていません。この呼び出しには、少なくとも状態フィルターが必要です。
				String msg = StringManager.get("E0060");
				throw new InvalidFilterException(msg);
			}
		
			if (attr == null) {
				// プロセス変数が未設定です。
				String E0131 = StringManager.get("E0131");
				throw new InvalidAttributeException(E0131);
			}
		
			DataAccessManager.begin(false);
				
			validateSession(session);

			ProcessManagerFactory pmf = ProcessManagerFactory.getInstance();
			ProcessManager pm = pmf.getProcessManager(pdid);
			pm.assignActivitiesAttribute(adid, filter, attr);
				
			DataAccessManager.commit();
				
			// 監査ログ出力
		    AuditDataRecord data = new AuditDataRecord(
		            new AuditPrefix("", "WMAssignedActivityInstanceAttributes", session),
		            new AuditSuffix());
		    data.setDataElement("AttributeName", attr.getName());
		    data.setDataElement("AttributeType", attr.getType());
		    data.setDataElement("NewAttributeValue", attr.getValue());
		    audit.info(data);

		} catch (InvalidSessionException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (InvalidProcessDefinitionException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (InvalidActivityNameException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (InvalidFilterException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (InvalidAttributeException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (Exception ex) {
			try { DataAccessManager.rollback(); } catch (Exception ex2) { /* Ignore */ }
			// アクティビティ指定のプロセス変数の設定に失敗しました。
			String E0158 = StringManager.get("E0158") + argInfo;
			eLog.error(E0158, ex);
			throw new InvalidAttributeException(E0158, ex);
		} finally {
			try { DataAccessManager.close(); } catch (Exception ex) { /* Ignore */ }
		}
	}

	/**
	 * 指定されたプロセス定義に属するプロセスインスタンスを
	 * フィルターで絞り込み、中断を行う。
	 *
	 * @param session セッションID
	 * @param pdid プロセス定義ID
	 * @param filter 検索用フィルター
	 * @throws InvalidSessionException 指定されたセッションが無効の場合
	 * @throws InvalidProcessDefinitionException 指定されたプロセス定義IDが有効でない場合
	 * @throws InvalidFilterException 指定されたフィルターが有効でない場合
	 * @see jp.co.argo21.nautica.workflow.wfmc.WorkflowAdminHandler#abortProcesses(java.lang.String, java.lang.String, jp.co.argo21.nautica.workflow.wfmc.Filter)
	 */
	public void abortProcesses(String session,
		String pdid, Filter filter)
	throws InvalidSessionException, InvalidProcessDefinitionException,
		InvalidFilterException
	{
		String argInfo = "(NAUTICA API = abortProcesses,"
			 + "session = [" + session + "],"
			 + "pdid = [" + pdid + "],"
			 + "filter = [" + filter + "])";
	
		try {
			checkProcessDefinitionID(pdid);
			
			if (filter == null)
			{
				// フィルターが設定されていません。この呼び出しには、少なくとも状態フィルターが必要です。
				String msg = StringManager.get("E0060");
				throw new InvalidFilterException(msg);
			}
			
			DataAccessManager.begin(false);
				
			validateSession(session);
	
			ProcessManagerFactory pmf = ProcessManagerFactory.getInstance();
			ProcessManager pm = pmf.getProcessManager(pdid);
			pm.abortProcesses(filter);
				
			DataAccessManager.commit();
				
			// 監査ログ出力
		    AuditDataRecord data = new AuditDataRecord(
		            new AuditPrefix("", "WMAbortedProcessInstance", session),
		            new AuditSuffix());
		    data.setDataElement("NewProcessState", ProcessState.CLOSED_ABORTED);
		    audit.info(data);

		} catch (InvalidSessionException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (InvalidProcessDefinitionException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (InvalidFilterException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (Exception ex) {
			// プロセスの中止に失敗しました。
			String E0137 = StringManager.get("E0137") + argInfo;
			eLog.error(E0137, ex);
			throw new InvalidFilterException(E0137, ex);
		} finally {
			try { DataAccessManager.close(); } catch (Exception ex) { /* Ignore */ }
		}
	}

	/**
	 * 指定されたプロセスインスタンスの中断を行う。
	 *
	 * @param session セッションID
	 * @param pid プロセスインスタンスID
	 * @throws InvalidSessionException 指定されたセッションが無効の場合
	 * @throws InvalidProcessInstanceException プロセスインスタンスIDが有効でない場合
	 * @see jp.co.argo21.nautica.workflow.wfmc.WorkflowAdminHandler#abortProcess(java.lang.String, java.lang.String)
	 */
	public void abortProcess(String session, String pid)
	throws InvalidSessionException, InvalidProcessInstanceException
	{
		String argInfo = "(NAUTICA API = abortProcesses,"
			 + "session = [" + session + "],"
			 + "pid = [" + pid + "])";
	
		try {
			if (pid == null || pid.trim().equals("")) {
				// プロセスIDが未設定です。
				String E0189 = StringManager.get("E0189");
				throw new InvalidProcessInstanceException(E0189);
			}
		
			DataAccessManager.begin(false);
				
			validateSession(session);
	
			ProcessManagerFactory pmf = ProcessManagerFactory.getInstance();
			ProcessManager pm = pmf.getOwnerProcessManager(pid);
			ProcessInternal proc = (ProcessInternal)pm.getProcess(pid);
			
			proc.abort();
				
			DataAccessManager.commit();
				
			// 監査ログ出力
		    AuditDataRecord data = new AuditDataRecord(
		            new AuditPrefix(pid, "WMAbortedProcessInstance", session),
		            new AuditSuffix());
		    data.setDataElement("NewProcessState", ProcessState.CLOSED_ABORTED);			    
		    audit.info(data);

		} catch (InvalidSessionException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (InvalidProcessInstanceException ex) {
			rollbackAndLogging(ex, argInfo);
			throw ex;
		} catch (Exception ex) {
			try { DataAccessManager.rollback(); } catch (Exception ex2) { /* Ignore */ }
			// プロセスの中止に失敗しました。
			String E0137 = StringManager.get("E0137") + argInfo;
			eLog.error(E0137, ex);
			throw new InvalidProcessInstanceException(E0137, ex);
		} finally {
			try { DataAccessManager.close(); } catch (Exception ex) { /* Ignore */ }
		}
	}
	
	/**
	 * ロールバック処理とエラーログの出力を行う。
	 *
	 * @param ex 例外
	 * @param argInfo 引数情報
	 */
	private void rollbackAndLogging(Exception ex, String argInfo)
	{
		try { DataAccessManager.rollback(); } catch (Exception ex2) { /* Ignore */ }
		String msg = ex.getMessage() + argInfo;
		eLog.error(msg, ex);
	}
	
	/**
	 * プロセス定義IDを検証する。
	 *
	 * @param pdid プロセス定義ID
	 * @throws InvalidProcessDefinitionException 無効なプロセス定義IDの場合
	 */
	private void checkProcessDefinitionID(String pdid)
	throws InvalidProcessDefinitionException
	{
		if (pdid == null || pdid.trim().equals("")) {
			// プロセス定義Idが未設定です。
			String E0188 = StringManager.get("E0188");
			throw new InvalidProcessDefinitionException(E0188);
		}
	}
	
	/**
	 * アクティビティ定義IDを検証する。
	 *
	 * @param adid アクティビティ定義ID
	 * @throws InvalidActivityNameException 無効なアクティビティ定義IDの場合
	 */
	private void checkActivityDefinitionID(String adid)
	throws InvalidActivityNameException
	{
		if (adid == null || adid.trim().equals("")) {
			// アクティビティ定義IDが未設定です。
			String E0190 = StringManager.get("E0190");
			throw new InvalidActivityNameException(E0190);
		}
	}

	/**
	 * セッションを検証する。
	 *
	 * @param session セッションID
	 * @throws InvalidSessionException 指定されたセッションが無効の場合
	 */
	private void validateSession(String session)
	throws InvalidSessionException
	{
		if (session == null || session.trim().equals("")) {
			// セッションIDが未設定です。
			String E0170 = StringManager.get("E0170");
			throw new InvalidSessionException(E0170);
		}

		SessionManagerFactory factory = SessionManagerFactory.getInstance();
		SessionManager manager = factory.getSessionManager();
		manager.validateSession(session);
		
		//管理者権限の検証
		User user = manager.getSessionUser(session);
		if (user == null) {
			// 不正な利用者です。
			String msg = StringManager.get("E0061");
			throw new InvalidSessionException(msg);
		} else {
			try {
				String uid = user.getID();
				SystemChecker.checkAdmin(uid);
			} catch (Exception ex) {
				// 管理者権限がありません。
				String msg = StringManager.get("E0062");
				throw new InvalidSessionException(msg);
			}
		}
	}
}
