Mercurial > hg > RemoteEditor > REPSessionManager
view rep/translater/TranslaterImp1.java @ 281:c3969dd625b2
GUIless test routine.
author | kono |
---|---|
date | Sat, 27 Sep 2008 22:55:13 +0900 |
parents | 6384ab65f60a |
children | 90965a3bd4f3 |
line wrap: on
line source
package rep.translater; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.LinkedList; import java.util.Stack; import java.util.TreeSet; import rep.REPCommand; import rep.REP; public class TranslaterImp1 implements Translater{ //List <REPCommand> userList; //List <REPCommand> tokenList; private LinkedList<REPCommand> sentCmds; //private LinkedList<REPCommand> unMergedCmds; private Stack<REPCommand> unMergedCmds; public int eid; private int seq; private LinkedList<REPCommand> undoReplaceList; private LinkedList<REPCommand> sentMergedList; private LinkedList<REPCommand> mergeAgainList; public TranslaterImp1(int _eid){ eid = _eid; sentCmds = new LinkedList<REPCommand>(); unMergedCmds = new Stack<REPCommand>(); undoReplaceList = new LinkedList<REPCommand>(); mergeAgainList = new LinkedList<REPCommand>(); sentMergedList = new LinkedList<REPCommand>(); } /** * Translate cmd When the editor send REPCommand. * but now, Only adding cmd to the queue is available. * @param cmd * @return translated command. */ public REPCommand transSendCmd(REPCommand cmd){ setCmdState(cmd); sentCmds.add(cmd); unMergedCmds.push(cmd); //マージ中にユーザから割り込みがあった場合 if(isMerging()){ mergeAgainList.add(cmd); } return cmd; } /** * Dequeue command cmd that was returned. * @param cmd */ public ArrayList<REPCommand> catchOwnCommand(REPCommand cmd){ ArrayList<REPCommand> returnCmds = new ArrayList<REPCommand>(); ArrayList<REPCommand> cmds = new ArrayList<REPCommand>(); // ringである以上、戻ってきたコマンドは確実にキューsentCmdsの先頭にある事を期待している REPCommand tmp = sentCmds.poll(); assert tmp.seq==cmd.seq; assert cmd.eid==eid; //スタック上にあるコマンドを全部undoコマンドにする while ( !unMergedCmds.isEmpty() ){ REPCommand cmd0 = unMergedCmds.pop(); returnCmds.add( createUndo(cmd0) ); cmds.add(cmd0); } /* 必要な分だけソートして返却用のリストに追加 */ //if (cmds.size()==0) return null; returnCmds.addAll( sortCmds(cmds) ); /* 残ったコマンドも再び実行させるが、まだマージされてないのでunMergedにも入れる */ for(int i=0; i<cmds.size(); i++){ returnCmds.add( cmds.get(i)); unMergedCmds.push( cmds.get(i)); } return returnCmds; } private REPCommand createUndo(REPCommand cmd){ String str = new String(cmd.string); REPCommand retCmd = new REPCommand(cmd.cmd, cmd.sid, cmd.eid, cmd.seq, cmd.lineno, str.length(), str); retCmd.eid = REP.MERGE_EID.id; if (cmd.cmd==REP.REPCMD_INSERT) retCmd.cmd=REP.REPCMD_DELETE; else if (cmd.cmd==REP.REPCMD_DELETE) retCmd.cmd=REP.REPCMD_INSERT; return retCmd; } class REPCommandComparator implements Comparator<REPCommand>{ public int compare(REPCommand o1, REPCommand o2) { if ( o2.lineno > o1.lineno ) return 1; else if ( o2.lineno < o1.lineno || o2.eid > o1.eid ) return -1; return 1; } } private Collection<REPCommand> sortCmds(ArrayList<REPCommand> cmds) { TreeSet<REPCommand> sortedCmds1 = new TreeSet<REPCommand>(new REPCommandComparator()); int top; int prevEid=-1; while ( -1 != (top=getPrecedence(cmds, prevEid+1)) ){ REPCommand tmp = cmds.remove(top); sortedCmds1.add(tmp); prevEid = tmp.eid; } return sortedCmds1; } /* search cmd. ordering by min EID that is lower lowEid and min SEQ. */ private int getPrecedence(ArrayList<REPCommand> cmds, int lowEid) { int cEid, cSeq; cEid=cSeq=Integer.MAX_VALUE; int ret=-1; for (int i=0; i<cmds.size(); i++){ REPCommand tmp = cmds.get(i); if ( tmp.eid<lowEid ) continue; else if ( tmp.eid>cEid ) continue; else if ( tmp.eid==cEid ) { if ( tmp.seq>cSeq ) continue; cSeq=tmp.seq; ret = i; } else { /* tmp.eid<cEid */ cEid = tmp.eid; cSeq = tmp.seq; ret = i; } } return ret; } /** * Translate Command cmd that was received from SeMa. * @param cmd the command to be translated. * @return translated commannd. */ public REPCommand[] transReceiveCmd(REPCommand cmd){ int i=0; REPCommand cmds[]; assert (cmd.eid != eid); // if (cmd.eid==eid){ // return catchOwnCommand(cmd); // } for (REPCommand cmd0 : unMergedCmds){ if (cmd0.eid==cmd.eid) i++; } if ( sentCmds.size()<i ){ //自分のエディタでされた編集コマンドより他のエディタでの編集コマンドのほうが多かった場合NOPを挿入 //自分のコマンドがないとマージできないのでNOPを挿入 cmds = new REPCommand[2]; String str = "NO OPERATION"; cmds[0] = setCmdState( new REPCommand(REP.REPCMD_NOP, 0, eid, 0, 0, str.length(), str) ); cmds[1] = cmd; //unMergedCmds.push(cmds[0]); unMergedCmds.push(cmd); sentCmds.add(cmds[0]); return cmds; } unMergedCmds.push(cmd); /* but.. */ cmds = new REPCommand[1]; cmds[0] = cmd; return cmds; } private REPCommand setCmdState(REPCommand cmd){ cmd.seq = seq++; cmd.eid = eid; return cmd; } public void setEid(int _eid){ eid = _eid; } public Stack<REPCommand> getList() { // TODO Auto-generated method stub return unMergedCmds; } public LinkedList<REPCommand> getSentCmds() { // TODO Auto-generated method stub return sentCmds; } public void setUndoCommand(REPCommand command) { // TODO Auto-generated method stub undoReplaceList.add(command); } public boolean checkMergeConflict(REPCommand command) { sentMergedList.remove(); if(mergeAgainList.size() > 0){ mergeAgainList.add(command); if(sentMergedList.size() == 0){ return true; } } return false; } public LinkedList<REPCommand> getMergeAgain() { LinkedList<REPCommand> returnCommand = new LinkedList<REPCommand>(); for(int i = 0; i < mergeAgainList.size(); i++){ //eid = REP.MEGE_EID returnCommand.add(createUndo(mergeAgainList.get(mergeAgainList.size() - i -1))); } for(REPCommand command : mergeAgainList){ if(command.eid == REP.MERGE_EID.id){ returnCommand.add(command); } } for(REPCommand command : mergeAgainList){ if(command.eid == eid){ command.eid = REP.MERGE_EID.id; returnCommand.add(command); } } mergeAgainList.clear(); sentMergedList = returnCommand; return returnCommand; } public boolean isFinished() { if(unMergedCmds.size() > 0) return false; if(sentMergedList.size() > 0) return false; if(sentCmds.size() > 0) return false; return true; } public boolean isMerging() { if(sentMergedList.size() > 0) return true; return false; } }