# HG changeset patch # User one@firefly.cr.ie.u-ryukyu.ac.jp # Date 1226322465 -32400 # Node ID 4b87f89b3afd00bddd63b1d5412bcd6e5c0e9bc5 # Parent 65fdb3dc188543aa2ae7ba7d149d16e9b64cfadf REP Session Manager (Java version) new structure diff -r 65fdb3dc1885 -r 4b87f89b3afd export/pin.jar Binary file export/pin.jar has changed diff -r 65fdb3dc1885 -r 4b87f89b3afd export/sessionmanager.jar Binary file export/sessionmanager.jar has changed diff -r 65fdb3dc1885 -r 4b87f89b3afd export/sessionmanager2.jar Binary file export/sessionmanager2.jar has changed diff -r 65fdb3dc1885 -r 4b87f89b3afd export/sm.sh --- a/export/sm.sh Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -java -classpath sessionmanager.jar rep.SessionManager diff -r 65fdb3dc1885 -r 4b87f89b3afd java.policy.applet --- a/java.policy.applet Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -/* AUTOMATICALLY GENERATED ON Tue Apr 16 17:20:59 EDT 2002*/ -/* DO NOT EDIT */ - -grant { - permission java.security.AllPermission; -}; - diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/CloseButtonEvent.java --- a/rep/CloseButtonEvent.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -package rep; - -public class CloseButtonEvent implements SessionManagerEvent { - - private Session session; - private SessionManagerEventListener listener; - - public CloseButtonEvent(Session session, SessionManagerEventListener listener) { - this.session = session; - this.listener = listener; - } - - public Session getSession(){ - return session; - } - - public void exec(SessionManager manager) { - listener.closeSession(this); - } - -} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/ConnectButtonEvent.java --- a/rep/ConnectButtonEvent.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ -package rep; - -public class ConnectButtonEvent implements SessionManagerEvent{ - - private String host; - - public ConnectButtonEvent(String host) { - this.host = host; - } - - public String getHost() { - return host; - } - - public void exec(SessionManager manager) { - manager.connectSessionManager(host); - } - -} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/ConnectionListener.java --- a/rep/ConnectionListener.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5 +0,0 @@ -package rep; - -public interface ConnectionListener { - public void connectionOccured(ConnectButtonEvent event); -} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/DoGUIUpdate.java --- a/rep/DoGUIUpdate.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,20 +0,0 @@ -package rep; - -import java.util.LinkedList; - -public class DoGUIUpdate implements Runnable{ - - private LinkedList slist; - private LinkedList elist; - private SessionManagerGUI gui; - - public DoGUIUpdate(LinkedList _slist, LinkedList _elist, SessionManagerGUI _gui) { - gui = _gui; - slist = _slist; elist = _elist; - } - - public void run() { - gui.update(slist, elist); - } - -} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/Editor.java --- a/rep/Editor.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,246 +0,0 @@ -package rep; - -import java.io.IOException; -import java.util.LinkedList; -import java.util.List; - -import rep.channel.REPSelectionKey; -import rep.channel.REPSocketChannel; -import rep.handler.PacketSet; -import rep.optimizers.*; -import rep.translator.Translator; -import rep.translator.TranslatorImpl; - -public class Editor extends Forwarder { - - private Translator translator; - private List sentList = new LinkedList(); - // REPCommands we are going to send to the next editor - //private REPCommand quit2 = null; - private SessionManager manager; - private REPCommand quit2=null; - - public Editor(SessionManager manager,boolean doOptimize,int editorNo){ - super(manager); - this.manager = manager; - eid = editorNo; - REPCommandOptimizer optimizer; - if (doOptimize) optimizer = new DeleteInsertOptimizer(); //タカノがつくったおぷてぃまいざ - else optimizer = new NullOptimizer(); //なにもしないけどOptimizer. - translator = new TranslatorImpl(eid,optimizer); - - } - - public Editor(SessionManager manager,int editorNo, REPSocketChannel channel){ - this(manager,false,editorNo); - this.channel = channel; - } - - public void translate(REPCommand command){ - - if(command.eid == eid){ - //エディタからの新たな編集コマンド - if (next==this) return; // singleton case - translator.transSendCmd(command); - sentList.add(new REPCommand(command)); - assert(sentList.size() key) throws IOException { - REPSocketChannel channel = key.channel1(); - REPCommand command = channel.read(); - SessionManager.logger.writeLog("REPHandlerImpl.handle() read : command = " + command +" from "+channel); - if (manager.sessionManage(this, command)) return; - manage(command); - } - - @Override - public void cancel(REPSocketChannel socketChannel) { - manager.remove(socketChannel); - } - - public boolean isMaster() { - return mode==REP.SMCMD_PUT; - } - - /* Handle special case first, usually these cases - * are handled in the next Editor in a session manager, but - * it is forwarded here. - */ - public void forwardedCommandManage(REPCommand command, Forwarder forwarder) { - if (command.cmd==REP.SMCMD_QUIT_2) { - // we have to wait next editor's finishing before sending this. - // this is odd, but the editor itself does not know it's merging - // state. Only this session manager knows it. - setQuit2(command); - } else if (command.eid==eid) { - // if we handle in editor.manage(), this editor cannot distinguish this - // and user input command from the editor. - switch(command.cmd) { - case REPCMD_DELETE: - case REPCMD_INSERT: - case REPCMD_NOP: - checkReturnedCommand(command); - return; - } - } - send(command); - } -} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/EditorList.java --- a/rep/EditorList.java Mon Nov 10 01:12:46 2008 +0000 +++ b/rep/EditorList.java Mon Nov 10 22:07:45 2008 +0900 @@ -2,7 +2,9 @@ import java.util.HashMap; -public class EditorList extends HashMap { +import rep.handler.REPNode; + +public class EditorList extends HashMap { /** * @@ -10,7 +12,7 @@ private static final long serialVersionUID = 1L; private int eid_root=0; - public void add(Editor fw) { + public void add(REPNode fw) { put(fw.getEID(),fw); } diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/EditorPlus.java --- a/rep/EditorPlus.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -package rep; - -import rep.channel.REPSocketChannel; - -public class EditorPlus { - - public int eid; // globally unique - public int sid=-1; // globally unique - public String host; - public String file; - public REPSocketChannel channel; - - public EditorPlus() { - - } - - public EditorPlus(int eid, REPSocketChannel channel) { - this.eid = eid; - this.channel = channel; - } - - public String getName() { - return file; - } - - public void setName(String string) { - file = string; - } - - - public void setSID(int sid) { - this.sid = sid; - } - - public int getSID() { - return sid; - } - - public boolean hasSession() { - return sid != -1; - } - - public String toString(){ - return ("Editor:" + eid); - } - - public void setEID(int eid) { - this.eid = eid; - } - - public int getEID(){ - return eid; - } - - public void setHost(String host){ - if (channel!=null) - this.host = host; - } - - - public String getHost(){ - return host; - } - public REPSocketChannel getChannel(){ - return channel; - - } - public void setChannel(REPSocketChannel channel) { - this.channel = channel; - } - - public void merge(EditorPlus editor) { - if (sid==-1) sid = editor.sid; - if (file==null) file = editor.file; - if (host==null) host = editor.host; - } -} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/FirstConnector.java --- a/rep/FirstConnector.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -package rep; - -import java.io.IOException; - -import rep.channel.REPSelectionKey; -import rep.channel.REPSocketChannel; - -public class FirstConnector extends Forwarder { - - public FirstConnector(SessionManager manager) { - super(manager); - } - - public void cancel(REPSocketChannel socketChannel) { - manager.remove(socketChannel); - } - - public void handle(REPSelectionKey key) throws IOException { - /* - * 接続要求は、EditorかSlave Editorで、 - *    join, put, sm_join - * が来る。それ以外はエラー。master もありか? - * sm_join_ack - */ - Forwarder fw; - REPSocketChannel channel = key.channel1(); - REPCommand command = channel.read(); - SessionManager.logger.writeLog("FirstConnector: command = " + command); - switch(command.cmd) { - case SMCMD_JOIN: - { - //どのSessionにも属さないエディタをリストに追加 - //エディタとchannelは1対1 (ではないかも) - //エディタが新しくputする場合は新しくソケットを作る - // 1対1でない場合は、multiplexerを挿めば良い - Editor editor = manager.newEditor(channel); - editor.setHost(manager.myHost); - command.eid = editor.eid; - command.sid = -1; - editor.setSID(-1); - fw = editor; - break; - } - case SMCMD_PUT: - { - // 新しいeditorとsessionをここで作る。eid,sidは、 - // session manager IDが付いているので、global unique - Editor editor = manager.newEditor(channel); - Session session = manager.newSession(editor); - session.setName(command.string); - editor.setName(command.string); - editor.setSID(session.getSID()); - command.eid = editor.eid; - command.sid = editor.sid; - fw = editor; - break; - } - case SMCMD_SM_JOIN: - { - fw = new Forwarder(manager); - manager.smList.addWaitingSessionManager(fw, command); - break; - } - case SMCMD_SM_JOIN_ACK: - manager.setSessionManagerID(command.sid); - manager.afterConnect(); - fw = new Forwarder(manager); - manager.setParent(fw); - break; - default: throw new IOException(); - } - //myHost を設定。 - //立ち上げ時にやるとlocalhostしか取れない - if(manager.myHost == null) manager.setMyHostName(getLocalHostName()); - fw.setMode(command.cmd); - fw.setHost(manager.myHost); - manager.registerChannel(channel, fw); - manager.sessionManage(fw, command); - - } - -} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/Forwarder.java --- a/rep/Forwarder.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,120 +0,0 @@ -package rep; - -import java.io.IOException; -import rep.channel.REPLogger; -import rep.channel.REPSelectionKey; -import rep.channel.REPSocketChannel; -import rep.handler.PacketSet; -import rep.handler.REPHandler; - -public class Forwarder extends EditorPlus implements REPHandler { - int seq = 0; - Forwarder next; - // REPCommands we sent to the next editor - final int limit=100; - REPLogger ns = REPLogger.singleton(); - SessionManager manager; - public REP mode = null; - - public Forwarder(SessionManager manager) { - this.manager = manager; - } - - public int seq() { - return seq++; - } - - public void send(REPCommand command) { - assert(command!=null); - assert(channel!=null); - REPCommand c = new REPCommand(command); - manager.addWriteQueue(new PacketSet(channel,null, c)); - } - - public REPSocketChannel getChannel() { - return channel; - } - - public void setChannel(REPSocketChannel channel) { - this.channel = channel; - } - - public void setQuit2(REPCommand cmd) { - send(cmd); - } - - public void setNext(Forwarder next) { - this.next = next; - } - - public Forwarder getNextForwarder() { - return next; - } - - public boolean manage(REPCommand command) { - next.send(command); - return true; - } - - public String toString(){ - return ("Forwarder:" + channel); - } - - public String getLocalHostName() { - return channel.getLocalHostName(); - } - - public void cancel(REPSocketChannel socketChannel) { - manager.remove(socketChannel); - } - - public void handle(REPSelectionKey key) throws IOException { - /* - * SessionManagerから来たコマンドは、Editor関係のコマンドは、 - * sessionとeidを判定して、そのeditorにforwardしてやれば良い。 - * 残りは、manager.manage() で処理する。 - */ - REPSocketChannel channel = key.channel1(); - REPCommand command = channel.read(); - SessionManager.logger.writeLog("REPHandlerImpl.handle() : command = " + command); - if (manager.sessionManage(this, command)) return; - - distpatchToEditor(channel, command); - } - - private void distpatchToEditor(REPSocketChannel channel, - REPCommand command) throws IOException { - Session s = manager.getSession(command.sid); - if (s==null) throw new IOException(); - Forwarder f = s.getForwarder(channel); - if (f==null) throw new IOException(); - if (!f.isDirect()) { - // another forwarder, pass it to the next session manager - f.send(command); - return; - } - /* - * local editor case. - */ - Editor editor = (Editor)f; - editor.forwardedCommandManage(command, this); - } - - public void setMode(REP cmd) { - mode = cmd; - } - - public boolean isEditor() { - return mode==REP.SMCMD_JOIN||mode==REP.SMCMD_PUT; - } - - public boolean isForwarder() { - return mode==REP.SMCMD_SM_JOIN||mode==REP.SMCMD_SM_JOIN_ACK; - } - - public boolean isDirect() { - return isEditor(); - } - - -} \ No newline at end of file diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/NullForwarder.java --- a/rep/NullForwarder.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -package rep; - -import java.io.IOException; - -import rep.channel.REPSelectionKey; -import rep.channel.REPSocketChannel; - -public class NullForwarder extends Forwarder { - - public NullForwarder(SessionManager manager) { - super(manager); - } - - public void send(REPCommand command) { - - } - public void cancel(REPSocketChannel socketChannel) { - - } - - public void handle(REPSelectionKey key) throws IOException { - - } - - public boolean manage(REPCommand command) { - return true; - } - - public boolean isEditor() { - return false; - } - - public boolean isForwarder() { - return false; - } - - public boolean isDirect() { - return false; - } - -} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/PacketSet.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rep/PacketSet.java Mon Nov 10 22:07:45 2008 +0900 @@ -0,0 +1,23 @@ +package rep; + +import rep.channel.REPSocketChannel; +import rep.handler.REPNode; + +public class PacketSet { + + public REPSocketChannel channel; + public REPNode editor; + public REPCommand command; + + public PacketSet(REPSocketChannel channel, REPNode editor, REPCommand command) { + this.channel = channel; + this.editor = editor; + this.command = command; + } + + public REPNode getEditor() { + return editor; + } + + +} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/REPCommand.java --- a/rep/REPCommand.java Mon Nov 10 01:12:46 2008 +0000 +++ b/rep/REPCommand.java Mon Nov 10 22:07:45 2008 +0900 @@ -9,12 +9,8 @@ public int seq; public int len; public int lineno; - public boolean stat; - public boolean throughMaster; public String string; - String host; - String port; public REPCommand(REP cmd,int sid,int eid, int seq, int lineno, String string) { this.cmd = cmd; @@ -23,8 +19,8 @@ this.seq = seq; this.lineno = lineno; this.string = string; - this.throughMaster = false; } + public REPCommand(REPCommand cmd){ this(cmd.cmd, cmd.sid, cmd.eid, cmd.seq, cmd.lineno, cmd.string); } @@ -40,7 +36,6 @@ this.seq = seq; this.lineno = lineno; this.string = string; - this.throughMaster = false; } public String toString(){ @@ -66,17 +61,6 @@ string = string2; } - public void setHost(String host) { - this.host = host; - } - - public void setPort(String port) { - this.port = port; - } - - public void setThroughMaster(boolean f){ - this.throughMaster=f; - } public void setSEQID(int i) { seq = i; } diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/REPCommandPacker.java --- a/rep/REPCommandPacker.java Mon Nov 10 01:12:46 2008 +0000 +++ b/rep/REPCommandPacker.java Mon Nov 10 22:07:45 2008 +0900 @@ -41,9 +41,7 @@ * @see rep.REPPack#packUConv(rep.REPCommand) */ public ByteBuffer packUConv(REPCommand command){ - int size = 0; - if (command.string!=null) size = command.string.length()*CHARSIZE; - ByteBuffer buffer = ByteBuffer.allocateDirect(HEADER_SIZE+size); + ByteBuffer buffer = ByteBuffer.allocateDirect(HEADER_SIZE+(command.string.length()*CHARSIZE)); buffer.clear(); // position = 0 buffer.putInt(command.cmd.id); buffer.putInt(command.sid); diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/RoutingTable.java --- a/rep/RoutingTable.java Mon Nov 10 01:12:46 2008 +0000 +++ b/rep/RoutingTable.java Mon Nov 10 22:07:45 2008 +0900 @@ -3,9 +3,11 @@ import java.util.HashMap; import java.util.Map.Entry; +import rep.handler.REPNode; + public class RoutingTable { - HashMap sessionManagers =new HashMap(); + HashMap sessionManagers =new HashMap(); SessionManager manager; // we don't need this, but we keep it because it is easy. // editor can be reached using this routing table. @@ -14,12 +16,12 @@ manager = sessionManager; } - public void add(Forwarder forwarder, int smid) { + public void add(REPNode forwarder, int smid) { if (smid>0) sessionManagers.put(smid, forwarder) ; } - public void remove(Forwarder f) { - for(Entry entry:sessionManagers.entrySet()) { + public void remove(REPNode f) { + for(Entry entry:sessionManagers.entrySet()) { if (entry.getValue()==f) sessionManagers.remove(entry.getKey()); } } @@ -28,8 +30,8 @@ sessionManagers.remove(smid); } - public Forwarder toSessionManager(int eid) { - Forwarder next = sessionManagers.get(eid); + public REPNode toSessionManager(int eid) { + REPNode next = sessionManagers.get(eid); if (next==null) return manager.smList.parent(); return next; } diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/SelectButtonEvent.java --- a/rep/SelectButtonEvent.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -package rep; - -import java.io.IOException; - -public class SelectButtonEvent implements SessionManagerEvent{ - - private int sid; - private Forwarder editor; - - public SelectButtonEvent(Forwarder editor, Session session) { - this.editor = editor; - this.sid = session.getSID(); - } - - public int getSID() { - return sid; - } - - public Forwarder getEditor() { - return editor; - } - - public void exec(SessionManager manager) { - try { - manager.selectSession(this); - } catch (IOException e) { - } - } - -} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/Session.java --- a/rep/Session.java Mon Nov 10 01:12:46 2008 +0000 +++ b/rep/Session.java Mon Nov 10 22:07:45 2008 +0900 @@ -4,35 +4,38 @@ import java.util.HashMap; import java.util.LinkedList; import rep.channel.REPSocketChannel; +import rep.handler.Editor; +import rep.handler.REPNode; +import rep.handler.Forwarder; -public class Session extends HashMap { +public class Session extends HashMap { /** * */ private static final long serialVersionUID = 1L; - private Forwarder masterEditor; + private REPNode masterEditor; private int sessionID; private String sessionName; // isOnwer means this session has active channels(forwarders). private boolean isOwner = false; - private Forwarder first; - private Forwarder last; + private REPNode first; + private REPNode last; - public Session(int sid, String name, Forwarder editor) { + public Session(int sid, String name, REPNode editor) { this(sid, editor); sessionName = name; } - public Session(int sid, Forwarder editor) { + public Session(int sid, REPNode master) { sessionID = sid; - if (editor!=null) { + if (master!=null) { // we have a master - masterEditor = last = editor; - editor.setSID(sid); - put(editor.eid,editor); - if(editor.channel!=null) { - first = editor; + masterEditor = last = master; + master.setSID(sid); + put(master.eid,master); + if(master.channel!=null) { + first = master; masterEditor.setNext(masterEditor); isOwner = true; } @@ -42,15 +45,15 @@ /* * どこにlocal editorを入れても良いのだが、まとめた方が良いか? */ - public void addForwarder(Forwarder forwarder) { + public void addForwarder(REPNode editor) { // add a forwarder and connect this to the session - forwarder.setSID(sessionID); - forwarder.setNext(last.getNextForwarder()); - last.setNext(forwarder); - last = forwarder; - put(forwarder.eid,forwarder); + editor.setSID(sessionID); + editor.setNext(last.getNextForwarder()); + last.setNext(editor); + last = editor; + put(editor.eid,editor); isOwner = true; - if(first==null) first = forwarder; + if(first==null) first = editor; // printSessionDetail(); } @@ -62,14 +65,14 @@ put(editor.eid,editor); } - public Collection getEditorList() { + public Collection getEditorList() { return values(); } public int getSID() { return sessionID; } - public Forwarder getOwner() { + public REPNode getOwner() { return masterEditor; } public String getName() { @@ -78,14 +81,14 @@ public boolean deleteEditor(REPSocketChannel channel) { - LinkedList toBeRemoved = new LinkedList(); - for (EditorPlus e:values() ) { + LinkedList toBeRemoved = new LinkedList(); + for (REPNode e:values() ) { if (e.getChannel()==channel) { unconnect((Forwarder)e); toBeRemoved.add(e); } } - for(EditorPlus e:toBeRemoved) { + for(REPNode e:toBeRemoved) { remove(e); } return !toBeRemoved.isEmpty(); @@ -98,7 +101,7 @@ private void unconnect(Forwarder e) { boolean hasOwner = false; - for(EditorPlus e1:values()) { + for(REPNode e1:values()) { Forwarder f = (Forwarder)e1; if(f.next==e) { f.next=e.next; @@ -121,7 +124,7 @@ public Editor getEditor(REPSocketChannel channel) { - for(EditorPlus editor : values()){ + for(REPNode editor : values()){ if(editor.getChannel() == channel) { return (Editor)editor; } @@ -132,14 +135,14 @@ public void closeSession() { - Forwarder f = first; + REPNode f = first; REPCommand command = new REPCommand(REP.REPCMD_CLOSE, sessionID, REP.SM_EID.id, 0, 0, ""); if (f!=null) f.send(command); } - public Forwarder getForwarder(REPSocketChannel channel) { - Forwarder f = first; + public REPNode getForwarder(REPSocketChannel channel) { + REPNode f = first; while(f.channel!=channel) f = f.next; SessionManager.logger.writeLog("getFirstForwarder="+f.next+"=>"+f.next.channel); return f.next; @@ -147,7 +150,7 @@ public void remove(SessionManager manager) { - for(EditorPlus editor : values()){ + for(REPNode editor : values()){ if(editor.getChannel() !=null) unconnect((Forwarder)editor); manager.editorList.remove(editor); @@ -156,8 +159,8 @@ public void merge(Session s) { - for(EditorPlus editor : s.values()){ - EditorPlus mine = get(editor.eid); + for(REPNode editor : s.values()){ + REPNode mine = get(editor.eid); if (mine==null) { put(editor.eid,editor); } else { @@ -179,7 +182,7 @@ } - public void setFirstForwarder(Forwarder f) { + public void setFirstForwarder(REPNode f) { f.setSID(sessionID); put(f.eid,f); f.setNext(f); @@ -187,7 +190,7 @@ } public void printSessionDetail() { - Forwarder f = first; + REPNode f = first; if (f==null) return; String log = "Session Detail "; while (f!=null) { diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/SessionManager.java --- a/rep/SessionManager.java Mon Nov 10 01:12:46 2008 +0000 +++ b/rep/SessionManager.java Mon Nov 10 22:07:45 2008 +0900 @@ -18,8 +18,18 @@ import rep.channel.REPLogger; import rep.channel.REPServerSocketChannel; import rep.channel.REPSocketChannel; -import rep.handler.PacketSet; -import rep.handler.REPHandler; +import rep.gui.CloseButtonEvent; +import rep.gui.DoGUIUpdate; +import rep.gui.SelectButtonEvent; +import rep.gui.SessionManagerEvent; +import rep.gui.SessionManagerEventListener; +import rep.gui.SessionManagerGUI; +import rep.gui.SessionManagerGUIimpl; +import rep.handler.Dispatcher; +import rep.handler.Editor; +import rep.handler.REPNode; +import rep.handler.FirstConnector; +import rep.handler.Forwarder; import rep.channel.REPSelector; import rep.xml.SessionXMLDecoder; import rep.xml.SessionXMLEncoder; @@ -61,7 +71,7 @@ private BlockingQueue waitingEventQueue = new LinkedBlockingQueue();; // host name of this server. One of connecting SocketChannel's hostname - String myHost; + public String myHost; // Single threaded write queueu. To avoid dead lock with too many writes. private LinkedList writeQueue = new LinkedList(); private int receive_port; @@ -75,7 +85,7 @@ SessionXMLDecoder decoder = new SessionXMLDecoder(); SessionXMLEncoder encoder = new SessionXMLEncoder(); // SocketChannel for our parent. At most one parent is allowed. - private Forwarder sm_join_channel; + private REPNode sm_join_channel; // Routing table for session and session manager. private RoutingTable routingTable = new RoutingTable(this); private SessionManagerEvent execAfterConnect = null;; @@ -118,7 +128,7 @@ //getAllByNameで取れた全てのアドレスに対してbindする ssc.socket().bind(new InetSocketAddress(port)); ssc.register(selector, SelectionKey.OP_ACCEPT, - new Forwarder(this)); + new Dispatcher(this)); // FirstConnector? sessionList = new SessionList(); smList = new SessionManagerList(); @@ -183,7 +193,7 @@ List w = waitingCommandInMerge; waitingCommandInMerge = new LinkedList(); for(PacketSet p: w) { - Editor e = p.getEditor(); + REPNode e = p.getEditor(); if(e.isMerging()) { // still merging do nothing waitingCommandInMerge.add(p); } else { @@ -219,7 +229,7 @@ */ private void close(REPSocketChannel channel) { REPSelectionKeykey = channel.keyFor1(selector); - REPHandler handler = (REPHandler)key.attachment(); + REPNode handler = (REPNode)key.attachment(); key.cancel(); handler.cancel(channel); // we have to remove session/enditor @@ -250,7 +260,7 @@ * A hadler throw IOException() in case of a trouble to * close the channel. */ - REPHandler handler = (REPHandler)(key.attachment()); + REPNode handler = (REPNode)key.attachment(); try { handler.handle(key); } catch (IOException e) { @@ -261,7 +271,7 @@ } } - void registerChannel(REPSocketChannel channel,Forwarder handler) throws IOException { + public void registerChannel(REPSocketChannel channel,REPNode handler) throws IOException { if(channel == null) { return; } @@ -280,7 +290,7 @@ } - private void removeChannel(Forwarder channel) { + private void removeChannel(REPNode channel) { REPSelectionKey key = channel.channel.keyFor1(selector); key.cancel(); try { @@ -293,17 +303,17 @@ void updateGUI() { //リストのコピーをGUIに渡す LinkedList sList = new LinkedList(sessionList.values()); - LinkedList eList; + LinkedList eList; if (false) { // local editor only - eList = new LinkedList(); - for(Editor e:editorList.values()) { + eList = new LinkedList(); + for(REPNode e:editorList.values()) { if (getSMID(e.eid)==smList.sessionManagerID()) { eList.add(e); } } } else { - eList = new LinkedList(editorList.values()); + eList = new LinkedList(editorList.values()); } //GUIに反映 Runnable doRun = new DoGUIUpdate(sList, eList, gui); @@ -312,13 +322,13 @@ - void setMyHostName(String localHostName) { + public void setMyHostName(String localHostName) { myHost = localHostName + receive_port; setHostToEditor(myHost); } private void setHostToEditor(String myHost2) { - for(Editor editor : editorList.values()){ + for(REPNode editor : editorList.values()){ if (editor.channel!=null) editor.setHost(myHost2); } @@ -344,7 +354,7 @@ REPSocketChannel sessionchannel = REPSocketChannel.create(new REPCommandPacker()); sessionchannel.connect(addr); while(!sessionchannel.finishConnect()); - Forwarder sm = new FirstConnector(this); + REPNode sm = new FirstConnector(this); registerChannel(sessionchannel, sm); sm_join(sm); }catch (IOException e) { @@ -359,7 +369,7 @@ * channel に SMCMD_SM_JOIN command を送る。 * @param channel */ - private void sm_join(Forwarder channel){ + private void sm_join(REPNode channel){ sm_join_channel = channel; //SM_JOINコマンドを生成。 REPCommand command = new REPCommand(); @@ -387,7 +397,7 @@ int sid = event.getSID(); Session session = sessionList.get(sid); if (session==null) throw new IOException(); - Editor editor = (Editor)event.getEditor(); + REPNode editor = event.getEditor(); if (editor.hasSession()) return; // assert(getSMID(editor.eid)==smList.sessionManagerID()); // assert(editor.channel!=null); @@ -395,12 +405,12 @@ selectSession0(sid, session, editor.getEID(), editor); } - private void selectSession0(int sid, Session session, int eid, Editor editor) { + private void selectSession0(int sid, Session session, int eid, REPNode editor) { if (editor.isDirect()&&editor.getEID()==eid) { selectSession(sid, session, editor.getEID(), editor); } else { // we don't have this editor, search the editor first. - Forwarder next = routingTable.toSessionManager(getSMID(eid)); + REPNode next = routingTable.toSessionManager(getSMID(eid)); // pass the select command to the next path. REPCommand command = new REPCommand(); command.setCMD(REP.SMCMD_SELECT0); @@ -415,7 +425,7 @@ * Select Session Protocol handler * called from GUI or incoming SMCMD_SELECT command. */ - private void selectSession(int sid, Session session, int eid, Forwarder editor) { + private void selectSession(int sid, Session session, int eid, REPNode editor) { if(session.hasOwner()){ // we have selected session. REPCommand sendCommand = new REPCommand(); @@ -440,12 +450,12 @@ } private void forwardSelect(int sid, Session session, int eid, - Forwarder editor) { - Forwarder next; + REPNode editor) { + REPNode next; // session searching continue... next = routingTable.toSessionManager(getSMID(sid)); // make a forwarding channel here - Forwarder f = createSessionDispatcher(sid, next); + REPNode f = createSessionForwarder(sid, next); session.setFirstForwarder(f); session.addForwarder(editor); // pass the select command to the next path. @@ -457,8 +467,9 @@ next.send(command); } - private Forwarder createSessionDispatcher(int sid, Forwarder editor) { - Forwarder f = new Editor(this, false, makeID(editorList.newEid())); + private REPNode createSessionForwarder(int sid, REPNode editor) { + REPNode f = new Forwarder(this); + f.setEID(makeID(editorList.newEid())); f.setChannel(editor.channel); // incoming channel f.setHost(myHost); f.setSID(sid); @@ -479,9 +490,9 @@ * Create new editor in this sessin manager. A dummy editor * is created also. */ - public Editor newEditor(REPSocketChannel channel) { + public REPNode newEditor(REPSocketChannel channel) { int eid = makeID(editorList.newEid()); - Editor editor = new Editor(this, eid, channel); + REPNode editor = new Editor(this, eid, channel); editorList.add(editor); return editor; } @@ -489,7 +500,7 @@ /* * Create new session. */ - public Session newSession(Forwarder master) { + public Session newSession(REPNode master) { int sid= makeID(sessionList.newSessionID()); Session session = new Session(sid, master); sessionList.put(sid, session); @@ -584,7 +595,7 @@ } - boolean sessionManage(Forwarder forwarder, REPCommand command) throws ClosedChannelException, + public boolean sessionManage(REPNode forwarder, REPCommand command) throws ClosedChannelException, IOException { switch(command.cmd){ @@ -652,9 +663,9 @@ /* * finding joining editor, do not make the path. */ - Forwarder editor = editorList.get(command.eid); + REPNode editor = editorList.get(command.eid); if (editor==null|| !editor.isDirect()) { - Forwarder next = routingTable.toSessionManager(getSMID(command.eid)); + REPNode next = routingTable.toSessionManager(getSMID(command.eid)); next.send(command); break; } @@ -671,7 +682,7 @@ } // Do not directly addForwarder(forwarder). It may be // shared among sessions. - Forwarder f = createSessionDispatcher(command.sid, forwarder); + REPNode f = createSessionForwarder(command.sid, forwarder); session.addForwarder(f); // f.next is set up here. selectSession(command.sid, session, command.eid, forwarder); } @@ -731,8 +742,8 @@ return true; } - private void registSessionManager(Forwarder forwarder, REPCommand command) { - Forwarder sm; + private void registSessionManager(REPNode forwarder, REPCommand command) { + REPNode sm; int psid = command.eid; if (forwarder.sid!=-1) { // すでに channelはSessionManager Idを持っていて、 @@ -770,7 +781,7 @@ * 指定されたeditorがlocalにあるかどうかを調べる。なければ、他に送る。戻って何回も探すことが * あり得るので、よろしくない。 */ - private void searchSelectedEditor(REPCommand command, Forwarder editor) { + private void searchSelectedEditor(REPCommand command, REPNode editor) { for(;editor.isDirect();editor = editor.getNextForwarder()) { if (editor.getEID()==command.eid) { // select したeditor を見つけた @@ -821,10 +832,10 @@ * @param forwarder Editor to be add * @param command */ - public void registEditor(Forwarder forwarder,REPCommand command) { + public void registEditor(REPNode forwarder,REPCommand command) { // make ack for PUT/JOIN. Do not send this to the editor, // before select. After select, ack is sent to the editor. - Editor editor; + REPNode editor; if (getSMID(command.eid)==smList.sessionManagerID()) { if (forwarder.isDirect()) { editor = (Editor)forwarder; @@ -880,7 +891,7 @@ execAfterConnect = null; } - public void setParent(Forwarder fw) { + public void setParent(REPNode fw) { smList.setParent(fw); } @@ -890,5 +901,9 @@ return "rep.SessionManager-"+myId+"@"+myHost+":"+receive_port; } + public void addWaitingSessionManager(REPNode fw, REPCommand command) { + smList.addWaitingSessionManager(fw, command) ; + } + } diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/SessionManagerEvent.java --- a/rep/SessionManagerEvent.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -package rep; - -public interface SessionManagerEvent { - - void exec(SessionManager manager); - -} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/SessionManagerEventListener.java --- a/rep/SessionManagerEventListener.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ -package rep; - -import java.io.IOException; - -//implemented class is SessionManager. - -public interface SessionManagerEventListener { - - public void buttonPressed(SessionManagerEvent event); - public void selectSession(SelectButtonEvent selectButtonEvent) throws IOException; - public void closeSession(SessionManagerEvent event); -} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/SessionManagerGUI.java --- a/rep/SessionManagerGUI.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -package rep; - -import java.util.LinkedList; - -public interface SessionManagerGUI { - - public void update(LinkedList slist, LinkedList elist); - - void invokeLater(Runnable doRun) ; -} \ No newline at end of file diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/SessionManagerGUIimpl.java --- a/rep/SessionManagerGUIimpl.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -package rep; - -import java.awt.Container; -import java.util.LinkedList; -import javax.swing.JFrame; -import javax.swing.SwingUtilities; - -import rep.gui.RPanel; - - -public class SessionManagerGUIimpl implements Runnable, SessionManagerGUI { - - public static void main(String[] args){ - SessionManagerGUIimpl gui = new SessionManagerGUIimpl(new SessionManagerEventListener() { - public void buttonPressed(SessionManagerEvent event) { - } - public void closeSession(SessionManagerEvent event) { - } - public void selectSession(SelectButtonEvent selectButtonEvent) { - } - }); - Thread th = new Thread( gui ); - th.start(); - } - - public SessionManagerGUIimpl(SessionManagerEventListener manager) { - rp = new RPanel(); - rp.addREPActionListener(manager); - Thread th = new Thread(this); - th.start(); - } - - private RPanel rp; - private JFrame frame; - - public void run() { - frame = new JFrame("SessionManager"); - frame.setBounds(100, 100, 600, 300); - Container cont = frame.getContentPane(); - cont.add(rp); - - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.setVisible(true); - - } - - /* (non-Javadoc) - * @see rep.SessionManagerGUIint#update(java.util.LinkedList, java.util.LinkedList) - */ - public void update(LinkedList slist, LinkedList elist) { - rp.setTableSession(slist); - rp.setTableEditor(elist); - } - - - public void invokeLater(Runnable doRun) { - SwingUtilities.invokeLater(doRun); - } - -} \ No newline at end of file diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/SessionManagerList.java --- a/rep/SessionManagerList.java Mon Nov 10 01:12:46 2008 +0000 +++ b/rep/SessionManagerList.java Mon Nov 10 22:07:45 2008 +0900 @@ -2,7 +2,10 @@ import java.util.LinkedList; -public class SessionManagerList extends LinkedList{ +import rep.handler.REPNode; +import rep.handler.NullForwarder; + +public class SessionManagerList extends LinkedList{ /** * @@ -10,11 +13,11 @@ private static final long serialVersionUID = 1L; private int mySMID=0; private int smid_root=0; - private Forwarder parent=new NullForwarder(null); - private LinkedList waiting= new LinkedList(); + private REPNode parent=new NullForwarder(null); + private LinkedList waiting= new LinkedList(); - public void setMaster(Forwarder f) { + public void setMaster(REPNode f) { this.parent = f; } @@ -23,7 +26,7 @@ } public void sendToSlaves(REPCommand repCmd) { - for(Forwarder channel : this){ + for(REPNode channel : this){ channel.send(repCmd); } } @@ -32,11 +35,11 @@ return !parent.isForwarder(); } - public int addNewSessionManager(Forwarder fw,REPCommand receivedCommand) { - add(fw); + public int addNewSessionManager(REPNode sm,REPCommand receivedCommand) { + add(sm); int sid = ++smid_root; - fw.setSID(sid); - fw.setName(receivedCommand.string); + sm.setSID(sid); + sm.setName(receivedCommand.string); return sid; } @@ -49,7 +52,7 @@ return mySMID; } - public void addWaitingSessionManager(Forwarder fw, REPCommand command) { + public void addWaitingSessionManager(REPNode fw, REPCommand command) { // SID assign 待ちのSessionManager Channelを登録する waiting.add(fw); @@ -58,7 +61,7 @@ public void assignSessionManagerIDtoWaitingSM(int sid) { // 待っていたSession Manager ChannelにSession IDを登録し,Session Manager List // に登録する。この次のsm_join_ackでSIDが確定する。 - Forwarder waiter; + REPNode waiter; if ((waiter=waiting.poll())!=null) { waiter.setSID(sid); add(waiter); @@ -67,11 +70,11 @@ assert false; } - public void setParent(Forwarder fw) { + public void setParent(REPNode fw) { parent = fw; } - public Forwarder parent() { + public REPNode parent() { return parent; } diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/SessionManagerNode.java --- a/rep/SessionManagerNode.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -package rep; - -import java.nio.channels.SocketChannel; - -public class SessionManagerNode { - - public SessionManagerNode(SocketChannel channel) { - } - -} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/SessionViewer.java --- a/rep/SessionViewer.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -package rep; - -import java.awt.Component; - -import javax.swing.JTree; -import javax.swing.event.TreeSelectionEvent; -import javax.swing.event.TreeSelectionListener; -import javax.swing.tree.DefaultMutableTreeNode; - -public class SessionViewer implements TreeSelectionListener { - /** - * - */ - private static final long serialVersionUID = 1L; - DefaultMutableTreeNode nRoot = new DefaultMutableTreeNode("top"); - DefaultMutableTreeNode nJapan = new DefaultMutableTreeNode("Session:1"); - DefaultMutableTreeNode nUsa = new DefaultMutableTreeNode("Session:2"); - DefaultMutableTreeNode nKantoh = new DefaultMutableTreeNode("Editor:1"); - DefaultMutableTreeNode nKansai = new DefaultMutableTreeNode("Editor:2"); - DefaultMutableTreeNode nTokyo = new DefaultMutableTreeNode("Editor:3"); - private JTree tree; - SessionViewer() { - tree = new JTree(nRoot); - tree.setRootVisible(true); - tree.addTreeSelectionListener(this); - //getContentPane().add(tree); - - nRoot.add(nJapan); - nRoot.add(nUsa); - nJapan.add(nKantoh); - nJapan.add(nKansai); - nUsa.add(nTokyo); - //nJapan.remove(0); - - //setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - //setTitle("JTreeTest"); - //setSize(200, 150); - //setVisible(true); - } - public void valueChanged(TreeSelectionEvent e) { - JTree tree = (JTree)e.getSource(); - DefaultMutableTreeNode node = - (DefaultMutableTreeNode)tree.getLastSelectedPathComponent(); - if (node != null) { - System.out.println((String)node.getUserObject()); - } - } - public static void main(String[] args) { - new SessionViewer(); - } - public Component getTree() { - // TODO Auto-generated method stub - return tree; - } - public void addSessionTree(int sid) { - // TODO Auto-generated method stub - nRoot.add(new DefaultMutableTreeNode("Session:"+sid)); - } -} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/Translator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rep/Translator.java Mon Nov 10 22:07:45 2008 +0900 @@ -0,0 +1,47 @@ +package rep; + +import rep.handler.REPNode; + +public interface Translator { + + /* + * Interface で分離する意味が良くわからない。Application毎に + * Transltorを換えるつもりなのか? + */ + /** + * Translate command When the editor send REPCommand to remote editor. + * @param command which the editor want to send. + * @return translated command which should be sent by the editor. + */ + public REPCommand transSendCmd(REPCommand cmd); + + /** + * Inform translater about that the editor receive own command which it sent. + * but in this case, you can use also transReceiveCmd() + * @param command which the editor sent. + */ + public boolean catchOwnCommand(REPNode editor); + + /** + * Translate Command cmd that was received from SeMa. + * @param cmd the command to be translated. + * @return translated command. + */ + public void transReceiveCmd(REPNode next,REPCommand cmd); + + /** + * set the editor's id. + * @param editor's id. + */ + public void setEid(int _eid); + + boolean checkMergeConflict(REPCommand command); + + public void getMergeAgain(REPNode editor); + + public void startMerge(REPCommand cmd); + + public boolean isMerging(); + + public void mergeAck(); +} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/TranslatorImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rep/TranslatorImpl.java Mon Nov 10 22:07:45 2008 +0900 @@ -0,0 +1,228 @@ +package rep; + +import java.util.Collection; +import java.util.Comparator; +import java.util.LinkedList; +import java.util.List; +import java.util.TreeSet; + +import rep.handler.REPNode; +import rep.optimizers.REPCommandOptimizer; + +public class TranslatorImpl implements Translator{ + public int eid; + + public REPCommandOptimizer optimizer; + private LinkedList unMergedCmds; + public LinkedList sentMergedList; + private LinkedList mergeAgainList; + boolean merge_mode = false; + + public TranslatorImpl(int _eid,REPCommandOptimizer opt){ + eid = _eid; + optimizer = opt; + unMergedCmds = new LinkedList(); + mergeAgainList = new LinkedList(); + sentMergedList = new LinkedList(); + } + + /** + * New command from an editor + * The command is sent to the next editor + * @param cmd + * @return translated command. + */ + public REPCommand transSendCmd(REPCommand cmd){ + assert(cmd.eid==eid); + unMergedCmds.add(cmd); + + //マージ中にユーザから割り込みがあった場合 + if(isMerging()){ + mergeAgainList.add(cmd); + } + + return cmd; + } + /** + * My command is returned from the session ring, and START_MERGE_ACK + * is returned. At this + * stage my writeQueue is empty, our editor is waiting for me. + * Start merge process. + * @param cmd + */ + public boolean catchOwnCommand(REPNode editor){ + LinkedList output = new LinkedList(); + LinkedList cmds = new LinkedList(); + //スタック上にあるコマンドを全部undoコマンドにする + while ( !unMergedCmds.isEmpty() ){ + REPCommand cmd0 = unMergedCmds.removeLast(); + output.add( createUndo(cmd0) ); + cmds.add(cmd0); + } + + /* 必要な分だけソートして返却用のリストに追加 */ + output.addAll( sortCmds(cmds) ); + + /* 残ったコマンドも再び実行させるが、まだマージされてないのでunMergedにも入れる */ + output.addAll(cmds); + for(REPCommand c: cmds) { + output.add(c); + unMergedCmds.add(c); + } + return optimizedSend(editor,output); + } + + /** + * Sent optimized merged command list + * @param editor + * @param output + * @return if any sent commands output + */ + public boolean optimizedSend(REPNode editor, LinkedList output) { + List output1 = optimizer.optimize(output); + if (output1.size()==0) { + merge_mode = false; + return false; + } + for(REPCommand c:output1) { + REPCommand m = new REPCommand(c); + m.setEID(REP.MERGE_EID.id); + m.setSEQID(editor.seq()); + sentMergedList.add(m); + editor.send(m); + } + return true; + } + + private REPCommand createUndo(REPCommand cmd){ + REPCommand retCmd = new REPCommand(cmd); + 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{ + + 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 sortCmds(LinkedList cmds) { + TreeSet sortedCmds1 = new TreeSet(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(LinkedList cmds, int lowEid) { + int cEid, cSeq; + cEid=cSeq=Integer.MAX_VALUE; + int ret=-1; + for (int i=0; icEid ) continue; + else if ( c.eid==cEid ) { + if ( c.seq>cSeq ) continue; + cSeq=c.seq; + ret = i; + } else { /* tmp.eid 0){ + mergeAgainList.add(command); + return true; + } + if(sentMergedList.size()==0) { + merge_mode=false; + } + return false; + } + + public void getMergeAgain(REPNode editor) { + LinkedList returnCommand = new LinkedList(); + 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(); + optimizedSend(editor, returnCommand); + } + + public boolean isFinished() { + if(unMergedCmds.size() > 0) return false; + if(sentMergedList.size() > 0) return false; + return true; + } + + public boolean isMerging() { + return merge_mode; + } + + public void startMerge(REPCommand cmd) { + merge_mode = true; + } + + public void mergeAck() { + } + + + +} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/channel/ChannelSimulator.java diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/channel/NetworkSimulator.java diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/channel/SelectionKeySimulator.java diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/channel/SelectorSimulator.java diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/channel/ServerChannelSimulator.java diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/gui/CloseButtonEvent.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rep/gui/CloseButtonEvent.java Mon Nov 10 22:07:45 2008 +0900 @@ -0,0 +1,24 @@ +package rep.gui; + +import rep.Session; +import rep.SessionManager; + +public class CloseButtonEvent implements SessionManagerEvent { + + private Session session; + private SessionManagerEventListener listener; + + public CloseButtonEvent(Session session, SessionManagerEventListener listener) { + this.session = session; + this.listener = listener; + } + + public Session getSession(){ + return session; + } + + public void exec(SessionManager manager) { + listener.closeSession(this); + } + +} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/gui/ConnectButtonEvent.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rep/gui/ConnectButtonEvent.java Mon Nov 10 22:07:45 2008 +0900 @@ -0,0 +1,21 @@ +package rep.gui; + +import rep.SessionManager; + +public class ConnectButtonEvent implements SessionManagerEvent{ + + private String host; + + public ConnectButtonEvent(String host) { + this.host = host; + } + + public String getHost() { + return host; + } + + public void exec(SessionManager manager) { + manager.connectSessionManager(host); + } + +} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/gui/DoGUIUpdate.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rep/gui/DoGUIUpdate.java Mon Nov 10 22:07:45 2008 +0900 @@ -0,0 +1,23 @@ +package rep.gui; + +import java.util.LinkedList; + +import rep.Session; +import rep.handler.REPNode; + +public class DoGUIUpdate implements Runnable{ + + private LinkedList slist; + private LinkedList elist; + private SessionManagerGUI gui; + + public DoGUIUpdate(LinkedList _slist, LinkedList list, SessionManagerGUI _gui) { + gui = _gui; + slist = _slist; elist = list; + } + + public void run() { + gui.update(slist, elist); + } + +} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/gui/RPanel.java --- a/rep/gui/RPanel.java Mon Nov 10 01:12:46 2008 +0000 +++ b/rep/gui/RPanel.java Mon Nov 10 22:07:45 2008 +0900 @@ -15,16 +15,10 @@ import javax.swing.JTextField; import javax.swing.table.DefaultTableModel; -import rep.CloseButtonEvent; -import rep.ConnectButtonEvent; -import rep.Editor; -import rep.EditorPlus; -import rep.Forwarder; import rep.REPCommand; -import rep.SelectButtonEvent; import rep.Session; -import rep.SessionManagerEventListener; import rep.channel.REPSocketChannel; +import rep.handler.REPNode; import java.util.*; @@ -49,7 +43,7 @@ private DefaultTableModel s_tableModel = new DefaultTableModel(session_column, 0); private DefaultTableModel e_tableModel = new DefaultTableModel(editor_column, 0); //LinkedList s_list = new LinkedList(); - LinkedList e_list = new LinkedList(); + LinkedList e_list = new LinkedList(); private String s_host; private String s_port; private String s_file; @@ -60,7 +54,7 @@ private JButton selectButton; private JButton closeButton; private SessionManagerEventListener listener; - private LinkedList editorList; + private LinkedList editorList; private LinkedList sessionList; public RPanel() { @@ -159,15 +153,15 @@ } } - public void setTableEditor(LinkedList list) { + public void setTableEditor(LinkedList elist) { /* * Editor.eid is unique in a session, we cannot use. * number it simply based on the order in the list */ e_tableModel.setRowCount(0); - editorList = list; + editorList = elist; int i=0; - for(Forwarder editor : list){ + for(REPNode editor : elist){ setTableEditor(i++, editor.getChannel()); } } diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/gui/SelectButtonEvent.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rep/gui/SelectButtonEvent.java Mon Nov 10 22:07:45 2008 +0900 @@ -0,0 +1,34 @@ +package rep.gui; + +import java.io.IOException; + +import rep.Session; +import rep.SessionManager; +import rep.handler.REPNode; + +public class SelectButtonEvent implements SessionManagerEvent{ + + private int sid; + private REPNode editor; + + public SelectButtonEvent(REPNode editorPlus, Session session) { + this.editor = editorPlus; + this.sid = session.getSID(); + } + + public int getSID() { + return sid; + } + + public REPNode getEditor() { + return editor; + } + + public void exec(SessionManager manager) { + try { + manager.selectSession(this); + } catch (IOException e) { + } + } + +} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/gui/SessionManagerEvent.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rep/gui/SessionManagerEvent.java Mon Nov 10 22:07:45 2008 +0900 @@ -0,0 +1,9 @@ +package rep.gui; + +import rep.SessionManager; + +public interface SessionManagerEvent { + + void exec(SessionManager manager); + +} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/gui/SessionManagerEventListener.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rep/gui/SessionManagerEventListener.java Mon Nov 10 22:07:45 2008 +0900 @@ -0,0 +1,13 @@ +package rep.gui; + +import java.io.IOException; + + +//implemented class is SessionManager. + +public interface SessionManagerEventListener { + + public void buttonPressed(SessionManagerEvent event); + public void selectSession(SelectButtonEvent selectButtonEvent) throws IOException; + public void closeSession(SessionManagerEvent event); +} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/gui/SessionManagerGUI.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rep/gui/SessionManagerGUI.java Mon Nov 10 22:07:45 2008 +0900 @@ -0,0 +1,13 @@ +package rep.gui; + +import java.util.LinkedList; + +import rep.Session; +import rep.handler.REPNode; + +public interface SessionManagerGUI { + + public void update(LinkedList slist, LinkedList elist); + + void invokeLater(Runnable doRun) ; +} \ No newline at end of file diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/gui/SessionManagerGUIimpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rep/gui/SessionManagerGUIimpl.java Mon Nov 10 22:07:45 2008 +0900 @@ -0,0 +1,61 @@ +package rep.gui; + +import java.awt.Container; +import java.util.LinkedList; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +import rep.Session; +import rep.handler.REPNode; + + +public class SessionManagerGUIimpl implements Runnable, SessionManagerGUI { + + public static void main(String[] args){ + SessionManagerGUIimpl gui = new SessionManagerGUIimpl(new SessionManagerEventListener() { + public void buttonPressed(SessionManagerEvent event) { + } + public void closeSession(SessionManagerEvent event) { + } + public void selectSession(SelectButtonEvent selectButtonEvent) { + } + }); + Thread th = new Thread( gui ); + th.start(); + } + + public SessionManagerGUIimpl(SessionManagerEventListener manager) { + rp = new RPanel(); + rp.addREPActionListener(manager); + Thread th = new Thread(this); + th.start(); + } + + private RPanel rp; + private JFrame frame; + + public void run() { + frame = new JFrame("SessionManager"); + frame.setBounds(100, 100, 600, 300); + Container cont = frame.getContentPane(); + cont.add(rp); + + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setVisible(true); + + } + + /* (non-Javadoc) + * @see rep.SessionManagerGUIint#update(java.util.LinkedList, java.util.LinkedList) + */ + public void update(LinkedList slist, LinkedList elist) { + rp.setTableSession(slist); + rp.setTableEditor(elist); + } + + + public void invokeLater(Runnable doRun) { + SwingUtilities.invokeLater(doRun); + } + +} \ No newline at end of file diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/handler/Dispatcher.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rep/handler/Dispatcher.java Mon Nov 10 22:07:45 2008 +0900 @@ -0,0 +1,77 @@ +package rep.handler; + +import java.io.IOException; + +import rep.REPCommand; +import rep.Session; +import rep.SessionManager; +import rep.channel.REPSelectionKey; +import rep.channel.REPSocketChannel; + +/** + * @author kono + * Handle SessionManager incoming Channel + * SessionManager Command and Multiplexed Editor Command come here. + * Dispatch Editor command according to the session and the channel. + */ +public class Dispatcher extends Forwarder { + + public Dispatcher(SessionManager manager) { + super(manager); + } + + public void setQuit2(REPCommand cmd) { + send(cmd); + } + + public boolean manage(REPCommand command) { + next.send(command); + return true; + } + + public String toString(){ + return ("Dispatcher:" + channel); + } + + + public void handle(REPSelectionKey key) throws IOException { + /* + * SessionManagerから来たコマンドは、Editor関係のコマンドは、 + * sessionとeidを判定して、そのeditorにforwardしてやれば良い。 + * 残りは、manager.manage() で処理する。 + */ + REPSocketChannel channel = key.channel1(); + REPCommand command = channel.read(); + SessionManager.logger.writeLog("REPHandlerImpl.handle() : command = " + command); + if (manager.sessionManage(this, command)) return; + + distpatchToEditor(channel, command); + } + + private void distpatchToEditor(REPSocketChannel channel, + REPCommand command) throws IOException { + Session s = manager.getSession(command.sid); + if (s==null) throw new IOException(); + REPNode f = s.getForwarder(channel); + if (f==null) throw new IOException(); + if (!f.isDirect()) { + // another forwarder, pass it to the next session manager + f.send(command); + return; + } + /* + * local editor case. + */ + Editor editor = (Editor)f; + editor.forwardedCommandManage(command, this); + } + + + public void setNext(REPNode f) { + next = f; + } + + public boolean isMerging() { + return false; + } +} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/handler/Editor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rep/handler/Editor.java Mon Nov 10 22:07:45 2008 +0900 @@ -0,0 +1,249 @@ +package rep.handler; + +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; + +import rep.PacketSet; +import rep.REP; +import rep.REPCommand; +import rep.SessionManager; +import rep.Translator; +import rep.TranslatorImpl; +import rep.channel.REPSelectionKey; +import rep.channel.REPSocketChannel; +import rep.optimizers.*; + +public class Editor extends Forwarder { + + private Translator translator; + private List sentList = new LinkedList(); + // REPCommands we are going to send to the next editor + //private REPCommand quit2 = null; + private SessionManager manager; + private REPCommand quit2=null; + + public Editor(SessionManager manager,boolean doOptimize,int editorNo){ + super(manager); + this.manager = manager; + eid = editorNo; + REPCommandOptimizer optimizer; + if (doOptimize) optimizer = new DeleteInsertOptimizer(); //タカノがつくったおぷてぃまいざ + else optimizer = new NullOptimizer(); //なにもしないけどOptimizer. + translator = new TranslatorImpl(eid,optimizer); + + } + + public Editor(SessionManager manager,int editorNo, REPSocketChannel channel){ + this(manager,false,editorNo); + this.channel = channel; + } + + public void translate(REPCommand command){ + + if(command.eid == eid){ + //エディタからの新たな編集コマンド + if (next==this) return; // singleton case + translator.transSendCmd(command); + sentList.add(new REPCommand(command)); + assert(sentList.size() key) throws IOException { + REPSocketChannel channel = key.channel1(); + REPCommand command = channel.read(); + SessionManager.logger.writeLog("REPHandlerImpl.handle() read : command = " + command +" from "+channel); + if (manager.sessionManage(this, command)) return; + manage(command); + } + + @Override + public void cancel(REPSocketChannel socketChannel) { + manager.remove(socketChannel); + } + + public boolean isMaster() { + return mode==REP.SMCMD_PUT; + } + + /* Handle special case first, usually these cases + * are handled in the next Editor in a session manager, but + * it is forwarded here. + */ + public void forwardedCommandManage(REPCommand command, REPNode forwarder) { + if (command.cmd==REP.SMCMD_QUIT_2) { + // we have to wait next editor's finishing before sending this. + // this is odd, but the editor itself does not know it's merging + // state. Only this session manager knows it. + setQuit2(command); + } else if (command.eid==eid) { + // if we handle in editor.manage(), this editor cannot distinguish this + // and user input command from the editor. + switch(command.cmd) { + case REPCMD_DELETE: + case REPCMD_INSERT: + case REPCMD_NOP: + checkReturnedCommand(command); + return; + } + } + manage(command); + } +} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/handler/FirstConnector.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rep/handler/FirstConnector.java Mon Nov 10 22:07:45 2008 +0900 @@ -0,0 +1,85 @@ +package rep.handler; + +import java.io.IOException; + +import rep.REPCommand; +import rep.Session; +import rep.SessionManager; +import rep.channel.REPSelectionKey; +import rep.channel.REPSocketChannel; + +public class FirstConnector extends Forwarder { + + public FirstConnector(SessionManager manager) { + super(manager); + } + + public void cancel(REPSocketChannel socketChannel) { + manager.remove(socketChannel); + } + + public void handle(REPSelectionKey key) throws IOException { + /* + * 接続要求は、EditorかSlave Editorで、 + *    join, put, sm_join + * が来る。それ以外はエラー。master もありか? + * sm_join_ack + */ + REPNode fw; + REPSocketChannel channel = key.channel1(); + REPCommand command = channel.read(); + SessionManager.logger.writeLog("FirstConnector: command = " + command); + switch(command.cmd) { + case SMCMD_JOIN: + { + //どのSessionにも属さないエディタをリストに追加 + //エディタとchannelは1対1 (ではないかも) + //エディタが新しくputする場合は新しくソケットを作る + // 1対1でない場合は、multiplexerを挿めば良い + REPNode editor = manager.newEditor(channel); + editor.setHost(manager.myHost); + command.eid = editor.eid; + command.sid = -1; + editor.setSID(-1); + fw = editor; + break; + } + case SMCMD_PUT: + { + // 新しいeditorとsessionをここで作る。eid,sidは、 + // session manager IDが付いているので、global unique + REPNode editor = manager.newEditor(channel); + Session session = manager.newSession(editor); + session.setName(command.string); + editor.setName(command.string); + editor.setSID(session.getSID()); + command.eid = editor.eid; + command.sid = editor.sid; + fw = editor; + break; + } + case SMCMD_SM_JOIN: + { + fw = new Dispatcher(manager); + manager.addWaitingSessionManager(fw, command); + break; + } + case SMCMD_SM_JOIN_ACK: + manager.setSessionManagerID(command.sid); + manager.afterConnect(); + fw = new Dispatcher(manager); + manager.setParent(fw); + break; + default: throw new IOException(); + } + //myHost を設定。 + //立ち上げ時にやるとlocalhostしか取れない + if(manager.myHost == null) manager.setMyHostName(getLocalHostName()); + fw.setMode(command.cmd); + fw.setHost(manager.myHost); + manager.registerChannel(channel, fw); + manager.sessionManage(fw, command); + + } + +} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/handler/Forwarder.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rep/handler/Forwarder.java Mon Nov 10 22:07:45 2008 +0900 @@ -0,0 +1,96 @@ +package rep.handler; + +import java.io.IOException; + +import rep.PacketSet; +import rep.REP; +import rep.REPCommand; +import rep.SessionManager; +import rep.channel.REPLogger; +import rep.channel.REPSelectionKey; +import rep.channel.REPSocketChannel; + +/** + * @author kono + * Forward Editor Command to the other Session Manager + * Basic send API is supported. + */ +public class Forwarder extends REPNode { + int seq = 0; + // REPCommands we sent to the next editor + final int limit=100; // debugging purpose, assert check only + final REPLogger ns = REPLogger.singleton(); + SessionManager manager; + public REP mode = null; + + public Forwarder(SessionManager manager) { + this.manager = manager; + } + + public int seq() { + return seq++; + } + + public void send(REPCommand command) { + assert(command!=null); + assert(channel!=null); + REPCommand c = new REPCommand(command); + manager.addWriteQueue(new PacketSet(channel,null, c)); + } + + public void sendWithSeq(REPCommand command) { + assert(command!=null); + assert(channel!=null); + REPCommand c = new REPCommand(command); + c.setSEQID(seq()); + manager.addWriteQueue(new PacketSet(channel,null, c)); + } + + public REPSocketChannel getChannel() { + return channel; + } + + public void setChannel(REPSocketChannel channel) { + this.channel = channel; + } + + public void setQuit2(REPCommand cmd) { + send(cmd); + } + + public void setNext(Forwarder next) { + this.next = next; + } + + public REPNode getNextForwarder() { + return next; + } + + public boolean manage(REPCommand command) { + next.send(command); + return true; + } + + public String toString(){ + return ("Forwarder:" + channel); + } + + public String getLocalHostName() { + return channel.getLocalHostName(); + } + + public void cancel(REPSocketChannel socketChannel) { + manager.remove(socketChannel); + } + + public void handle(REPSelectionKey key) throws IOException { + assert false; + } + + + public boolean isMerging() { + return false; + } + + +} \ No newline at end of file diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/handler/NullForwarder.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rep/handler/NullForwarder.java Mon Nov 10 22:07:45 2008 +0900 @@ -0,0 +1,43 @@ +package rep.handler; + +import java.io.IOException; + +import rep.REPCommand; +import rep.SessionManager; +import rep.channel.REPSelectionKey; +import rep.channel.REPSocketChannel; + +public class NullForwarder extends Forwarder { + + public NullForwarder(SessionManager manager) { + super(manager); + } + + public void send(REPCommand command) { + + } + public void cancel(REPSocketChannel socketChannel) { + + } + + public void handle(REPSelectionKey key) throws IOException { + + } + + public boolean manage(REPCommand command) { + return true; + } + + public boolean isEditor() { + return false; + } + + public boolean isForwarder() { + return false; + } + + public boolean isDirect() { + return false; + } + +} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/handler/PacketSet.java --- a/rep/handler/PacketSet.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -package rep.handler; - -import rep.Editor; -import rep.REPCommand; -import rep.channel.REPSocketChannel; - -public class PacketSet { - - public REPSocketChannel channel; - public Editor editor; - public REPCommand command; - - public PacketSet(REPSocketChannel channel, Editor editor, REPCommand command) { - this.channel = channel; - this.editor = editor; - this.command = command; - } - - public Editor getEditor() { - return editor; - } - - -} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/handler/REPHandler.java --- a/rep/handler/REPHandler.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -package rep.handler; - -import java.io.IOException; - -import rep.REPCommand; -import rep.channel.REPSelectionKey; -import rep.channel.REPSocketChannel; - -public interface REPHandler { - void handle(REPSelectionKey key) throws IOException; - - void cancel(REPSocketChannel socketChannel); - -} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/handler/REPNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rep/handler/REPNode.java Mon Nov 10 22:07:45 2008 +0900 @@ -0,0 +1,130 @@ +package rep.handler; + +import java.io.IOException; + +import rep.REP; +import rep.REPCommand; +import rep.channel.REPSelectionKey; +import rep.channel.REPSocketChannel; + +public abstract class REPNode { + + public int eid; // globally unique + public int sid=-1; // globally unique + public String host; + public String file; + public REP mode; + public REPSocketChannel channel; + public REPNode next; + + public REPNode() { + + } + + public REPNode(int eid, REPSocketChannel channel) { + this.eid = eid; + this.channel = channel; + } + + public String getName() { + return file; + } + + public void setName(String string) { + file = string; + } + + + public void setSID(int sid) { + this.sid = sid; + } + + public int getSID() { + return sid; + } + + public boolean hasSession() { + return sid != -1; + } + + public String toString(){ + return ("Editor:" + eid); + } + + public void setEID(int eid) { + this.eid = eid; + } + + public int getEID(){ + return eid; + } + + public void setHost(String host){ + if (channel!=null) + this.host = host; + } + + + public String getHost(){ + return host; + } + public REPSocketChannel getChannel(){ + return channel; + + } + public void setChannel(REPSocketChannel channel) { + this.channel = channel; + } + + public void merge(REPNode editor) { + if (sid==-1) sid = editor.sid; + if (file==null) file = editor.file; + if (host==null) host = editor.host; + } + + public abstract void handle(REPSelectionKey key) throws IOException; + + + public abstract void cancel(REPSocketChannel channel1) ; + + public abstract String getLocalHostName(); + + + public abstract void send(REPCommand command) ; + + + public abstract void setQuit2(REPCommand receivedCommand) ; + + public abstract int seq() ; + + public abstract boolean isMerging() ; + + + public abstract boolean manage(REPCommand command) ; + + + public void setMode(REP cmd) { + mode = cmd; + } + + public boolean isEditor() { + return mode==REP.SMCMD_JOIN||mode==REP.SMCMD_PUT; + } + + public boolean isForwarder() { + return mode==REP.SMCMD_SM_JOIN||mode==REP.SMCMD_SM_JOIN_ACK; + } + + public boolean isDirect() { + return isEditor(); + } + + public REPNode getNextForwarder() { + return next; + } + public void setNext(REPNode f) { + next = f; + } + + +} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/translator/Translator.java --- a/rep/translator/Translator.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -package rep.translator; - -import rep.Editor; -import rep.Forwarder; -import rep.REPCommand; - -public interface Translator { - - /* - * Interface で分離する意味が良くわからない。Application毎に - * Transltorを換えるつもりなのか? - */ - /** - * Translate command When the editor send REPCommand to remote editor. - * @param command which the editor want to send. - * @return translated command which should be sent by the editor. - */ - public REPCommand transSendCmd(REPCommand cmd); - - /** - * Inform translater about that the editor receive own command which it sent. - * but in this case, you can use also transReceiveCmd() - * @param command which the editor sent. - */ - public boolean catchOwnCommand(Editor editor); - - /** - * Translate Command cmd that was received from SeMa. - * @param cmd the command to be translated. - * @return translated command. - */ - public void transReceiveCmd(Forwarder nextEditor,REPCommand cmd); - - /** - * set the editor's id. - * @param editor's id. - */ - public void setEid(int _eid); - - boolean checkMergeConflict(REPCommand command); - - public void getMergeAgain(Editor editor); - - public void startMerge(REPCommand cmd); - - public boolean isMerging(); - - public void mergeAck(); -} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/translator/TranslatorImpl.java --- a/rep/translator/TranslatorImpl.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,233 +0,0 @@ -package rep.translator; - -import java.util.Collection; -import java.util.Comparator; -import java.util.LinkedList; -import java.util.List; -import java.util.TreeSet; - -import rep.Editor; -import rep.Forwarder; -import rep.REPCommand; -import rep.REP; -import rep.optimizers.REPCommandOptimizer; - -public class TranslatorImpl implements Translator{ - public int eid; - - public REPCommandOptimizer optimizer; - private LinkedList unMergedCmds; - public LinkedList sentMergedList; - private LinkedList mergeAgainList; - boolean merge_mode = false; - - public TranslatorImpl(int _eid,REPCommandOptimizer opt){ - eid = _eid; - optimizer = opt; - unMergedCmds = new LinkedList(); - mergeAgainList = new LinkedList(); - sentMergedList = new LinkedList(); - } - - /** - * New command from an editor - * The command is sent to the next editor - * @param cmd - * @return translated command. - */ - public REPCommand transSendCmd(REPCommand cmd){ - assert(cmd.eid==eid); - unMergedCmds.add(cmd); - - //マージ中にユーザから割り込みがあった場合 - if(isMerging()){ - mergeAgainList.add(cmd); - } - - return cmd; - } - /** - * My command is returned from the session ring, and START_MERGE_ACK - * is returned. At this - * stage my writeQueue is empty, our editor is waiting for me. - * Start merge process. - * @param cmd - */ - public boolean catchOwnCommand(Editor editor){ - LinkedList output = new LinkedList(); - LinkedList cmds = new LinkedList(); - //スタック上にあるコマンドを全部undoコマンドにする - while ( !unMergedCmds.isEmpty() ){ - REPCommand cmd0 = unMergedCmds.removeLast(); - output.add( createUndo(cmd0) ); - cmds.add(cmd0); - } - - /* 必要な分だけソートして返却用のリストに追加 */ - output.addAll( sortCmds(cmds) ); - - /* 残ったコマンドも再び実行させるが、まだマージされてないのでunMergedにも入れる */ - output.addAll(cmds); - for(REPCommand c: cmds) { - output.add(c); - unMergedCmds.add(c); - } - return optimizedSend(editor,output); - } - - /** - * Sent optimized merged command list - * @param editor - * @param output - * @return if any sent commands output - */ - public boolean optimizedSend(Editor editor, LinkedList output) { - List output1 = optimizer.optimize(output); - if (output1.size()==0) { - merge_mode = false; - return false; - } - for(REPCommand c:output1) { - REPCommand m = new REPCommand(c); - m.setEID(REP.MERGE_EID.id); - m.setSEQID(editor.seq()); - sentMergedList.add(m); - editor.send(m); - } - merge_mode = true; - return true; - } - - private REPCommand createUndo(REPCommand cmd){ - REPCommand retCmd = new REPCommand(cmd); - 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{ - - 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 sortCmds(LinkedList cmds) { - TreeSet sortedCmds1 = new TreeSet(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(LinkedList cmds, int lowEid) { - int cEid, cSeq; - cEid=cSeq=Integer.MAX_VALUE; - int ret=-1; - for (int i=0; icEid ) continue; - else if ( c.eid==cEid ) { - if ( c.seq>cSeq ) continue; - cSeq=c.seq; - ret = i; - } else { /* tmp.eid 0){ - mergeAgainList.add(command); - return true; - } - if(sentMergedList.size()==0) { - merge_mode=false; - } - return false; - } - - public void getMergeAgain(Editor editor) { - LinkedList returnCommand = new LinkedList(); - 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(); - optimizedSend(editor, returnCommand); - } - - public boolean isFinished() { - if(unMergedCmds.size() > 0) return false; - if(sentMergedList.size() > 0) return false; - return true; - } - - public boolean isMerging() { - return merge_mode; - } - - public void startMerge(REPCommand cmd) { - merge_mode = true; - } - - public void mergeAck() { - } - - - - -} diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/xml/SessionXMLDecoder.java --- a/rep/xml/SessionXMLDecoder.java Mon Nov 10 01:12:46 2008 +0000 +++ b/rep/xml/SessionXMLDecoder.java Mon Nov 10 22:07:45 2008 +0900 @@ -13,9 +13,9 @@ import org.xml.sax.InputSource; import org.xml.sax.SAXException; -import rep.Editor; import rep.Session; import rep.SessionList; +import rep.handler.Editor; public class SessionXMLDecoder { diff -r 65fdb3dc1885 -r 4b87f89b3afd rep/xml/SessionXMLEncoder.java --- a/rep/xml/SessionXMLEncoder.java Mon Nov 10 01:12:46 2008 +0000 +++ b/rep/xml/SessionXMLEncoder.java Mon Nov 10 22:07:45 2008 +0900 @@ -14,9 +14,9 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; -import rep.EditorPlus; import rep.Session; import rep.SessionList; +import rep.handler.REPNode; public class SessionXMLEncoder { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); @@ -64,7 +64,7 @@ root.appendChild(elementSession); elementSession.setAttribute("sid", Integer.toString(session.getSID())); - for(EditorPlus editor : session.getEditorList()){ + for(REPNode editor : session.getEditorList()){ Element elementEditor = doc.createElement("Editor"); elementEditor.setAttribute("eid", Integer.toString(editor.getEID())); elementSession.appendChild(elementEditor); diff -r 65fdb3dc1885 -r 4b87f89b3afd test/ConnectionPanel.java --- a/test/ConnectionPanel.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -package test; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -import javax.swing.JButton; -import javax.swing.JPanel; -import javax.swing.JTextField; - -public class ConnectionPanel extends JPanel implements ActionListener{ - - /** - * - */ - private static final long serialVersionUID = 1L; - private JButton button; - private JTextField textField; - public String host; - - public ConnectionPanel() { - button = new JButton("Connect"); - textField = new JTextField("localhost"); - - button.setBounds(160, 5, 100, 20); - textField.setBounds(5, 5, 150, 20); - - this.setLayout(null); - this.add(textField); - this.add( button); - - button.addActionListener(this); - } - - - public void actionPerformed(ActionEvent event) { - if (event.getSource() == button) { - host = textField.getText(); - //System.out.println("pressed!"); - } - } - -} diff -r 65fdb3dc1885 -r 4b87f89b3afd test/DefaultTableModelTest.java --- a/test/DefaultTableModelTest.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -package test; import java.awt.*; import javax.swing.*; import javax.swing.table.*; class DefaultTableModelTest extends JFrame { /** * */ private static final long serialVersionUID = 1L; DefaultTableModelTest() { getContentPane().setLayout(new FlowLayout()); String[][] rowData = { { "A1", "B1", "C1" }, { "A2", "B2", "C2" }, { "A3", "B3", "C3" }, { "A4", "B4", "C4" }, }; String[] colNames = { "A", "B", "C" }; DefaultTableModel tm = new DefaultTableModel(rowData, colNames); JTable tb = new JTable(tm); JScrollPane sp = new JScrollPane(tb); sp.setPreferredSize(new Dimension(230, 80)); getContentPane().add(sp); String[] data = { "A5", "B5", "C5" }; tm.addRow(data); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("DefaultTableModelTest"); setSize(250, 120); setVisible(true); } public static void main(String[] args) { new DefaultTableModelTest(); } } \ No newline at end of file diff -r 65fdb3dc1885 -r 4b87f89b3afd test/JTableTest.java --- a/test/JTableTest.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -package test; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; class JTableTest extends JFrame implements ActionListener, FocusListener, ListSelectionListener{ /** * */ private static final long serialVersionUID = 1L; private JTable tb; JTableTest() { getContentPane().setLayout(new FlowLayout()); tb = new JTable(10, 5); tb.setValueAt("AAA", 0, 0); tb.setValueAt("BBB", 1, 1); tb.setValueAt("CCC", 2, 2); tb.addFocusListener(this); JScrollPane sp = new JScrollPane(tb); sp.setPreferredSize(new Dimension(230, 80)); getContentPane().add(sp); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("JTableTest"); setSize(250, 120); setVisible(true); } public static void main(String[] args) { new JTableTest(); } public void actionPerformed(ActionEvent event) { //if(event.getSource() == tb){ // int a = tb.getSelectedColumn(); // int b = tb.getSelectedRow(); // System.out.println("Selected item is " + a + ":" + b); //} } public void focusGained(FocusEvent event) { int column = tb.getSelectedColumn(); int row = tb.getSelectedRow(); System.out.println("Gained item is " + column + ":" + row); } public void focusLost(FocusEvent event) { } public void valueChanged(ListSelectionEvent event) { int column = tb.getSelectedColumn(); int row = tb.getSelectedRow(); Object value = tb.getValueAt(row, column); System.out.println("Gained item is " + column + ":" + row + "," + value); } } \ No newline at end of file diff -r 65fdb3dc1885 -r 4b87f89b3afd test/RepCommandOptimizeTest.java diff -r 65fdb3dc1885 -r 4b87f89b3afd test/SessionXMLDecoder2.java --- a/test/SessionXMLDecoder2.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -package test; - -import java.io.IOException; -import java.io.StringReader; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; - -public class SessionXMLDecoder2 { - void parse(String string){ - try { - SAXParserFactory spfactory = SAXParserFactory.newInstance(); - SAXParser parser = spfactory.newSAXParser(); - InputSource source = new InputSource(new StringReader(string)); - parser.parse(source, new SessionXMLParser()); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (ParserConfigurationException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (SAXException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } -} diff -r 65fdb3dc1885 -r 4b87f89b3afd test/SessionXMLParser.java --- a/test/SessionXMLParser.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -package test; - -import java.io.IOException; -import java.io.StringReader; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -import org.xml.sax.Attributes; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - -public class SessionXMLParser extends DefaultHandler{ - - public void startDocument() { - System.out.println("Start Document."); - } - - public void startElement(String uri, String localName, String qName, Attributes attributes){ - - } - - - public static void main(String[] args) { - String string = null; - if(args.length > 0) { - string = args[0]; - } - try { - SAXParserFactory spfactory = SAXParserFactory.newInstance(); - SAXParser parser = spfactory.newSAXParser(); - InputSource source = new InputSource(new StringReader(string)); - parser.parse(source, new SessionXMLParser()); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (ParserConfigurationException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (SAXException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - -} diff -r 65fdb3dc1885 -r 4b87f89b3afd test/TestGUI.java --- a/test/TestGUI.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -package test; - -import java.awt.Container; -import javax.swing.JFrame; - - -public class TestGUI { - - private static JFrame frame; - private static ConnectionPanel cp; - //private static ConnectionListener listener; - - public TestGUI() { - } - - public static void main(String[] args){ - frame = new JFrame("SessionManager"); - frame.setBounds(100, 100, 400, 100); - cp = new ConnectionPanel(); - Container cont = frame.getContentPane(); - cont.add(cp); - - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.setVisible(true); - } - -} diff -r 65fdb3dc1885 -r 4b87f89b3afd test/TestSelector.java --- a/test/TestSelector.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ -package test; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.nio.channels.SelectionKey; -import java.nio.channels.Selector; -import java.nio.channels.ServerSocketChannel; - -public class TestSelector { - public static void main(String[] args) throws IOException{ - Selector selector = Selector.open(); - ServerSocketChannel ssc = ServerSocketChannel.open(); - ssc.configureBlocking(false); - ssc.socket().bind(new InetSocketAddress(8765)); - ssc.register(selector, SelectionKey.OP_ACCEPT); - - - } -} diff -r 65fdb3dc1885 -r 4b87f89b3afd test/TestUTF8.java --- a/test/TestUTF8.java Mon Nov 10 01:12:46 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,115 +0,0 @@ -//package rep; -package test; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.CharacterCodingException; -import java.nio.charset.Charset; -import java.nio.charset.CharsetDecoder; -import java.nio.charset.CharsetEncoder; - -import rep.REPCommand; - -public class TestUTF8 { - - public static ByteBuffer pack(REPCommand command){ - System.out.println("send command: " + command.toString()); - ByteBuffer buffer = ByteBuffer.allocateDirect(24+(command.string).length()*2); - buffer.clear(); // position = 0 - buffer.putInt(command.cmd.id); buffer.putInt(command.sid); buffer.putInt(command.eid); - buffer.putInt(command.seq); buffer.putInt(command.lineno); - System.out.println("Plane: Set REPComand textlen(Byte) : " + command.string.length()*2); - buffer.putInt(command.string.length()*2); - for(int i=0;i cmd:"+cmd+" sid:"+sid+" eid:"+eid+"seqid:"+seqid+" lineno:"+lineno+" textsiz:" +textsiz+" text: "+string); - } - - public static void unpackUConv_check(ByteBuffer buffer) { - int cmd = buffer.getInt(); - int sid = buffer.getInt(); - int eid = buffer.getInt(); - int seqid = buffer.getInt(); - int lineno = buffer.getInt(); - int textsiz = buffer.getInt(); - - Charset charset1 = Charset.forName("UTF-8"); - CharsetDecoder decoder = charset1.newDecoder(); - CharBuffer cb = null; - try { - cb = decoder.decode(buffer); - } catch (CharacterCodingException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - String string = cb.toString(); - System.out.println("UTF-8: => cmd:"+cmd+" sid:"+sid+" eid:"+eid+"seqid:"+seqid+" lineno:"+lineno+" textsiz:" +textsiz+" text: "+string); - //System.out.println("string size:"+string.length()); - //System.out.println(string); - } - - public static void main(String[] args) throws IOException{ - String text = "あいうえお、かきくけこ、さしすせそ"; - REPCommand utf8buf = new REPCommand(1, 2, 3, 4, 5, 0, text); - REPCommand buf = new REPCommand(1, 2, 3, 4, 5, 0, text); - ByteBuffer buf1,buf2; - - buf1 = pack(buf); - buf2 = packUConv(utf8buf); - System.out.println(" "); - System.out.println("Encode TEST"); - - System.out.println("Plane: ByteBuffer :" +buf1.toString()); - System.out.println("UTF-8: Encoded byteBuffer :" +buf2.toString()); - - - unpack_check(buf1); - unpackUConv_check(buf2); - } -} diff -r 65fdb3dc1885 -r 4b87f89b3afd test/XMLTest.java --- a/test/XMLTest.java Mon Nov 10 01:12:46 2008 +0000 +++ b/test/XMLTest.java Mon Nov 10 22:07:45 2008 +0900 @@ -1,8 +1,8 @@ package test; -import rep.Editor; import rep.Session; import rep.SessionList; +import rep.handler.Editor; import rep.xml.SessionXMLDecoder; import rep.xml.SessionXMLEncoder; diff -r 65fdb3dc1885 -r 4b87f89b3afd test/channeltest/testEditor.java diff -r 65fdb3dc1885 -r 4b87f89b3afd test/channeltest/testNetworkSimulator.java diff -r 65fdb3dc1885 -r 4b87f89b3afd test/channeltest/testSeMa.java diff -r 65fdb3dc1885 -r 4b87f89b3afd test/channeltest/testSeMaSlave.java diff -r 65fdb3dc1885 -r 4b87f89b3afd test/sematest/TestEditor.java diff -r 65fdb3dc1885 -r 4b87f89b3afd test/sematest/TestGUI.java --- a/test/sematest/TestGUI.java Mon Nov 10 01:12:46 2008 +0000 +++ b/test/sematest/TestGUI.java Mon Nov 10 22:07:45 2008 +0900 @@ -2,13 +2,13 @@ import java.util.LinkedList; -import rep.Editor; -import rep.SelectButtonEvent; import rep.Session; -import rep.SessionManagerEvent; -import rep.SessionManagerEventListener; -import rep.SessionManagerGUI; import rep.channel.REPLogger; +import rep.gui.SelectButtonEvent; +import rep.gui.SessionManagerEvent; +import rep.gui.SessionManagerEventListener; +import rep.gui.SessionManagerGUI; +import rep.handler.REPNode; /** * @author kono @@ -19,7 +19,7 @@ public class TestGUI implements SessionManagerGUI { public LinkedList slist; - public LinkedList elist; + public LinkedList elist; SessionManagerEventListener manager; int count = 0; private REPLogger ns; @@ -33,14 +33,14 @@ doRun.run(); } - public void update(LinkedList slist, LinkedList elist) { + public void update(LinkedList slist, LinkedList elist) { int i = 0; this.slist = slist; this.elist = elist; // fair and deterministic select session for an empty editor if (slist.size()==0) return; Session s = slist.get(count++ % slist.size()); - for(Editor e :elist) { + for(REPNode e :elist) { if (e.isDirect() && !e.hasSession()) { SessionManagerEvent event = new SelectButtonEvent(e, s); ns.writeLog("Select session "+s.getSID()+" and editor "+i); diff -r 65fdb3dc1885 -r 4b87f89b3afd test/sematest/TestInterManagerSession.java --- a/test/sematest/TestInterManagerSession.java Mon Nov 10 01:12:46 2008 +0000 +++ b/test/sematest/TestInterManagerSession.java Mon Nov 10 22:07:45 2008 +0900 @@ -6,8 +6,8 @@ import rep.REP; import rep.REPCommand; import rep.SessionManager; -import rep.SessionManagerEvent; import rep.channel.REPServerSocketChannel; +import rep.gui.SessionManagerEvent; public class TestInterManagerSession extends TestSessionManager { diff -r 65fdb3dc1885 -r 4b87f89b3afd test/sematest/TestSessionManager.java --- a/test/sematest/TestSessionManager.java Mon Nov 10 01:12:46 2008 +0000 +++ b/test/sematest/TestSessionManager.java Mon Nov 10 22:07:45 2008 +0900 @@ -2,10 +2,10 @@ import java.io.IOException; import rep.SessionManager; -import rep.SessionManagerEvent; -import rep.SessionManagerGUI; import rep.channel.REPLogger; import rep.channel.REPServerSocketChannel; +import rep.gui.SessionManagerEvent; +import rep.gui.SessionManagerGUI; public class TestSessionManager {