blob: 25519b151056334a602431bc74d7fece0ed67fbb [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2018 IBM Corporation and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
*******************************************************************************/
package org.eclipse.dltk.dbgp.internal;
import java.io.IOException;
import org.eclipse.dltk.dbgp.IDbgpCommunicator;
import org.eclipse.dltk.dbgp.IDbgpNotificationManager;
import org.eclipse.dltk.dbgp.IDbgpRawListener;
import org.eclipse.dltk.dbgp.IDbgpSession;
import org.eclipse.dltk.dbgp.IDbgpSessionInfo;
import org.eclipse.dltk.dbgp.commands.IDbgpCoreCommands;
import org.eclipse.dltk.dbgp.commands.IDbgpExtendedCommands;
import org.eclipse.dltk.dbgp.commands.IDbgpSpawnpointCommands;
import org.eclipse.dltk.dbgp.exceptions.DbgpException;
import org.eclipse.dltk.dbgp.internal.commands.DbgpCoreCommands;
import org.eclipse.dltk.dbgp.internal.commands.DbgpDebuggingEngineCommunicator;
import org.eclipse.dltk.dbgp.internal.commands.DbgpExtendedCommands;
import org.eclipse.dltk.dbgp.internal.commands.DbgpSpawnpointCommands;
import org.eclipse.dltk.dbgp.internal.managers.DbgpNotificationManager;
import org.eclipse.dltk.dbgp.internal.managers.DbgpStreamManager;
import org.eclipse.dltk.dbgp.internal.managers.IDbgpStreamManager;
import org.eclipse.dltk.dbgp.internal.packets.DbgpResponsePacket;
import org.eclipse.dltk.dbgp.internal.utils.DbgpXmlEntityParser;
import org.eclipse.dltk.debug.core.IDebugOptions;
import org.eclipse.dltk.debug.core.model.DefaultDebugOptions;
public class DbgpSession extends DbgpTermination
implements IDbgpSession, IDbgpTerminationListener {
private final IDbgpDebugingEngine engine;
private final IDbgpCoreCommands coreCommands;
private final IDbgpExtendedCommands extendedCommands;
private final IDbgpSpawnpointCommands spawnpointCommands;
private final DbgpNotificationManager notificationManager;
private final DbgpStreamManager streamManager;
private IDbgpSessionInfo info;
private final Object terminatedLock = new Object();
private boolean terminated = false;
private DbgpDebuggingEngineCommunicator communicator;
private void requestTerminateImpl(Object object) {
if (object != engine) {
engine.requestTermination();
}
if (object != streamManager && streamManager != null) {
streamManager.requestTermination();
}
if (object != notificationManager && notificationManager != null) {
notificationManager.requestTermination();
}
}
private void waitTerminatedImpl(Object object) throws InterruptedException {
if (object != engine) {
engine.waitTerminated();
}
if (streamManager != null && object != streamManager) {
streamManager.waitTerminated();
}
if (notificationManager != null && object != notificationManager) {
notificationManager.waitTerminated();
}
}
public DbgpSession(IDbgpDebugingEngine engine)
throws DbgpException, IOException {
if (engine == null) {
throw new IllegalArgumentException();
}
this.engine = engine;
try {
DbgpResponsePacket responsePacket = engine.getResponsePacket(-1, 0);
if (responsePacket == null) {
throw new DbgpException();
}
info = DbgpXmlEntityParser
.parseSession(responsePacket.getContent());
} catch (InterruptedException e) {
}
// Engine
this.engine.addTerminationListener(this);
// Notification manager
this.notificationManager = new DbgpNotificationManager(engine);
this.notificationManager.addTerminationListener(this);
// Stream manager
this.streamManager = new DbgpStreamManager(engine,
"DBGP - Stream manager"); //$NON-NLS-1$
this.streamManager.addTerminationListener(this);
communicator = createDbgpEngineCommunicator(engine);
this.coreCommands = new DbgpCoreCommands(communicator);
this.extendedCommands = new DbgpExtendedCommands(communicator);
this.spawnpointCommands = new DbgpSpawnpointCommands(communicator,
this);
// Starting all
this.notificationManager.start();
this.streamManager.start();
}
protected DbgpDebuggingEngineCommunicator createDbgpEngineCommunicator(
IDbgpDebugingEngine engine) {
return new DbgpDebuggingEngineCommunicator(engine,
DefaultDebugOptions.getDefaultInstance());
}
@Override
public IDbgpSessionInfo getInfo() {
return info;
}
@Override
public String toString() {
return "Session. appid: " + info.getApplicationId(); //$NON-NLS-1$
}
@Override
public IDbgpCoreCommands getCoreCommands() {
return coreCommands;
}
@Override
public IDbgpExtendedCommands getExtendedCommands() {
return extendedCommands;
}
@Override
public IDbgpStreamManager getStreamManager() {
return streamManager;
}
@Override
public IDbgpNotificationManager getNotificationManager() {
return notificationManager;
}
// IDbgpTermination
@Override
public void requestTermination() {
synchronized (terminatedLock) {
if (terminated) {
return;
}
requestTerminateImpl(null);
}
}
@Override
public void waitTerminated() throws InterruptedException {
synchronized (terminatedLock) {
if (terminated) {
return;
}
waitTerminatedImpl(null);
}
}
// IDbgpTerminationListener
@Override
public void objectTerminated(Object object, Exception e) {
// Allows to unblock all terminating threads
synchronized (terminatedLock) {
if (terminated)
return;
terminated = true;
}
engine.removeTerminationListener(this);
if (streamManager != null) {
streamManager.removeTerminationListener(this);
}
if (notificationManager != null) {
notificationManager.removeTerminationListener(this);
}
// Request terminate
requestTerminateImpl(object);
try {
waitTerminatedImpl(object);
} catch (InterruptedException ex) {
// OK, interrrputed
}
fireObjectTerminated(e);
}
@Override
public void addRawListener(IDbgpRawListener listener) {
engine.addRawListener(listener);
}
@Override
public void removeRawListenr(IDbgpRawListener listener) {
engine.removeRawListenr(listener);
}
@Override
public IDbgpCommunicator getCommunicator() {
return this.communicator;
}
@Override
public IDebugOptions getDebugOptions() {
return communicator.getDebugOptions();
}
@Override
public void configure(IDebugOptions debugOptions) {
communicator.configure(debugOptions);
}
@Override
public <T> T get(Class<T> type) {
if (type == IDbgpSpawnpointCommands.class) {
return type.cast(spawnpointCommands);
} else if (type == IDbgpCoreCommands.class) {
return type.cast(coreCommands);
} else if (type == IDbgpExtendedCommands.class) {
return type.cast(extendedCommands);
}
return null;
}
}