/*
 * @(#)AssertionParser.java
 *
 * Copyright (C) 2006 Infocity Inc. All Rights Reserved.
 */
package info.dragonlady.sso.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;


import org.opensaml.SAMLAction;
import org.opensaml.SAMLAssertion;
import org.opensaml.SAMLAttribute;
import org.opensaml.SAMLAttributeStatement;
import org.opensaml.SAMLAuthenticationStatement;
import org.opensaml.SAMLAuthorizationDecisionStatement;
import org.opensaml.SAMLDecision;

/**
 * アサーション解析クラス。
 * 
 * @author Hiroshi.Ebata(INFOCITY)
 * @version $Revision: 1.0 $ $Date: 2006/12/01 12:59:24 $
 */
public class AssertionParser {

	private SAMLAssertion assertion = null;

	private SAMLAuthenticationStatement authStatement = null;

	private SAMLAttributeStatement attrStatement = null;

	private SAMLAuthorizationDecisionStatement decisionStatement = null;

	/**
	 * コンストラクタ。
	 * 
	 * @param assertion アサーション
	 */
	public AssertionParser(SAMLAssertion assertion) {
		if(assertion != null) {
			this.assertion = assertion;
			extractStatement(assertion);
		}
	}

	private void extractStatement(SAMLAssertion assertion) {
		Iterator itr = assertion.getStatements();
		while(itr.hasNext()) {
			Object statement = itr.next();
			if(statement instanceof SAMLAuthenticationStatement) {
				authStatement = (SAMLAuthenticationStatement)statement;
			} else if(statement instanceof SAMLAttributeStatement) {
				attrStatement = (SAMLAttributeStatement)statement;
			} else if(statement instanceof SAMLAuthorizationDecisionStatement) {
				decisionStatement = (SAMLAuthorizationDecisionStatement)statement;
			}
		}
	}

	/**
	 * 認証ID取得。
	 * 
	 * @return String 認証ID
	 */
	public String getName() {
		String name = null;
		if(authStatement != null) {
			name = authStatement.getSubject().getNameIdentifier().getName();
		} else if(attrStatement != null) {
			name = attrStatement.getSubject().getNameIdentifier().getName();
		} else if(decisionStatement != null) {
			name = decisionStatement.getSubject().getNameIdentifier().getName();
		}
		return name;
	}

	/**
	 * 属性取得。
	 * 
	 * @return Map<String, List<String>> 属性
	 */
	public Map<String, List<String>> getAttribute() {
		Map<String, List<String>> attributes = null;
		if(attrStatement != null) {
			attributes = new HashMap<String, List<String>>();
			Iterator<SAMLAttribute> itr = attrStatement.getAttributes();
			while(itr.hasNext()) {
				SAMLAttribute attribute = itr.next();
				String name = attribute.getName();
				List<String> value = new ArrayList<String>();
				Iterator<String> valItr = attribute.getValues();
				while(valItr.hasNext()) {
					value.add(valItr.next());
				}
				attributes.put(name, value);
			}
		}
		return attributes;
	}

	/**
	 * リソースへのアクセスが許可されているかどうか。
	 * 
	 * @return boolean true：許可されている／false：許可されていない
	 */
	public boolean isPermitted() {
		return decisionStatement != null ? decisionStatement.getDecision().equals(SAMLDecision.PERMIT) : false;
	}

	/**
	 * 許可されているアクションを取得。
	 * 
	 * @return Iterator<SAMLAction> 許可されているアクション
	 */
	public Iterator<SAMLAction> getPermittedActions() {
		return decisionStatement != null ? decisionStatement.getActions() : null;
	}

	/**
	 * リソースへのパスを取得。
	 * 
	 * @return String リソースパス
	 */
	public String getResource() {
		return decisionStatement != null ? decisionStatement.getResource() : null;
	}

	/**
	 * アサーションに認証ステートメントが含まれているかどうか。
	 * 
	 * @return boolean true：含まれている／false：含まれていない
	 */
	public boolean containsAuthenticationStatement() {
		return authStatement != null;
	}

	/**
	 * アサーションに属性ステートメントが含まれているかどうか。
	 * 
	 * @return boolean true：含まれている／false：含まれていない
	 */
	public boolean containsAttributeStatement() {
		return attrStatement != null;
	}

	/**
	 * アサーションに認可決定ステートメントが含まれているかどうか。
	 * 
	 * @return boolean true：含まれている／false：含まれていない
	 */
	public boolean containsDecisionStatement() {
		return decisionStatement != null;
	}

	/**
	 * 属性ステートメントを取得。
	 * 
	 * @return SAMLAttributeStatement 属性ステートメント
	 */
	public SAMLAttributeStatement getAttributeStatement() {
		return attrStatement;
	}

	/**
	 * 認証ステートメントを取得。
	 * 
	 * @return SAMLAuthenticationStatement 認証ステートメント
	 */
	public SAMLAuthenticationStatement getAuthenticationStatement() {
		return authStatement;
	}

	/**
	 * 認可決定ステートメントを取得。
	 * 
	 * @return SAMLAuthorizationDecisionStatement
	 */
	public SAMLAuthorizationDecisionStatement getDecisionStatement() {
		return decisionStatement;
	}

}
