Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbvosburgh2009-10-08 13:55:41 +0000
committerbvosburgh2009-10-08 13:55:41 +0000
commitd2aa7cb47ed229aa124ace66add8a91e67804978 (patch)
tree2a558515085d5c492d4eb1c02ca58af1be25080a /jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal
parentd3c4d9da79b36435a3e856fae1be29f1f293e8fe (diff)
downloadwebtools.dali-d2aa7cb47ed229aa124ace66add8a91e67804978.tar.gz
webtools.dali-d2aa7cb47ed229aa124ace66add8a91e67804978.tar.xz
webtools.dali-d2aa7cb47ed229aa124ace66add8a91e67804978.zip
handle synchronization exceptions
Diffstat (limited to 'jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal')
-rw-r--r--jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/CompositeException.java27
-rw-r--r--jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/AsynchronousSynchronizer.java63
-rw-r--r--jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/CallbackAsynchronousSynchronizer.java4
-rw-r--r--jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/CallbackSynchronousSynchronizer.java4
-rw-r--r--jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/Synchronizer.java6
-rw-r--r--jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/SynchronousSynchronizer.java32
6 files changed, 118 insertions, 18 deletions
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/CompositeException.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/CompositeException.java
new file mode 100644
index 0000000000..69d5f89166
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/CompositeException.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.utility.internal;
+
+public class CompositeException
+ extends RuntimeException
+{
+ private final Throwable[] exceptions;
+ private static final long serialVersionUID = 1L;
+
+ public CompositeException(Throwable[] exceptions) {
+ super();
+ this.exceptions = exceptions;
+ }
+
+ public Throwable[] getExceptions() {
+ return this.exceptions;
+ }
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/AsynchronousSynchronizer.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/AsynchronousSynchronizer.java
index 300bee3a66..75d6fea7fa 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/AsynchronousSynchronizer.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/AsynchronousSynchronizer.java
@@ -9,7 +9,10 @@
******************************************************************************/
package org.eclipse.jpt.utility.internal.synchronizers;
+import java.util.Vector;
+
import org.eclipse.jpt.utility.Command;
+import org.eclipse.jpt.utility.internal.CompositeException;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.jpt.utility.internal.SynchronizedBoolean;
@@ -50,6 +53,11 @@ public class AsynchronousSynchronizer
*/
private Thread thread;
+ /**
+ * A list of the uncaught exceptions thrown by the command.
+ */
+ final Vector<Throwable> exceptions = new Vector<Throwable>();
+
// ********** construction **********
@@ -82,7 +90,21 @@ public class AsynchronousSynchronizer
/**
* Build and start the synchronization thread, but postpone the first
- * synchronization until requested, via {@link #synchronize()}.
+ * synchronization until requested, i.e. via a call to
+ * {@link #synchronize()}.
+ * <p>
+ * Note: We don't clear the "synchronize" flag here; so if the flag has
+ * been set <em>before</em> getting here, the first synchronization will
+ * start promptly (albeit, asynchronously).
+ * The "synchronize" flag will be set if:<ul>
+ * <li>{@link #synchronize()} was called after the synchronizer was
+ * constructed but before {@link #start()} was called; or
+ * <li>{@link #synchronize()} was called after {@link #stop()} was called
+ * but before {@link #start()} was called (to restart the synchronizer); or
+ * <li>{@link #stop()} was called when there was an outstanding request
+ * for a synchronization (i.e. the "synchronization" flag was set at
+ * the time {@link #stop()} was called)
+ * </ul>
*/
public synchronized void start() {
if (this.thread != null) {
@@ -101,18 +123,27 @@ public class AsynchronousSynchronizer
}
/**
- * Set the "synchronize" flag so the synchronization thread will execute
- * a synchronization.
+ * Set the "synchronize" flag so the synchronization thread will either<ul>
+ * <li>if the thread is quiesced, start a synchronization immediately, or
+ * <li>if the thread is currently executing a synchronization, execute another
+ * synchronization once the current synchronization is complete
+ * </ul>
*/
public void synchronize() {
this.synchronizeFlag.setTrue();
}
+ /**
+ * Interrupt the synchronization thread so that it stops executing at the
+ * end of the current synchronization. Suspend the current thread until
+ * the synchronization thread is finished executing. If any uncaught
+ * exceptions were thrown while the synchronization thread was executing,
+ * wrap them in a composite exception and throw the composite exception.
+ */
public synchronized void stop() {
if (this.thread == null) {
throw new IllegalStateException("The Synchronizer was not started."); //$NON-NLS-1$
}
- this.synchronizeFlag.setFalse();
this.thread.interrupt();
try {
this.thread.join();
@@ -123,6 +154,12 @@ public class AsynchronousSynchronizer
// after its current execution - we just won't wait around for it...
}
this.thread = null;
+
+ if (this.exceptions.size() > 0) {
+ Throwable[] temp = this.exceptions.toArray(new Throwable[this.exceptions.size()]);
+ this.exceptions.clear();
+ throw new CompositeException(temp);
+ }
}
@Override
@@ -142,7 +179,9 @@ public class AsynchronousSynchronizer
* the command will be re-executed immediately. Stop the thread by calling
* {@link Thread#interrupt()}.
*/
- class RunnableSynchronization implements Runnable {
+ class RunnableSynchronization
+ implements Runnable
+ {
/** The client-supplied command that executes on this thread. */
private final Command command;
@@ -181,9 +220,21 @@ public class AsynchronousSynchronizer
}
/**
+ * Execute the client-supplied command. Do not allow any unhandled
+ * exceptions to kill the thread. Store them up for later pain.
+ */
+ private void execute() {
+ try {
+ this.execute_();
+ } catch (Throwable ex) {
+ AsynchronousSynchronizer.this.exceptions.add(ex);
+ }
+ }
+
+ /**
* Execute the client-supplied command.
*/
- void execute() {
+ void execute_() {
this.command.execute();
}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/CallbackAsynchronousSynchronizer.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/CallbackAsynchronousSynchronizer.java
index 28eab58170..28c610d642 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/CallbackAsynchronousSynchronizer.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/CallbackAsynchronousSynchronizer.java
@@ -104,8 +104,8 @@ public class CallbackAsynchronousSynchronizer
}
@Override
- void execute() {
- super.execute();
+ void execute_() {
+ super.execute_();
// hmmm - we will notify listeners even when we our thread is "interrupted";
// that seems ok... ~bjv
if (CallbackAsynchronousSynchronizer.this.synchronizeFlag.isFalse()) {
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/CallbackSynchronousSynchronizer.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/CallbackSynchronousSynchronizer.java
index 22477627fa..ab101511ec 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/CallbackSynchronousSynchronizer.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/CallbackSynchronousSynchronizer.java
@@ -70,8 +70,8 @@ public class CallbackSynchronousSynchronizer
// ********** override **********
@Override
- void execute() {
- super.execute();
+ void execute_() {
+ super.execute_();
if (this.state.getValue() != State.REPEAT) {
// hmmm - we will notify listeners even when we are "stopped";
// that seems ok... ~bjv
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/Synchronizer.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/Synchronizer.java
index 85f45af88d..7b5a459ec6 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/Synchronizer.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/Synchronizer.java
@@ -23,12 +23,6 @@ import java.io.Serializable;
* a single master thread that would control the synchronizer's lifecycle and
* the {@link #synchronize()} method will be called multiple times, possibly from
* multiple threads.
- * <p>
- * Provisional API: This interface is part of an interim API that is still
- * under development and expected to change significantly before reaching
- * stability. It is available at this early stage to solicit feedback from
- * pioneering adopters on the understanding that any code that uses this API
- * will almost certainly be broken (repeatedly) as the API evolves.
*/
public interface Synchronizer {
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/SynchronousSynchronizer.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/SynchronousSynchronizer.java
index 71202f72ea..ea0c6090e9 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/SynchronousSynchronizer.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/synchronizers/SynchronousSynchronizer.java
@@ -9,7 +9,10 @@
******************************************************************************/
package org.eclipse.jpt.utility.internal.synchronizers;
+import java.util.Vector;
+
import org.eclipse.jpt.utility.Command;
+import org.eclipse.jpt.utility.internal.CompositeException;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.jpt.utility.internal.SynchronizedObject;
@@ -57,6 +60,11 @@ public class SynchronousSynchronizer
STOPPING
}
+ /**
+ * A list of the uncaught exceptions thrown by the command.
+ */
+ final Vector<Throwable> exceptions = new Vector<Throwable>();
+
// ********** construction **********
@@ -152,9 +160,21 @@ public class SynchronousSynchronizer
}
/**
+ * Execute the client-supplied command. Do not allow any unhandled
+ * exceptions to kill the thread. Store them up for later pain.
+ */
+ private void execute() {
+ try {
+ this.execute_();
+ } catch (Throwable ex) {
+ this.exceptions.add(ex);
+ }
+ }
+
+ /**
* By default, just execute the command.
*/
- void execute() {
+ void execute_() {
this.command.execute();
}
@@ -185,7 +205,9 @@ public class SynchronousSynchronizer
}
/**
- * Set the flags so that no further synchronizations occur.
+ * Set the flags so that no further synchronizations occur. If any uncaught
+ * exceptions were thrown while the synchronization was executing,
+ * wrap them in a composite exception and throw the composite exception.
*/
public synchronized void stop() {
switch (this.state.getValue()) {
@@ -206,6 +228,12 @@ public class SynchronousSynchronizer
default:
throw this.buildIllegalStateException();
}
+
+ if (this.exceptions.size() > 0) {
+ Throwable[] temp = this.exceptions.toArray(new Throwable[this.exceptions.size()]);
+ this.exceptions.clear();
+ throw new CompositeException(temp);
+ }
}
/**

Back to the top