/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：物流管理システム
*   モジュール名    ：JDKStructuredMap
*   ソースファイル名：JDKStructuredMap.java
*   作成者          ：富士通
*   日付            ：2012年04月16日
*＜機能概要＞
*   階層構造のマップです。
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v3.00.00    2012/04/16   下原        ANK-0316-00-00
*
**********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 階層構造のマップです。
 * @author 909139
 */
public class JDKStructuredMap <K, V> {
	/** 新規キーかどうか */
	private boolean isNew = true;
	/** 内包する値 */
	private V val;
	/** 内包する下位構造 */
	private Map<K, JDKStructuredMap<K, V>> rep = new HashMap<K, JDKStructuredMap<K,V>>();
	
	/**
	 * キーに対応する値を取得します。
	 * @param k キー
	 * @return あたい
	 */
	public JDKStructuredMap<K, V> get(K...k)
	{
		if (k.length == 0)
		{
			return this;
		}
		JDKStructuredMap<K, V> child = rep.get(k[0]);
		if (child == null)
		{
			child = new JDKStructuredMap<K, V>();
			rep.put(k[0], child);
		}
		
		if (k.length == 1)
		{
			return child;
		}
		
		List<K> ks = new ArrayList<K>();
		for (int i = 1;i < k.length;i++)
		{
			ks.add(k[i]);
		}
		@SuppressWarnings("unchecked")
		K [] chompedK = (K[])ks.toArray();
		return child.get(chompedK);
	}
	
	/**
	 * 値を設定します。
	 * @param v 設定値
	 */
	public void put(V v)
	{
		this.val = v;
		this.isNew = false;
	}
	
	/**
	 * 値を取得します。
	 * @return 値
	 */
	public V value() 
	{
		return this.val;
	}
	
	/**
	 * 下位構造の値を取得します
	 * @param k キー
	 * @return
	 */
	public V getValue(K...k)
	{
		return get(k).value();
	}
	
	/**
	 * 下位構造に値を設定します。
	 * @param v キー
	 * @param k 値
	 */
	public void setValue(V v, K...k)
	{
		get(k).put(v);
	}
	
	/**
	 * 新規データかどうかを判断します。
	 * @return 新規か否か
	 */
	public boolean isNew()
	{
		return this.isNew;
	}
}
