view rep/Session.java @ 360:b25f832f875d

*** empty log message ***
author kono
date Sun, 19 Oct 2008 20:30:52 +0900
parents fa041bae35f1
children 65c6d12a5835
line wrap: on
line source

package rep;

import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import rep.channel.REPSocketChannel;

public class Session extends HashMap<Integer,EditorPlus> {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Forwarder masterEditor;
	private int sessionID;
	private String sessionName;
	// isOnwer means this session has active channels(forwarders).
	private boolean isOwner = false;
	private Forwarder firstForwarder;
	private Forwarder last;
	
	public Session(int sid, String name, Forwarder editor) {
		this(sid, editor);
		sessionName = name;
	}
	

	public Session(int sid, Forwarder editor) {
		sessionID = sid;
		if (editor!=null) {
			// we have a master
			masterEditor = last = editor;
			editor.setSID(sid);
			put(editor.eid,editor);
			if(editor.channel!=null) {
				firstForwarder = editor;
				masterEditor.setNext(masterEditor);
				isOwner = true;
			}
		}
	}
	
	public void addForwarder(Forwarder forwarder) {
		// add a forwarder and connect this to the session 
		forwarder.setNext(last.getNextForwarder());
		last.setNext(forwarder);
		last = forwarder;
		put(forwarder.eid,forwarder);
		isOwner = true;
		if(firstForwarder==null) firstForwarder = forwarder;
	}
	
	public void addEditor(Editor editor) {
		// add a not-connected editor in a sassion
		// the editor is outside of this manager 
		put(editor.eid,editor);
	}
	
	public Collection<EditorPlus> getEditorList() {
		return values();
	}
	
	public int getSID() {
		return sessionID;
	}
	public Forwarder getOwner() {
		return masterEditor;
	}
	public String getName() {
		return sessionName;
	}
	
	
	public boolean deleteEditor(REPSocketChannel<REPCommand> channel) {
		LinkedList<EditorPlus> toBeRemoved = new LinkedList<EditorPlus>();
	    for (EditorPlus e:values() ) {
			if (e.getChannel()==channel) {
				unconnect((Forwarder)e);
				toBeRemoved.add(e);
			}
		}
	    for(EditorPlus e:toBeRemoved) {
	    	remove(e);
	    }
		return !toBeRemoved.isEmpty();
	}
	
	public boolean deleteForwarder(Forwarder editor) {
		unconnect(editor);
		return remove(editor)!=null;
	}
	
	private void unconnect(Forwarder e) {
		boolean hasOwner = false;
		for(EditorPlus e1:values()) {
			Forwarder f = (Forwarder)e1;
			if(f.next==e) {
				f.next=e.next;
			} else {
				if (f.channel!=null) hasOwner=true;
			}
		}
		if(firstForwarder==e) firstForwarder=null;
		if(masterEditor==e) masterEditor=null;
		isOwner = hasOwner;
	}
	
	public void setSID(int sid) {
		sessionID = sid;
	}
	
	public boolean hasOwner() {
		return isOwner;
	}
	
	
	public Editor getEditor(REPSocketChannel<REPCommand> channel) {
		for(EditorPlus editor : values()){
			if(editor.getChannel() == channel) {
				return (Editor)editor;
			}
		}
		return null;
	}

	
	Forwarder getNextEditor(Forwarder editor) {
		return editor.getNextForwarder();
	}
	
	public void closeSession() {
		Forwarder first = firstForwarder;
		REPCommand command = new REPCommand(REP.REPCMD_CLOSE, sessionID, REP.SM_EID.id, 0, 0, "");
		if (first!=null)
			first.send(command);
	}
	

	
	public Forwarder getFirstForwarder() {
		return firstForwarder;
	}


	public void remove(SessionManager manager) {
		for(EditorPlus editor : values()){
			if(editor.getChannel() !=null) 
				unconnect((Forwarder)editor);
			manager.editorList.remove(editor);
		}	
	}


	public void merge(Session s) {
		for(EditorPlus editor : s.values()){
			EditorPlus mine = get(editor.eid);
			if (mine==null) {
				put(editor.eid,editor);
			} else {
				mine.merge(editor);
			}
		}	
	}
	
	@Override
	public String toString() {
		String s = super.toString();
		return s+" sid="+sessionID+" "+sessionName+" master="+
			((masterEditor==null)?"null":masterEditor.toString());
	}


	public void setName(String string) {
		sessionName = string;
	}

}