Mercurial > hg > Members > shoshi > TreeCMSv2
view src/treecms/tree/util/NodeChildrenImpl.java @ 22:fa784faafc78
commit
author | shoshi |
---|---|
date | Tue, 07 Jun 2011 16:42:49 +0900 |
parents | f3150b37f9be |
children | 77a894c0b919 |
line wrap: on
line source
package treecms.tree.util; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CopyOnWriteArrayList; import treecms.api.NodeAttributes; import treecms.api.NodeChildren; import treecms.api.NodeContext; import treecms.api.NodeID; public class NodeChildrenImpl<T extends NodeContext & NodeAttributes & NodeChildren<T>> implements NodeChildren<T> { private final ConcurrentMap<String,T> m_map; private final List<T> m_list; private final List<T> m_readOnlyList; public NodeChildrenImpl() { m_map = new ConcurrentHashMap<String,T>(); m_list = new CopyOnWriteArrayList<T>(); m_readOnlyList = Collections.unmodifiableList(m_list); } public NodeChildrenImpl(T... _args) { this(); for(T i : _args){ String fid = i.getID().getFamilyID(); if(!m_map.containsKey(fid)){ m_map.put(fid,i); m_list.add(i); } } } public NodeChildrenImpl(NodeChildren<T> _list) { this(); if(_list != null){ addAll(_list); }else{ throw new NullPointerException("_list is null"); } } @Override public synchronized List<T> getList() { return m_readOnlyList; } @Override public T create(NodeAttributes _attr) { throw new UnsupportedOperationException(); } public synchronized T replace(T _node) { String fid = _node.getID().getFamilyID(); T old = m_map.get(fid); if(old != null){ m_map.put(fid,_node); //find index of _node , better put index with node in the map? int size = m_list.size(); for(int i = 0;i < size;i ++){ T n = m_list.get(i); NodeID nid = n.getID(); if(nid.isFamily(nid)){ m_list.set(i,_node); return old; } } throw new IllegalStateException("FamilyID is found on the map but not found on the list"); } return null; } public synchronized boolean add(T _n) { if(!m_map.containsKey(_n.getID().getFamilyID())){ m_map.put(_n.getID().getFamilyID(),_n); return m_list.add(_n); } return false; } public synchronized boolean addAll(NodeChildren<T> _list) { if(_list == this){ return false; } if(Collections.disjoint(getFamilyIDSet(),_list.getFamilyIDSet())){ HashMap<String,T> map = new HashMap<String,T>(); for(T item : _list.getList()){ NodeID id = item.getID(); map.put(id.getFamilyID(),item); } return m_list.addAll(_list.getList()); } return false; } @Override public synchronized T get(int _index) { return m_list.get(_index); } @Override public synchronized T get(String _familyID) { return m_map.get(_familyID); } @Override public synchronized T remove(int _index) { T n = m_list.remove(_index); NodeID id = n.getID(); if(m_map.remove(id.getFamilyID()) != null){ return n; } throw new IllegalStateException(""); } @Override public synchronized boolean contains(NodeID _id) { T n = m_map.get(_id); NodeID id = n.getID(); return id.equals(_id); } @Override public synchronized void clearChildren() { m_map.clear(); m_list.clear(); } @SuppressWarnings("unchecked") @Override public synchronized boolean equals(Object _o) { NodeChildrenImpl<T> list = (NodeChildrenImpl<T>)_o; return m_list.equals(list.m_list); } @Override public synchronized int hashCode() { int result = 17; result = 37*result + m_list.hashCode(); result = 37*result + m_map.hashCode(); return result; } @Override public synchronized Set<String> getFamilyIDSet() { return m_map.keySet(); } @Override public synchronized T remove(String _fid) { return m_map.remove(_fid); } @Override public synchronized boolean swap(String _fid1, String _fid2) { if(m_map.containsKey(_fid1) && m_map.containsKey(_fid2)){ int index1,index2; index1 = index2 = -1; int size = m_list.size(); for(int i = 0;i < size;i ++){ T n = m_list.get(i); String fid = n.getID().getFamilyID(); if(fid.equals(_fid1)){ index1 = i; }else if(fid.equals(_fid2)){ index2 = i; } if(index1 != -1 && index2 != -1){ Collections.swap(m_list, index1, index2); return true; } } } return false; } }