view src/treecms/proto/simple/SimpleEditor.java @ 29:174bc0d21712

modified SimpleEditor.merge .commit
author ShoshiTAMAKI
date Tue, 09 Nov 2010 18:13:54 +0900
parents 64359341c04a
children 02ef906d0341
line wrap: on
line source

package treecms.proto.simple;

import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.LinkedList;
import treecms.proto.api.Editor;
import treecms.proto.api.Node;

public class SimpleEditor implements Editor
{
	private AtomicReference<Node> m_contents;
	private Node m_tip,m_modified;
	
	private LinkedList<Node> m_log;
	
	public SimpleEditor(AtomicReference<Node> _contents)
	{
		m_contents = _contents;
		m_tip = m_contents.get();
		m_modified = null;
		m_log = new LinkedList<Node>();
	}
	
	public boolean checkUpdate()
	{
		return m_contents.equals(m_modified);
	}
	
	public boolean commit(boolean _force)
	{
		if(_force){
			m_contents.set(m_tip);
			update();
			return true;
		}
		return m_contents.compareAndSet(m_modified,m_tip);
	}
	
	public void merge()
	{
		LinkedList<Node> log = new LinkedList<Node>(m_log);
		update();
		for(Node node : log){
			edit(node);
		}
	}
	
	public void discard()
	{
		m_modified = null;
		m_log.clear();
	}

	@Override
	public Node useContents()
	{
		// TODO Auto-generated method stub
		return m_contents.get();
	}

	@Override
	public void login(String user, String pass)
	{
		// TODO Auto-generated method stub
	}

	@Override
	public void logout()
	{
		// TODO Auto-generated method stub
	}

	@Override
	public Node edit(Node _target)
	{
		// TODO Auto-generated method stub
		LinkedList<Node> path = findPath(m_tip,_target);
		if(path.isEmpty()){
			return null;
		}
		
		LinkedList<Node> change = new LinkedList<Node>();
		Node root = path.poll().cloneNode();
		change.add(root);
		cloneTree(path,root,change);
		
		if(m_modified == null){
			m_modified = m_tip;
		}
		m_tip = root;
		m_log.add(change.peekLast());
		return change.peekLast();
	}
	
	private void cloneTree(LinkedList<Node> _path,Node _parent,LinkedList<Node> _change)
	{
		List<Node> children = _parent.getChildren();
		Node target = _path.poll();
		if(target == null){
			return;
		}
		for(int i = 0;i < children.size();i ++){
			Node _child = children.get(i);
			if(_child.getID().compare(target.getID()) != -2){
				//clone node
				Node clone = _child.cloneNode();
				_change.add(clone);
				
				//remove old node from clonedTree
				_parent.addChild(clone);
				_parent.removeChild(_child);
				
				cloneTree(_path,clone,_change);
				break;
			}
		}
	}
	
	private LinkedList<Node> findPath(Node _root,Node _child)
	{
		LinkedList<Node> list = new LinkedList<Node>();
		findPath(_root,_child,list);
		list.addFirst(_root);
		return list;
	}
	
	private boolean findPath(Node _root,Node _child,LinkedList<Node> _list)
	{
		if(_root == _child){
			return true;
		}
		
		for(Node child : _root.getChildren()){
			if(findPath(child,_child,_list)){
				_list.addFirst(child);
				return true;
			}
		}
		return false;
	}

	@Override
	public Node getUncommited()
	{
		// TODO Auto-generated method stub
		return this.m_tip;
	}

	@Override
	public boolean update()
	{
		// TODO Auto-generated method stub
		discard();
		m_modified = m_contents.get();
		return false;
	}

	@Override
	public boolean check()
	{
		// TODO Auto-generated method stub
		return m_contents.equals(m_modified);
	}
}