view src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/DefaultTreeEditor.java @ 104:f9a0e7069811

delete worning halfway
author one
date Fri, 12 Sep 2014 16:22:22 +0900
parents bed3afd5c2e2
children 98e256d9fd57
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;
import jp.ac.u_ryukyu.ie.cr.tatsuki.jungle.store.index.Logging;

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