Mercurial > hg > Members > shoshi > TreeCMSv2
view src/treecms/tree/util/NodeChildrenImpl.java @ 26:9cb971a68cc5
added CachedForest.java
author | Shoshi TAMAKI <shoshi@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 18 Jul 2011 20:22:53 +0900 |
parents | c1e7ec6b3d44 |
children |
line wrap: on
line source
package treecms.tree.util; import java.util.Collections; import java.util.List; 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(_node.getID())){ 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())){ for(T item : _list.getList()){ NodeID id = item.getID(); m_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.getFamilyID()); if(n == null){ return false; } NodeID id = n.getID(); String fid1 = id.getFamilyID(); String fid2 = _id.getFamilyID(); return fid1.equals(fid2); } @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; } @Override public String toString() { return m_list.toString(); } }