Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbvosburgh2012-04-05 21:02:02 +0000
committerbvosburgh2012-04-05 21:02:02 +0000
commitab6dbade8a4502bddc3c1c786c0d6904b8c2d7dc (patch)
treef66ea2fce0c41c66a07aed40c8c9fe394313a44d /common/plugins
parent96a78271f51aa80ffdd8defa7525729aa1609913 (diff)
downloadwebtools.dali-ab6dbade8a4502bddc3c1c786c0d6904b8c2d7dc.tar.gz
webtools.dali-ab6dbade8a4502bddc3c1c786c0d6904b8c2d7dc.tar.xz
webtools.dali-ab6dbade8a4502bddc3c1c786c0d6904b8c2d7dc.zip
capture sync and update stack traces for debugging
Diffstat (limited to 'common/plugins')
-rw-r--r--common/plugins/org.eclipse.jpt.common.core/.options4
-rw-r--r--common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/JptCommonCorePlugin.java23
-rw-r--r--common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/JptPlugin.java212
-rw-r--r--common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/utility/command/RepeatingJobCommandWrapper.java31
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/CollectingExceptionHandler.java3
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/StackTrace.java106
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/command/AsynchronousRepeatingCommandWrapper.java25
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/command/RepeatingCommandWrapper.java28
8 files changed, 403 insertions, 29 deletions
diff --git a/common/plugins/org.eclipse.jpt.common.core/.options b/common/plugins/org.eclipse.jpt.common.core/.options
new file mode 100644
index 0000000000..987ec33b47
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.core/.options
@@ -0,0 +1,4 @@
+# Debugging options for the org.eclipse.jpt.common.core plugin.
+
+# Turn on debugging for the org.eclipse.jpt.common.core plugin.
+org.eclipse.jpt.common.core/debug=true
diff --git a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/JptCommonCorePlugin.java b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/JptCommonCorePlugin.java
index ccbb34d598..afdd2e5884 100644
--- a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/JptCommonCorePlugin.java
+++ b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/JptCommonCorePlugin.java
@@ -9,19 +9,18 @@
******************************************************************************/
package org.eclipse.jpt.common.core;
-import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.Plugin;
-import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jpt.common.core.internal.JptPlugin;
import org.eclipse.jpt.common.core.internal.libval.LibraryValidatorManager;
import org.eclipse.jpt.common.core.libprov.JptLibraryProviderInstallOperationConfig;
import org.eclipse.jpt.common.core.libval.LibraryValidator;
import org.osgi.framework.BundleContext;
+// TODO bjv move to *private* internal package and move all public stuff to adapters etc.
public class JptCommonCorePlugin
- extends Plugin
+ extends JptPlugin
{
// ********** public constants **********
@@ -100,30 +99,23 @@ public class JptCommonCorePlugin
* Log the specified message.
*/
public static void log(String msg) {
- log(msg, null);
+ INSTANCE.logError(msg);
}
/**
* Log the specified exception or error.
*/
public static void log(Throwable throwable) {
- log(throwable.getLocalizedMessage(), throwable);
+ INSTANCE.logError(throwable);
}
/**
* Log the specified message and exception or error.
*/
public static void log(String msg, Throwable throwable) {
- log(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.OK, msg, throwable));
+ INSTANCE.logError(msg, throwable);
}
- /**
- * Log the specified status.
- */
- public static void log(IStatus status) {
- INSTANCE.getLog().log(status);
- }
-
// ********** plug-in implementation **********
@@ -145,8 +137,7 @@ public class JptCommonCorePlugin
@Override
public void stop(BundleContext context) throws Exception {
- super.stop(context);
// nothing yet...
+ super.stop(context);
}
}
-
diff --git a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/JptPlugin.java b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/JptPlugin.java
new file mode 100644
index 0000000000..361438a741
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/JptPlugin.java
@@ -0,0 +1,212 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Oracle. 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:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.common.core.internal;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jpt.common.utility.internal.StringTools;
+
+/**
+ * Common Dali plug-in behavior.
+ */
+public abstract class JptPlugin
+ extends Plugin
+{
+ protected JptPlugin() {
+ super();
+ }
+
+
+ // ********** logging **********
+
+ /**
+ * Log the specified message with a severity of
+ * {@link IStatus#ERROR ERROR}.
+ * @see #log(int, String)
+ * @see IStatus
+ */
+ public void logError(String message) {
+ this.log(IStatus.ERROR, message);
+ }
+
+ /**
+ * Log the specified message with the specified severity.
+ * @see IStatus#getSeverity()
+ */
+ public void log(int severity, String message) {
+ this.log(severity, message, null);
+ }
+
+ /**
+ * Log the specified exception or error with a severity of
+ * {@link IStatus#ERROR ERROR}.
+ * @see #log(int, Throwable)
+ * @see IStatus
+ */
+ public void logError(Throwable throwable) {
+ this.log(IStatus.ERROR, throwable);
+ }
+
+ /**
+ * Log the specified exception or error with the specified severity.
+ * @see IStatus#getSeverity()
+ */
+ public void log(int severity, Throwable throwable) {
+ this.log(severity, throwable.getLocalizedMessage(), throwable);
+ }
+
+ /**
+ * Log the specified message and exception or error with a severity of
+ * {@link IStatus#ERROR ERROR}.
+ * @see #log(int, String, Throwable)
+ * @see IStatus
+ */
+ public void logError(String msg, Throwable throwable) {
+ this.log(IStatus.ERROR, msg, throwable);
+ }
+
+ /**
+ * Log the specified message and exception or error
+ * with the specified severity.
+ * @see IStatus#getSeverity()
+ * @see IStatus#getCode()
+ */
+ public void log(int severity, String msg, Throwable throwable) {
+ this.log(severity, IStatus.OK, msg, throwable);
+ }
+
+ /**
+ * Log the specified message and exception or error
+ * with the specified severity and code.
+ * @see IStatus#getSeverity()
+ * @see IStatus#getCode()
+ */
+ public void log(int severity, int code, String msg, Throwable throwable) {
+ this.getLog().log(new Status(severity, this.getPluginID(), code, msg, throwable));
+ }
+
+
+ // ********** debug options **********
+
+ /**
+ * Return the specified debug option as a <code>boolean</code> value.
+ * Return <code>false</code> if no such option is found.
+ * <p>
+ * The debug option is within the scope of the plug-in's debug options
+ * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
+ * the specified option <code>"foo"</code> will be mapped to
+ * the {@link Platform} option
+ * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
+ */
+ public boolean getBooleanDebugOption(String option) {
+ return this.getBooleanDebugOption(option, false);
+ }
+
+ /**
+ * Return the specified debug option as a <code>boolean</code> value.
+ * Return the specified default value if no such option is found.
+ * <p>
+ * The debug option is within the scope of the plug-in's debug options
+ * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
+ * the specified option <code>"foo"</code> will be mapped to
+ * the {@link Platform} option
+ * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
+ */
+ public boolean getBooleanDebugOption(String option, boolean defaultValue) {
+ String value = this.getDebugOption(option);
+ return (value == null) ? defaultValue : Boolean.parseBoolean(value.trim());
+ }
+
+ /**
+ * Return the specified debug option as an <code>int</code> value.
+ * Return <code>-1</code> if no such option is found.
+ * <p>
+ * The debug option is within the scope of the plug-in's debug options
+ * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
+ * the specified option <code>"foo"</code> will be mapped to
+ * the {@link Platform} option
+ * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
+ */
+ public int getIntegerDebugOption(String option) {
+ return this.getIntegerDebugOption(option, -1);
+ }
+
+ /**
+ * Return the specified debug option as an <code>int</code> value.
+ * Return the specified default value if no such option is found.
+ * <p>
+ * The debug option is within the scope of the plug-in's debug options
+ * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
+ * the specified option <code>"foo"</code> will be mapped to
+ * the {@link Platform} option
+ * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
+ */
+ public int getIntegerDebugOption(String option, int defaultValue) {
+ String value = this.getDebugOption(option);
+ return (value == null) ? defaultValue : Integer.parseInt(value.trim());
+ }
+
+ /**
+ * Return the specified debug option.
+ * Return <code>null</code> if no such option is found.
+ * <p>
+ * The debug option is within the scope of the plug-in's debug options
+ * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
+ * the specified option <code>"foo"</code> will be mapped to
+ * the {@link Platform} option
+ * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
+ */
+ public String getDebugOption(String option) {
+ return this.getDebugOption(option, null);
+ }
+
+ /**
+ * Return the specified debug option.
+ * Return the specified default value if no such option is found.
+ * <p>
+ * The debug option is within the scope of the plug-in's debug options
+ * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
+ * the specified option <code>"foo"</code> will be mapped to
+ * the {@link Platform} option
+ * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
+ */
+ public String getDebugOption(String option, String defaultValue) {
+ return this.isDebugging() ? this.getDebugOption_(option, defaultValue) : defaultValue;
+ }
+
+ protected String getDebugOption_(String option, String defaultValue) {
+ if (StringTools.stringIsEmpty(option)) {
+ throw new IllegalArgumentException("debug option cannot be blank"); //$NON-NLS-1$
+ }
+ String value = this.getPlatformDebugOption(option);
+ return (value != null) ? value : defaultValue;
+ }
+
+ protected String getPlatformDebugOption(String option) {
+ return Platform.getDebugOption(this.getPluginDebugOption() + option);
+ }
+
+ /**
+ * Return the plug-in's debug option path.
+ */
+ protected String getPluginDebugOption() {
+ return this.getPluginID() + DEBUG_OPTION_SCOPE;
+ }
+ protected static final String DEBUG_OPTION_SCOPE = "/debug/"; //$NON-NLS-1$
+
+
+ // ********** misc **********
+
+ public String getPluginID() {
+ return this.getBundle().getSymbolicName();
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/utility/command/RepeatingJobCommandWrapper.java b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/utility/command/RepeatingJobCommandWrapper.java
index 8fee7f6366..ce34a4765c 100644
--- a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/utility/command/RepeatingJobCommandWrapper.java
+++ b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/utility/command/RepeatingJobCommandWrapper.java
@@ -9,14 +9,17 @@
******************************************************************************/
package org.eclipse.jpt.common.core.internal.utility.command;
+import java.util.ArrayList;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
+import org.eclipse.jpt.common.core.JptCommonCorePlugin;
import org.eclipse.jpt.common.core.utility.command.JobCommand;
import org.eclipse.jpt.common.core.utility.command.JobCommandExecutor;
import org.eclipse.jpt.common.core.utility.command.RepeatingJobCommand;
import org.eclipse.jpt.common.utility.ExceptionHandler;
+import org.eclipse.jpt.common.utility.internal.StackTrace;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.jpt.common.utility.internal.command.RepeatingCommandState;
@@ -74,6 +77,17 @@ public class RepeatingJobCommandWrapper
*/
final RepeatingCommandState state;
+ /**
+ * List of stack traces for each (repeating) invocation of the command,
+ * starting with the initial invocation. The list is cleared with each
+ * initial invocation of the command.
+ */
+ private final ArrayList<StackTrace> stackTraces = debug() ? new ArrayList<StackTrace>() : null;
+
+ private static boolean debug() {
+ return JptCommonCorePlugin.instance().isDebugging();
+ }
+
// ********** construction **********
@@ -124,14 +138,25 @@ public class RepeatingJobCommandWrapper
* It is possible to come back here if the wrapped command recurses
* to the client and triggers another execution.
*/
- // pretty sure no need for this method to be 'synchronized'
- public IStatus execute(IProgressMonitor monitor) {
+ public synchronized IStatus execute(IProgressMonitor monitor) {
if (this.state.isReadyToStartExecutionCycle()) {
- this.startCommandExecutor.execute(this.startCommand);
+ if (debug()) {
+ this.stackTraces.clear();
+ this.stackTraces.add(new StackTrace());
+ }
+ this.executeStartCommand();
+ } else {
+ if (debug()) {
+ this.stackTraces.add(new StackTrace());
+ }
}
return Status.OK_STATUS;
}
+ /* private protected */ void executeStartCommand() {
+ this.startCommandExecutor.execute(this.startCommand);
+ }
+
public void stop() throws InterruptedException {
this.state.stop();
}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/CollectingExceptionHandler.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/CollectingExceptionHandler.java
index 93ac401f0a..55f90eb25c 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/CollectingExceptionHandler.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/CollectingExceptionHandler.java
@@ -11,7 +11,6 @@ package org.eclipse.jpt.common.utility.internal;
import java.util.Vector;
import org.eclipse.jpt.common.utility.ExceptionHandler;
-import org.eclipse.jpt.common.utility.internal.iterables.LiveCloneIterable;
import org.eclipse.jpt.common.utility.internal.iterables.SnapshotCloneIterable;
/**
@@ -32,7 +31,7 @@ public class CollectingExceptionHandler
* Return the current list of exceptions handled by the handler so far.
*/
public Iterable<Throwable> getExceptions() {
- return new LiveCloneIterable<Throwable>(this.exceptions);
+ return new SnapshotCloneIterable<Throwable>(this.exceptions);
}
/**
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/StackTrace.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/StackTrace.java
new file mode 100644
index 0000000000..05a141e3af
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/StackTrace.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Oracle. 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:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.common.utility.internal;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+/**
+ * Container for holding and printing the {@StackTraceElement stack trace
+ * elements} produced by a thread or exception.
+ *
+ * @see Thread#getStackTrace()
+ * @see Throwable#getStackTrace()
+ */
+public class StackTrace
+ implements Serializable
+{
+ private final StackTraceElement[] elements;
+ private volatile String string;
+ private static final long serialVersionUID = 1L;
+
+
+ public StackTrace() {
+ super();
+ this.elements = this.buildElements();
+ }
+
+ /**
+ * Strip off all the elements associated with this class and {@link Thread}.
+ */
+ private StackTraceElement[] buildElements() {
+ StackTraceElement[] result = Thread.currentThread().getStackTrace();
+ int len = result.length;
+ if (len == 0) {
+ return result;
+ }
+
+ String className = this.getClass().getName();
+ boolean found = false;
+ int i = 0;
+ while (i < len) {
+ if (result[i].getClassName().equals(className)) {
+ found = true;
+ } else {
+ if (found) {
+ break;
+ }
+ }
+ i++;
+ }
+ return found ? ArrayTools.subArray(result, i, len) : result;
+ }
+
+ /**
+ * Append the stack trace to the specified stream.
+ */
+ public void appendTo(Appendable stream) throws IOException {
+ this.appendTo(stream, null);
+ }
+
+ /**
+ * Append the stack trace to the specified stream, prefixing each line
+ * with the specified prefix.
+ */
+ public void appendTo(Appendable stream, String prefix) throws IOException {
+ for (StackTraceElement element : this.elements) {
+ if (prefix != null) {
+ stream.append(prefix);
+ }
+ stream.append(String.valueOf(element)).append(StringTools.CR);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return this.getString();
+ }
+
+ private String getString() {
+ if (this.string == null) {
+ synchronized (this) {
+ if (this.string == null) {
+ this.string = this.buildString();
+ }
+ }
+ }
+ return this.string;
+ }
+
+ private String buildString() {
+ StringBuffer sb = new StringBuffer(1000);
+ try {
+ this.appendTo(sb);
+ } catch (IOException ex) {
+ throw new RuntimeException(ex); // should not happen with a StringBuffer
+ }
+ return sb.toString();
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/command/AsynchronousRepeatingCommandWrapper.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/command/AsynchronousRepeatingCommandWrapper.java
index 76331d4728..7baa423bb8 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/command/AsynchronousRepeatingCommandWrapper.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/command/AsynchronousRepeatingCommandWrapper.java
@@ -9,12 +9,14 @@
******************************************************************************/
package org.eclipse.jpt.common.utility.internal.command;
+import java.util.ArrayList;
import java.util.concurrent.ThreadFactory;
import org.eclipse.jpt.common.utility.ExceptionHandler;
import org.eclipse.jpt.common.utility.command.Command;
import org.eclipse.jpt.common.utility.command.RepeatingCommand;
import org.eclipse.jpt.common.utility.internal.ConsumerThreadCoordinator;
import org.eclipse.jpt.common.utility.internal.SimpleThreadFactory;
+import org.eclipse.jpt.common.utility.internal.StackTrace;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.jpt.common.utility.internal.SynchronizedBoolean;
@@ -22,10 +24,6 @@ import org.eclipse.jpt.common.utility.internal.SynchronizedBoolean;
* This repeating command will perform a client-supplied command in a separate
* thread, allowing calls to {@link org.eclipse.jpt.common.utility.command.Command#execute()}
* to return immediately.
- * <p>
- * <strong>NB:</strong> The client-supplied command should handle any exceptions
- * appropriately (e.g. log the exception and return gracefully so the thread
- * can continue the execution process).
*/
public class AsynchronousRepeatingCommandWrapper
implements RepeatingCommand
@@ -43,6 +41,15 @@ public class AsynchronousRepeatingCommandWrapper
*/
private final ConsumerThreadCoordinator consumerThreadCoordinator;
+ /**
+ * List of stack traces for each (repeating) invocation of the command,
+ * starting with the initial invocation. The list is cleared with each
+ * initial invocation of the command.
+ */
+ private final ArrayList<StackTrace> stackTraces = DEBUG ? new ArrayList<StackTrace>() : null;
+ // see AsynchronousRepeatingCommandWrapperTests.testDEBUG()
+ private static final boolean DEBUG = false;
+
// ********** construction **********
@@ -133,7 +140,15 @@ public class AsynchronousRepeatingCommandWrapper
* </ul>
*/
public void execute() {
- this.executeFlag.setTrue();
+ synchronized (this.executeFlag) {
+ if (DEBUG) {
+ if (this.executeFlag.isFalse()) {
+ this.stackTraces.clear();
+ }
+ this.stackTraces.add(new StackTrace());
+ }
+ this.executeFlag.setTrue();
+ }
}
/**
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/command/RepeatingCommandWrapper.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/command/RepeatingCommandWrapper.java
index be9e4e127e..fcdb26b33b 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/command/RepeatingCommandWrapper.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/command/RepeatingCommandWrapper.java
@@ -9,10 +9,12 @@
******************************************************************************/
package org.eclipse.jpt.common.utility.internal.command;
+import java.util.ArrayList;
import org.eclipse.jpt.common.utility.ExceptionHandler;
import org.eclipse.jpt.common.utility.command.Command;
import org.eclipse.jpt.common.utility.command.CommandExecutor;
import org.eclipse.jpt.common.utility.command.RepeatingCommand;
+import org.eclipse.jpt.common.utility.internal.StackTrace;
import org.eclipse.jpt.common.utility.internal.StringTools;
/**
@@ -57,6 +59,15 @@ public class RepeatingCommandWrapper
*/
final RepeatingCommandState state;
+ /**
+ * List of stack traces for each (repeating) invocation of the command,
+ * starting with the initial invocation. The list is cleared with each
+ * initial invocation of the command.
+ */
+ private final ArrayList<StackTrace> stackTraces = DEBUG ? new ArrayList<StackTrace>() : null;
+ // see RepeatingCommandWrapperTests.testDEBUG()
+ private static final boolean DEBUG = false;
+
// ********** construction **********
@@ -107,13 +118,24 @@ public class RepeatingCommandWrapper
* It is possible to come back here if the wrapped command recurses
* to the client and triggers another execution.
*/
- // pretty sure no need for this method to be 'synchronized'
- public void execute() {
+ public synchronized void execute() {
if (this.state.isReadyToStartExecutionCycle()) {
- this.startCommandExecutor.execute(this.startCommand);
+ if (DEBUG) {
+ this.stackTraces.clear();
+ this.stackTraces.add(new StackTrace());
+ }
+ this.executeStartCommand();
+ } else {
+ if (DEBUG) {
+ this.stackTraces.add(new StackTrace());
+ }
}
}
+ /* private protected */ void executeStartCommand() {
+ this.startCommandExecutor.execute(this.startCommand);
+ }
+
public void stop() throws InterruptedException {
this.state.stop();
}

Back to the top