blob: 085b832eb24e8b96c9fb986d81fdacdadaa968ce [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 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.wst.jsdt.debug.internal.rhino.transport;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
/**
* Implementation of a transport service that using a {@link Socket} for communication
*
* @since 1.0
*/
public class SocketTransportService implements TransportService {
static final Class serverSocketClass = ServerSocket.class; // temporary used to pre-load the ServerSocket.class
/**
* Key implementation
*/
public static class SocketListenerKey implements ListenerKey {
private String address;
public SocketListenerKey(String address) {
this.address = address;
}
public String address() {
return address;
}
}
/**
* Map of {@link ListenerKey} to {@link ServerSocket}s
*/
Map listeners = new HashMap();
/* (non-Javadoc)
* @see org.eclipse.wst.jsdt.debug.internal.core.jsdi.connect.TransportService#startListening(java.lang.String)
*/
public synchronized ListenerKey startListening(String address) throws IOException {
String host = null;
int port = 0;
if (address != null) {
String[] strings = address.split(Constants.COLON);
if (strings.length == 2) {
host = strings[0];
port = Integer.parseInt(strings[1]);
} else {
port = Integer.parseInt(strings[0]);
}
}
if (host == null) {
host = LOCALHOST;
}
if (!host.equals(LOCALHOST)) {
throw new IllegalArgumentException("Only localhost is supported."); //$NON-NLS-1$
}
ListenerKey key = new SocketListenerKey(host + Constants.COLON + port);
ServerSocket serverSocket = new ServerSocket(port);
listeners.put(key, serverSocket);
return key;
};
/* (non-Javadoc)
* @see org.eclipse.wst.jsdt.debug.internal.core.jsdi.connect.TransportService#stopListening(org.eclipse.wst.jsdt.debug.internal.core.jsdi.connect.TransportService.ListenerKey)
*/
public void stopListening(ListenerKey key) throws IOException {
ServerSocket serverSocket = (ServerSocket) listeners.remove(key);
if (serverSocket != null) {
serverSocket.close();
}
}
/* (non-Javadoc)
* @see org.eclipse.wst.jsdt.debug.internal.core.jsdi.connect.TransportService#accept(org.eclipse.wst.jsdt.debug.internal.core.jsdi.connect.TransportService.ListenerKey, long, long)
*/
public Connection accept(ListenerKey key, long attachTimeout, long handshakeTimeout) throws IOException {
ServerSocket serverSocket = (ServerSocket) listeners.get(key);
if (serverSocket == null) {
throw new IllegalStateException("Accept failed. Not listening for address: key.address()"); //$NON-NLS-1$
}
int timeout = (int) attachTimeout;
if (timeout > 0) {
if (timeout > Integer.MAX_VALUE) {
timeout = Integer.MAX_VALUE; // approximately 25 days!
}
serverSocket.setSoTimeout(timeout);
}
Connection connection = new SocketConnection(serverSocket.accept());
Packet packet = connection.readPacket();
if (!(packet instanceof Request)) {
throw new IOException("failure establishing_connection"); //$NON-NLS-1$
}
Request request = (Request) packet;
if (!request.getCommand().equals(JSONConstants.CONNECT)) {
throw new IOException("failure establishing connection"); //$NON-NLS-1$
}
Response response = new Response(request.getSequence(), request.getCommand());
connection.writePacket(response);
return connection;
}
/* (non-Javadoc)
* @see org.eclipse.wst.jsdt.debug.internal.core.jsdi.connect.TransportService#attach(java.lang.String, long, long)
*/
public Connection attach(String address, long attachTimeout, long handshakeTimeout) throws IOException {
String host = null;
int port = 0;
if (address != null) {
String[] strings = address.split(Constants.COLON);
if (strings.length == 2) {
host = strings[0];
port = Integer.parseInt(strings[1]);
} else {
port = Integer.parseInt(strings[0]);
}
}
if (host == null) {
host = LOCALHOST;
}
Connection connection = new SocketConnection(new Socket(host, port));
Request request = new Request(JSONConstants.CONNECT);
connection.writePacket(request);
Packet packet = connection.readPacket();
if (!(packet instanceof Response)) {
throw new IOException("failure establishing connection"); //$NON-NLS-1$
}
Response response = (Response) packet;
if (!response.getCommand().equals(JSONConstants.CONNECT) || response.getRequestSequence() != request.getSequence() || !response.isSuccess() || !response.isRunning()) {
throw new IOException("failure establishing connection"); //$NON-NLS-1$
}
return connection;
}
}