/* $Id: WorkItemInternal.java,v 1.2 2007/12/06 07:47:15 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.dataaccess.ActivityBean;
import jp.co.argo21.nautica.workflow.dataaccess.ActivityDAO;
import jp.co.argo21.nautica.workflow.dataaccess.WorkItemDAO;
import jp.co.argo21.nautica.workflow.dataaccess.WorkflowDAOFactory;
import jp.co.argo21.nautica.workflow.omg.InvalidResourceException;
import jp.co.argo21.nautica.workflow.omg.WfActivity;
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.security.OrganizationManager;
import jp.co.argo21.nautica.workflow.security.RoleManager;
import jp.co.argo21.nautica.workflow.security.UserManager;
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インタフェースとの整合性のために提供する。
 *
 * @author  nito(Argo 21, Corp.)
 * @version $Revision: 1.2 $
 * @since   Nautica Workflow 1.0
 */
public class WorkItemInternal implements WfAssignment
{
	/** シリアルバージョンUID */
	private static final long serialVersionUID = 20050000000000001L;

	/** エンジンログ */
	@SuppressWarnings("unused")
	private static Logger eLog = LogManager.getEngineLogger();
	
	/** 作業項目 */
	private WorkItem workItem;
	
	/**
	 * エンジン内部で管理される作業項目オブジェクトを生成する。
	 *
	 * @param item 作業項目
	 */
	public WorkItemInternal(WorkItem item)
	{
		this.workItem = item;
	}

	/**
	 * リソースを割り当てるアクティビティを返す。
	 *
	 * @return WfActivity
	 * @throws WorkflowException　ワークフロー関連で例外が発生した場合
	 * @see jp.co.argo21.nautica.workflow.omg.WfAssignment#getActivity()
	 */
	public WfActivity getActivity() throws WorkflowException
	{
		try {
			String pid = workItem.getProcessID();
			String aid = workItem.getActivityID();
			WorkflowDAOFactory daoFactory
				= DataAccessManager.getDAOFactory();
			ActivityDAO activityDAO = daoFactory.getActivityDAO();
		
			ActivityBean bean = activityDAO.findByPrimaryKey(pid, aid);
			WfActivity act = new ActivityInternal(bean);
			return act;
		} catch (WorkflowException ex) {
			throw ex;
		} catch (Exception ex) {
			// アクティビティの取得に失敗しました。
			String E0124 = StringManager.get("E0124");
			throw new WorkflowException(E0124, ex);
		}
	}

	/**
	 * 割り当てられたリソースを返す。
	 *
	 * @return WfResource
	 * @throws WorkflowException　ワークフロー関連で例外が発生した場合
	 * @see jp.co.argo21.nautica.workflow.omg.WfAssignment#getAssignee()
	 */
	public WfResource getAssignee() throws WorkflowException
	{
		try {
			Participant part = null;
			int ptype = workItem.getParticipantType();
			String pname = workItem.getParticipantName();
			ResourceManagerFactory rmf = ResourceManagerFactory.getInstance();
			if (ptype == Participant.HUMAN || ptype == Participant.SYSTEM) {
				UserManager um = rmf.getUserManager();
				part = um.getUser(pname);
			} else if (ptype == Participant.ORGANIZATIONAL_UNIT) {
				OrganizationManager om = rmf.getOrganizationManager();
				part = om.getOrganization(pname);
			} else if (ptype == Participant.ROLE) {
				RoleManager rm = rmf.getRoleManager();
				part = rm.getRole(pname);
			} else {
				// ユーザとして不適切なワークフロー参加者です。
				String E0143 = StringManager.get("E0143");
				throw new WorkflowException(E0143);
			}
			if (part == null) {
				// ワークフロー参加者が存在しません。
				String E0145 = StringManager.get("E0145");
				throw new WorkflowException(E0145);
			}
			WfResource ret = new ResourceInternal(part);
			return ret;
		} catch (WorkflowException ex) {
			throw ex;
		} catch (Exception ex) {
			// ワークフロー参加者の取得に失敗しました。
			String E0141 = StringManager.get("E0141");
			throw new WorkflowException(E0141, ex);
		}
	}

	/**
	 * 指定されたリソースを設定する。
	 *
	 * @param value WfResource
	 * @throws InvalidResourceException 無効なリソースの場合
	 * @throws WorkflowException　ワークフロー関連で例外が発生した場合
	 * @see jp.co.argo21.nautica.workflow.omg.WfAssignment#setAssignee(jp.co.argo21.nautica.workflow.omg.WfResource)
	 */
	public void setAssignee(WfResource value)
	throws InvalidResourceException, WorkflowException
	{
		try {
			if (value == null || value instanceof ResourceInternal == false) {
				// 適切なリソースではありません。
				String E0144 = StringManager.get("E0144");
				throw new InvalidResourceException(E0144);
			}
			ResourceInternal rsc = (ResourceInternal)value;
			Participant part = rsc.getParticipant();
			if (part == null) {
				// ワークフロー参加者が存在しません。
				String E0145 = StringManager.get("E0145");
				throw new InvalidResourceException(E0145);
			}
			int sparttype = workItem.getParticipantType();
			String spartid = workItem.getParticipantName();
			Participant src = new ParticipantImpl(spartid, "", sparttype);
			WorkflowDAOFactory daoFactory
				= DataAccessManager.getDAOFactory();
			WorkItemDAO workItemDAO = daoFactory.getWorkItemDAO();
			workItemDAO.updateParticipant(workItem.getID(), src, part);
		} catch (WorkflowException ex) {
			throw ex;
		} catch (Exception ex) {
			// ワークフロー参加者の設定に失敗しました。
			String E0142 = StringManager.get("E0142");
			throw new WorkflowException(E0142, ex);
		}
	}
	
	/**
	 * 保持している作業項目を返す。
	 *
	 * @return 作業項目
	 */
	WorkItem getWorkItem()
	{
		return workItem;
	}
}
