view src/treecms/tree/util/NodeChildrenImpl.java @ 16:bb9760760744

commit
author shoshi
date Sat, 21 May 2011 04:46:00 +0900
parents 22cd920986c5
children 168deb591f21
line wrap: on
line source

package treecms.tree.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.List;
import treecms.api.Node;
import treecms.api.NodeChildren;

/**
 * 子供ノードを格納するため専用のリストです.java.util.List<T>は継承しておりません.
 * 子供ノードのリストには リスト内に同じUUIDを持つNodeが存在 してはいけません.
 * @author shoshi
 */
public class NodeChildrenImpl<T extends Node<T>> implements NodeChildren<T>
{
	private List<T> m_list;
	private Set<String> m_set;
	
	public NodeChildrenImpl()
	{
		m_list = new ArrayList<T>();
		m_set = new HashSet<String>();
	}
	
	public NodeChildrenImpl(NodeChildren<T> _list)
	{
		this();
		
		if(_list != null){
			addAll(_list);
		}
	}
	
	public List<T> getList()
	{
		return Collections.unmodifiableList(m_list);
	}
	
	public Set<String> getUUIDSet()
	{
		return Collections.unmodifiableSet(m_set);
	}
	
	@Override
	public T replace(T _newChild)
	{
		String uuid = _newChild.getID().getUUID();
		int size = m_list.size();
		for(int i = 0;i < size;i ++){
			T n = m_list.get(i);
			if(uuid.equals(n.getID().getUUID())){
				//_newChildと同一なUUIDを見つけた
				return m_list.set(i,_newChild);
			}
		}
		//見つからなかった
		return null;
	}
	
	/**
	 * このリストに新しく子供を追加します.
	 * @param _n
	 * @return 追加に成功した場合true
	 */
	public boolean add(T _n)
	{
		if(m_set.contains(_n.getID().getUUID())){
			return false;
		}
		
		m_set.add(_n.getID().getUUID());
		m_list.add(_n);
		return true;
	}
	
	/**
	 * _listに含まれている子供がすべてこのリストに含まれない場合にのみ、要素をすべて追加します。
	 * @param _list
	 * @return 追加に成功した場合true
	 */
	public boolean addAll(NodeChildren<T> _list)
	{
		if(Collections.disjoint(m_set,_list.getUUIDSet())){
			//共通要素がない
			m_set.addAll(_list.getUUIDSet());
			m_list.addAll(_list.getList());
		}
		return false;
	}
	
	/**
	 * 指定されたNodeID
	 * @param _id
	 * @return 子供ノード
	 */
	public T get(String _uuid)
	{
		for(T n : m_list){
			String uuid = n.getID().getUUID();
			if(uuid.equals(_uuid)){
				return n;
			}
		}
		
		return null;
	}
	
	/**
	 * 指定された_indexの場所に位置する子供を削除します
	 * @param _index
	 * @return 消される子供ノード
	 */
	public T get(int _index)
	{
		return m_list.get(_index);
	}
	
	/**
	 * 指定されたUUIDを持つ子どもを削除します
	 * @param _id
	 * @return 削除される子供ノード
	 */
	public T remove(String _uuid)
	{
		int size = m_list.size();
		
		for(int i = 0;i < size;i ++){
			String uuid = m_list.get(i).getID().getUUID();
			if(uuid.equals(_uuid)){
				//NodeIDのUUIDが一致した
				return m_list.remove(i);
			}
		}
		
		return null;
	}
	
	/**
	 * 指定された場所の子供ノードを削除します
	 * @param _index
	 * @return 削除された子供ノード
	 */
	public T remove(int _index)
	{
		return m_list.remove(_index);
	}
	
	/**
	 * このリストに指定されたUUIDを持つNodeがあるか確認します
	 * @param _id
	 * @return 存在する場合true
	 */
	public boolean contains(String _uuid)
	{
		return m_set.contains(_uuid);
	}
	
	/**
	 * 指定された二つのUUID(_uuid1,_uuid2)がリスト上に存在する場合、その二つの順番を入れ替えます
	 * @param _uuid1 String
	 * @param _uuid2 String
	 * @return 成功した場合はtrue,NodeIDが見つからなかった場合はfalse
	 */
	public boolean swap(String _uuid1,String _uuid2)
	{
		/*
		 * 二つのNodeIDの位置を求める
		 */
		int index1 = -1;
		int index2 = -1;
		
		int size = m_list.size();
		for(int i = 0;i < size && (index1 == -1 || index2 == 1);i ++){
			String uuid = m_list.get(i).getID().getUUID();
			if(uuid.equals(_uuid1)){
				index1 = i;
				continue;
			}
			
			if(uuid.equals(_uuid2)){
				index2 = i;
				continue;
			}
		}
		
		/*
		 * Collection.swapを使って入れ替える
		 */
		if(index1 != -1 && index2 != -1){
			Collections.swap(m_list,index1,index2);
			return true;
		}
		
		//NodeIDがリスト上になかった
		return false;
	}
	
	/**
	 * 子供ノードのリストをクリアします
	 */
	public void clearChildren()
	{
		m_set.clear();
		m_list.clear();
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public boolean equals(Object _o)
	{
		NodeChildrenImpl<T> list = (NodeChildrenImpl<T>)_o;
		return m_list.equals(list.m_list);
	}
	
	@Override
	public int hashCode()
	{
		int result = 17;
		result = 37*result + m_list.hashCode();
		result = 37*result + m_set.hashCode();
		return result;
	}
	
	public static NodeChildren<? extends Node<?>> hoge(Node<?> hoge)
	{
		return null;
	}
}