/*******************************************************************************
* Copyright (c) 2005, 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
*
*******************************************************************************/
package org.eclipse.dltk.dbgp.internal;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.Socket;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.dbgp.DbgpRequest;
import org.eclipse.dltk.dbgp.IDbgpRawListener;
import org.eclipse.dltk.dbgp.IDbgpRawPacket;
import org.eclipse.dltk.dbgp.internal.packets.DbgpNotifyPacket;
import org.eclipse.dltk.dbgp.internal.packets.DbgpPacketReceiver;
import org.eclipse.dltk.dbgp.internal.packets.DbgpPacketSender;
import org.eclipse.dltk.dbgp.internal.packets.DbgpResponsePacket;
import org.eclipse.dltk.dbgp.internal.packets.DbgpStreamPacket;
import org.eclipse.dltk.dbgp.internal.packets.IDbgpRawLogger;
import org.eclipse.dltk.debug.core.ExtendedDebugEventDetails;
import org.eclipse.dltk.internal.debug.core.model.DebugEventHelper;
public class DbgpDebugingEngine extends DbgpTermination implements
IDbgpDebugingEngine, IDbgpTerminationListener {
private final Socket socket;
private final DbgpPacketReceiver receiver;
private final DbgpPacketSender sender;
private final Object terminatedLock = new Object();
private boolean terminated = false;
private final int id;
private static int lastId = 0;
private static final Object idLock = new Object();
public DbgpDebugingEngine(Socket socket) throws IOException {
this.socket = socket;
synchronized (idLock) {
id = ++lastId;
}
receiver = new DbgpPacketReceiver(new BufferedInputStream(socket
.getInputStream()));
receiver.setLogger(new IDbgpRawLogger() {
public void log(IDbgpRawPacket output) {
firePacketReceived(output);
}
});
receiver.addTerminationListener(this);
receiver.start();
sender = new DbgpPacketSender(new BufferedOutputStream(socket
.getOutputStream()));
sender.setLogger(new IDbgpRawLogger() {
public void log(IDbgpRawPacket output) {
firePacketSent(output);
}
});
/*
* FIXME this event is delivered on the separate thread, so sometimes
* logging misses a few initial packets.
*/
DebugEventHelper.fireExtendedEvent(this,
ExtendedDebugEventDetails.DGBP_NEW_CONNECTION);
}
public DbgpStreamPacket getStreamPacket() throws IOException,
InterruptedException {
return receiver.getStreamPacket();
}
public DbgpNotifyPacket getNotifyPacket() throws IOException,
InterruptedException {
return receiver.getNotifyPacket();
}
public DbgpResponsePacket getResponsePacket(int transactionId, int timeout)
throws IOException, InterruptedException {
return receiver.getResponsePacket(transactionId, timeout);
}
public void sendCommand(DbgpRequest command) throws IOException {
sender.sendCommand(command);
}
// IDbgpTerminataion
public void requestTermination() {
// always just close the socket
try {
socket.close();
} catch (IOException e) {
if (DLTKCore.DEBUG) {
e.printStackTrace();
}
}
}
public void waitTerminated() throws InterruptedException {
synchronized (terminatedLock) {
if (terminated) {
return;
}
receiver.waitTerminated();
}
}
public void objectTerminated(Object object, Exception e) {
synchronized (terminatedLock) {
if (terminated)
return;
receiver.removeTerminationListener(this);
try {
receiver.waitTerminated();
} catch (InterruptedException e1) {
// OK, interrupted
}
terminated = true;
}
fireObjectTerminated(e);
}
private final ListenerList listeners = new ListenerList();
protected void firePacketReceived(IDbgpRawPacket content) {
Object[] list = listeners.getListeners();
for (int i = 0; i < list.length; ++i) {
((IDbgpRawListener) list[i]).dbgpPacketReceived(id, content);
}
}
protected void firePacketSent(IDbgpRawPacket content) {
Object[] list = listeners.getListeners();
for (int i = 0; i < list.length; ++i) {
((IDbgpRawListener) list[i]).dbgpPacketSent(id, content);
}
}
public void addRawListener(IDbgpRawListener listener) {
listeners.add(listener);
}
public void removeRawListenr(IDbgpRawListener listener) {
listeners.remove(listener);
}
}