view src/jungle/test/bbs/NetworkJungleBulletinBoard.java @ 47:686057add8a4

confirmed LogUpdateCodeSegment
author one
date Fri, 12 Jul 2013 11:45:12 +0900
parents fd3643699f83
children a89c3539bff2
line wrap: on
line source

package jungle.test.bbs;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicInteger;

import alice.jungle.core.NetworkDefaultJungle;
import alice.jungle.datasegment.store.operations.DefaultTreeOperationLogContainer;
import alice.jungle.transaction.NetworkDefaultJungleTreeEditor;
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.Children;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.Node;
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.operations.TreeOperation;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.EditableNode;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.NodeEditor;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.traverser.DefaultTraverser;
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.shoshi.jungle.util.IterableConverter;
import jungle.test.bbs.codesegment.NullCodeSegmentForUpdate;

public class NetworkJungleBulletinBoard implements BulletinBoard
{
	private JungleManager jm;
	private final Jungle jungle;
	
	public NetworkJungleBulletinBoard(String _serverName)
	{
		Jungle _j = new NetworkDefaultJungle(null,"hoge",new DefaultTreeEditor(new DefaultTraverser()), _serverName);	
		JungleManager.setJungle(_j);
		jungle = JungleManager.getJungle();
		jungle.createNewTree("boards");
	}

	public Iterable<String> getBoards()
	{
		JungleTree tree = jungle.getTreeByName("boards");
		Node node = tree.getRootNode();
		Children<Node> chs = node.getChildren();
		
		IterableConverter.Converter<String,Node> converter = new IterableConverter.Converter<String,Node>(){
			public String conv(Node _b) {
				ByteBuffer e = _b.getAttributes().get("name");
				return new String(e.array());
			}
		};
		
		return new IterableConverter<String,Node>(chs,converter);
	}

	public void createBoards(final String _name,final String _author,final String _initMessage,final String _editKey)
	{
		if(null == jungle.createNewTree(_name)){
			throw new IllegalStateException();
		}
		
		JungleTree tree = jungle.getTreeByName("boards");
		JungleTreeEditor editor = tree.getTreeEditor();
		DefaultNodePath root = new DefaultNodePath();
		Either<Error,JungleTreeEditor> either = editor.addNewChildAt(root,0);
		if(either.isA()){
			throw new IllegalStateException();
		}
		editor = either.b();
		
		either = editor.putAttribute(root.add(0),"name",ByteBuffer.wrap(_name.getBytes()));
		if(either.isA()){
			throw new IllegalStateException();
		}
		editor = either.b();
		Either<Error,JungleTreeEditor> result = editor.success();
		if(result.isA()){
			throw new IllegalStateException();
		}
		/* Put DataSegment */
		try {
			putTreeOperationLog((NetworkDefaultJungleTreeEditor)result.b());
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		
		tree = jungle.getTreeByName(_name);
		editor = tree.getTreeEditor();
		either = editor.addNewChildAt(root,0);
		if(either.isA()){
			throw new IllegalStateException();
		}
		editor = either.b();
		
		NodeEditor e = new NodeEditor(){
			public <T extends EditableNode<T>> Either<Error, T> edit(T _e){
				_e = _e.getAttributes().put("author",ByteBuffer.wrap(_author.getBytes())).b();
				_e = _e.getAttributes().put("mes",ByteBuffer.wrap(_initMessage.getBytes())).b();
				_e = _e.getAttributes().put("key",ByteBuffer.wrap(_editKey.getBytes())).b();
				return DefaultEither.newB(_e);
			}
		};
		
		either = editor.edit(root.add(0),e);
		if(either.isA()){
			throw new IllegalStateException();
		}
		editor = either.b();
		editor.success();
		/* Put DataSegment */
		try {
			putTreeOperationLog((NetworkDefaultJungleTreeEditor)result.b());
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		
	}

	public void createBoardMessage(final String _board,final String _author,final String _message,final String _editKey)
	{
		JungleTree tree = jungle.getTreeByName(_board);
		if(tree == null){
			throw new IllegalStateException();
		}
		
		JungleTreeEditor editor;
		Either<Error, JungleTreeEditor> either;
		do{
			Node node = tree.getRootNode();
			int size = node.getChildren().size();
			DefaultNodePath path = new DefaultNodePath();
		
			editor = tree.getTreeEditor();
			either = editor.addNewChildAt(path,size);
			if(either.isA()){
				throw new IllegalStateException();
			}
			editor = either.b();
		
			NodeEditor e = new NodeEditor(){
				public <T extends EditableNode<T>> Either<Error, T> edit(T _e){
					_e = _e.getAttributes().put("author",ByteBuffer.wrap(_author.getBytes())).b();
					_e = _e.getAttributes().put("mes",ByteBuffer.wrap(_message.getBytes())).b();
					_e = _e.getAttributes().put("key",ByteBuffer.wrap(_editKey.getBytes())).b();
					return DefaultEither.newB(_e);
				}
			};
		
			path = path.add(size);
			either = editor.edit(path,e);
			if(either.isA()){
				throw new IllegalStateException();
			}
			editor = either.b();

			either = editor.success();
			/* Put DataSegment */
			try {
				putTreeOperationLog((NetworkDefaultJungleTreeEditor)editor);
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}while(either.isA());
	}

	public void editMessage(String _board,String _uuid,final String _author,final String _message,final String _editKey)
	{
		JungleTreeEditor editor = null;
		Either<Error,JungleTreeEditor>  either = null;
		do{
			DefaultNodePath path = new DefaultNodePath();
			path = path.add(Integer.parseInt(_uuid));
		
			JungleTree tree = jungle.getTreeByName(_board);
			editor = tree.getTreeEditor();
			NodeEditor e = new NodeEditor(){
				public <T extends EditableNode<T>> Either<Error, T> edit(T _e){
					_e = _e.getAttributes().put("author",ByteBuffer.wrap(_author.getBytes())).b();
					_e = _e.getAttributes().put("mes",ByteBuffer.wrap(_message.getBytes())).b();
					_e = _e.getAttributes().put("key",ByteBuffer.wrap(_editKey.getBytes())).b();
				return DefaultEither.newB(_e);
				}
			};
		
			either = editor.edit(path,e);
			if(either.isA()){
				throw new IllegalStateException();
			}
			editor = either.b();
			either = editor.success();
			/* Put DataSegment */
			try {
				putTreeOperationLog((NetworkDefaultJungleTreeEditor)editor);
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}while(either.isA());
	}

	public Iterable<BoardMessage> getMessages(String _boardName)
	{
		JungleTree tree = jungle.getTreeByName(_boardName);
		Node node = tree.getRootNode();
		Children<Node> chs = node.getChildren();
		
		final AtomicInteger counter = new AtomicInteger(0);
		IterableConverter.Converter<BoardMessage,Node> converter = new IterableConverter.Converter<BoardMessage,Node>(){
			public BoardMessage conv(Node _b) {
				String uuid = Integer.toString(counter.get());
				String author = new String(_b.getAttributes().get("author").array());
				String message = new String(_b.getAttributes().get("mes").array());
				counter.incrementAndGet();
				return new BoardMessageImpl(author,message,uuid);
			}
		};
		
		return new IterableConverter<BoardMessage,Node>(chs,converter);
	}
	
	private void putTreeOperationLog(NetworkDefaultJungleTreeEditor editor) throws IOException {
		String uuid = editor.getID();
		String treeName = editor.getTreeName();
		String serverName = editor.getServerName();
		long revision = Long.parseLong(editor.getRevision());
		Iterable<TreeOperation> log = editor.getTreeOperationLog();
		putDataSegment(uuid, treeName, serverName, log, revision);
	}
	
	private void putDataSegment(String _uuid, String _treeName, String _serverName, Iterable<TreeOperation> _log, long nextRevision) throws IOException {
		DefaultTreeOperationLogContainer container = new DefaultTreeOperationLogContainer();
		container.setTreeName(_treeName);
		container.setUUID(_uuid);
		container.setServerName(_serverName);
		container.setRevision(nextRevision);
		container.unconvert(_log);
		NullCodeSegmentForUpdate cs = new NullCodeSegmentForUpdate();
		cs.ods.put("log", container);
	}

	
	private static class BoardMessageImpl implements BoardMessage
	{
		private final String author;
		private final String message;
		private final String uuid;
		
		public BoardMessageImpl(String _author,String _message,String _uuid)
		{
			author = _author;
			message = _message;
			uuid = _uuid;
		}

		public String getAuthor()
		{
			return author;
		}

		public String getMessage()
		{
			return message;
		}

		public String getUUID()
		{
			return uuid;
		}
	}
}