view src/remoteeditor/editors/RemoteEditor.java @ 184:736fd137d9a3

*** empty log message ***
author pin
date Sat, 20 Sep 2008 10:59:20 +0900
parents 54a9dba5ce2a
children 42563c465a6e
line wrap: on
line source

package remoteeditor.editors;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SocketChannel;
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.ITextInputListener;
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.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 sample.merge.Translate;


public class RemoteEditor extends TextEditor implements ITextListener, REPCommandListener, ITextInputListener{
	
	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);
	
	
	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);
		viewer.addTextInputListener(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);
		
		repreceive.addCommandListener(this);
		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("RemoteEditor.textChanged() : replaceText = " + replacedText);
		System.out.println("RemoteEditor.textChanged() : inputText = " + inputText + " : " + inputText.length());
		
		int numberOfLinesNew = 0;
		numberOfLinesNew = document.getNumberOfLines();
		
		if(numberOfLinesNew == numberOfLinesOld){
			sendDelete(textOffset, inputText, replacedText);
			sendInsert(textOffset, inputText, replacedText);

		}else if(numberOfLinesNew > numberOfLinesOld){
			sendInsert(textOffset, inputText, replacedText);
			
		}else if(numberOfLinesNew < numberOfLinesOld){
			sendDelete(textOffset, inputText, replacedText);
			
		}

		numberOfLinesOld = document.getNumberOfLines();
	}

	private void sendInsert(int textOffset, String inputText, String replacedText){
		int lineno = 0;
		String text = null;
		try {
			lineno = document.getNumberOfLines(0, textOffset);
			int lineOffset = document.getLineOffset(lineno-1);		//行頭
			int length = document.getLineLength(lineno-1);
			text = document.get(lineOffset, length);
		} catch (BadLocationException e) {
			e.printStackTrace();
		}
		REPCommand command = new REPCommand(REP.REPCMD_INSERT, mysid, myeid, myseq++, lineno, text.length(), text);
		repsend.send(command);
	}

	private void sendDelete(int textOffset, String inputText, String replacedText) {
		int lineno = 0;
		try {
			lineno = document.getNumberOfLines(0, textOffset);
		} catch (BadLocationException e) {
			e.printStackTrace();
		}
		String text = getBeforeText(textOffset, inputText, replacedText);
		REPCommand command = new REPCommand(REP.REPCMD_DELETE, mysid, myeid, myseq++, lineno, text.length(), text);
		repsend.send(command);
	}

	private String getBeforeText(int textOffset, String inputText, String replacedText) {
		String lineText = null;
		int offsetInLine = 0;
		try {
			int lineno = document.getNumberOfLines(0, textOffset);
			int lineOffset = document.getLineOffset(lineno-1);
			int length = document.getLineLength(lineno-1);
			lineText = document.get(lineOffset, length);
			offsetInLine = textOffset - lineOffset;
		} catch (BadLocationException e) {
			e.printStackTrace();
		}
		StringBuffer sb = new StringBuffer(lineText);
		sb.delete(offsetInLine, offsetInLine + inputText.length());
		
		if(replacedText != null){
			sb.insert(offsetInLine, replacedText);
		}
		String beforeText = sb.toString();
		return beforeText;
	}

	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(){
		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);
		}
		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;
		case REP.SMCMD_GET_UNDO:
			try {
					String text = getTextByLineNo(command.lineno);
					sendCommand = new REPCommand(REP.SMCMD_GET_UNDO_ACK, mysid, myeid, 0, command.lineno, 0, text);
				} catch (BadLocationException e) {
					e.printStackTrace();
				}
			break;
		}
	}



	private String getTextByLineNo(int lineno) throws BadLocationException {
		int offset = document.getLineOffset(lineno-1);
		int length = document.getLineLength(lineno-1);
		String text = document.get(offset, length);
		return text;
	}

	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));
		}
	}

	public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
		System.out.println("---------- old Input ----------");
		System.out.println(oldInput.get());
		System.out.println();
		System.out.println("---------- new Input ----------");
		System.out.println(newInput.get());
	}

	public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
		// TODO Auto-generated method stub
		
	}
}