/*
 * @(#)AssertionServiceWrapper.java
 *
 * Copyright 2006 Sony Corporation
 */
package info.dragonlady.cluster;

import info.dragonlady.sso.AssertionManager;
import info.dragonlady.sso.helper.SSOServletConfig;
import info.dragonlady.sso.message.SSOMessageResource;

import java.rmi.ConnectException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.util.Map;

import org.opensaml.SAMLAssertion;

/**
 * アサーション操作用サービスラッパークラス。
 * 
 * @author Hiroshi.Ebata(INFOCITY)
 * @version $Revision: 1.5 $ $Date: 2006/09/26 08:16:04 $
 */
public class AssertionServiceWrapper {

	/**
	 * コンストラクタ。
	 */
	public AssertionServiceWrapper() {
		super();
	}

	/**
	 * ローカルサーバ及びクラスタリングサーバのアサーション情報を設定。
	 * 
	 * @param id アサーション管理ID
	 * @param assertion アサーション
	 * @throws AssertionServiceException
	 */
	public static final void put(String id, SAMLAssertion assertion) throws AssertionServiceException {
		try {
			Friend[] friends = SSOServletConfig.getFriends();
			for(int i = 0; i < friends.length; i++) {
				String[] args = {friends[i].getHost(), friends[i].getPort()};
				try {
					// リモートサーバに情報設定
					String name = SSOServletConfig.getServiceName(args[0], args[1], AssertionService.SERVICE_NAME);
					AssertionService service = (AssertionService)Naming.lookup(name);
					// ハンドル文字列取得
					String handleStr = (String)AssertionManager.getInstance().getHandleMap().get(id);
					// SAMLAssertionはSerializeされていない為、Stringで送る
					service.put(id, handleStr, assertion.toString());
				} catch(ConnectException e) {
					// 失敗したホスト名とポート番号をログ出力
					String message = SSOMessageResource.getMessage("", args);
					System.out.println(message);
					e.printStackTrace();
				} catch(NotBoundException e) {
					// 失敗したホスト名とポート番号をログ出力
					String message = SSOMessageResource.getMessage("", args);
					System.out.println(message);
					e.printStackTrace();
				} catch(Exception e) {
					// 失敗したホスト名とポート番号をログ出力
					String message = SSOMessageResource.getMessage("", args);
					System.out.println(message);
					e.printStackTrace();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			String message = SSOMessageResource.getMessage("");
			throw new AssertionServiceException(message, e);
		}
	}

	/**
	 * ローカルサーバ及びクラスタリングサーバのアサーション情報から指定ユーザコードの情報を削除。
	 * 
	 * @param id アサーション管理ID
	 * @throws AssertionServiceException
	 */
	public static final void remove(String id) throws AssertionServiceException {
		try {
			Friend[] friends = SSOServletConfig.getFriends();
			for(int i = 0; i < friends.length; i++) {
				String[] args = {friends[i].getHost(), friends[i].getPort()};
				try {
					// リモートサーバから情報削除
					String name = SSOServletConfig.getServiceName(args[0], args[1], AssertionService.SERVICE_NAME);
					AssertionService service = (AssertionService)Naming.lookup(name);
					service.removeById(id);
				} catch(ConnectException e) {
					// 失敗したホスト名とポート番号をログ出力
					String message = SSOMessageResource.getMessage("", args);
					System.out.println(message);
					e.printStackTrace();
				} catch(NotBoundException e) {
					// 失敗したホスト名とポート番号をログ出力
					String message = SSOMessageResource.getMessage("", args);
					System.out.println(message);
					e.printStackTrace();
				} catch(Exception e) {
					// 失敗したホスト名とポート番号をログ出力
					String message = SSOMessageResource.getMessage("", args);
					System.out.println(message);
					e.printStackTrace();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			String message = SSOMessageResource.getMessage("");
			throw new AssertionServiceException(message, e);
		}
	}

	/**
	 * ローカルサーバのアサーション情報をクラスタリングサーバのアサーション情報と同期化。
	 * 
	 * @throws AssertionServiceException
	 */
	public static final void synchronize() throws AssertionServiceException {
		try {
			Friend[] friends = SSOServletConfig.getFriends();
			for(int i = 0; i < friends.length; i++) {
				String[] args = {friends[i].getHost(), friends[i].getPort()};
				try {
					// リモートサーバから情報取得
					String name = SSOServletConfig.getServiceName(args[0], args[1], AssertionService.SERVICE_NAME);
					AssertionService service = (AssertionService)Naming.lookup(name);
					Map handleMap = service.getHandleMap();
					Map assertionMap = service.getAssertionMap();
					if(handleMap != null && assertionMap != null) {
						// ローカルサーバに情報を設定
						AssertionManager.getInstance().setHandleMap(handleMap);
						AssertionManager.getInstance().setAssertionMap(assertionMap);
						break;
					}
				} catch(ConnectException e) {
					// 失敗したホスト名とポート番号をログ出力
					String message = SSOMessageResource.getMessage("", args);
					System.out.println(message);
					e.printStackTrace();
				} catch(NotBoundException e) {
					// 失敗したホスト名とポート番号をログ出力
					String message = SSOMessageResource.getMessage("", args);
					System.out.println(message);
					e.printStackTrace();
				} catch(Exception e) {
					// 失敗したホスト名とポート番号をログ出力
					String message = SSOMessageResource.getMessage("", args);
					System.out.println(message);
					e.printStackTrace();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			String message = SSOMessageResource.getMessage("");
			throw new AssertionServiceException(message, e);
		}
	}

}
