package org.phosphoresce.commons.ldaps;

import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttributes;

/**
 * LDAPオブジェクトエントリクラス<br>
 *
 * @author Kitagawa<br>
 *
 *<!--
 * 更新日		更新者			更新内容
 * 2008/11/27	Kitagawa		新規作成
 *-->
 */
public class LDAPEntry implements Serializable {

	/** エントリデータ */
	private Map data;

	/** 大文字小文字無視フラグ */
	private boolean ignoreCase;

	/**
	 * コンストラクタ<br>
	 */
	public LDAPEntry() {
		super();
		this.data = new LinkedHashMap();
		this.ignoreCase = false;
	}

	/**
	 * 指定された属性集合オブジェクトからこのクラスの情報に変換して提供します。<br>
	 * @param attributes 属性集合オブジェクト
	 * @return LDAPオブジェクトエントリクラスインスタンス
	 * @throws NamingException LDAP属性集合オブジェクトからの情報取得を正常に行えなかった場合に発生
	 */
	public static LDAPEntry createEntry(Attributes attributes) throws NamingException {
		LDAPEntry entry = new LDAPEntry();
		entry.ignoreCase = attributes.isCaseIgnored();
		NamingEnumeration enumeration = attributes.getAll();
		while (enumeration.hasMore()) {
			Attribute attribute = (Attribute) enumeration.next();
			LDAPAttribute ldapAttribute = LDAPAttribute.createAttribute(attribute);
			entry.addAttribute(ldapAttribute);
		}
		return entry;
	}

	/**
	 * クラスの情報から属性集合オブジェクトを新規に生成します。<br>
	 * @return 属性集合オブジェクト
	 */
	public BasicAttributes createBasicAttributes() {
		BasicAttributes attributes = new BasicAttributes();
		for (Iterator iterator = data.keySet().iterator(); iterator.hasNext();) {
			String name = (String) iterator.next();
			LDAPAttribute attribute = (LDAPAttribute) data.get(name);
			attributes.put(attribute.createBasicAttribute());
		}
		return attributes;
	}

	/**
	 * 大文字小文字無視フラグを取得します。<br>
	 * @return 大文字小文字無視フラグ
	 */
	public boolean isIgnoreCase() {
		return ignoreCase;
	}

	/**
	 * 大文字小文字無視フラグを設定します。<br>
	 * @param ignoreCase 大文字小文字無視フラグ
	 */
	public void setIgnoreCase(boolean ignoreCase) {
		this.ignoreCase = ignoreCase;
	}

	/**
	 * 指定した属性名で属性が保持されているか判定します。<br>
	 * @param name 属性名
	 * @return 属性オブジェクト
	 */
	public boolean containsAttribute(String name) {
		return data.containsKey(name);
	}

	/**
	 * 指定された属性名で属性を追加します。<br>
	 * @param attribute 属性オブジェクト
	 */
	public void addAttribute(LDAPAttribute attribute) {
		String name = attribute.getName();
		for (Iterator iterator = attribute.getValues().iterator(); iterator.hasNext();) {
			Object value = iterator.next();
			addAttribute(name, value);
		}
	}

	/**
	 * 指定された属性名で属性を追加します。<br>
	 * @param name 属性名
	 * @param value 属性値
	 */
	public void addAttribute(String name, Object value) {
		if (!containsAttribute(name)) {
			LDAPAttribute attribute = new LDAPAttribute(name);
			attribute.addValue(value);
			data.put(name, attribute);
		} else {
			LDAPAttribute attribute = getAttribute(name);
			attribute.addValue(value);
		}
	}

	/**
	 * 指定された属性名で保持されている属性を取得します。<br>
	 * @param name 属性名
	 * @return 属性オブジェクト
	 */
	public LDAPAttribute getAttribute(String name) {
		return (LDAPAttribute) data.get(name);
	}

	/**
	 * 保持されている属性オブジェクトを全て取得します。<br>
	 * @return 属性オブジェクト配列
	 */
	public LDAPAttribute[] getAttributes() {
		Collection collection = data.values();
		return (LDAPAttribute[]) collection.toArray(new LDAPAttribute[collection.size()]);
	}

	/**
	 * オブジェクトの文字列表現を返します。<br>
	 * @return オブジェクトの文字列表現
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		StringBuffer buffer = new StringBuffer();
		buffer.append(data);
		return buffer.toString();
	}
}

