mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-20 23:45:23 +02:00
Bug 321084: Create a new ReflectionSequence and have FinalLaunchSequence use it. The goal to to make FinalLaunchSequence easier to extend.
This commit is contained in:
parent
785a5d1913
commit
ca255eb6e6
3 changed files with 1037 additions and 552 deletions
|
@ -19,8 +19,8 @@ import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
|
||||||
import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector;
|
import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector;
|
||||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
|
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.ReflectionSequence;
|
||||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.Sequence;
|
|
||||||
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
||||||
import org.eclipse.cdt.dsf.datamodel.DataModelInitializedEvent;
|
import org.eclipse.cdt.dsf.datamodel.DataModelInitializedEvent;
|
||||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||||
|
@ -49,26 +49,60 @@ import org.eclipse.core.runtime.jobs.Job;
|
||||||
import org.eclipse.debug.core.DebugPlugin;
|
import org.eclipse.debug.core.DebugPlugin;
|
||||||
import org.eclipse.debug.core.IStatusHandler;
|
import org.eclipse.debug.core.IStatusHandler;
|
||||||
|
|
||||||
public class FinalLaunchSequence extends Sequence {
|
public class FinalLaunchSequence extends ReflectionSequence {
|
||||||
|
|
||||||
Step[] fSteps = new Step[] {
|
private GdbLaunch fLaunch;
|
||||||
new Step() { @Override
|
private SessionType fSessionType;
|
||||||
public void execute(RequestMonitor requestMonitor) {
|
private boolean fAttach;
|
||||||
fTracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), fLaunch.getSession().getId());
|
|
||||||
requestMonitor.done();
|
private IGDBControl fCommandControl;
|
||||||
|
private IGDBBackend fGDBBackend;
|
||||||
|
private IMIProcesses fProcService;
|
||||||
|
private CommandFactory fCommandFactory;
|
||||||
|
|
||||||
|
private DsfServicesTracker fTracker;
|
||||||
|
|
||||||
|
public FinalLaunchSequence(DsfExecutor executor, GdbLaunch launch, SessionType sessionType, boolean attach, IProgressMonitor pm) {
|
||||||
|
super(executor, pm, LaunchMessages.getString("FinalLaunchSequence.0"), LaunchMessages.getString("FinalLaunchSequence.1")); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
fLaunch = launch;
|
||||||
|
fSessionType = sessionType;
|
||||||
|
fAttach = attach;
|
||||||
}
|
}
|
||||||
@Override
|
|
||||||
public void rollBack(RequestMonitor requestMonitor) {
|
|
||||||
if (fTracker != null) fTracker.dispose();
|
|
||||||
fTracker = null;
|
|
||||||
requestMonitor.done();
|
|
||||||
}},
|
|
||||||
|
|
||||||
/*
|
@Override
|
||||||
* Fetch the GDBBackend, CommandControl and Process services for later use
|
protected String[] getExecutionOrder(String group) {
|
||||||
|
if (GROUP_TOP_LEVEL.equals(group)) {
|
||||||
|
return new String[] {
|
||||||
|
"stepInitializeFinalLaunchSequence", //$NON-NLS-1$
|
||||||
|
"stepSetEnvironmentDirectory", //$NON-NLS-1$
|
||||||
|
"stepSourceGDBInitFile", //$NON-NLS-1$
|
||||||
|
"stepSetEnvironmentVariables", //$NON-NLS-1$
|
||||||
|
"stepSetExecutable", //$NON-NLS-1$
|
||||||
|
"stepSetArguments", //$NON-NLS-1$
|
||||||
|
"stepSetNonStop", //$NON-NLS-1$
|
||||||
|
"stepSetAutoLoadSharedLibrarySymbols", //$NON-NLS-1$
|
||||||
|
"stepSetSharedLibraryPaths", //$NON-NLS-1$
|
||||||
|
"stepSetSourceLookupPath", //$NON-NLS-1$
|
||||||
|
"stepSpecifyCoreFile", //$NON-NLS-1$
|
||||||
|
"stepRemoteConnection", //$NON-NLS-1$
|
||||||
|
"stepAttachToProcess", //$NON-NLS-1$
|
||||||
|
"stepStartTrackingBreakpoints", //$NON-NLS-1$
|
||||||
|
"stepStartExecution", //$NON-NLS-1$
|
||||||
|
"stepDataModelInitializationComplete", //$NON-NLS-1$
|
||||||
|
"stepCleanup", //$NON-NLS-1$
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the members of the {@link FinalLaunchSequence} class.
|
||||||
|
* This step is mandatory for the rest fo the sequence to complete.
|
||||||
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
new Step() { @Override
|
@Execute
|
||||||
public void execute(RequestMonitor requestMonitor) {
|
public void stepInitializeFinalLaunchSequence(RequestMonitor requestMonitor) {
|
||||||
|
fTracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), fLaunch.getSession().getId());
|
||||||
fGDBBackend = fTracker.getService(IGDBBackend.class);
|
fGDBBackend = fTracker.getService(IGDBBackend.class);
|
||||||
if (fGDBBackend == null) {
|
if (fGDBBackend == null) {
|
||||||
requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot obtain GDBBackend service", null)); //$NON-NLS-1$
|
requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot obtain GDBBackend service", null)); //$NON-NLS-1$
|
||||||
|
@ -93,12 +127,25 @@ public class FinalLaunchSequence extends Sequence {
|
||||||
}
|
}
|
||||||
|
|
||||||
requestMonitor.done();
|
requestMonitor.done();
|
||||||
}},
|
}
|
||||||
/*
|
|
||||||
* Specify GDB's working directory
|
/**
|
||||||
|
* Rollback method for {@link #stepInitializeFinalLaunchSequence()}
|
||||||
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
new Step() { @Override
|
@RollBack("stepInitializeFinalLaunchSequence")
|
||||||
public void execute(final RequestMonitor requestMonitor) {
|
public void rollBackInitializeFinalLaunchSequence(RequestMonitor requestMonitor) {
|
||||||
|
if (fTracker != null) fTracker.dispose();
|
||||||
|
fTracker = null;
|
||||||
|
requestMonitor.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify GDB's working directory.
|
||||||
|
* @since 4.0
|
||||||
|
*/
|
||||||
|
@Execute
|
||||||
|
public void stepSetEnvironmentDirectory(final RequestMonitor requestMonitor) {
|
||||||
IPath dir = null;
|
IPath dir = null;
|
||||||
try {
|
try {
|
||||||
dir = fGDBBackend.getGDBWorkingDirectory();
|
dir = fGDBBackend.getGDBWorkingDirectory();
|
||||||
|
@ -115,12 +162,14 @@ public class FinalLaunchSequence extends Sequence {
|
||||||
} else {
|
} else {
|
||||||
requestMonitor.done();
|
requestMonitor.done();
|
||||||
}
|
}
|
||||||
}},
|
}
|
||||||
/*
|
|
||||||
* Source the gdbinit file specified in the launch
|
/**
|
||||||
|
* Source the gdbinit file specified in the launch.
|
||||||
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
new Step() { @Override
|
@Execute
|
||||||
public void execute(final RequestMonitor requestMonitor) {
|
public void stepSourceGDBInitFile(final RequestMonitor requestMonitor) {
|
||||||
try {
|
try {
|
||||||
final String gdbinitFile = fGDBBackend.getGDBInitFile();
|
final String gdbinitFile = fGDBBackend.getGDBInitFile();
|
||||||
|
|
||||||
|
@ -147,12 +196,14 @@ public class FinalLaunchSequence extends Sequence {
|
||||||
requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot get gdbinit option", e)); //$NON-NLS-1$
|
requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot get gdbinit option", e)); //$NON-NLS-1$
|
||||||
requestMonitor.done();
|
requestMonitor.done();
|
||||||
}
|
}
|
||||||
}},
|
}
|
||||||
/*
|
|
||||||
|
/**
|
||||||
* Specify environment variables if needed
|
* Specify environment variables if needed
|
||||||
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
new Step() { @Override
|
@Execute
|
||||||
public void execute(final RequestMonitor requestMonitor) {
|
public void stepSetEnvironmentVariables(final RequestMonitor requestMonitor) {
|
||||||
boolean clear = false;
|
boolean clear = false;
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
try {
|
try {
|
||||||
|
@ -169,12 +220,14 @@ public class FinalLaunchSequence extends Sequence {
|
||||||
} else {
|
} else {
|
||||||
requestMonitor.done();
|
requestMonitor.done();
|
||||||
}
|
}
|
||||||
}},
|
}
|
||||||
/*
|
|
||||||
|
/**
|
||||||
* Specify the executable file to be debugged and read the symbol table.
|
* Specify the executable file to be debugged and read the symbol table.
|
||||||
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
new Step() { @Override
|
@Execute
|
||||||
public void execute(final RequestMonitor requestMonitor) {
|
public void stepSetExecutable(final RequestMonitor requestMonitor) {
|
||||||
boolean noFileCommand = IGDBLaunchConfigurationConstants.DEBUGGER_USE_SOLIB_SYMBOLS_FOR_APP_DEFAULT;
|
boolean noFileCommand = IGDBLaunchConfigurationConstants.DEBUGGER_USE_SOLIB_SYMBOLS_FOR_APP_DEFAULT;
|
||||||
try {
|
try {
|
||||||
noFileCommand = fLaunch.getLaunchConfiguration().getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_USE_SOLIB_SYMBOLS_FOR_APP,
|
noFileCommand = fLaunch.getLaunchConfiguration().getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_USE_SOLIB_SYMBOLS_FOR_APP,
|
||||||
|
@ -194,12 +247,14 @@ public class FinalLaunchSequence extends Sequence {
|
||||||
} else {
|
} else {
|
||||||
requestMonitor.done();
|
requestMonitor.done();
|
||||||
}
|
}
|
||||||
}},
|
}
|
||||||
/*
|
|
||||||
* Specify the arguments to the executable file
|
/**
|
||||||
|
* Specify the arguments to the executable file.
|
||||||
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
new Step() { @Override
|
@Execute
|
||||||
public void execute(final RequestMonitor requestMonitor) {
|
public void stepSetArguments(final RequestMonitor requestMonitor) {
|
||||||
try {
|
try {
|
||||||
String args = fGDBBackend.getProgramArguments();
|
String args = fGDBBackend.getProgramArguments();
|
||||||
|
|
||||||
|
@ -214,12 +269,14 @@ public class FinalLaunchSequence extends Sequence {
|
||||||
requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot get inferior arguments", e)); //$NON-NLS-1$
|
requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot get inferior arguments", e)); //$NON-NLS-1$
|
||||||
requestMonitor.done();
|
requestMonitor.done();
|
||||||
}
|
}
|
||||||
}},
|
}
|
||||||
/*
|
|
||||||
* Enable non-stop mode if necessary
|
/**
|
||||||
|
* Enable non-stop mode if requested.
|
||||||
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
new Step() { @Override
|
@Execute
|
||||||
public void execute(final RequestMonitor requestMonitor) {
|
public void stepSetNonStop(final RequestMonitor requestMonitor) {
|
||||||
boolean isNonStop = false;
|
boolean isNonStop = false;
|
||||||
try {
|
try {
|
||||||
isNonStop = fLaunch.getLaunchConfiguration().getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP,
|
isNonStop = fLaunch.getLaunchConfiguration().getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP,
|
||||||
|
@ -251,12 +308,14 @@ public class FinalLaunchSequence extends Sequence {
|
||||||
} else {
|
} else {
|
||||||
requestMonitor.done();
|
requestMonitor.done();
|
||||||
}
|
}
|
||||||
}},
|
}
|
||||||
/*
|
|
||||||
|
/**
|
||||||
* Tell GDB to automatically load or not the shared library symbols
|
* Tell GDB to automatically load or not the shared library symbols
|
||||||
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
new Step() { @Override
|
@Execute
|
||||||
public void execute(RequestMonitor requestMonitor) {
|
public void stepSetAutoLoadSharedLibrarySymbols(RequestMonitor requestMonitor) {
|
||||||
try {
|
try {
|
||||||
boolean autolib = fLaunch.getLaunchConfiguration().getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_AUTO_SOLIB,
|
boolean autolib = fLaunch.getLaunchConfiguration().getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_AUTO_SOLIB,
|
||||||
IGDBLaunchConfigurationConstants.DEBUGGER_AUTO_SOLIB_DEFAULT);
|
IGDBLaunchConfigurationConstants.DEBUGGER_AUTO_SOLIB_DEFAULT);
|
||||||
|
@ -267,12 +326,14 @@ public class FinalLaunchSequence extends Sequence {
|
||||||
requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot set shared library option", e)); //$NON-NLS-1$
|
requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot set shared library option", e)); //$NON-NLS-1$
|
||||||
requestMonitor.done();
|
requestMonitor.done();
|
||||||
}
|
}
|
||||||
}},
|
}
|
||||||
/*
|
|
||||||
* Set the shared library paths
|
/**
|
||||||
|
* Set the shared library paths.
|
||||||
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
new Step() { @Override
|
@Execute
|
||||||
public void execute(final RequestMonitor requestMonitor) {
|
public void stepSetSharedLibraryPaths(final RequestMonitor requestMonitor) {
|
||||||
try {
|
try {
|
||||||
List<String> p = fGDBBackend.getSharedLibraryPaths();
|
List<String> p = fGDBBackend.getSharedLibraryPaths();
|
||||||
|
|
||||||
|
@ -283,16 +344,16 @@ public class FinalLaunchSequence extends Sequence {
|
||||||
new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor) {
|
new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor) {
|
||||||
@Override
|
@Override
|
||||||
protected void handleSuccess() {
|
protected void handleSuccess() {
|
||||||
// Sysroot is not available in GDB6.6 and will make the launch fail in that case.
|
// Sysroot is not available in GDB6.6 and will make the launch fail in that case.
|
||||||
// Let's remove it for now
|
// Let's remove it for now
|
||||||
requestMonitor.done();
|
requestMonitor.done();
|
||||||
// // If we are able to set the solib-search-path,
|
// // If we are able to set the solib-search-path,
|
||||||
// // we should disable the sysroot variable, as indicated
|
// // we should disable the sysroot variable, as indicated
|
||||||
// // in the GDB documentation. This is to avoid the sysroot
|
// // in the GDB documentation. This is to avoid the sysroot
|
||||||
// // variable finding libraries that were not meant to be found.
|
// // variable finding libraries that were not meant to be found.
|
||||||
// fCommandControl.queueCommand(
|
// fCommandControl.queueCommand(
|
||||||
// new MIGDBSetSysroot(fCommandControl.getContext()),
|
// new MIGDBSetSysroot(fCommandControl.getContext()),
|
||||||
// new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor));
|
// new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor));
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -302,25 +363,24 @@ public class FinalLaunchSequence extends Sequence {
|
||||||
requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot set share library paths", e)); //$NON-NLS-1$
|
requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot set share library paths", e)); //$NON-NLS-1$
|
||||||
requestMonitor.done();
|
requestMonitor.done();
|
||||||
}
|
}
|
||||||
}},
|
}
|
||||||
/*
|
|
||||||
* Setup the source paths
|
/**
|
||||||
|
* Setup the source paths.
|
||||||
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
new Step() { @Override
|
@Execute
|
||||||
public void execute(RequestMonitor requestMonitor) {
|
public void stepSetSourceLookupPath(RequestMonitor requestMonitor) {
|
||||||
CSourceLookup sourceLookup = fTracker.getService(CSourceLookup.class);
|
CSourceLookup sourceLookup = fTracker.getService(CSourceLookup.class);
|
||||||
CSourceLookupDirector locator = (CSourceLookupDirector)fLaunch.getSourceLocator();
|
CSourceLookupDirector locator = (CSourceLookupDirector)fLaunch.getSourceLocator();
|
||||||
ISourceLookupDMContext sourceLookupDmc = (ISourceLookupDMContext)fCommandControl.getContext();
|
ISourceLookupDMContext sourceLookupDmc = (ISourceLookupDMContext)fCommandControl.getContext();
|
||||||
|
|
||||||
sourceLookup.setSourceLookupPath(sourceLookupDmc, locator.getSourceContainers(), requestMonitor);
|
sourceLookup.setSourceLookupPath(sourceLookupDmc, locator.getSourceContainers(), requestMonitor);
|
||||||
}},
|
}
|
||||||
/*
|
|
||||||
* Specify the core file to be debugged if we are launching such a debug session.
|
/** @since 4.0 */
|
||||||
*/
|
protected class PromptForCoreJob extends Job {
|
||||||
new Step() {
|
protected DataRequestMonitor<String> fRequestMonitor;
|
||||||
// Need a job because prompter.handleStatus will block
|
|
||||||
class PromptForCoreJob extends Job {
|
|
||||||
DataRequestMonitor<String> fRequestMonitor;
|
|
||||||
|
|
||||||
public PromptForCoreJob(String name, DataRequestMonitor<String> rm) {
|
public PromptForCoreJob(String name, DataRequestMonitor<String> rm) {
|
||||||
super(name);
|
super(name);
|
||||||
|
@ -359,8 +419,13 @@ public class FinalLaunchSequence extends Sequence {
|
||||||
return Status.OK_STATUS;
|
return Status.OK_STATUS;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@Override
|
|
||||||
public void execute(final RequestMonitor requestMonitor) {
|
/**
|
||||||
|
* If we are dealing with a post-mortem debug session, specify the core file.
|
||||||
|
* @since 4.0
|
||||||
|
*/
|
||||||
|
@Execute
|
||||||
|
public void stepSpecifyCoreFile(final RequestMonitor requestMonitor) {
|
||||||
if (fSessionType == SessionType.CORE) {
|
if (fSessionType == SessionType.CORE) {
|
||||||
try {
|
try {
|
||||||
String coreFile = fLaunch.getLaunchConfiguration().getAttribute(ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, ""); //$NON-NLS-1$
|
String coreFile = fLaunch.getLaunchConfiguration().getAttribute(ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, ""); //$NON-NLS-1$
|
||||||
|
@ -424,11 +489,8 @@ public class FinalLaunchSequence extends Sequence {
|
||||||
requestMonitor.done();
|
requestMonitor.done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
/*
|
|
||||||
* If remote debugging, connect to target.
|
|
||||||
*/
|
|
||||||
new Step() {
|
|
||||||
private boolean fTcpConnection;
|
private boolean fTcpConnection;
|
||||||
private String fRemoteTcpHost;
|
private String fRemoteTcpHost;
|
||||||
private String fRemoteTcpPort;
|
private String fRemoteTcpPort;
|
||||||
|
@ -483,8 +545,12 @@ public class FinalLaunchSequence extends Sequence {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public void execute(final RequestMonitor requestMonitor) {
|
* If we are dealing with a remote debugging session, connect to the target.
|
||||||
|
* @since 4.0
|
||||||
|
*/
|
||||||
|
@Execute
|
||||||
|
public void stepRemoteConnection(final RequestMonitor requestMonitor) {
|
||||||
if (fSessionType == SessionType.REMOTE) {
|
if (fSessionType == SessionType.REMOTE) {
|
||||||
if (!checkConnectionType(requestMonitor)) return;
|
if (!checkConnectionType(requestMonitor)) return;
|
||||||
|
|
||||||
|
@ -508,13 +574,13 @@ public class FinalLaunchSequence extends Sequence {
|
||||||
requestMonitor.done();
|
requestMonitor.done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
/*
|
/**
|
||||||
* If attach session, perform the attach.
|
* If we are dealing with an attach debugging session, perform the attach.
|
||||||
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
new Step() {
|
@Execute
|
||||||
@Override
|
public void stepAttachToProcess(final RequestMonitor requestMonitor) {
|
||||||
public void execute(final RequestMonitor requestMonitor) {
|
|
||||||
// A local attach can figure out the binary from the attach
|
// A local attach can figure out the binary from the attach
|
||||||
// command. This allows the user not to specify the binary
|
// command. This allows the user not to specify the binary
|
||||||
// in the launch. But for breakpoints to work, we must do the
|
// in the launch. But for breakpoints to work, we must do the
|
||||||
|
@ -550,12 +616,14 @@ public class FinalLaunchSequence extends Sequence {
|
||||||
requestMonitor.done();
|
requestMonitor.done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
/*
|
/**
|
||||||
* Start tracking the breakpoints once we know we are connected to the target (necessary for remote debugging)
|
* Start tracking the breakpoints. Note that for remote debugging
|
||||||
|
* we should first connect to the target.
|
||||||
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
new Step() { @Override
|
@Execute
|
||||||
public void execute(final RequestMonitor requestMonitor) {
|
public void stepStartTrackingBreakpoints(final RequestMonitor requestMonitor) {
|
||||||
if (fSessionType != SessionType.CORE) {
|
if (fSessionType != SessionType.CORE) {
|
||||||
MIBreakpointsManager bpmService = fTracker.getService(MIBreakpointsManager.class);
|
MIBreakpointsManager bpmService = fTracker.getService(MIBreakpointsManager.class);
|
||||||
IBreakpointsTargetDMContext breakpointDmc = (IBreakpointsTargetDMContext)fCommandControl.getContext();
|
IBreakpointsTargetDMContext breakpointDmc = (IBreakpointsTargetDMContext)fCommandControl.getContext();
|
||||||
|
@ -564,65 +632,41 @@ public class FinalLaunchSequence extends Sequence {
|
||||||
} else {
|
} else {
|
||||||
requestMonitor.done();
|
requestMonitor.done();
|
||||||
}
|
}
|
||||||
}},
|
}
|
||||||
/*
|
|
||||||
* Start the program.
|
/**
|
||||||
|
* Start executing the program.
|
||||||
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
new Step() {
|
@Execute
|
||||||
@Override
|
public void stepStartExecution(final RequestMonitor requestMonitor) {
|
||||||
public void execute(final RequestMonitor requestMonitor) {
|
|
||||||
if (fSessionType != SessionType.CORE) {
|
if (fSessionType != SessionType.CORE) {
|
||||||
fCommandControl.start(fLaunch, requestMonitor);
|
fCommandControl.start(fLaunch, requestMonitor);
|
||||||
} else {
|
} else {
|
||||||
requestMonitor.done();
|
requestMonitor.done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
/*
|
/**
|
||||||
* Indicate that the Data Model has been filled. This will trigger the Debug view to expand.
|
* Indicate that the Data Model has been filled. This will trigger the Debug view to expand.
|
||||||
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
new Step() {
|
@Execute
|
||||||
@Override
|
public void stepDataModelInitializationComplete(final RequestMonitor requestMonitor) {
|
||||||
public void execute(final RequestMonitor requestMonitor) {
|
|
||||||
fLaunch.getSession().dispatchEvent(new DataModelInitializedEvent(fCommandControl.getContext()),
|
fLaunch.getSession().dispatchEvent(new DataModelInitializedEvent(fCommandControl.getContext()),
|
||||||
fCommandControl.getProperties());
|
fCommandControl.getProperties());
|
||||||
requestMonitor.done();
|
requestMonitor.done();
|
||||||
}
|
}
|
||||||
},
|
|
||||||
/*
|
/**
|
||||||
* Cleanup
|
* Cleanup now that the sequence has been run.
|
||||||
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
new Step() {
|
@Execute
|
||||||
@Override
|
public void stepCleanup(final RequestMonitor requestMonitor) {
|
||||||
public void execute(final RequestMonitor requestMonitor) {
|
|
||||||
fTracker.dispose();
|
fTracker.dispose();
|
||||||
fTracker = null;
|
fTracker = null;
|
||||||
requestMonitor.done();
|
requestMonitor.done();
|
||||||
}
|
}
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
GdbLaunch fLaunch;
|
|
||||||
SessionType fSessionType;
|
|
||||||
boolean fAttach;
|
|
||||||
|
|
||||||
private IGDBControl fCommandControl;
|
|
||||||
private IGDBBackend fGDBBackend;
|
|
||||||
private IMIProcesses fProcService;
|
|
||||||
private CommandFactory fCommandFactory;
|
|
||||||
|
|
||||||
DsfServicesTracker fTracker;
|
|
||||||
|
|
||||||
public FinalLaunchSequence(DsfExecutor executor, GdbLaunch launch, SessionType sessionType, boolean attach, IProgressMonitor pm) {
|
|
||||||
super(executor, pm, LaunchMessages.getString("FinalLaunchSequence.0"), LaunchMessages.getString("FinalLaunchSequence.1")); //$NON-NLS-1$ //$NON-NLS-2$
|
|
||||||
fLaunch = launch;
|
|
||||||
fSessionType = sessionType;
|
|
||||||
fAttach = attach;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Step[] getSteps() {
|
|
||||||
return fSteps;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,264 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2010 Wind River Systems 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:
|
||||||
|
* Wind River Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.dsf.concurrent;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Inherited;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.dsf.internal.DsfPlugin;
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A type of {@link Sequence} which uses reflection and annotations to
|
||||||
|
* declare its different {@link Sequence.Step}. It can be used to make
|
||||||
|
* larger DSF sequences more readable and easier to override.
|
||||||
|
*
|
||||||
|
* The order of execution of the {@code @Execute} methods is determined by
|
||||||
|
* the {@link #getExecutionOrder()} method.
|
||||||
|
*
|
||||||
|
* {@code @Execute} methods can be grouped in a hierarchical set of groups,
|
||||||
|
* which should be included in the result of {@link #getExecutionOrder()}.
|
||||||
|
* Using groups can make overriding slightly simpler.
|
||||||
|
*
|
||||||
|
* A usage example follows: <code><pre>
|
||||||
|
* public class MyReflectionSequence extends ReflectionSequence {
|
||||||
|
*
|
||||||
|
* public MyReflectionSequence(DsfExecutor executor) {
|
||||||
|
* super(executor);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* protected static final String GROUP_INIT = "GROUP_INIT";
|
||||||
|
*
|
||||||
|
* {@code @Override}
|
||||||
|
* protected String[] getExecutionOrder(String group) {
|
||||||
|
* if (GROUP_TOP_LEVEL.equals(group)) {
|
||||||
|
* // This is the top level group which contains
|
||||||
|
* // all sub-groups, or steps that are not in
|
||||||
|
* // other groups.
|
||||||
|
* return new String[] { GROUP_INIT, "step3", "step4" };
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // Now deal with the content of sub-groups
|
||||||
|
* if (GROUP_INIT.equals(group)) {
|
||||||
|
* return new String[] { "step1", "step2" };
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // An invalid group was requested
|
||||||
|
* return null;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* {@code @Execute}
|
||||||
|
* public void step1(RequestMonitor rm) {
|
||||||
|
* // Do something
|
||||||
|
* rm.done();
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* {@code @RollBack("step1")}
|
||||||
|
* public void rollBack1(RequestMonitor rm) {
|
||||||
|
* // Rollback what was done in step1()
|
||||||
|
* rm.done();
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* {@code @Execute}
|
||||||
|
* public void step2(RequestMonitor rm) {
|
||||||
|
* // Do something else
|
||||||
|
* rm.done();
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* {@code @Execute}
|
||||||
|
* public void step3(RequestMonitor rm) {
|
||||||
|
* // Do something else
|
||||||
|
* rm.done();
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* {@code @Execute}
|
||||||
|
* public void step4(RequestMonitor rm) {
|
||||||
|
* // Do something else
|
||||||
|
* rm.done();
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* </pre></code>
|
||||||
|
*
|
||||||
|
* @since 2.2
|
||||||
|
*/
|
||||||
|
abstract public class ReflectionSequence extends Sequence {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The top-level group in which all sub-groups or steps that
|
||||||
|
* are not part of any sub-groups are contained. This group
|
||||||
|
* identifier is the one that will be used in the first call to
|
||||||
|
* {@link #getExecutionOrder()}.
|
||||||
|
*/
|
||||||
|
public static final String GROUP_TOP_LEVEL = "GROUP_TOP_LEVEL"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
private Step[] fReflectionSteps;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Annotation used to indicate that a method corresponds to an
|
||||||
|
* {@link Sequence.Step#execute()} method of a {@link Sequence.Step}.
|
||||||
|
* The annotated method must be declared public.
|
||||||
|
*/
|
||||||
|
@Inherited
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
public static @interface Execute {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Annotation used to indicate that a method corresponds to a
|
||||||
|
* {@link Sequence.Step#rollBack()} method of a {@link Sequence.Step}.
|
||||||
|
* Declaring such a method is optional. If declared, the annotated
|
||||||
|
* method must be declared public.
|
||||||
|
*/
|
||||||
|
@Inherited
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
public static @interface RollBack {
|
||||||
|
/**
|
||||||
|
* Name of the method tagged with the {@link Execute} annotation that this method rolls back.
|
||||||
|
*/
|
||||||
|
String value();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ReflectionStep extends Step {
|
||||||
|
final private Method fExecuteMethod;
|
||||||
|
final private Method fRollbackMethod;
|
||||||
|
|
||||||
|
private ReflectionStep(Method executeMethod, Method rollbackMethod) {
|
||||||
|
assert executeMethod != null;
|
||||||
|
|
||||||
|
fExecuteMethod = executeMethod;;
|
||||||
|
fRollbackMethod = rollbackMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(RequestMonitor rm) {
|
||||||
|
try {
|
||||||
|
fExecuteMethod.invoke(ReflectionSequence.this, rm);
|
||||||
|
} catch (Exception e) {
|
||||||
|
rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Error executing step execute method: " + fExecuteMethod.getName(), e)); //$NON-NLS-1$
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void rollBack(RequestMonitor rm) {
|
||||||
|
if (fRollbackMethod == null) {
|
||||||
|
super.rollBack(rm);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
fRollbackMethod.invoke(ReflectionSequence.this, rm);
|
||||||
|
} catch (Exception e) {
|
||||||
|
rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Error executing step rollback method: " + fRollbackMethod.getName(), e)); //$NON-NLS-1$
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReflectionSequence(DsfExecutor executor) {
|
||||||
|
super(executor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReflectionSequence(DsfExecutor executor, RequestMonitor rm) {
|
||||||
|
super(executor, rm);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReflectionSequence(DsfExecutor executor, IProgressMonitor pm, String taskName, String rollbackTaskName) {
|
||||||
|
super(executor, pm, taskName, rollbackTaskName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReflectionSequence(DsfExecutor executor, RequestMonitorWithProgress rm, String taskName, String rollbackTaskName) {
|
||||||
|
super(executor, rm, taskName, rollbackTaskName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method must return the execution order of {@code @Execute} methods and/or groups.
|
||||||
|
*
|
||||||
|
* @param groupName The name of a group for which the list of {@code @Execute} methods
|
||||||
|
* or sub-groups should be returned in the order they should be executed.
|
||||||
|
* If the concept of groups is not used, then this parameter can be ignored,
|
||||||
|
* at the top-level ordering should be returned.
|
||||||
|
*
|
||||||
|
* @return An array containing the list of @Execute methods and groups in the order
|
||||||
|
* they should be executed, or null if the specified groupName is unknown.
|
||||||
|
*/
|
||||||
|
abstract protected String[] getExecutionOrder(String groupName);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Step[] getSteps() {
|
||||||
|
if (fReflectionSteps == null) {
|
||||||
|
Map<String, Method> executeMethods = getAnnotatedMethods(Execute.class);
|
||||||
|
Map<String, Method> rollBackMethods = getAnnotatedMethods(RollBack.class);
|
||||||
|
List<Step> steps = getGroupSteps(GROUP_TOP_LEVEL, executeMethods, rollBackMethods);
|
||||||
|
fReflectionSteps = steps.toArray(new ReflectionStep[steps.size()]);
|
||||||
|
}
|
||||||
|
return fReflectionSteps;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Step> getGroupSteps(String groupId, Map<String, Method> executeMethods, Map<String, Method> rollBackMethods) {
|
||||||
|
List<Step> steps = new ArrayList<Step>(executeMethods.size());
|
||||||
|
|
||||||
|
String[] order = getExecutionOrder(groupId);
|
||||||
|
if (order == null) {
|
||||||
|
throw new RuntimeException("Unknown group in sequence: " + groupId); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String name : order) {
|
||||||
|
Method executeMethod = executeMethods.get(name);
|
||||||
|
if (executeMethod == null) {
|
||||||
|
// name is a group id
|
||||||
|
steps.addAll(getGroupSteps(name, executeMethods, rollBackMethods));
|
||||||
|
} else {
|
||||||
|
steps.add(new ReflectionStep(executeMethod, rollBackMethods.get(executeMethod.getName())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return steps;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Method> getAnnotatedMethods(Class<? extends Annotation> annotationType) {
|
||||||
|
Map<String, Method> retVal = new HashMap<String, Method>();
|
||||||
|
try {
|
||||||
|
Method[] methods = getClass().getMethods();
|
||||||
|
for (Method method : methods) {
|
||||||
|
if (method.isAnnotationPresent(annotationType)) {
|
||||||
|
Class<?>[] paramTypes = method.getParameterTypes();
|
||||||
|
if (paramTypes.length != 1) { // must have one and only param, the RequestMonitor
|
||||||
|
throw new IllegalArgumentException("Method " + //$NON-NLS-1$
|
||||||
|
method.getDeclaringClass().getSimpleName() + "#" + method.getName() + //$NON-NLS-1$
|
||||||
|
" must have a single parameter"); //$NON-NLS-1$
|
||||||
|
} else {
|
||||||
|
if (annotationType.equals(Execute.class)) {
|
||||||
|
retVal.put(method.getName(), method);
|
||||||
|
} else {// @Rollback
|
||||||
|
retVal.put(method.getAnnotation(RollBack.class).value(), method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(SecurityException e) {
|
||||||
|
throw new IllegalArgumentException("No permission to access ReflectionSequence method"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -17,6 +17,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
import junit.framework.Assert;
|
import junit.framework.Assert;
|
||||||
|
|
||||||
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.ReflectionSequence;
|
||||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.Sequence;
|
import org.eclipse.cdt.dsf.concurrent.Sequence;
|
||||||
import org.eclipse.cdt.tests.dsf.DsfTestPlugin;
|
import org.eclipse.cdt.tests.dsf.DsfTestPlugin;
|
||||||
|
@ -94,6 +95,55 @@ public class DsfSequenceTests {
|
||||||
Assert.assertTrue(!sequence.isCancelled());
|
Assert.assertTrue(!sequence.isCancelled());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class SimpleReflectionSequence extends ReflectionSequence {
|
||||||
|
|
||||||
|
public int fStepCounter;
|
||||||
|
|
||||||
|
public SimpleReflectionSequence() {
|
||||||
|
super(fExecutor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getExecutionOrder(String groupName) {
|
||||||
|
return new String[] { "step1", "step2"};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Execute()
|
||||||
|
public void step1(RequestMonitor rm) {
|
||||||
|
fStepCounter++;
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Execute()
|
||||||
|
public void step2(RequestMonitor rm) {
|
||||||
|
fStepCounter++;
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void simpleReflectionTest() throws InterruptedException, ExecutionException {
|
||||||
|
|
||||||
|
// Create, start, and wait for the sequence.
|
||||||
|
SimpleReflectionSequence sequence = new SimpleReflectionSequence();
|
||||||
|
|
||||||
|
//Sequence sequence = new SimpleReflectionSequence();
|
||||||
|
Assert.assertTrue(!sequence.isDone());
|
||||||
|
Assert.assertTrue(!sequence.isCancelled());
|
||||||
|
|
||||||
|
fExecutor.execute(sequence);
|
||||||
|
sequence.get();
|
||||||
|
|
||||||
|
// Check the count
|
||||||
|
Assert.assertTrue(sequence.fStepCounter == 2);
|
||||||
|
|
||||||
|
// Check post conditions
|
||||||
|
Assert.assertTrue(sequence.isDone());
|
||||||
|
Assert.assertTrue(!sequence.isCancelled());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test (expected = ExecutionException.class)
|
@Test (expected = ExecutionException.class)
|
||||||
public void rollbackTest() throws InterruptedException, ExecutionException {
|
public void rollbackTest() throws InterruptedException, ExecutionException {
|
||||||
// Create a counter for tracking number of steps performed and steps
|
// Create a counter for tracking number of steps performed and steps
|
||||||
|
@ -149,6 +199,133 @@ public class DsfSequenceTests {
|
||||||
Assert.assertTrue("Exception should have been thrown", false); //$NON-NLS-1$
|
Assert.assertTrue("Exception should have been thrown", false); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class RollBackReflectionSequence extends ReflectionSequence {
|
||||||
|
|
||||||
|
public int fStepCounter;
|
||||||
|
public int fRollBackCounter;
|
||||||
|
|
||||||
|
public RollBackReflectionSequence() {
|
||||||
|
super(fExecutor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getExecutionOrder(String groupName) {
|
||||||
|
return new String[] { "step1", "step2"};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Execute()
|
||||||
|
public void step1(RequestMonitor rm) {
|
||||||
|
fStepCounter++;
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
@RollBack("step1")
|
||||||
|
public void rollBack1(RequestMonitor rm) {
|
||||||
|
fRollBackCounter++;
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Execute()
|
||||||
|
public void step2(RequestMonitor rm) {
|
||||||
|
fStepCounter++;
|
||||||
|
rm.setStatus(new Status(IStatus.ERROR, DsfTestPlugin.PLUGIN_ID, -1, "", null)); //$NON-NLS-1$
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
@RollBack("step2")
|
||||||
|
public void rollBack2(RequestMonitor rm) {
|
||||||
|
fRollBackCounter++;
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test (expected = ExecutionException.class)
|
||||||
|
public void rollbackReflectionTest() throws InterruptedException, ExecutionException {
|
||||||
|
// Create and start.
|
||||||
|
RollBackReflectionSequence sequence = new RollBackReflectionSequence();
|
||||||
|
fExecutor.execute(sequence);
|
||||||
|
|
||||||
|
// Block and wait for sequence to complete.
|
||||||
|
try {
|
||||||
|
sequence.get();
|
||||||
|
} finally {
|
||||||
|
// Both steps should be performed
|
||||||
|
Assert.assertEquals(2, sequence.fStepCounter);
|
||||||
|
// Only one step is rolled back, the first one.
|
||||||
|
Assert.assertEquals(1, sequence.fRollBackCounter);
|
||||||
|
|
||||||
|
// Check state from Future interface
|
||||||
|
Assert.assertTrue(sequence.isDone());
|
||||||
|
Assert.assertTrue(!sequence.isCancelled());
|
||||||
|
}
|
||||||
|
Assert.assertTrue("Exception should have been thrown", false); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RollBackReflectionSequence2 extends ReflectionSequence {
|
||||||
|
|
||||||
|
public int fStepCounter;
|
||||||
|
public int fRollBackCounter;
|
||||||
|
|
||||||
|
public RollBackReflectionSequence2() {
|
||||||
|
super(fExecutor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getExecutionOrder(String groupName) {
|
||||||
|
return new String[] { "step1", "step2", "step3" };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Execute()
|
||||||
|
public void step1(RequestMonitor rm) {
|
||||||
|
fStepCounter++;
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
@RollBack("step1")
|
||||||
|
public void rollBack1(RequestMonitor rm) {
|
||||||
|
fRollBackCounter++;
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
@Execute()
|
||||||
|
|
||||||
|
public void step2(RequestMonitor rm) {
|
||||||
|
fStepCounter++;
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Execute()
|
||||||
|
public void step3(RequestMonitor rm) {
|
||||||
|
fStepCounter++;
|
||||||
|
rm.setStatus(new Status(IStatus.ERROR, DsfTestPlugin.PLUGIN_ID, -1, "", null)); //$NON-NLS-1$
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test (expected = ExecutionException.class)
|
||||||
|
public void rollbackReflectionWithoutRollBackMethodTest() throws InterruptedException, ExecutionException {
|
||||||
|
// Create and start.
|
||||||
|
RollBackReflectionSequence2 sequence = new RollBackReflectionSequence2();
|
||||||
|
fExecutor.execute(sequence);
|
||||||
|
|
||||||
|
// Block and wait for sequence to complete.
|
||||||
|
try {
|
||||||
|
sequence.get();
|
||||||
|
} finally {
|
||||||
|
// All three steps should be performed
|
||||||
|
Assert.assertEquals(3, sequence.fStepCounter);
|
||||||
|
// Two steps are rolled back, but only the first one has
|
||||||
|
// a rollback method.
|
||||||
|
Assert.assertEquals(1, sequence.fRollBackCounter);
|
||||||
|
|
||||||
|
// Check state from Future interface
|
||||||
|
Assert.assertTrue(sequence.isDone());
|
||||||
|
Assert.assertTrue(!sequence.isCancelled());
|
||||||
|
}
|
||||||
|
Assert.assertTrue("Exception should have been thrown", false); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The goal of this test it to check that if an exception is thrown within
|
* The goal of this test it to check that if an exception is thrown within
|
||||||
* the Step.execute(), the step will return from the Future.get() method.
|
* the Step.execute(), the step will return from the Future.get() method.
|
||||||
|
|
Loading…
Add table
Reference in a new issue