view rep/handler/Forwarder.java @ 387:6f356d160e58

IPv6 any address
author one@firefly.cr.ie.u-ryukyu.ac.jp
date Mon, 10 Nov 2008 22:21:52 +0900
parents bba62c4ac323
children 4b535bef903a
line wrap: on
line source

package rep.handler;

import java.io.IOException;

import rep.PacketSet;
import rep.REP;
import rep.REPCommand;
import rep.Session;
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();

	public Forwarder(SessionManager manager,
			REPSocketChannel<REPCommand> channel) {
		super(manager,channel);
	}

	public Forwarder(int editorNo, SessionManager manager,
			REPSocketChannel<REPCommand> channel) {
		super(editorNo,manager,channel);
	}

	public int seq() {
		return seq++;
	}

	@Override
	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<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 REPNode getNextForwarder() {
		return next;
	}

	public boolean manage(REPCommand command) {
		assert false;
		return true;
	}

	public String toString(){
		return ("Forwarder:" + channel);
	}
	
	public String getLocalHostName() {
		return channel.getLocalHostName();
	}

	@Override
	public void cancel(REPSocketChannel<REPCommand> socketChannel) {
		manager.remove(socketChannel);
	}

	@Override
	public void handle(REPCommand command, REPSelectionKey<REPCommand> key) throws IOException {
		assert false;
	}


	public boolean isMerging() {
		return false;
	}

	public void selectSession(REPCommand sendCommand,Session session) {
		if(session.hasOwner()){
			// we have a selected session.
			if (isDirect()&&getEID()==sendCommand.eid) {
				// Found directly connected joined editor. Send join_ack().
				// we have one more point to send JOIN_ACK to the editor.
				session.addForwarder(this);
				manager.sendUpdate(session.getSID());
				sendCommand.setCMD(REP.SMCMD_JOIN_ACK);
				if (manager.sync) {
					REPCommand sync = new REPCommand(sendCommand);
					sync.setCMD(REP.SMCMD_SYNC);
					sendSync(sync);
				}
			} else {
				// We have a session, but joined editor is on the other sm.
				// SELECT_ACK is sent to the session ring to
				// find out the joined editor.
				sendCommand.setCMD(REP.SMCMD_SELECT_ACK);
			}
			sendCommand.string = session.getName();
			send(sendCommand);
		}else {
			manager.forwardSelect(sid, session, eid, this);
		}
	}

	
	
	
	
}