package com.limegroup.gnutella.handshaking;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
import java.util.List;
import java.util.Properties;
import org.limewire.logging.Log;
import org.limewire.logging.LogFactory;
import org.limewire.nio.channel.NIOMultiplexor;
import org.limewire.nio.statemachine.IOState;
import org.limewire.nio.statemachine.IOStateMachine;
import org.limewire.nio.statemachine.IOStateObserver;
import com.limegroup.gnutella.Constants;
public class AsyncOutgoingHandshaker implements Handshaker, IOStateObserver {
private static final Log LOG =
LogFactory.getLog(AsyncOutgoingHandshaker.class);
private final HandshakeSupport support;
private final IOStateMachine shaker;
private final Socket socket;
private final HandshakeObserver observer;
public AsyncOutgoingHandshaker(Properties requestHeaders, HandshakeResponder responder,
Socket socket, HandshakeObserver observer) {
this.socket = socket;
this.support = new HandshakeSupport(socket.getInetAddress().getHostAddress());
List<IOState> states = HandshakeState.getOutgoingHandshakeStates(support, requestHeaders, responder);
this.shaker = new IOStateMachine(this, states);
this.observer = observer;
}
public void shake() throws SocketException {
socket.setSoTimeout(Constants.TIMEOUT);
((NIOMultiplexor)socket).setReadObserver(shaker);
((NIOMultiplexor)socket).setWriteObserver(shaker);
}
public HandshakeResponse getWrittenHeaders() {
return support.getWrittenHandshakeResponse();
}
public HandshakeResponse getReadHeaders() {
return support.getReadHandshakeResponse();
}
public void handleStatesFinished() {
if(LOG.isDebugEnabled()) {
LOG.debug("Finished handshake with " +
socket.getInetAddress().getHostAddress() +
":" + socket.getPort());
}
observer.handleHandshakeFinished(this);
}
public void handleIOException(IOException iox) {
if(LOG.isDebugEnabled()) {
LOG.debug(iox + ", " + socket.getInetAddress().getHostAddress() +
":" + socket.getPort());
}
if(iox instanceof NoGnutellaOkException) {
NoGnutellaOkException ngok = (NoGnutellaOkException)iox;
observer.handleNoGnutellaOk(ngok.getCode(), ngok.getMessage());
} else {
observer.handleBadHandshake();
}
}
public void shutdown() {
if(LOG.isDebugEnabled()) {
LOG.debug("Shutting down handshake with " +
socket.getInetAddress().getHostAddress() +
":" + socket.getPort());
}
observer.shutdown();
}
}