Mercurial > hg > RemoteEditor > REPSessionManager
view rep/Forwarder.java @ 376:c4ffdac26132
*** empty log message ***
author | kono |
---|---|
date | Wed, 22 Oct 2008 03:19:57 +0900 |
parents | ab4405cd3351 |
children | c78569ab5fce |
line wrap: on
line source
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<REPCommand> getChannel() { return channel; } public void setChannel(REPSocketChannel<REPCommand> 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<REPCommand> socketChannel) { manager.remove(socketChannel); } public void handle(REPSelectionKey<REPCommand> key) throws IOException { /* * SessionManagerから来たコマンドは、Editor関係のコマンドは、 * sessionとeidを判定して、そのeditorにforwardしてやれば良い。 * 残りは、manager.manage() で処理する。 */ REPSocketChannel<REPCommand> 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<REPCommand> channel, REPCommand command) throws IOException { Session s = manager.getSession(command.sid); if (s==null) throw new IOException(); Forwarder editor = s.getForwarder(channel); if (editor==null) throw new IOException(); if (!editor.isDirect()) { editor.send(command); return; } /* * local editor case. Handle special case first, usually these cases * are handled in the next Editor in a session manager, but * it is forwarded here. */ 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. editor.setQuit2(command); } else if (command.eid==editor.eid) { // if we handle in editor.manage(), this editor cannot distinguish this // and user input command from the editor. ((Editor)editor).checkReturnedCommand(command); } else { editor.manage(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(); } }