Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreutarass2008-09-29 18:16:21 +0000
committereutarass2008-09-29 18:16:21 +0000
commit4eda31b90ed1a201fd6e670d2a833e02fe44ed18 (patch)
treed0b7702656d2342cd36a5e32645b8548487297e6
parentc6d9344ab3988164cf6008d45fc80f83036a5f51 (diff)
downloadorg.eclipse.tcf-4eda31b90ed1a201fd6e670d2a833e02fe44ed18.tar.gz
org.eclipse.tcf-4eda31b90ed1a201fd6e670d2a833e02fe44ed18.tar.xz
org.eclipse.tcf-4eda31b90ed1a201fd6e670d2a833e02fe44ed18.zip
1. Extended IErrorReport interface: now error report details are accessible from TCF clients
2. TCF Debugger UI: Got rid of meaningless method TCFNode.invalidateNode() 3. TCF Debugger UI: improved cache performance
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFArgumentsTab.java1
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFMainTab.java93
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenStackTrace.java13
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java7
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java50
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExpression.java10
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeLaunch.java5
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeRegister.java13
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java44
-rw-r--r--plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java4
-rw-r--r--plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/FileSystemProxy.java40
-rw-r--r--plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/MemoryProxy.java37
-rw-r--r--plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/Command.java99
-rw-r--r--plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/protocol/IErrorReport.java22
-rw-r--r--plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/util/TCFDataCache.java25
15 files changed, 261 insertions, 202 deletions
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFArgumentsTab.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFArgumentsTab.java
index c13c7b310..fcfad26dd 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFArgumentsTab.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFArgumentsTab.java
@@ -112,7 +112,6 @@ public class TCFArgumentsTab extends AbstractLaunchConfigurationTab {
public void setDefaults(ILaunchConfigurationWorkingCopy config) {
config.setAttribute(TCFLaunchDelegate.ATTR_PROGRAM_ARGUMENTS, (String)null);
- config.setAttribute(TCFLaunchDelegate.ATTR_WORKING_DIRECTORY, (String)null);
}
public void initializeFrom(ILaunchConfiguration configuration) {
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFMainTab.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFMainTab.java
index d9402707d..8642356bb 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFMainTab.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFMainTab.java
@@ -56,6 +56,7 @@ public class TCFMainTab extends AbstractLaunchConfigurationTab {
private Text working_dir_text;
private Button default_dir_button;
private Button terminal_button;
+ private Exception init_error;
public void createControl(Composite parent) {
Composite comp = new Composite(parent, SWT.NONE);
@@ -198,6 +199,17 @@ public class TCFMainTab extends AbstractLaunchConfigurationTab {
default_dir_button = new Button(group, SWT.CHECK);
default_dir_button.setText("Use default");
default_dir_button.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false));
+ default_dir_button.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent evt) {
+ updateLaunchConfigurationDialog();
+ }
+ });
+ }
+
+ protected void updateLaunchConfigurationDialog() {
+ super.updateLaunchConfigurationDialog();
+ working_dir_text.setEnabled(!default_dir_button.getSelection());
}
private ITCFLaunchContext getLaunchContext(IProject project) {
@@ -257,66 +269,20 @@ public class TCFMainTab extends AbstractLaunchConfigurationTab {
}
public void initializeFrom(ILaunchConfiguration config) {
- updateProjectFromConfig(config);
- updateLocalProgramFromConfig(config);
- updateRemoteProgramFromConfig(config);
- updateTerminalFromConfig(config);
- updateWorkingDirFromConfig(config);
- }
-
- private void updateTerminalFromConfig(ILaunchConfiguration config) {
- boolean use_terminal = true;
try {
- use_terminal = config.getAttribute(TCFLaunchDelegate.ATTR_USE_TERMINAL, true);
+ project_text.setText(config.getAttribute(TCFLaunchDelegate.ATTR_PROJECT_NAME, ""));
+ local_program_text.setText(config.getAttribute(TCFLaunchDelegate.ATTR_LOCAL_PROGRAM_FILE, ""));
+ remote_program_text.setText(config.getAttribute(TCFLaunchDelegate.ATTR_REMOTE_PROGRAM_FILE, ""));
+ working_dir_text.setText(config.getAttribute(TCFLaunchDelegate.ATTR_WORKING_DIRECTORY, ""));
+ default_dir_button.setSelection(!config.hasAttribute(TCFLaunchDelegate.ATTR_WORKING_DIRECTORY));
+ terminal_button.setSelection(config.getAttribute(TCFLaunchDelegate.ATTR_USE_TERMINAL, true));
}
- catch (CoreException e) {
+ catch (Exception e) {
+ init_error = e;
+ setErrorMessage("Cannot read launch configuration: " + init_error);
Activator.log(e);
}
- terminal_button.setSelection(use_terminal);
- }
-
- private void updateProjectFromConfig(ILaunchConfiguration config) {
- String project_name = "";
- try {
- project_name = config.getAttribute(TCFLaunchDelegate.ATTR_PROJECT_NAME, "");
- }
- catch (CoreException ce) {
- Activator.log(ce);
- }
- project_text.setText(project_name);
- }
-
- private void updateLocalProgramFromConfig(ILaunchConfiguration config) {
- String program_name = "";
- try {
- program_name = config.getAttribute(TCFLaunchDelegate.ATTR_LOCAL_PROGRAM_FILE, "");
- }
- catch (CoreException ce) {
- Activator.log(ce);
- }
- local_program_text.setText(program_name);
- }
-
- private void updateRemoteProgramFromConfig(ILaunchConfiguration config) {
- String program_name = "";
- try {
- program_name = config.getAttribute(TCFLaunchDelegate.ATTR_REMOTE_PROGRAM_FILE, "");
- }
- catch (CoreException ce) {
- Activator.log(ce);
- }
- remote_program_text.setText(program_name);
- }
-
- private void updateWorkingDirFromConfig(ILaunchConfiguration config) {
- String name = "";
- try {
- name = config.getAttribute(TCFLaunchDelegate.ATTR_WORKING_DIRECTORY, ""); //$NON-NLS-1$
- }
- catch (CoreException ce) {
- Activator.log(ce);
- }
- working_dir_text.setText(name);
+ updateLaunchConfigurationDialog();
}
private IProject getProject() {
@@ -329,7 +295,12 @@ public class TCFMainTab extends AbstractLaunchConfigurationTab {
config.setAttribute(TCFLaunchDelegate.ATTR_PROJECT_NAME, project_text.getText());
config.setAttribute(TCFLaunchDelegate.ATTR_LOCAL_PROGRAM_FILE, local_program_text.getText());
config.setAttribute(TCFLaunchDelegate.ATTR_REMOTE_PROGRAM_FILE, remote_program_text.getText());
- config.setAttribute(TCFLaunchDelegate.ATTR_WORKING_DIRECTORY, working_dir_text.getText());
+ if (default_dir_button.getSelection()) {
+ config.removeAttribute(TCFLaunchDelegate.ATTR_WORKING_DIRECTORY);
+ }
+ else {
+ config.setAttribute(TCFLaunchDelegate.ATTR_WORKING_DIRECTORY, working_dir_text.getText());
+ }
config.setAttribute(TCFLaunchDelegate.ATTR_USE_TERMINAL, terminal_button.getSelection());
}
@@ -341,7 +312,7 @@ public class TCFMainTab extends AbstractLaunchConfigurationTab {
if (project == null) {
MessageDialog.openInformation(getShell(),
"Project required",
- "Enter project before searching for program");
+ "Enter project before searching for program");
return;
}
ITCFLaunchContext launch_context = getLaunchContext(project);
@@ -412,6 +383,11 @@ public class TCFMainTab extends AbstractLaunchConfigurationTab {
setErrorMessage(null);
setMessage(null);
+ if (init_error != null) {
+ setErrorMessage("Cannot read launch configuration: " + init_error);
+ return false;
+ }
+
String project_name = project_text.getText().trim();
if (project_name.length() != 0) {
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(project_name);
@@ -476,6 +452,7 @@ public class TCFMainTab extends AbstractLaunchConfigurationTab {
public void setDefaults(ILaunchConfigurationWorkingCopy config) {
config.setAttribute(TCFLaunchDelegate.ATTR_PROJECT_NAME, "");
config.setAttribute(TCFLaunchDelegate.ATTR_USE_TERMINAL, true);
+ config.setAttribute(TCFLaunchDelegate.ATTR_WORKING_DIRECTORY, (String)null);
ITCFLaunchContext launch_context = getLaunchContext(null);
if (launch_context != null) launch_context.setDefaults(getLaunchConfigurationDialog(), config);
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenStackTrace.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenStackTrace.java
index 6cb91e615..e6fb7fbc5 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenStackTrace.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenStackTrace.java
@@ -13,8 +13,10 @@ package org.eclipse.tm.internal.tcf.debug.ui.model;
import java.util.HashMap;
import java.util.Map;
+import org.eclipse.tm.internal.tcf.debug.model.TCFContextState;
import org.eclipse.tm.tcf.protocol.IToken;
import org.eclipse.tm.tcf.services.IStackTrace;
+import org.eclipse.tm.tcf.util.TCFDataCache;
public class TCFChildrenStackTrace extends TCFChildren {
@@ -61,8 +63,15 @@ public class TCFChildrenStackTrace extends TCFChildren {
@Override
protected boolean startDataRetrieval() {
final HashMap<String,TCFNode> data = new HashMap<String,TCFNode>();
- if (!node.isSuspended()) {
- set(null, null, data);
+ TCFDataCache<TCFContextState> state = node.getState();
+ if (!state.validate()) {
+ state.wait(this);
+ return false;
+ }
+ Throwable state_error = state.getError();
+ TCFContextState state_data = state.getData();
+ if (state_error != null || state_data == null || !state_data.is_suspended) {
+ set(null, state_error, data);
return true;
}
IStackTrace st = node.model.getLaunch().getService(IStackTrace.class);
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java
index 0a4a42067..55994f550 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java
@@ -77,7 +77,6 @@ public abstract class TCFNode extends PlatformObject implements Comparable<TCFNo
void dispose() {
assert !disposed;
if (parent != null) parent.dispose(id);
- invalidateNode();
if (id != null) {
assert model.getNode(id) == this;
model.removeNode(id);
@@ -319,12 +318,6 @@ public abstract class TCFNode extends PlatformObject implements Comparable<TCFNo
/* Node data retrieval state machine */
/**
- * Invalidate the node - flush all cached data.
- * Subclasses should override this method to flush any additional data.
- */
- public abstract void invalidateNode();
-
- /**
* Validate node - retrieve and put into a cache missing data from remote peer.
* The method should initiate retrieval of all data needed by TCFNode.update() methods.
* Validation is done asynchronously. If the node is already valid,
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java
index b7a39c250..efc8f95be 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java
@@ -127,6 +127,9 @@ public class TCFNodeExecContext extends TCFNode {
@Override
void dispose() {
+ run_context.reset(null);
+ mem_context.reset(null);
+ state.reset(null);
children_exec.dispose();
children_stack.dispose();
super.dispose();
@@ -448,52 +451,29 @@ public class TCFNodeExecContext extends TCFNode {
}
@Override
- public void invalidateNode() {
- run_context.reset();
- mem_context.reset();
- state.reset();
- children_exec.reset();
- children_stack.reset();
- }
-
- @Override
public boolean validateNode(Runnable done) {
assert !disposed;
- mem_context.validate();
- run_context.validate();
- if (!mem_context.isValid()) {
- mem_context.wait(done);
- return false;
- }
- if (!run_context.isValid()) {
- run_context.wait(done);
- return false;
- }
- state.validate();
- children_exec.validate();
- if (!state.isValid()) {
- state.wait(done);
- return false;
- }
- if (!children_exec.isValid()) {
- children_exec.wait(done);
+ TCFDataCache<?> pending = null;
+
+ if (!mem_context.validate()) pending = mem_context;
+ if (!run_context.validate()) pending = run_context;
+ if (pending != null) {
+ pending.wait(done);
return false;
}
- children_stack.validate();
+ if (!state.validate()) pending = state;
+ if (!children_exec.validate()) pending = children_exec;
+ if (!children_stack.validate()) pending = children_stack;
IRunControl.RunControlContext ctx = run_context.getData();
if (ctx != null && !ctx.hasState()) {
// Container need to validate children for
// hasSuspendedChildren() method to return valid value.
TCFDataCache<?> dt = validateChildrenState();
- if (dt != null) {
- dt.wait(done);
- return false;
- }
+ if (dt != null) pending = dt;
}
-
- if (!children_stack.isValid()) {
- children_stack.wait(done);
+ if (pending != null) {
+ pending.wait(done);
return false;
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExpression.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExpression.java
index 5d2c0f43a..89308f55f 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExpression.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExpression.java
@@ -212,6 +212,9 @@ public class TCFNodeExpression extends TCFNode {
@Override
void dispose() {
+ value.reset(null);
+ type.reset(null);
+ children.reset(null);
children.dispose();
super.dispose();
if (!expression.isValid() || expression.getData() == null) return;
@@ -446,13 +449,6 @@ public class TCFNodeExpression extends TCFNode {
}
@Override
- public void invalidateNode() {
- value.reset();
- type.reset();
- children.reset();
- }
-
- @Override
public boolean validateNode(Runnable done) {
TCFDataCache<?> pending = null;
if (!field.validate()) pending = field;
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeLaunch.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeLaunch.java
index 33e733461..8c40f3e41 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeLaunch.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeLaunch.java
@@ -88,11 +88,6 @@ public class TCFNodeLaunch extends TCFNode {
}
@Override
- public void invalidateNode() {
- children.reset();
- }
-
- @Override
public boolean validateNode(Runnable done) {
if (!children.validate()) {
children.wait(done);
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeRegister.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeRegister.java
index 4ada16a84..371bed81e 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeRegister.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeRegister.java
@@ -67,6 +67,13 @@ public class TCFNodeRegister extends TCFNode {
}
};
}
+
+ @Override
+ public void dispose() {
+ context.reset(null);
+ value.reset(null);
+ super.dispose();
+ }
@Override
protected void getData(ILabelUpdate result) {
@@ -214,12 +221,6 @@ public class TCFNodeRegister extends TCFNode {
}
@Override
- public void invalidateNode() {
- context.reset();
- value.reset();
- }
-
- @Override
public boolean validateNode(Runnable done) {
TCFDataCache<?> pending = null;
if (!context.validate()) pending = context;
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java
index f93d76bef..98baa6423 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java
@@ -132,6 +132,8 @@ public class TCFNodeStackFrame extends TCFNode {
@Override
void dispose() {
+ stack_trace_context.reset(null);
+ line_info.reset(null);
children_regs.dispose();
children_vars.dispose();
children_exps.dispose();
@@ -270,23 +272,30 @@ public class TCFNodeStackFrame extends TCFNode {
@Override
protected void getData(ILabelUpdate result) {
result.setImageDescriptor(ImageCache.getImageDescriptor(getImageName()), 0);
- Throwable error = stack_trace_context.getError();
- if (error == null) error = line_info.getError();
- if (error != null && ((TCFNodeExecContext)parent).isSuspended()) {
- result.setForeground(new RGB(255, 0, 0), 0);
- result.setLabel(error.getClass().getName() + ": " + error.getMessage(), 0);
+ TCFChildrenStackTrace st = ((TCFNodeExecContext)parent).getStackTrace();
+ if (st.getData().get(id) == null) {
+ result.setLabel("", 0);
}
else {
- TCFSourceRef l = line_info.getData();
- if (l == null) {
- result.setLabel("...", 0);
+ Throwable error = stack_trace_context.getError();
+ if (error == null) error = line_info.getError();
+ if (error != null && ((TCFNodeExecContext)parent).isSuspended()) {
+ System.out.println(error.toString());
+ result.setForeground(new RGB(255, 0, 0), 0);
+ result.setLabel(error.getClass().getName() + ": " + error.getMessage(), 0);
}
else {
- String label = makeHexAddrString(l.address);
- if (l.area != null && l.area.file != null) {
- label += ": " + l.area.file + ", line " + l.area.start_line;
+ TCFSourceRef l = line_info.getData();
+ if (l == null) {
+ result.setLabel("...", 0);
+ }
+ else {
+ String label = makeHexAddrString(l.address);
+ if (l.area != null && l.area.file != null) {
+ label += ": " + l.area.file + ", line " + l.area.start_line;
+ }
+ result.setLabel(label, 0);
}
- result.setLabel(label, 0);
}
}
}
@@ -324,17 +333,10 @@ public class TCFNodeStackFrame extends TCFNode {
}
@Override
- public void invalidateNode() {
- stack_trace_context.reset();
- line_info.reset();
- children_regs.reset();
- children_vars.reset();
- children_exps.reset();
- }
-
- @Override
public boolean validateNode(Runnable done) {
TCFDataCache<?> pending = null;
+ TCFChildrenStackTrace stack_trace = ((TCFNodeExecContext)parent).getStackTrace();
+ if (!stack_trace.validate()) pending = stack_trace;
if (!stack_trace_context.validate()) pending = stack_trace_context;
if (!children_regs.validate()) pending = children_regs;
if (!children_vars.validate()) pending = children_vars;
diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java
index 76bb99c13..b21625153 100644
--- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java
+++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java
@@ -214,14 +214,14 @@ public class TCFLaunch extends Launch {
}
};
if (local_file.length() == 0 || remote_file.length() == 0) r.run();
- else copyToRemoteTarget(getProgramPath(project, local_file), remote_file, r);
+ else copyFileToRemoteTarget(getProgramPath(project, local_file), remote_file, r);
}
catch (Exception x) {
channel.terminate(x);
}
}
- private void copyToRemoteTarget(String local_file, String remote_file, final Runnable done) {
+ private void copyFileToRemoteTarget(String local_file, String remote_file, final Runnable done) {
if (local_file == null) {
channel.terminate(new Exception("Program does not exist"));
return;
diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/FileSystemProxy.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/FileSystemProxy.java
index 5cdec13a4..cd953fa33 100644
--- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/FileSystemProxy.java
+++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/FileSystemProxy.java
@@ -40,25 +40,48 @@ public class FileSystemProxy implements IFileSystem {
}
}
- private static final class Status extends FileSystemException {
+ private static final class Status extends FileSystemException implements IErrorReport {
private static final long serialVersionUID = -1636567076145085980L;
private final int status;
+ private final Map<String,Object> attrs;
- Status(int status, String message) {
+ Status(int status, String message, Map<String,Object> attrs) {
super(message);
- this.status = status;
+ this.status = status;
+ this.attrs = attrs;
}
Status(Exception x) {
super(x);
- this.status = IErrorReport.TCF_ERROR_OTHER;
+ this.status = IErrorReport.TCF_ERROR_OTHER;
+ this.attrs = new HashMap<String,Object>();
}
public int getStatus() {
return status;
}
+
+ public int getErrorCode() {
+ Number n = (Number)attrs.get(ERROR_CODE);
+ if (n == null) return 0;
+ return n.intValue();
+ }
+
+ public int getAltCode() {
+ Number n = (Number)attrs.get(ERROR_ALT_CODE);
+ if (n == null) return 0;
+ return n.intValue();
+ }
+
+ public String getAltOrg() {
+ return (String)attrs.get(ERROR_ALT_ORG);
+ }
+
+ public Map<String, Object> getAttributes() {
+ return attrs;
+ }
}
private abstract class FileSystemCommand extends Command {
@@ -71,14 +94,17 @@ public class FileSystemProxy implements IFileSystem {
public Status toFSError(Object data) {
if (data == null) return null;
Map<String,Object> map = (Map<String,Object>)data;
- Number error_code = (Number)map.get(ERROR_CODE);
+ Number error_code = (Number)map.get(IErrorReport.ERROR_CODE);
String cmd = getCommandString();
if (cmd.length() > 72) cmd = cmd.substring(0, 72) + "...";
- return new Status(error_code.intValue(),
+ Status s = new Status(error_code.intValue(),
"TCF command exception:" +
"\nCommand: " + cmd +
"\nException: " + toErrorString(data) +
- "\nError code: " + error_code);
+ "\nError code: " + error_code, map);
+ Object caused_by = map.get(IErrorReport.ERROR_CAUSE_BY);
+ if (caused_by != null) s.initCause(toError(caused_by, false));
+ return s;
}
}
diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/MemoryProxy.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/MemoryProxy.java
index e2e7f13ba..f22f78818 100644
--- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/MemoryProxy.java
+++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/MemoryProxy.java
@@ -22,6 +22,7 @@ import org.eclipse.tm.internal.tcf.core.ReadOnlyMap;
import org.eclipse.tm.tcf.core.Base64;
import org.eclipse.tm.tcf.core.Command;
import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IErrorReport;
import org.eclipse.tm.tcf.protocol.IToken;
import org.eclipse.tm.tcf.protocol.JSON;
import org.eclipse.tm.tcf.services.IMemory;
@@ -46,14 +47,16 @@ public class MemoryProxy implements IMemory {
}
}
- private class MemoryErrorReport extends MemoryError implements ErrorOffset {
+ private class MemoryErrorReport extends MemoryError implements ErrorOffset, IErrorReport {
private static final long serialVersionUID = 796525409870265390L;
+ private final Map<String,Object> attrs;
private final Range[] ranges;
@SuppressWarnings("unchecked")
- MemoryErrorReport(String msg, Number addr, Object ranges) {
+ MemoryErrorReport(String msg, Map<String,Object> attrs, Number addr, Object ranges) {
super(msg);
+ this.attrs = attrs;
Collection<Map<String,Object>> c = (Collection<Map<String,Object>>)ranges;
this.ranges = c == null ? null : new Range[c.size()];
if (c != null) {
@@ -77,6 +80,26 @@ public class MemoryProxy implements IMemory {
}
}
+ public int getErrorCode() {
+ Number n = (Number)attrs.get(ERROR_CODE);
+ if (n == null) return 0;
+ return n.intValue();
+ }
+
+ public int getAltCode() {
+ Number n = (Number)attrs.get(ERROR_ALT_CODE);
+ if (n == null) return 0;
+ return n.intValue();
+ }
+
+ public String getAltOrg() {
+ return (String)attrs.get(ERROR_ALT_ORG);
+ }
+
+ public Map<String, Object> getAttributes() {
+ return attrs;
+ }
+
public String getMessage(int offset) {
if (ranges == null) return null;
int l = 0;
@@ -312,14 +335,18 @@ public class MemoryProxy implements IMemory {
MemoryError toMemoryError(Number addr, Object data, Object ranges) {
if (data == null) return null;
Map<String,Object> map = (Map<String,Object>)data;
- Integer code = (Integer)map.get(ERROR_CODE);
+ Integer code = (Integer)map.get(IErrorReport.ERROR_CODE);
String cmd = getCommandString();
if (cmd.length() > 72) cmd = cmd.substring(0, 72) + "...";
- return new MemoryErrorReport(
+ MemoryError e = new MemoryErrorReport(
"TCF command exception:" +
"\nCommand: " + cmd +
"\nException: " + toErrorString(data) +
- "\nError code: " + code, addr, ranges);
+ "\nError code: " + code,
+ map, addr, ranges);
+ Object caused_by = map.get(IErrorReport.ERROR_CAUSE_BY);
+ if (caused_by != null) e.initCause(toError(caused_by, false));
+ return e;
}
}
diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/Command.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/Command.java
index 14ac70130..bd9d0c420 100644
--- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/Command.java
+++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/Command.java
@@ -56,7 +56,7 @@ import org.eclipse.tm.tcf.protocol.Protocol;
* }.token;
* }
*/
-public abstract class Command implements IErrorReport, IChannel.ICommandListener {
+public abstract class Command implements IChannel.ICommandListener {
private final IService service;
private final String command;
@@ -68,6 +68,39 @@ public abstract class Command implements IErrorReport, IChannel.ICommandListener
private static final SimpleDateFormat timestamp_format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+ private class ErrorReport extends Exception implements IErrorReport {
+
+ private static final long serialVersionUID = 3687543884858739977L;
+ private final Map<String,Object> attrs;
+
+ ErrorReport(String msg, Map<String,Object> attrs) {
+ super(msg);
+ this.attrs = attrs;
+ Object caused_by = attrs.get(IErrorReport.ERROR_CAUSE_BY);
+ if (caused_by != null) initCause(toError(caused_by, false));
+ }
+
+ public int getErrorCode() {
+ Number n = (Number)attrs.get(ERROR_CODE);
+ if (n == null) return 0;
+ return n.intValue();
+ }
+
+ public int getAltCode() {
+ Number n = (Number)attrs.get(ERROR_ALT_CODE);
+ if (n == null) return 0;
+ return n.intValue();
+ }
+
+ public String getAltOrg() {
+ return (String)attrs.get(ERROR_ALT_ORG);
+ }
+
+ public Map<String, Object> getAttributes() {
+ return attrs;
+ }
+ }
+
public Command(IChannel channel, IService service, String command, Object[] args) {
this.service = service;
this.command = command;
@@ -143,17 +176,17 @@ public abstract class Command implements IErrorReport, IChannel.ICommandListener
public static String toErrorString(Object data) {
if (data == null) return null;
Map<String,Object> map = (Map<String,Object>)data;
- String fmt = (String)map.get(ERROR_FORMAT);
+ String fmt = (String)map.get(IErrorReport.ERROR_FORMAT);
if (fmt != null) {
- Collection<Object> c = (Collection<Object>)map.get(ERROR_PARAMS);
+ Collection<Object> c = (Collection<Object>)map.get(IErrorReport.ERROR_PARAMS);
if (c != null) return new MessageFormat(fmt).format(c.toArray());
return fmt;
}
- Number code = (Number)map.get(ERROR_CODE);
+ Number code = (Number)map.get(IErrorReport.ERROR_CODE);
if (code != null) {
- if (code.intValue() == TCF_ERROR_OTHER) {
- String alt_org = (String)map.get(ERROR_ALT_ORG);
- Number alt_code = (Number)map.get(ERROR_ALT_CODE);
+ if (code.intValue() == IErrorReport.TCF_ERROR_OTHER) {
+ String alt_org = (String)map.get(IErrorReport.ERROR_ALT_ORG);
+ Number alt_code = (Number)map.get(IErrorReport.ERROR_ALT_CODE);
if (alt_org != null && alt_code != null) {
return alt_org + " Error " + alt_code;
}
@@ -163,13 +196,13 @@ public abstract class Command implements IErrorReport, IChannel.ICommandListener
return "Invalid error report format";
}
- private void appendErrorProps(StringBuffer bf, Map<String,Object> map) {
- Number time = (Number)map.get(ERROR_TIME);
- Number code = (Number)map.get(ERROR_CODE);
- String service = (String)map.get(ERROR_SERVICE);
- Number severity = (Number)map.get(ERROR_SEVERITY);
- Number alt_code = (Number)map.get(ERROR_ALT_CODE);
- String alt_org = (String)map.get(ERROR_ALT_ORG);
+ private static void appendErrorProps(StringBuffer bf, Map<String,Object> map) {
+ Number time = (Number)map.get(IErrorReport.ERROR_TIME);
+ Number code = (Number)map.get(IErrorReport.ERROR_CODE);
+ String service = (String)map.get(IErrorReport.ERROR_SERVICE);
+ Number severity = (Number)map.get(IErrorReport.ERROR_SEVERITY);
+ Number alt_code = (Number)map.get(IErrorReport.ERROR_ALT_CODE);
+ String alt_org = (String)map.get(IErrorReport.ERROR_ALT_ORG);
if (time != null) {
bf.append('\n');
bf.append("Time: ");
@@ -180,9 +213,9 @@ public abstract class Command implements IErrorReport, IChannel.ICommandListener
bf.append("Severity: ");
bf.append(toErrorString(map));
switch (severity.intValue()) {
- case SEVERITY_ERROR: bf.append("Error");
- case SEVERITY_FATAL: bf.append("Fatal");
- case SEVERITY_WARNING: bf.append("Warning");
+ case IErrorReport.SEVERITY_ERROR: bf.append("Error");
+ case IErrorReport.SEVERITY_FATAL: bf.append("Fatal");
+ case IErrorReport.SEVERITY_WARNING: bf.append("Warning");
default: bf.append("Unknown");
}
}
@@ -209,34 +242,24 @@ public abstract class Command implements IErrorReport, IChannel.ICommandListener
}
}
- @SuppressWarnings("unchecked")
public Exception toError(Object data) {
- if (data == null) return null;
- Map<String,Object> map = (Map<String,Object>)data;
- String cmd = getCommandString();
- if (cmd.length() > 72) cmd = cmd.substring(0, 72) + "...";
- StringBuffer bf = new StringBuffer();
- bf.append("TCF command error:");
- bf.append('\n');
- bf.append("Command: ");
- bf.append(cmd);
- appendErrorProps(bf, map);
- Exception x = new Exception(bf.toString());
- Object caused_by = map.get(ERROR_CAUSE_BY);
- if (caused_by != null) x.initCause(toNestedError(caused_by));
- return x;
+ return toError(data, true);
}
@SuppressWarnings("unchecked")
- private Exception toNestedError(Object data) {
+ public Exception toError(Object data, boolean include_command_text) {
if (data == null) return null;
Map<String,Object> map = (Map<String,Object>)data;
StringBuffer bf = new StringBuffer();
- bf.append("TCF error:");
+ bf.append("TCF error report:");
+ bf.append('\n');
+ if (include_command_text) {
+ String cmd = getCommandString();
+ if (cmd.length() > 72) cmd = cmd.substring(0, 72) + "...";
+ bf.append("Command: ");
+ bf.append(cmd);
+ }
appendErrorProps(bf, map);
- Exception x = new Exception(bf.toString());
- Object caused_by = map.get(ERROR_CAUSE_BY);
- if (caused_by != null) x.initCause(toNestedError(caused_by));
- return x;
+ return new ErrorReport(bf.toString(), map);
}
}
diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/protocol/IErrorReport.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/protocol/IErrorReport.java
index 66349fef6..8e0c6c558 100644
--- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/protocol/IErrorReport.java
+++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/protocol/IErrorReport.java
@@ -10,8 +10,20 @@
*******************************************************************************/
package org.eclipse.tm.tcf.protocol;
+import java.util.Map;
+
/**
- * This interface defines TCF standard format of error reports.
+ * This interface defines TCF standard format of error reports.
+ *
+ * Exception objects can implement this interface to make error report details
+ * available for clients.
+ *
+ * Usage example:
+ *
+ * Exception x = ...
+ * if (x instanceof IErrorReport) {
+ * int error_code = ((IErrorReport)x).getErrorCode();
+ * ...
*
* @noextend This interface is not intended to be extended by clients.
*/
@@ -75,4 +87,12 @@ public interface IErrorReport {
TCF_ERROR_SYM_NOT_FOUND = 22,
TCF_ERROR_UNSUPPORTED = 23,
TCF_ERROR_INV_DATA_TYPE = 24;
+
+ public int getErrorCode();
+
+ public int getAltCode();
+
+ public String getAltOrg();
+
+ public Map<String,Object> getAttributes();
}
diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/util/TCFDataCache.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/util/TCFDataCache.java
index e9cb43150..c914a0e9b 100644
--- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/util/TCFDataCache.java
+++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/util/TCFDataCache.java
@@ -28,6 +28,7 @@ public abstract class TCFDataCache<V> implements Runnable {
private Throwable error;
private boolean valid;
+ private boolean posted;
private V data;
protected final IChannel channel;
@@ -40,6 +41,13 @@ public abstract class TCFDataCache<V> implements Runnable {
this.channel = channel;
}
+ private void post() {
+ if (posted) return;
+ if (waiting_list.isEmpty()) return;
+ Protocol.invokeLater(this);
+ posted = true;
+ }
+
/**
* @return true if cache contains up-to-date data (or data retrieval error).
*/
@@ -79,10 +87,13 @@ public abstract class TCFDataCache<V> implements Runnable {
*/
public void run() {
assert Protocol.isDispatchThread();
- if (waiting_list.isEmpty()) return;
+ posted = false;
Runnable[] arr = waiting_list.toArray(new Runnable[waiting_list.size()]);
waiting_list.clear();
- for (Runnable r : arr) r.run();
+ for (Runnable r : arr) {
+ if (r instanceof TCFDataCache<?> && ((TCFDataCache<?>)r).posted) continue;
+ r.run();
+ }
}
/**
@@ -113,7 +124,7 @@ public abstract class TCFDataCache<V> implements Runnable {
}
assert valid;
assert command == null;
- run();
+ post();
return true;
}
@@ -131,7 +142,7 @@ public abstract class TCFDataCache<V> implements Runnable {
this.error = error;
this.data = data;
valid = true;
- Protocol.invokeLater(this);
+ post();
}
/**
@@ -147,7 +158,7 @@ public abstract class TCFDataCache<V> implements Runnable {
this.data = data;
error = null;
valid = true;
- Protocol.invokeLater(this);
+ post();
}
/**
@@ -158,7 +169,7 @@ public abstract class TCFDataCache<V> implements Runnable {
error = null;
valid = false;
data = null;
- Protocol.invokeLater(this);
+ post();
}
/**
@@ -173,7 +184,7 @@ public abstract class TCFDataCache<V> implements Runnable {
error = null;
valid = false;
data = null;
- Protocol.invokeLater(this);
+ post();
}
/**

Back to the top