view Main/jungle-main/store/impl/DefaultTreeEditor.cs @ 35:f2ea780b3e80

fix
author Kazuma Takeda
date Wed, 22 Feb 2017 16:30:19 +0900
parents 236a58985e22
children
line wrap: on
line source

using System.Collections;
using System.Collections.Generic;

namespace JungleDB {
	public class DefaultTreeEditor : TreeEditor {
		private Traverser traverser;

		public DefaultTreeEditor(Traverser traverser){
			this.traverser = traverser;
		}

		public Either<Error,LoggingNode> edit(TreeNode root,NodePath path, NodeEditor editor){
			DefaultEvaluator e = new DefaultEvaluator (path);
			Either<Error, Traversal> either = traverser.traverse (root, e);

			if (either.isA ()) {
				return DefaultEither<Error, LoggingNode>.newA (either.a ());
			}
			Traversal t = either.b ();
			return clone (t, editor);
		}

		private Either<Error, LoggingNode> clone(Traversal t, NodeEditor editor){
			List<Direction<TreeNode>> path = new List<Direction<TreeNode>> ();

			foreach (Direction<TreeNode> direction in t) {
				path = path.addLast (direction);
			}

			Direction<TreeNode> targetDirection = path.headList ();
			TreeNode target = targetDirection.getTarget ();
			Either<Error, LoggingNode> either = editor.edit (target);

			if (either.isA ())
				return DefaultEither<Error, LoggingNode>.newA (either.a ());

			LoggingNode newWrap = either.b ();

			int pos = targetDirection.getPosition ();
			TreeNode child = newWrap.getWrap ();

			foreach (Direction<TreeNode> parentDirection in path.deleteHead()) {
				TreeNodeChildren chs = parentDirection.getTarget ().getChildren ();

				Either<Error, TreeNode> ret = chs.replaceNode (pos, child);

				if (ret.isA ())
					return DefaultEither<Error, LoggingNode>.newA (ret.a ());

				child = ret.b ();
				pos = parentDirection.getPosition ();
			}

			TreeNode newRoot = child;
			LoggingNode logNode = editor.wrap (newRoot, newWrap.getOperationLog ());
			return DefaultEither<Error, LoggingNode>.newB (logNode);

		}
	}
}