blob: 5917b84f62bdeed03d49c599841994fdde8acd8f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008, 2017 xored software, Inc. 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
*
* Contributors:
* xored software, Inc. - initial API and Implementation (Alex Panchenko)
*******************************************************************************/
package org.eclipse.dltk.dbgp.internal.commands;
import java.net.URI;
import org.eclipse.dltk.dbgp.DbgpBaseCommands;
import org.eclipse.dltk.dbgp.DbgpRequest;
import org.eclipse.dltk.dbgp.IDbgpCommunicator;
import org.eclipse.dltk.dbgp.IDbgpFeature;
import org.eclipse.dltk.dbgp.IDbgpSpawnpoint;
import org.eclipse.dltk.dbgp.commands.IDbgpCommands;
import org.eclipse.dltk.dbgp.commands.IDbgpFeatureCommands;
import org.eclipse.dltk.dbgp.commands.IDbgpSpawnpointCommands;
import org.eclipse.dltk.dbgp.exceptions.DbgpException;
import org.eclipse.dltk.debug.core.DLTKDebugPlugin;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class DbgpSpawnpointCommands extends DbgpBaseCommands
implements IDbgpSpawnpointCommands {
private static final String ELEMENT_SPAWNPOINT = "spawnpoint"; //$NON-NLS-1$
private static final String ATTR_ID = "id"; //$NON-NLS-1$
private static final String ATTR_STATE = "state"; //$NON-NLS-1$
private static final String ATTR_FILENAME = "filename"; //$NON-NLS-1$
private static final String ATTR_LINENO = "lineno"; //$NON-NLS-1$
private static final String CMD_GET = "spawnpoint_get"; //$NON-NLS-1$
private static final String CMD_SET = "spawnpoint_set"; //$NON-NLS-1$
private static final String CMD_LIST = "spawnpoint_list"; //$NON-NLS-1$
private static final String CMD_REMOVE = "spawnpoint_remove"; //$NON-NLS-1$
private static final String CMD_UPDATE = "spawnpoint_update"; //$NON-NLS-1$
private static final String OPTION_ID = "-d"; //$NON-NLS-1$
private static final String OPTION_FILENAME = "-f"; //$NON-NLS-1$
private static final String OPTION_LINE = "-n"; //$NON-NLS-1$
private static final String OPTION_STATE = "-s"; //$NON-NLS-1$
private static final String STATE_ENABLED = "enabled"; //$NON-NLS-1$
private static final String STATE_DISABLED = "disabled"; //$NON-NLS-1$
private final IDbgpCommands commands;
/**
* @param communicator
* @param commands
*/
public DbgpSpawnpointCommands(IDbgpCommunicator communicator,
IDbgpCommands commands) {
super(communicator);
this.commands = commands;
}
private boolean initialized = false;
private void initSpawnpoints() {
if (initialized) {
return;
}
try {
commands.getCoreCommands().setFeature(
IDbgpFeatureCommands.MULTIPLE_SESSIONS,
IDbgpFeature.ONE_VALUE);
} catch (DbgpException e) {
DLTKDebugPlugin.logWarning("Error setting '" //$NON-NLS-1$
+ IDbgpFeatureCommands.MULTIPLE_SESSIONS + "' feature to '" //$NON-NLS-1$
+ IDbgpFeature.ONE_VALUE + "'", e); //$NON-NLS-1$
}
initialized = true;
}
private static abstract class AbstractSpawnpoint
implements IDbgpSpawnpoint {
private final String id;
private final boolean enabled;
private final int lineNumber;
/**
* @param id
* @param enabled
* @param lineNumber
*/
public AbstractSpawnpoint(String id, boolean enabled, int lineNumber) {
this.id = id;
this.enabled = enabled;
this.lineNumber = lineNumber;
}
@Override
public String getId() {
return id;
}
@Override
public int getLineNumber() {
return lineNumber;
}
@Override
public boolean isEnabled() {
return enabled;
}
@Override
public String toString() {
return id + '/' + (enabled ? STATE_ENABLED : STATE_DISABLED) + '/'
+ getFilename() + ':' + lineNumber;
}
}
private static class DbgpSpawnpoint extends AbstractSpawnpoint {
private final URI uri;
/**
* @param id
* @param equals
* @param uri
* @param lineNumber
*/
public DbgpSpawnpoint(String id, boolean enabled, URI uri,
int lineNumber) {
super(id, enabled, lineNumber);
this.uri = uri;
}
@Override
public String getFilename() {
return uri.toString();
}
}
private static class DbgpSpawnpointString extends AbstractSpawnpoint {
private final String filename;
/**
* @param id
* @param equals
* @param uri
* @param lineNumber
*/
public DbgpSpawnpointString(String id, boolean enabled, String filename,
int lineNumber) {
super(id, enabled, lineNumber);
this.filename = filename;
}
@Override
public String getFilename() {
return filename;
}
}
@Override
public IDbgpSpawnpoint getSpawnpoint(String spawnpointId)
throws DbgpException {
initSpawnpoints();
final DbgpRequest request = createRequest(CMD_GET);
request.addOption(OPTION_ID, spawnpointId);
final Element response = communicate(request);
final String id = response.getAttribute(ATTR_ID);
if (id != null) {
return new DbgpSpawnpointString(id, parseState(response),
response.getAttribute(ATTR_FILENAME),
parseLineNumber(response));
} else {
return null;
}
}
@Override
public IDbgpSpawnpoint[] listSpawnpoints() throws DbgpException {
initSpawnpoints();
final DbgpRequest request = createRequest(CMD_LIST);
final Element response = communicate(request);
final NodeList points = response
.getElementsByTagName(ELEMENT_SPAWNPOINT);
final IDbgpSpawnpoint[] result = new IDbgpSpawnpoint[points
.getLength()];
int count = 0;
for (int i = 0; i < points.getLength(); ++i) {
final Element point = (Element) points.item(i);
final String id = point.getAttribute(ATTR_ID);
if (id != null) {
result[count++] = new DbgpSpawnpointString(id,
parseState(point), point.getAttribute(ATTR_FILENAME),
parseLineNumber(point));
}
}
if (count < result.length) {
final IDbgpSpawnpoint[] newResult = new IDbgpSpawnpoint[count];
System.arraycopy(result, 0, newResult, 0, count);
return newResult;
} else {
return result;
}
}
@Override
public void removeSpawnpoint(String spawnpointId) throws DbgpException {
if (spawnpointId == null) {
return;
}
initSpawnpoints();
final DbgpRequest request = createRequest(CMD_REMOVE);
request.addOption(OPTION_ID, spawnpointId);
communicate(request);
}
@Override
public IDbgpSpawnpoint setSpawnpoint(URI uri, int lineNumber,
boolean enabled) throws DbgpException {
initSpawnpoints();
final DbgpRequest request = createRequest(CMD_SET);
request.addOption(OPTION_FILENAME, uri.toString());
request.addOption(OPTION_LINE, lineNumber);
request.addOption(OPTION_STATE,
enabled ? STATE_ENABLED : STATE_DISABLED);
final Element response = communicate(request);
final String id = response.getAttribute(ATTR_ID);
if (id != null) {
return new DbgpSpawnpoint(id, parseState(response), uri,
lineNumber);
} else {
return null;
}
}
@Override
public void updateSpawnpoint(String spawnpointId, boolean enabled)
throws DbgpException {
initSpawnpoints();
final DbgpRequest request = createRequest(CMD_UPDATE);
request.addOption(OPTION_ID, spawnpointId);
request.addOption(OPTION_STATE,
enabled ? STATE_ENABLED : STATE_DISABLED);
communicate(request);
}
private static boolean parseState(final Element response) {
return STATE_ENABLED.equals(response.getAttribute(ATTR_STATE));
}
private static int parseLineNumber(final Element point) {
try {
return Integer.parseInt(point.getAttribute(ATTR_LINENO));
} catch (NumberFormatException e) {
return -1;
}
}
}