view src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/DefaultTreeEditor.java @ 76:2fc0b0313dc0

Move to Bullet in Board but has worning
author one
date Fri, 29 Aug 2014 03:16:27 +0900
parents 240a385bf79d
children 540a27dde42f
line wrap: on
line source

package jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl;

import fj.data.List;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.NodePath;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.TreeEditor;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.NodeEditor;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.traverser.DefaultEvaluator;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.traverser.Direction;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.traverser.Traversal;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.traverser.Traverser;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.DefaultEither;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Either;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Error;

public class DefaultTreeEditor implements TreeEditor
{
	private final Traverser traverser;
	
	public DefaultTreeEditor(Traverser _traverser)
	{
		traverser = _traverser;
	}
	
	@Override
	public <T extends TreeNode<T>> Either<Error,T> edit(T _root,NodePath _path,NodeEditor _editor)
	{
		DefaultEvaluator e = new DefaultEvaluator(_path);
		//TraversableNodeWrapper<T> wrap = new TraversableNodeWrapper<T>(_root);
		Either<Error, Traversal<T>> either = traverser.traverse(_root,e);
		
		if(either.isA()){
			return DefaultEither.newA(either.a());
		}
		
		Traversal<T> t = either.b();
		Either<Error,T> ret = clone(t,_editor);
		
		return ret;
	}
	
	private <T extends TreeNode<T>> Either<Error,T> clone(Traversal<T> _t,NodeEditor _editor)
	{
		// copying nodes from bottom to root
		
		List<Direction<T>> path = List.nil();
		for(Direction<T> direction : _t){
			path = path.cons(direction);
		}
		
		// target
		Direction<T> targetDirection = path.head();
		T target = targetDirection.getTarget();
		EditableNodeWrapper<T> wrapper = new EditableNodeWrapper<T>(target);
		Either<Error,EditableNodeWrapper<T>> either = _editor.edit(wrapper);
		if(either.isA()){
			return DefaultEither.newA(either.a());
		}
		
		T newNode = either.b().getWrap();
		
		// top
		int pos = targetDirection.getPosition();
		T child = newNode;
		for(Direction<T> parentDirection : path.tail()){
			TreeNodeChildren<T> chs =  parentDirection.getTarget().getChildren();
					
			Either<Error,T> ret = chs.replaceNode(pos,child);
			if(ret.isA()){
				return DefaultEither.newA(ret.a());
			}
			
			T newParent = ret.b();
			child = newParent;
			pos = parentDirection.getPosition();
		}
		
		T newRoot = child;
		return DefaultEither.newB(newRoot);
	}
}