/* $Id: EndActivityRequestWatcher.java,v 1.4 2007/11/28 07:09:06 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.io.Serializable;
import java.util.HashMap;

import org.apache.log4j.Logger;

import jp.co.argo21.nautica.workflow.jms.WorkflowMessage;
import jp.co.argo21.nautica.workflow.jms.WorkflowMessageAdapter;
import jp.co.argo21.nautica.workflow.util.StringManager;
import jp.co.argo21.nautica.workflow.wfmc.ProcessState;

/**
 * アクティビティ終了要求キューを監視する。
 *
 * @author  nito(Argo 21, Corp.)
 * @version $Revision: 1.4 $
 * @since   Nautica Workflow 1.0
 */
class EndActivityRequestWatcher extends WorkflowMessageAdapter
{
	/** エンジンログ */
	private static Logger eLog = LogManager.getEngineLogger();
	/** メッセージキュー名 */
	public static final String NAME = "END_ACTIVITY_REQUEST";
	
	/**
	 * アクティビティ終了要求キュー監視を生成する。
	 */
	EndActivityRequestWatcher()
	{
	}

	@Override
	protected WorkflowMessage getMessage(HashMap<String, Serializable> map)
	{
		return new EndActivityRequestMessage(map);
	}

	/**
	 * アクティビティ終了要求を処理する。
	 *
	 * @param mid メッセージID
	 * @param message メッセージ
	 * @param isRedelivered 再配信フラグ
	 * @see jp.co.argo21.nautica.workflow.jms.WorkflowMessageAdapter#onMessage(java.lang.String, jp.co.argo21.nautica.workflow.jms.WorkflowMessage, boolean)
	 */
	public void onMessage(String mid, WorkflowMessage message, boolean isRedelivered)
	{
		if (message instanceof EndActivityRequestMessage == false) {
			//ログに出力して無視
			// 不正なメッセージ形式です。
			String E0099 = StringManager.get("E0099");
			eLog.error(E0099);
			return;
		}
		EndActivityRequestMessage msg = (EndActivityRequestMessage)message;
		String pid = msg.getProcessID();
		String aid = msg.getActivityID();

		ActivityInternal act = null;
		try {
			DataAccessManager.begin(false);
			
			ProcessState subprocState = msg.getSubprocessState();
			ProcessManagerFactory pmf = ProcessManagerFactory.getInstance();
			ProcessManager pm = pmf.getOwnerProcessManager(pid);
			ProcessInternal proc = (ProcessInternal)pm.getProcess(pid);
			act = (ActivityInternal)proc.getStep(aid);
			
			if (subprocState == null || ProcessState.CLOSED_COMPLETED.equals(subprocState)) {
				act.complete();
			} else if (ProcessState.CLOSED_TERMINATED.equals(subprocState)) {
				act.terminate(false);
			} else if (ProcessState.CLOSED_ABORTED.equals(subprocState)) {
				act.abort(false);
			}
		} catch (Exception ex) {
			try {
				String E0103 = StringManager.get("E0103");
				eLog.error(E0103, ex);

				//アクティビティ異常終了を試みる。
				act.terminate(false);
			} catch (Exception ex2) {
				String F0103 = StringManager.get("F0103");
				eLog.fatal(F0103, ex);
			}
		} finally {
			try { DataAccessManager.commit(); } catch (Exception ex) { /* Ignore */ }
			try { DataAccessManager.close(); } catch (Exception ex) { /* Ignore */ }
		}
	}
}
