blob: 7d75ea19234453defbe24da836fdb632e3512faa [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - Initial API and implementation
*******************************************************************************/
package org.eclipse.ptp.proxy.server;
import java.io.IOException;
import java.net.Socket;
import java.nio.channels.ReadableByteChannel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.ptp.proxy.command.IProxyCommand;
import org.eclipse.ptp.proxy.command.IProxyCommandFactory;
import org.eclipse.ptp.proxy.command.IProxyCommandListener;
import org.eclipse.ptp.proxy.command.IProxyExtendedCommand;
import org.eclipse.ptp.proxy.command.IProxyQuitCommand;
import org.eclipse.ptp.proxy.packet.ProxyPacket;
public abstract class AbstractProxyServer implements IProxyServer {
private enum ServerState {WAITING, CONNECTED, RUNNING, SHUTTING_DOWN, SHUTDOWN}
public static final int MAX_ERRORS = 5;
private ServerState state = ServerState.SHUTDOWN;
private String sessHost;
private int sessPort;
private Socket sessSocket;
private ReadableByteChannel sessInput;
private IProxyCommandFactory proxyCommandFactory;
private Thread commandThread;
private List<IProxyCommandListener> listeners =
Collections.synchronizedList(new ArrayList<IProxyCommandListener>());
public AbstractProxyServer(String host, int port, IProxyCommandFactory factory) {
this.sessHost = host;
this.sessPort = port;
this.proxyCommandFactory = factory;
}
/* (non-Javadoc)
* @see org.eclipse.ptp.proxy.server.IProxyServer#addListener(org.eclipse.ptp.proxy.command.IProxyCommandListener)
*/
public void addListener(IProxyCommandListener listener) {
listeners.add(listener);
}
/* (non-Javadoc)
* @see org.eclipse.ptp.proxy.server.IProxyServer#addListener(org.eclipse.ptp.proxy.command.IProxyCommandListener)
*/
public void removeListener(IProxyCommandListener listener) {
listeners.remove(listener);
}
public void connect() throws IOException {
sessSocket = new Socket(sessHost, sessPort);
sessInput = sessSocket.getChannel();
}
/**
* Start a thread to process commands from the proxy by repeatedly
* calling sessionProgress().
*/
public void start() {
commandThread = new Thread("Proxy Server Command Thread") { //$NON-NLS-1$
public void run() {
boolean error = false;
int errorCount = 0;
System.out.println("server command thread starting..."); //$NON-NLS-1$
try {
while (errorCount < MAX_ERRORS && !isInterrupted()) {
synchronized(state) {
if (state == ServerState.SHUTDOWN) {
break;
}
}
if (!sessionProgress()) {
errorCount++;
}
}
} catch (IOException e) {
synchronized(state) {
if (!isInterrupted() && state != ServerState.SHUTTING_DOWN) {
error = true;
System.out.println("event thread IOException . . . " + e.getMessage()); //$NON-NLS-1$
}
}
}
if (errorCount >= MAX_ERRORS) {
error = true;
}
try {
sessSocket.close();
} catch (IOException e) {
}
synchronized(state) {
state = ServerState.SHUTDOWN;
}
System.out.println("server thread exited"); //$NON-NLS-1$
if (error) {
System.out.println(" due to errors"); //$NON-NLS-1$
} else {
System.out.println(" normally"); //$NON-NLS-1$
}
}
};
try {
commandThread.join();
} catch (InterruptedException e) {
}
}
/**
* Process commands from the wire
*
* @return
* @throws IOException
*/
private boolean sessionProgress() throws IOException {
ProxyPacket packet = new ProxyPacket();
if (!packet.read(sessInput)) {
return false;
}
/*
* Now convert the event into an IProxyEvent
*/
IProxyCommand cmd = proxyCommandFactory.toCommand(packet);
if (cmd != null) {
if (cmd instanceof IProxyQuitCommand) {
fireProxyQuitCommand((IProxyQuitCommand)cmd);
} else if (cmd instanceof IProxyExtendedCommand) {
fireProxyExtendedCommand((IProxyExtendedCommand)cmd);
}
return true;
}
return false;
}
/**
* Send command to command handlers
*
* @param cmd
*/
protected void fireProxyExtendedCommand(IProxyExtendedCommand cmd) {
IProxyCommandListener[] la = listeners.toArray(new IProxyCommandListener[0]);
for (IProxyCommandListener listener : la) {
listener.handleCommand(cmd);
}
}
/**
* Send command to command handlers
*
* @param cmd
*/
protected void fireProxyQuitCommand(IProxyQuitCommand cmd) {
IProxyCommandListener[] la = listeners.toArray(new IProxyCommandListener[0]);
for (IProxyCommandListener listener : la) {
listener.handleCommand(cmd);
}
}
}