/* $Id: WorkItemPool.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 java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import jp.co.argo21.nautica.workflow.security.Organization;
import jp.co.argo21.nautica.workflow.security.OrganizationManager;
import jp.co.argo21.nautica.workflow.security.Role;
import jp.co.argo21.nautica.workflow.security.RoleManager;
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.InvalidSessionException;
import jp.co.argo21.nautica.workflow.wfmc.Participant;

import org.apache.log4j.Logger;

/**
 * 作業項目プール。
 *
 * @author  nito(Argo 21, Corp.)
 * @version $Revision: 1.2 $
 * @since   Nautica Workflow 1.0
 */
public class WorkItemPool
{
	/** エンジンログ */
	private static Logger eLog = LogManager.getEngineLogger();
	
	/** WorkItemPoolのシングルトン */
	private static WorkItemPool singleton;

	/** 作業項目コンテナ用ハッシュテーブル */
	private Map<String, WorkItemContainer> containers = new Hashtable<String, WorkItemContainer>();
	
	/**
	 * WorkItemPoolの生成と初期化を行う。
	 *
	 * @throws Exception 任意の例外
	 */
	static void create() throws Exception
	{
		try {
			singleton = new WorkItemPool();
			singleton.init();
		} catch (Exception ex) {
			// 作業項目プールの初期化に失敗しました。
			String E0113 = StringManager.get("E0113");
			eLog.error(E0113);
			throw ex;
		}
	}

	/**
	 * WorkItemPoolのインスタンスを返す。
	 *
	 * @return WorkItemPool
	 */
	static WorkItemPool getInstance()
	{
		return singleton;
	}
	
	/**
	 * WorkItemPoolを生成する。
	 */
	private WorkItemPool()
	{
	}
	
	/**
	 * WorkItemPoolを初期化する。
	 *
	 * @throws Exception 任意の例外
	 */
	private void init() throws Exception
	{
	}

	/**
	 * 作業項目コンテナを返す。
	 *
	 * @return 作業項目コンテナ
	 */
	WorkItemContainer getWorkItemContainer(String session)
	throws InvalidSessionException
	{
		try {
			SessionManagerFactory smf = SessionManagerFactory.getInstance();
			SessionManager sm = smf.getSessionManager();
			User user = sm.getSessionUser(session);
			String uid = user.getID();

			WorkItemContainer container = (WorkItemContainer)containers.get(uid);

			//既存のコンテナがなければ作成する。
			if (container == null || container.isExpired()) {
				Participant userResource;
				List<Participant> orgResources = new ArrayList<Participant>();
				List<Participant> roleResources = new ArrayList<Participant>();

				userResource = user;

				ResourceManagerFactory rmf = ResourceManagerFactory.getInstance();
				
				//ユーザが所属する組織リソースを取得
				OrganizationManager om = rmf.getOrganizationManager();
				Organization[] orgs = om.getOrganizationByUser(user);
				for (int i = 0; i < orgs.length; i++) {
					orgResources.add(orgs[i]);
				}

				//ユーザが持っている権限リソースを取得
				RoleManager rm = rmf.getRoleManager();
				Role[] userRoles = rm.getAttachedRoles(user);
				for (int i = 0; i < userRoles.length; i++) {
					roleResources.add(userRoles[i]);
				}

				//管理下にユーザ用のコンテナを追加する
				container = new WorkItemContainer(userResource, orgResources, roleResources);
				containers.put(uid, container);
			}
			return container;
		} catch (InvalidSessionException ex) {
			throw ex;
		} catch (Exception ex) {
			// 作業項目コンテナの取得に失敗しました。
			String E0161 = StringManager.get("E0161");
			throw new InvalidSessionException(E0161, ex);
		}
	}
}
