/* $Id: ResourceInternal.java,v 1.1 2007/10/29 02:55:36 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 jp.co.argo21.nautica.workflow.dataaccess.WorkItemBean;
import jp.co.argo21.nautica.workflow.dataaccess.WorkItemDAO;
import jp.co.argo21.nautica.workflow.dataaccess.WorkflowDAOFactory;
import jp.co.argo21.nautica.workflow.omg.NotAssignedException;
import jp.co.argo21.nautica.workflow.omg.WfAssignment;
import jp.co.argo21.nautica.workflow.omg.WfResource;
import jp.co.argo21.nautica.workflow.omg.WorkflowException;
import jp.co.argo21.nautica.workflow.util.StringManager;
import jp.co.argo21.nautica.workflow.wfmc.Participant;
import jp.co.argo21.nautica.workflow.wfmc.WorkItem;

/**
 * エンジン内部でのリソースを表すオブジェクト。
 * 今回は、一部の機能のみ利用する。
 * OMGのWfResourceインタフェースとの整合性のために提供する。
 *
 * @author  nito(Argo 21, Corp.)
 * @version $Revision: 1.1 $
 * @since   Nautica Workflow 1.0
 */
public class ResourceInternal implements WfResource
{
	/** シリアルバージョンUID */
	private static final long serialVersionUID = 20050000000000001L;

	/** ワークフロー参加者 */
	private Participant participant;

	/**
	 * エンジン内部でのリソースを生成する。
	 *
	 * @param part ワークフロー参加者
	 */
	public ResourceInternal(Participant part)
	{
		this.participant = part;
	}

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

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

	/**
	 * リソースに関連付けられたアサインメントの個数を返す。
	 *
	 * @return 名称
	 * @throws WorkflowException　ワークフロー関連で例外が発生した場合
	 * @see jp.co.argo21.nautica.workflow.omg.WfResource#getWorkItemCount()
	 */
	public int getWorkItemCount() throws WorkflowException
	{
		try {
			String name = participant.getID();
			int type = participant.getType();

			WorkflowDAOFactory daoFactory
				= DataAccessManager.getDAOFactory();
			WorkItemDAO workitemDAO = daoFactory.getWorkItemDAO();

			return workitemDAO.findCountByParticipant(name, type);
		} catch (WorkflowException ex) {
			throw ex;
		} catch (Exception ex) {
			// 作業項目数の取得に失敗しました。
			String E0114 = StringManager.get("E0114");
			throw new WorkflowException(E0114, ex);
		}
	}

	/**
	 * IDで指定されたアサインメントを返す。
	 *
	 * @param wid ID
	 * @return アサインメント
	 * @throws WorkflowException　ワークフロー関連で例外が発生した場合
	 * @see jp.co.argo21.nautica.workflow.omg.WfResource#getWorkItem(java.lang.String)
	 */
	public WfAssignment getWorkItem(String wid) throws WorkflowException
	{
		try {
			WorkflowDAOFactory daoFactory
				= DataAccessManager.getDAOFactory();
			WorkItemDAO workitemDAO = daoFactory.getWorkItemDAO();

			WorkItemBean bean = workitemDAO.findByPrimaryKey(wid);
			if (bean == null) {
				// 作業項目が存在しません。
				String E0115 = StringManager.get("E0115") + "(WorkItemID = " + wid + ")";
				throw new WorkflowException(E0115);
			}
			return new WorkItemInternal(bean);
		} catch (WorkflowException ex) {
			throw ex;
		} catch (Exception ex) {
			// 作業項目の取得に失敗しました。
			String E0116 = StringManager.get("E0116") + "(WorkItemID = " + wid + ")";
			throw new WorkflowException(E0116, ex);
		}
	}

	/**
	 * リソースに関連付けられたすべてのアサインメントを返す。
	 *
	 * @return アサインメントの一覧
	 * @throws WorkflowException　ワークフロー関連で例外が発生した場合
	 * @see jp.co.argo21.nautica.workflow.omg.WfResource#getAllWorkItem()
	 */
	public WfAssignment[] getAllWorkItem() throws WorkflowException
	{
		try {
			String name = participant.getID();
			int type = participant.getType();

			WorkflowDAOFactory daoFactory
				= DataAccessManager.getDAOFactory();
			WorkItemDAO workitemDAO = daoFactory.getWorkItemDAO();

			WorkItemBean[] beans = workitemDAO.findByParticipant(name, type);
			WorkItemInternal[] workitems = new WorkItemInternal[beans.length];
			for (int i = 0; i < beans.length; i++) {
				workitems[i] = new WorkItemInternal(beans[i]);
			}
			return workitems;
		} catch (WorkflowException ex) {
			throw ex;
		} catch (Exception ex) {
			// 全作業項目の取得に失敗しました
			String E0117 = StringManager.get("E0117");
			throw new WorkflowException(E0117, ex);
		}
	}

	/**
	 * 引数で指定されたアサインメントと、関連を持つかどうかを返す。
	 *
	 * @param ass アサインメント
	 * @return 関連を持つ場合はtrue
	 * @throws WorkflowException　ワークフロー関連で例外が発生した場合
	 * @see jp.co.argo21.nautica.workflow.omg.WfResource#isMemberOfWorkItems(jp.co.argo21.nautica.workflow.omg.WfAssignment)
	 */
	public boolean isMemberOfWorkItems(WfAssignment ass)
			throws WorkflowException
	{
		try {
			if (ass == null || ass instanceof WorkItem == false) {
				// 作業項目が未設定です。
				String E0118 = StringManager.get("E0118");
				throw new WorkflowException(E0118);
			}
			WfResource rsc = ass.getAssignee();
			if (rsc == null || rsc instanceof Participant == false) {
				// ワークフロー参加者が未設定です。
				String E0119 = StringManager.get("E0119");
				throw new WorkflowException(E0119);
			}
			Participant part = (Participant)rsc;
			if (part.getType() == participant.getType()
					&& part.getID().equals(participant.getID())) {
				return true;
			} else {
				return false;
			}
		} catch (WorkflowException ex) {
			throw ex;
		} catch (Exception ex) {
			// 作業項目の判定に失敗しました。
			String E0120 = StringManager.get("E0120");
			throw new WorkflowException(E0120, ex);
		}
	}

	/**
	 * 引数に指定したアサインメントにとって、
	 * リソースが不要になったことを通知するリスナーインタフェース。
	 * 引数として、もうリソースに関連付けられていないアサインメントと、
	 * リソースを解放する理由をとる。
	 * このインタフェースは、アサインメントが削除された場合や、
	 * アサインメントが他のリソースへ再割り当てされた場合に
	 * 内部的に呼び出されることを想定している。
	 *
	 * @param ass アサインメント
	 * @param info 開放する理由
	 * @throws NotAssignedException アサインメントが関連していない場合
	 * @throws WorkflowException　ワークフロー関連で例外が発生した場合
	 * @see jp.co.argo21.nautica.workflow.omg.WfResource#release(jp.co.argo21.nautica.workflow.omg.WfAssignment, java.lang.String)
	 */
	public void release(WfAssignment ass, String info)
			throws NotAssignedException, WorkflowException
	{
		try {
			if (isMemberOfWorkItems(ass)) {
				WorkItemInternal workitem = (WorkItemInternal)ass;
				WorkItem bean = workitem.getWorkItem();

				WorkflowDAOFactory daoFactory
					= DataAccessManager.getDAOFactory();
				WorkItemDAO workitemDAO = daoFactory.getWorkItemDAO();

				workitemDAO.updateParticipant(bean.getID(), participant, null);
			} else {
				// 関連する作業項目ではありません。
				String E0121 = StringManager.get("E0121");
				throw new WorkflowException(E0121);
			}
		} catch (WorkflowException ex) {
			throw ex;
		} catch (Exception ex) {
			// 作業項目の解放に失敗しました。
			String E0122 = StringManager.get("E0122");
			throw new WorkflowException(E0122, ex);
		}
	}

	/**
	 * 保持しているワークフロー参加者を返す。
	 *
	 * @return ワークフロー参加者
	 */
	Participant getParticipant()
	{
		return participant;
	}
}
