view src/jungle/app/bbs/JungleManager.java @ 103:1a5384cd1da4

Version up to 0.2
author one
date Mon, 25 Nov 2013 18:11:17 +0900
parents 9865ccfd0123
children
line wrap: on
line source

package jungle.app.bbs;

import java.nio.ByteBuffer;
import java.util.Iterator;

import alice.jungle.operations.NetworkTreeOperationLog;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.DefaultJungle;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.Jungle;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.JungleTree;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.JungleTreeEditor;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.Node;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.Command;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.NodePath;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.DefaultNodePath;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.DefaultTreeEditor;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.logger.TreeOperationLog;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.operations.NodeOperation;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.operations.TreeOperation;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.traverser.DefaultTraverser;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Either;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Error;

public class JungleManager {
	private static JungleManager jm = new JungleManager();
	private Jungle jungle;
	private static int NOT_CHANGE_POSITION = 0;

	private JungleManager() {
		jungle = new DefaultJungle(null,"hogehoge",new DefaultTreeEditor(new DefaultTraverser()));
	}
	
	public static void setJungle(Jungle _j) {
		jm.jungle = _j;
	}
	
	public static Jungle getJungle() {
		return jm.jungle;
	}
	
	public static JungleTree createNewTree(String name) {
		return jm.jungle.createNewTree(name);		
	}

	public static Either<Error, JungleTreeEditor> edit(JungleTreeEditor _editor ,TreeOperationLog _log, int pos) {
		JungleTreeEditor editor = _editor;
		Either<Error, JungleTreeEditor> either = null;
		for (TreeOperation op : _log) {
			either = _edit(editor, op, pos);
			if(either.isA()) {
				return either;
			}
			editor = either.b();
		}
		return either;
	}
	
	private static Either<Error, JungleTreeEditor> _edit(JungleTreeEditor editor,
			TreeOperation op, int _pos) {
		NodePath path = new DefaultNodePath();
		NodeOperation nodeOp = op.getNodeOperation();
		int pos = _pos;
		if (_pos == NOT_CHANGE_POSITION ) {
			pos = nodeOp.getPosition();
		}
		Command c = nodeOp.getCommand();
		String key = "";
		switch (c) {
		case PUT_ATTRIBUTE:
			path = op.getNodePath();
			key = nodeOp.getKey();
			ByteBuffer value = nodeOp.getValue();
			return editor.putAttribute(path, key, value);
		case DELETE_ATTRIBUTE:
			key = nodeOp.getKey();
			return editor.deleteAttribute(path, key);
		case APPEND_CHILD:
			return editor.addNewChildAt(path, pos);
		case DELETE_CHILD:
			return editor.deleteChildAt(path, 0);
		}
		return null;
	}
	
	public static Either<Error, JungleTreeEditor> update(NetworkTreeOperationLog netLog) {
		String treeName = netLog.getTreeName();
		Jungle jungle = JungleManager.getJungle(); 
		if (jungle.getTreeByName(treeName) == null) {
			if(null == jungle.createNewTree(treeName)){
				throw new IllegalStateException();
			}
		}
		JungleTree tree = jungle.getTreeByName(treeName);
		JungleTreeEditor editor = tree.getLocalTreeEditor();

		//		int pos = calculatePosition(tree.getRootNode(), netLog.getTimeStamp());
		int pos = 0;
		Either<Error, JungleTreeEditor> either = JungleManager.edit(editor, netLog, pos);
		if(either.isA()) {
			throw new IllegalStateException();
		}
		editor = either.b();
		either = editor.success();
		if(either.isA()) {
			throw new IllegalStateException();
		}
		return either;
	}
	
	private static int calculatePosition(Node node, long newNodeTimeStamp) {
		int count = 0;
		long childTimeStamp = 0;
		for(Iterator<Node> iter = node.getChildren().iterator();iter.hasNext();) {
			Node n = iter.next();
			if(n.getAttributes().get("timestamp") == null) {
				return NOT_CHANGE_POSITION;
			}
			if(n.getAttributes().get("timestamp") != null) {
				childTimeStamp = n.getAttributes().get("timestamp").getLong();
				if (newNodeTimeStamp < childTimeStamp) {
					break;
				}
			}
			count++;
		}
		return count;
	}
}