view src/remoteeditor/editors/RemoteEditor.java @ 142:75034fcaa1f1

*** empty log message ***
author pin
date Tue, 05 Feb 2008 19:46:29 +0900
parents 347ebb50ff05
children 7218ba447b7a
line wrap: on
line source

package remoteeditor.editors;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.nio.CharBuffer;
import java.nio.channels.SocketChannel;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextListener;
import org.eclipse.jface.text.TextEvent;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.editors.text.TextEditor;

import remoteeditor.command.REPCommand;
import remoteeditor.command.REPCommandEvent;
import remoteeditor.command.REPCommandListener;
import remoteeditor.network.REP;
import remoteeditor.network.REPPacketReceive;
import remoteeditor.network.REPPacketSend;
import remoteeditor.network.RSocketEvent;
import remoteeditor.network.RSocketListener;
import remoteeditor.ui.REPSelectWindow;
import sample.merge.Translate;


public class RemoteEditor extends TextEditor implements ITextListener, REPCommandListener{
	
	private ISourceViewer viewer;
	private IDocument document;
	
	REPPacketReceive repreceive;
	REPPacketSend repsend;
	
	List <REPCommand> userCmdList = new LinkedList<REPCommand>();
	List <REPCommand> tokenCmdList = new LinkedList<REPCommand>();
	Translate trans = new Translate(userCmdList, tokenCmdList);
	
	//Translate trans = new Translate();
	
	
	int numberOfLinesOld;
	int offset_con;
	private SocketChannel sc;
	private int myeid = 0;
	private int myseq = 0;
	private int mysid = 0;
	private String filename = "afro";
	protected boolean lock;
	private String myHostAndPort;
	
	
	//private Translate translate;
	
	public RemoteEditor() {
		super();
		//filename = this.getEditorInput().getName();

	}
	
	public void createPartControl(Composite parent) {
		super.createPartControl(parent);
		viewer = getSourceViewer();
		viewer.addTextListener(this);
		document = viewer.getDocument();
		filename = this.getEditorInput().getName();
		numberOfLinesOld = document.getNumberOfLines();
		
		int port = 8766;
		String host = "localhost";
		InetSocketAddress addr = new InetSocketAddress(host, port);
		try {
			sc = SocketChannel.open();
			sc.configureBlocking(true);
			sc.connect(addr);
			while(!sc.finishConnect()){
				System.out.println("afro");
			}
		}catch (IOException e) {
			e.printStackTrace();
		}
		getSocketString(sc);
		repreceive = new REPPacketReceive(sc);
		repsend = new REPPacketSend(sc);
		
//		IWorkbench workbench = PlatformUI.getWorkbench();
//		Display display = workbench.getDisplay();
//		REPSelectWindow selectwindow = new REPSelectWindow(display);
//		selectwindow.initWindow();
//		selectwindow.setName(this.getEditorInput().getName());
//		selectwindow.setChannel(sc);
//		selectwindow.open();
		
		//REPCommand temp = repreceive.unpack();
		//myeid = temp.eid; mysid = temp.sid;
		repreceive.addCommandListener(this);
		//repsend.send(new REPCommand(REP.REPCMD_READ, mysid, myeid, myseq, 0, 0, ""));
		//joinPart();
		if(document.getLength() < 1){
			joinPart();
		}else {
			putPart();
		}
	}
	
	private void getSocketString(SocketChannel sc2) {
		String socketString = sc2.socket().getLocalSocketAddress().toString();
		System.out.println(socketString);
		String[] str = socketString.split("/");
		//String String str2;
		for(String str2: str){
			this.myHostAndPort = str2;
		}
		//this.myHostAndPort = socketString;
	}

	public void dispose() {
		//rep.dispose();
		super.dispose();
	}
	public void textChanged(TextEvent event) {
		if(lock) {
			numberOfLinesOld = document.getNumberOfLines();
			return;
		}
		String replacedText = event.getReplacedText();
		String inputText = event.getText();
				
		//ページ先頭からの文字数による座標(改行を含む)
		int textOffset = event.getOffset();
		
		System.out.println("replace = " + replacedText);
		System.out.println("input = " + inputText + " : " + inputText.length());
		
		int line = 0;
		int offset = 0;
		int length = 0;
		int cmd = 0;
		int numberOfLinesNew = 0;
		String lineText = null;
		try {
			line = document.getNumberOfLines(0, textOffset); // lineno を取得してます。
			offset = document.getLineOffset(line-1);
			length = document.getLineLength(line-1);
			lineText = document.get(offset, length);
			numberOfLinesNew = document.getNumberOfLines();
		} catch (BadLocationException e1) {
			e1.printStackTrace();
		}
		if(numberOfLinesNew > numberOfLinesOld){
			//insert, delete, replace 行数で判断
			cmd = REP.REPCMD_INSERT;
			try {
				sendInsert(line);
				createUndoCommand(cmd, textOffset - offset, replacedText, inputText, line);
			} catch (BadLocationException e) {
				e.printStackTrace();
			}

		}else if(numberOfLinesNew == numberOfLinesOld){
			cmd = REP.REPCMD_REPLACE;
			try {
				sendReplace(line);
				createUndoCommand(cmd, textOffset - offset, replacedText, inputText, line);
			} catch (BadLocationException e) {
				e.printStackTrace();
			}
		}else {
			cmd = REP.REPCMD_DELETE;
			try {
				sendDelete(line);
				createUndoCommand(cmd, textOffset - offset, replacedText, inputText, line);
			} catch (BadLocationException e) {
				e.printStackTrace();
			}
		}
		//rep.sendCmd(cmd, line, length, lineText);
//		if(!lock){
//			REPCommand usercmd = new REPCommand(cmd, mysid, myeid, myseq, line, lineText.length(), lineText);
//			repsend.send(usercmd);
//			//translate.addUserList(usercmd);
//			trans.addUserList(usercmd);
//			//System.out.println("User List" + userCmdList.toString());
//			//System.out.println("Token List" + tokenCmdList.toString());
//		}else{		}
		//numberOfLinesOld = numberOfLinesNew;
		numberOfLinesOld = document.getNumberOfLines();
	}
	
	private void createUndoCommand(int cmd, int offset, String replacedText, String inputText, int line) {
		int undoCmd = 0;
		String undoString = null;
		REPCommand undoCommand;
		REPPacketSend send = new REPPacketSend(sc);
		
		if(cmd == REP.REPCMD_INSERT){
			undoCmd = REP.REPCMD_DELETE;
			undoString = "";
			
		}else if(cmd == REP.REPCMD_REPLACE){
			undoCmd = REP.REPCMD_REPLACE;
			String lineText = null;
			try {
				int lineOffset = document.getLineOffset(line-1);
				int length = document.getLineLength(line-1);
				lineText = document.get(lineOffset, length);
			} catch (BadLocationException e) {
				e.printStackTrace();
			}
			StringBuffer sb = new StringBuffer(lineText);
			sb.delete(offset, offset + inputText.length());
			//undoString = sb.toString();
			if(replacedText != null){
				sb.insert(offset, replacedText);
			}
			undoString = sb.toString();
			//sb.insert(offset, inputText);
			//if(replacedText == null){
			//	sb.delete(offset, inputText.length());
			//}else {
				//sb.replace(offset, inputText.length(), replacedText);
			//}
			//undoString = sb.toString();
			
		}else if(cmd == REP.REPCMD_DELETE){
			undoCmd = REP.REPCMD_INSERT;
			undoString = replacedText;
		}
		
		undoCommand = new REPCommand(undoCmd, mysid, 0, -1, line, undoString.length(), undoString);
		send.send(undoCommand);
	}

	private void sendDelete(int line) throws BadLocationException {
		if(!lock){
			int offset = document.getLineOffset(line-1);
			int length = document.getLineLength(line-1);
			String lineText = document.get(offset, length);
			REPCommand usercmd = new REPCommand(REP.REPCMD_REPLACE, mysid, myeid, myseq, line, lineText.length(), lineText);
			repsend.send(usercmd);
			
			offset = document.getLineOffset(line);
			length = document.getLineLength(line);
			lineText = document.get(offset, length);
			usercmd = new REPCommand(REP.REPCMD_DELETE, mysid, myeid, myseq, line, lineText.length(), lineText);
			repsend.send(usercmd);
		}
	}

	private void sendReplace(int line) throws BadLocationException {
		if(!lock){
			int offset = document.getLineOffset(line-1);
			int length = document.getLineLength(line-1);
			String lineText = document.get(offset, length);
			REPCommand usercmd = new REPCommand(REP.REPCMD_REPLACE, mysid, myeid, myseq, line, lineText.length(), lineText);
			repsend.send(usercmd);
		}
	}

	private void sendInsert(int line) throws BadLocationException {
		if(!lock){
		int offset = document.getLineOffset(line-1);
		int length = document.getLineLength(line-1);
		String lineText = document.get(offset, length);
		REPCommand usercmd = new REPCommand(REP.REPCMD_REPLACE, mysid, myeid, myseq, line, lineText.length(), lineText);
		repsend.send(usercmd);
		
		offset = document.getLineOffset(line);
		length = document.getLineLength(line);
		lineText = document.get(offset, length);
		usercmd = new REPCommand(REP.REPCMD_INSERT, mysid, myeid, myseq, line, lineText.length(), lineText);
		repsend.send(usercmd);
		}
	}

	private void changeText(int kindOfCmd, int lineNo, int LineLength, String text) throws Exception{
		System.out.println("Replace Text : " + text);
		final int offset = document.getLineOffset(lineNo-1);
		final String changedText = text;

			final int replaceLength = document.getLineLength(lineNo-1);
		
		viewer.getTextWidget().getDisplay().syncExec(new Runnable() {

			public void run() {
				try {
					lock = true;
					//document.replace(offset, replaceLength, changedText);
					document.replace(offset, replaceLength, changedText);
					lock = false;
				} catch (BadLocationException e) {
					e.printStackTrace();
				}
			}
		});
	}
/*
//	public void packetReceived(final RSocketEvent evt) {
//		final int lineNo = evt.getLineNo();
//		final int Linelength = evt.getLength();
//		final String text = evt.getText();
//		try {
//			changeText(evt.getCmd(), lineNo, Linelength, text);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//	}*/
	
	public void joinPart(){
		//String string = "test.txt";
		repsend.send(new REPCommand(REP.SMCMD_JOIN, 0, 0, 0, 0, 0, myHostAndPort));
	}
	
	public void putPart(){
		if(this.getEditorInput() != null) filename = this.getEditorInput().getName();
		repsend.send(new REPCommand(REP.SMCMD_PUT, mysid, myeid, myseq, 0, filename.length(), filename));
	}
	
	
	public void selectPart(){
		repsend.send(new REPCommand(REP.SMCMD_SELECT, mysid, myeid, myseq, 0, 0, ""));
	}

	public void CommandReceived(REPCommandEvent event) {
		REPCommand receivedCommand = event.getCommand();
		if(receivedCommand.eid == myeid){
			System.out.println("my REP Command.");
		}else{
			tokenCmdList.add(receivedCommand);
		}
		//System.out.println("received command : " + receivedCommand.toString());
		commandManager(receivedCommand);
	}

	private void commandManager(REPCommand command) {
		switch(command.cmd){
		case REP.SMCMD_JOIN_ACK:
			mysid = command.sid;
			myeid = command.eid;
			trans.myeid = myeid;
			REPCommand sendCommand = new REPCommand(REP.REPCMD_READ, mysid, myeid, 0, 0, 0, "");
			repsend.send(sendCommand);
			//putPart();
			break;
		case REP.SMCMD_PUT_ACK:
			mysid = command.sid;
			myeid = command.eid;
			//selectPart();
			break;
		case REP.SMCMD_SELECT_ACK:
			mysid = command.sid;
			break;
		case REP.REPCMD_INSERT:
			try {
					if(command.eid == myeid) break;	//mergerを導入する時に消す
					textInsert(command.lineno, command.len, command.string);
				} catch (Exception e) {
					e.printStackTrace();
				}
			break;
		case REP.REPCMD_REPLACE:
			try {
					if(command.eid == myeid) break;//mergerを導入する時に消す
					if(command.seq > 0) repsend.send(command);
					changeText(command.cmd, command.lineno, command.len, command.string);
				} catch (Exception e1) {
					e1.printStackTrace();
				}
			break;
		case REP.REPCMD_DELETE:
			try {
					if(command.eid == myeid) break;//mergerを導入する時に消す
					textDelete(command.lineno, command.len, command.string);
				} catch (BadLocationException e1) {
					e1.printStackTrace();
				}
			break;
		case REP.REPCMD_READ:
			try {
					receiveReadCMD(command.eid);
				} catch (BadLocationException e) {
					e.printStackTrace();
				}
			break;
		case REP.REPCMD_READ_ACK:
			try {
				if(command.sid == mysid && command.eid == myeid){
					read(command);
				}else{
					repsend.send(command);
				}
				
				} catch (BadLocationException e) {
					e.printStackTrace();
				}
			break;
		}
	}



	private void read(REPCommand command) throws BadLocationException {
		final int offset = document.getLineOffset(command.lineno);
		final String string = command.string;
		
		viewer.getTextWidget().getDisplay().syncExec(new Runnable() {
			public void run() {
				try {
					lock = true;
					//document.replace(offset, replaceLength, changedText);
					document.replace(offset, 0, string);
					lock = false;
				} catch (BadLocationException e) {
					e.printStackTrace();
				}
			}
		});
	}

	private void textDelete(int lineNo, int len, String string) throws BadLocationException {
		final int offset = document.getLineOffset(lineNo);
		//final String changedText = string;

			final int replaceLength = document.getLineLength(lineNo);
		
		viewer.getTextWidget().getDisplay().syncExec(new Runnable() {
			public void run() {
				try {
					lock = true;
					//document.replace(offset, replaceLength, changedText);
					document.replace(offset, replaceLength, "");
					lock = false;
				} catch (BadLocationException e) {
					e.printStackTrace();
				}
			}
		});
	}

	private void textInsert(int lineNo, int j, String text) throws BadLocationException {
		final int offset = document.getLineOffset(lineNo);
		final String changedText = text;

			//final int replaceLength = document.getLineLength(lineNo);
		
		viewer.getTextWidget().getDisplay().syncExec(new Runnable() {
			public void run() {
				try {
					lock = true;
					//document.replace(offset, replaceLength, changedText);
					document.replace(offset, 0, changedText);
					lock = false;
				} catch (BadLocationException e) {
					e.printStackTrace();
				}
			}
		});
	}

	private void receiveReadCMD(int desteid) throws BadLocationException {
		for(int i = 0; i < document.getNumberOfLines(); i++){
			int offset = document.getLineOffset(i);
			int length = document.getLineLength(i);
			String text = document.get(offset, length);
			repsend.send(new REPCommand(REP.REPCMD_READ_ACK, mysid, desteid, myseq, i, text.length(), text));
		}
	}
}