Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Vosburgh2016-07-20 15:18:39 +0000
committerBrian Vosburgh2017-05-18 22:38:09 +0000
commitf91968e110d50306c5d8144ea401ba888c66abf7 (patch)
treef08428c2acdfd2b60917445443ce84ef237a6a32
parent9f7381368b8b5df01ae18db6d6d7dbb1870298e8 (diff)
downloadwebtools.dali-f91968e110d50306c5d8144ea401ba888c66abf7.tar.gz
webtools.dali-f91968e110d50306c5d8144ea401ba888c66abf7.tar.xz
webtools.dali-f91968e110d50306c5d8144ea401ba888c66abf7.zip
add BiClosure
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/closure/BiClosure.java38
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/closure/InterruptibleBiClosure.java39
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/BiClosureAdapter.java34
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/BiClosureTools.java364
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/BiClosureWrapper.java53
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ClosureTools.java381
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/CommandBiClosure.java45
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/CompositeBiClosure.java46
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/CompositeClosure.java6
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/CompositeInterruptibleBiClosure.java46
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/CompositeInterruptibleClosure.java6
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ConditionalClosure.java10
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ConditionalInterruptibleClosure.java10
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/DisabledBiClosure.java54
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/FactoryBiClosure.java46
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/InterruptedBiClosure.java54
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/InterruptibleBiClosureAdapter.java35
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/InterruptibleBiClosureWrapper.java53
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/InterruptibleCommandBiClosure.java45
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/InterruptibleFactoryBiClosure.java46
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/MethodClosure.java10
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/NullBiClosure.java54
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/NullCheckClosureWrapper.java5
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/NullCheckInterruptibleClosureWrapper.java5
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/RepeatingBiClosure.java49
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/RepeatingClosure.java6
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/RepeatingInterruptibleBiClosure.java49
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/RepeatingInterruptibleClosure.java4
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SafeBiClosureWrapper.java56
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SafeClosureWrapper.java7
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SafeInterruptibleBiClosureWrapper.java58
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SafeInterruptibleClosureWrapper.java7
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SwitchClosure.java13
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SwitchInterruptibleClosure.java19
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ThreadLocalBiClosure.java66
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ThreadLocalClosure.java5
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ThreadLocalInterruptibleBiClosure.java67
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ThreadLocalInterruptibleClosure.java13
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/UntilClosure.java9
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/UntilInterruptibleClosure.java9
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/WhileClosure.java7
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/WhileInterruptibleClosure.java7
-rw-r--r--common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/JptCommonUtilityTests.java4
-rw-r--r--common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/closure/BiClosureToolsTests.java726
-rw-r--r--common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/closure/ClosureToolsTests.java1854
-rw-r--r--common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/closure/JptCommonUtilityClosureTests.java2
46 files changed, 4430 insertions, 92 deletions
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/closure/BiClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/closure/BiClosure.java
new file mode 100644
index 0000000000..5a308c54f4
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/closure/BiClosure.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.closure;
+
+/**
+ * Simple interface for implementing a command that takes two arguments.
+ * The expectation is the closure will have side effects.
+ * <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.
+ *
+ * @param <A1> the type of the first object passed to the command
+ * @param <A2> the type of the second object passed to the command
+ *
+ * @see Closure
+ * @see org.eclipse.jpt.common.utility.command.Command
+ * @see org.eclipse.jpt.common.utility.factory.Factory
+ * @see org.eclipse.jpt.common.utility.transformer.Transformer
+ */
+public interface BiClosure<A1, A2>
+ extends InterruptibleBiClosure<A1, A2>
+{
+ /**
+ * Execute the command. The semantics of the command
+ * is determined by the contract between the client and server.
+ */
+ void execute(A1 argument1, A2 argument2);
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/closure/InterruptibleBiClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/closure/InterruptibleBiClosure.java
new file mode 100644
index 0000000000..e1e64b7960
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/closure/InterruptibleBiClosure.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.closure;
+
+/**
+ * Simple interface for implementing a command that takes two arguments
+ * and allows for the closure to throw an {@link InterruptedException}.
+ * The expectation is the closure will have side effects.
+ * <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.
+ *
+ * @param <A1> the type of the first object passed to the command
+ * @param <A2> the type of the second object passed to the command
+ *
+ * @see BiClosure
+ * @see InterruptibleClosure
+ * @see org.eclipse.jpt.common.utility.command.InterruptibleCommand
+ * @see org.eclipse.jpt.common.utility.factory.InterruptibleFactory
+ * @see org.eclipse.jpt.common.utility.transformer.InterruptibleTransformer
+ */
+public interface InterruptibleBiClosure<A1, A2> {
+
+ /**
+ * Execute the command. The semantics of the command
+ * is determined by the contract between the client and server.
+ */
+ void execute(A1 argument1, A2 argument2) throws InterruptedException;
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/BiClosureAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/BiClosureAdapter.java
new file mode 100644
index 0000000000..4713a8a48b
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/BiClosureAdapter.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2016 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.closure;
+
+import org.eclipse.jpt.common.utility.closure.BiClosure;
+import org.eclipse.jpt.common.utility.internal.ObjectTools;
+
+/**
+ * Convenience bi-closure that does nothing.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ *
+ * @see NullBiClosure
+ */
+public class BiClosureAdapter<A1, A2>
+ implements BiClosure<A1, A2>
+{
+ public void execute(A1 argument1, A2 argument2) {
+ // NOP
+ }
+
+ @Override
+ public String toString() {
+ return ObjectTools.toString(this);
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/BiClosureTools.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/BiClosureTools.java
new file mode 100644
index 0000000000..b0d2e342c2
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/BiClosureTools.java
@@ -0,0 +1,364 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2016 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.closure;
+
+import org.eclipse.jpt.common.utility.closure.BiClosure;
+import org.eclipse.jpt.common.utility.closure.InterruptibleBiClosure;
+import org.eclipse.jpt.common.utility.command.Command;
+import org.eclipse.jpt.common.utility.command.InterruptibleCommand;
+import org.eclipse.jpt.common.utility.exception.ExceptionHandler;
+import org.eclipse.jpt.common.utility.factory.Factory;
+import org.eclipse.jpt.common.utility.factory.InterruptibleFactory;
+import org.eclipse.jpt.common.utility.internal.ArrayTools;
+import org.eclipse.jpt.common.utility.internal.exception.DefaultExceptionHandler;
+
+/**
+ * {@link BiClosure} utility methods.
+ */
+public final class BiClosureTools {
+
+ // ********** adapters **********
+
+ /**
+ * Adapt the specified {@link Command} to the {@link BiClosure} interface.
+ * The closure's argument is ignored.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ */
+ public static <A1, A2> BiClosure<A1, A2> adapt(Command command) {
+ return new CommandBiClosure<>(command);
+ }
+
+ /**
+ * Adapt the specified {@link InterruptibleCommand} to the {@link InterruptibleBiClosure} interface.
+ * The closure's argument is ignored.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ */
+ public static <A1, A2> InterruptibleBiClosure<A1, A2> adapt(InterruptibleCommand command) {
+ return new InterruptibleCommandBiClosure<>(command);
+ }
+
+ /**
+ * Adapt the specified {@link Factory} to the {@link BiClosure} interface.
+ * The closure's argument and the factory's output are ignored. This really
+ * only useful for a factory that has side-effects.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ */
+ public static <A1, A2> BiClosure<A1, A2> adapt(Factory<?> factory) {
+ return new FactoryBiClosure<>(factory);
+ }
+
+ /**
+ * Adapt the specified {@link InterruptibleFactory} to the {@link InterruptibleBiClosure} interface.
+ * The closure's argument and the factory's output are ignored. This really
+ * only useful for a factory that has side-effects.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ */
+ public static <A1, A2> InterruptibleBiClosure<A1, A2> adapt(InterruptibleFactory<?> factory) {
+ return new InterruptibleFactoryBiClosure<>(factory);
+ }
+
+
+ // ********** null closure **********
+
+ /**
+ * Return a closure that will do nothing.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ *
+ * @see NullBiClosure
+ */
+ public static <A1, A2> BiClosure<A1, A2> nullBiClosure() {
+ return NullBiClosure.instance();
+ }
+
+
+ // ********** thread local **********
+
+ /**
+ * Return a closure that allows the client to specify a different closure
+ * for each thread. If there is no closure for the current thread, the
+ * closure will do nothing.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ * @see ThreadLocalBiClosure
+ */
+ public static <A1, A2> ThreadLocalBiClosure<A1, A2> threadLocalBiClosure() {
+ return threadLocalBiClosure(NullBiClosure.instance());
+ }
+
+ /**
+ * Return a closure that allows the client to specify a different closure
+ * for each thread. If there is no closure for the current thread, the
+ * specified default closure is executed.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ * @see ThreadLocalBiClosure
+ */
+ public static <A1, A2> ThreadLocalBiClosure<A1, A2> threadLocalBiClosure(BiClosure<? super A1, ? super A2> defaultClosure) {
+ return new ThreadLocalBiClosure<>(defaultClosure);
+ }
+
+ /**
+ * Return a closure that allows the client to specify a different closure
+ * for each thread. If there is no closure for the current thread, the
+ * closure will do nothing.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ * @see ThreadLocalBiClosure
+ */
+ public static <A1, A2> ThreadLocalInterruptibleBiClosure<A1, A2> threadLocalInterruptibleBiClosure() {
+ return threadLocalInterruptibleBiClosure(NullBiClosure.instance());
+ }
+
+ /**
+ * Return a closure that allows the client to specify a different closure
+ * for each thread. If there is no closure for the current thread, the
+ * specified default closure is executed.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ * @see ThreadLocalBiClosure
+ */
+ public static <A1, A2> ThreadLocalInterruptibleBiClosure<A1, A2> threadLocalInterruptibleBiClosure(InterruptibleBiClosure<? super A1, ? super A2> defaultClosure) {
+ return new ThreadLocalInterruptibleBiClosure<>(defaultClosure);
+ }
+
+
+ // ********** wrappers **********
+
+ /**
+ * Return a closure that can have its wrapped closure changed,
+ * allowing a client to change a previously-supplied closure's
+ * behavior mid-stream.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ *
+ * @see BiClosureWrapper
+ */
+ public static <A1, A2> BiClosureWrapper<A1, A2> wrap(BiClosure<? super A1, ? super A2> closure) {
+ return new BiClosureWrapper<>(closure);
+ }
+
+ /**
+ * Return a closure that can have its wrapped closure changed,
+ * allowing a client to change a previously-supplied closure's
+ * behavior mid-stream.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ *
+ * @see InterruptibleBiClosureWrapper
+ */
+ public static <A1, A2> InterruptibleBiClosureWrapper<A1, A2> wrap(InterruptibleBiClosure<? super A1, ? super A2> closure) {
+ return new InterruptibleBiClosureWrapper<>(closure);
+ }
+
+
+ // ********** safe wrappers **********
+
+ /**
+ * Return closure that will handle any exceptions thrown by the specified
+ * closure. If the wrapped closure throws an exception,
+ * the exception's stack trace will be printed to {@link System#err
+ * the "standard" error output stream}.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ *
+ * @see #safeBiClosure(BiClosure, ExceptionHandler)
+ */
+ public static <A1, A2> BiClosure<A1, A2> safeBiClosure(BiClosure<? super A1, ? super A2> closure) {
+ return safeBiClosure(closure, DefaultExceptionHandler.instance());
+ }
+
+ /**
+ * Return closure that will handle any exceptions thrown by the specified
+ * closure with the specified exception handler. If the
+ * wrapped closure throws an exception, the safe closure will handle
+ * the exception and return.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ *
+ * @see #safeBiClosure(BiClosure)
+ */
+ public static <A1, A2> BiClosure<A1, A2> safeBiClosure(BiClosure<? super A1, ? super A2> closure, ExceptionHandler exceptionHandler) {
+ return new SafeBiClosureWrapper<>(closure, exceptionHandler);
+ }
+
+ /**
+ * Return closure that will handle any exceptions thrown by the specified
+ * closure. If the wrapped closure throws an exception,
+ * the exception's stack trace will be printed to {@link System#err
+ * the "standard" error output stream}.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ *
+ * @see #safeBiClosure(InterruptibleBiClosure, ExceptionHandler)
+ */
+ public static <A1, A2> InterruptibleBiClosure<A1, A2> safeBiClosure(InterruptibleBiClosure<? super A1, ? super A2> closure) {
+ return safeBiClosure(closure, DefaultExceptionHandler.instance());
+ }
+
+ /**
+ * Return closure that will handle any exceptions thrown by the specified
+ * closure with the specified exception handler. If the
+ * wrapped closure throws an exception, the safe closure will handle
+ * the exception and return.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ *
+ * @see #safeBiClosure(InterruptibleBiClosure)
+ */
+ public static <A1, A2> InterruptibleBiClosure<A1, A2> safeBiClosure(InterruptibleBiClosure<? super A1, ? super A2> closure, ExceptionHandler exceptionHandler) {
+ return new SafeInterruptibleBiClosureWrapper<>(closure, exceptionHandler);
+ }
+
+
+ // ********** composite **********
+
+ /**
+ * Return a composite of the specified closures. The composite's argument
+ * will be passed to each closure, in sequence.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ */
+ @SafeVarargs
+ public static <A1, A2> BiClosure<A1, A2> compositeBiClosure(BiClosure<? super A1, ? super A2>... closures) {
+ return (closures.length != 0) ? compositeBiClosure_(ArrayTools.iterable(closures)) : nullBiClosure();
+ }
+
+ /**
+ * Return a composite of the specified closures. The composite's argument
+ * will be passed to each closure, in sequence.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ */
+ public static <A1, A2> BiClosure<A1, A2> compositeBiClosure(Iterable<? extends BiClosure<? super A1, ? super A2>> closures) {
+ return (closures.iterator().hasNext()) ? compositeBiClosure_(closures) : nullBiClosure();
+ }
+
+ /**
+ * assume non-empty
+ */
+ private static <A1, A2> BiClosure<A1, A2> compositeBiClosure_(Iterable<? extends BiClosure<? super A1, ? super A2>> closures) {
+ return new CompositeBiClosure<>(closures);
+ }
+
+ /**
+ * Return a composite of the specified closures. The composite's argument
+ * will be passed to each closure, in sequence.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ */
+ @SafeVarargs
+ public static <A1, A2> InterruptibleBiClosure<A1, A2> compositeInterruptibleBiClosure(InterruptibleBiClosure<? super A1, ? super A2>... closures) {
+ return (closures.length != 0) ? compositeInterruptibleBiClosure_(ArrayTools.iterable(closures)) : nullBiClosure();
+ }
+
+ /**
+ * Return a composite of the specified closures. The composite's argument
+ * will be passed to each closure, in sequence.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ */
+ public static <A1, A2> InterruptibleBiClosure<A1, A2> compositeInterruptibleBiClosure(Iterable<? extends InterruptibleBiClosure<? super A1, ? super A2>> closures) {
+ return (closures.iterator().hasNext()) ? compositeInterruptibleBiClosure_(closures) : nullBiClosure();
+ }
+
+ /**
+ * assume non-empty
+ */
+ private static <A1, A2> InterruptibleBiClosure<A1, A2> compositeInterruptibleBiClosure_(Iterable<? extends InterruptibleBiClosure<? super A1, ? super A2>> closures) {
+ return new CompositeInterruptibleBiClosure<>(closures);
+ }
+
+
+ // ********** disabled **********
+
+ /**
+ * Return a closure that will throw an
+ * {@link UnsupportedOperationException exception} when executed.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ */
+ public static <A1, A2> BiClosure<A1, A2> disabledBiClosure() {
+ return DisabledBiClosure.instance();
+ }
+
+
+ // ********** interrupted **********
+
+ /**
+ * Return a closure that will throw an
+ * {@link InterruptedException exception} when executed.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ */
+ public static <A1, A2> InterruptibleBiClosure<A1, A2> interruptedBiClosure() {
+ return InterruptedBiClosure.instance();
+ }
+
+ // ********** looping **********
+
+ /**
+ * Return a closure that executes the specified closure the specified
+ * number of times.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ */
+ public static <A1, A2> BiClosure<A1, A2> repeatingBiClosure(BiClosure<? super A1, ? super A2> closure, int count) {
+ return new RepeatingBiClosure<>(closure, count);
+ }
+
+ /**
+ * Return a closure that executes the specified closure the specified
+ * number of times.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ */
+ public static <A1, A2> InterruptibleBiClosure<A1, A2> repeatingBiClosure(InterruptibleBiClosure<? super A1, ? super A2> closure, int count) {
+ return new RepeatingInterruptibleBiClosure<>(closure, count);
+ }
+
+
+ // ********** constructor **********
+
+ /**
+ * Suppress default constructor, ensuring non-instantiability.
+ */
+ private BiClosureTools() {
+ super();
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/BiClosureWrapper.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/BiClosureWrapper.java
new file mode 100644
index 0000000000..6f7d4feb6a
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/BiClosureWrapper.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2016 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.closure;
+
+import org.eclipse.jpt.common.utility.closure.BiClosure;
+import org.eclipse.jpt.common.utility.internal.ObjectTools;
+
+/**
+ * Closure wrapper that can have its wrapped closure changed,
+ * allowing a client to change a previously-supplied closure's
+ * behavior mid-stream.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ *
+ * @see #setClosure(BiClosure)
+ */
+public class BiClosureWrapper<A1, A2>
+ implements BiClosure<A1, A2>
+{
+ protected volatile BiClosure<? super A1, ? super A2> closure;
+
+ public BiClosureWrapper(BiClosure<? super A1, ? super A2> closure) {
+ super();
+ if (closure == null) {
+ throw new NullPointerException();
+ }
+ this.closure = closure;
+ }
+
+ public void execute(A1 argument1, A2 argument2) {
+ this.closure.execute(argument1, argument2);
+ }
+
+ public void setClosure(BiClosure<? super A1, ? super A2> closure) {
+ if (closure == null) {
+ throw new NullPointerException();
+ }
+ this.closure = closure;
+ }
+
+ @Override
+ public String toString() {
+ return ObjectTools.toString(this, this.closure);
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ClosureTools.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ClosureTools.java
index 83a4a8f576..aa0864869c 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ClosureTools.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ClosureTools.java
@@ -11,15 +11,19 @@ package org.eclipse.jpt.common.utility.internal.closure;
import org.eclipse.jpt.common.utility.Association;
import org.eclipse.jpt.common.utility.closure.Closure;
+import org.eclipse.jpt.common.utility.closure.InterruptibleClosure;
import org.eclipse.jpt.common.utility.command.Command;
+import org.eclipse.jpt.common.utility.command.InterruptibleCommand;
import org.eclipse.jpt.common.utility.exception.ExceptionHandler;
import org.eclipse.jpt.common.utility.factory.Factory;
+import org.eclipse.jpt.common.utility.factory.InterruptibleFactory;
import org.eclipse.jpt.common.utility.internal.ArrayTools;
import org.eclipse.jpt.common.utility.internal.ClassTools;
import org.eclipse.jpt.common.utility.internal.ObjectTools;
import org.eclipse.jpt.common.utility.internal.command.NullCommand;
import org.eclipse.jpt.common.utility.internal.exception.DefaultExceptionHandler;
import org.eclipse.jpt.common.utility.predicate.Predicate;
+import org.eclipse.jpt.common.utility.transformer.InterruptibleTransformer;
import org.eclipse.jpt.common.utility.transformer.Transformer;
/**
@@ -32,6 +36,7 @@ public final class ClosureTools {
/**
* Adapt the specified {@link Command} to the {@link Closure} interface.
* The closure's argument is ignored.
+ *
* @param <A> the type of the object passed to the closure
*/
public static <A> Closure<A> adapt(Command command) {
@@ -39,9 +44,20 @@ public final class ClosureTools {
}
/**
+ * Adapt the specified {@link InterruptibleCommand} to the {@link InterruptibleClosure} interface.
+ * The closure's argument is ignored.
+ *
+ * @param <A> the type of the object passed to the closure
+ */
+ public static <A> InterruptibleClosure<A> adapt(InterruptibleCommand command) {
+ return new InterruptibleCommandClosure<>(command);
+ }
+
+ /**
* Adapt the specified {@link Factory} to the {@link Closure} interface.
- * The closure's argument and the factory's output are ignored. This really
- * only useful for a factory that has side-effects.
+ * The closure's argument and the factory's output are ignored. In practice,
+ * this is useful only for a factory that has side-effects.
+ *
* @param <A> the type of the object passed to the closure
*/
public static <A> Closure<A> adapt(Factory<?> factory) {
@@ -49,9 +65,21 @@ public final class ClosureTools {
}
/**
+ * Adapt the specified {@link InterruptibleFactory} to the {@link InterruptibleClosure} interface.
+ * The closure's argument and the factory's output are ignored. In practice,
+ * this is useful only for a factory that has side-effects.
+ *
+ * @param <A> the type of the object passed to the closure
+ */
+ public static <A> InterruptibleClosure<A> adapt(InterruptibleFactory<?> factory) {
+ return new InterruptibleFactoryClosure<>(factory);
+ }
+
+ /**
* Adapt the specified {@link Transformer} to the {@link Closure} interface.
- * The transformer's output is ignored. This really only useful for a
+ * The transformer's output is ignored. In practice, this is useful only for a
* transformer that has side-effects.
+ *
* @param <A> the type of the object passed to the closure and forwarded to
* the transformer
*/
@@ -59,6 +87,32 @@ public final class ClosureTools {
return new TransformerClosure<>(transformer);
}
+ /**
+ * Adapt the specified {@link InterruptibleTransformer} to the {@link InterruptibleClosure} interface.
+ * The transformer's output is ignored. In practice, this is useful only for a
+ * transformer that has side-effects.
+ *
+ * @param <A> the type of the object passed to the closure and forwarded to
+ * the transformer
+ */
+ public static <A> InterruptibleClosure<A> adapt(InterruptibleTransformer<? super A, ?> transformer) {
+ return new InterruptibleTransformerClosure<>(transformer);
+ }
+
+
+ // ********** null closure **********
+
+ /**
+ * Return a closure that will do nothing.
+ *
+ * @param <A> the type of the object passed to the closure
+ *
+ * @see NullClosure
+ */
+ public static <A> Closure<A> nullClosure() {
+ return NullClosure.instance();
+ }
+
// ********** thread local **********
@@ -66,33 +120,94 @@ public final class ClosureTools {
* Return a closure that allows the client to specify a different closure
* for each thread. If there is no closure for the current thread, the
* closure will do nothing.
+ *
* @param <A> the type of the object passed to the closure
+ *
* @see ThreadLocalClosure
*/
public static <A> ThreadLocalClosure<A> threadLocalClosure() {
- return threadLocalClosure(NullClosure.instance());
+ return threadLocalClosure(nullClosure());
}
/**
* Return a closure that allows the client to specify a different closure
* for each thread. If there is no closure for the current thread, the
* specified default closure is executed.
+ *
* @param <A> the type of the object passed to the closure
+ *
* @see ThreadLocalClosure
*/
public static <A> ThreadLocalClosure<A> threadLocalClosure(Closure<? super A> defaultClosure) {
return new ThreadLocalClosure<>(defaultClosure);
}
+ /**
+ * Return a closure that allows the client to specify a different closure
+ * for each thread. If there is no closure for the current thread, the
+ * closure will do nothing.
+ *
+ * @param <A> the type of the object passed to the closure
+ *
+ * @see ThreadLocalInterruptibleClosure
+ */
+ public static <A> ThreadLocalInterruptibleClosure<A> threadLocalInterruptibleClosure() {
+ return threadLocalInterruptibleClosure(nullClosure());
+ }
- // ********** wrappers **********
+ /**
+ * Return a closure that allows the client to specify a different closure
+ * for each thread. If there is no closure for the current thread, the
+ * specified default closure is executed.
+ *
+ * @param <A> the type of the object passed to the closure
+ *
+ * @see ThreadLocalInterruptibleClosure
+ */
+ public static <A> ThreadLocalInterruptibleClosure<A> threadLocalInterruptibleClosure(InterruptibleClosure<? super A> defaultClosure) {
+ return new ThreadLocalInterruptibleClosure<>(defaultClosure);
+ }
+
+
+ // ********** plain wrappers **********
+
+ /**
+ * Return a closure that can have its wrapped closure changed,
+ * allowing a client to change a previously-supplied closure's
+ * behavior mid-stream.
+ *
+ * @param <A> the type of the object passed to the closure
+ *
+ * @see ClosureWrapper
+ */
+ public static <A> ClosureWrapper<A> wrap(Closure<? super A> closure) {
+ return new ClosureWrapper<>(closure);
+ }
+
+ /**
+ * Return a closure that can have its wrapped closure changed,
+ * allowing a client to change a previously-supplied closure's
+ * behavior mid-stream.
+ *
+ * @param <A> the type of the object passed to the closure
+ *
+ * @see InterruptibleClosureWrapper
+ */
+ public static <A> InterruptibleClosureWrapper<A> wrap(InterruptibleClosure<? super A> closure) {
+ return new InterruptibleClosureWrapper<>(closure);
+ }
+
+
+ // ********** null check wrappers **********
/**
* Return a closure that wraps the specified closure and checks
* for a <code>null</code> argument before forwarding the argument to the
* specified closure. If the argument is <code>null</code>, the closure will
* do nothing.
+ *
* @param <A> the type of the object passed to the closure
+ *
* @see #nullCheck(Closure, Command)
*/
public static <A> Closure<A> nullCheck(Closure<? super A> closure) {
@@ -104,7 +219,9 @@ public final class ClosureTools {
* for a <code>null</code> argument before forwarding the argument to the
* specified closure. If the argument is <code>null</code>,
* the closure will execute the specified command.
+ *
* @param <A> the type of the object passed to the closure
+ *
* @see #nullCheck(Closure)
*/
public static <A> Closure<A> nullCheck(Closure<? super A> closure, Command nullCommand) {
@@ -112,18 +229,35 @@ public final class ClosureTools {
}
/**
- * Return a closure that can have its wrapped closure changed,
- * allowing a client to change a previously-supplied closure's
- * behavior mid-stream.
+ * Return a closure that wraps the specified closure and checks
+ * for a <code>null</code> argument before forwarding the argument to the
+ * specified closure. If the argument is <code>null</code>, the closure will
+ * do nothing.
+ *
* @param <A> the type of the object passed to the closure
- * @see ClosureWrapper
+ *
+ * @see #nullCheck(InterruptibleClosure, InterruptibleCommand)
*/
- public static <A> ClosureWrapper<A> wrap(Closure<? super A> closure) {
- return new ClosureWrapper<>(closure);
+ public static <A> InterruptibleClosure<A> nullCheck(InterruptibleClosure<? super A> closure) {
+ return nullCheck(closure, NullCommand.instance());
}
+ /**
+ * Return a closure that wraps the specified closure and checks
+ * for a <code>null</code> argument before forwarding the argument to the
+ * specified closure. If the argument is <code>null</code>,
+ * the closure will execute the specified command.
+ *
+ * @param <A> the type of the object passed to the closure
+ *
+ * @see #nullCheck(InterruptibleClosure)
+ */
+ public static <A> InterruptibleClosure<A> nullCheck(InterruptibleClosure<? super A> closure, InterruptibleCommand nullCommand) {
+ return new NullCheckInterruptibleClosureWrapper<>(closure, nullCommand);
+ }
- // ********** safe **********
+
+ // ********** safe wrappers **********
/**
* Return closure that will handle any exceptions thrown by the specified
@@ -131,10 +265,12 @@ public final class ClosureTools {
* the exception's stack trace will be printed to {@link System#err
* the "standard" error output stream}.
* @param <A> the type of the object passed to the closure
- * @see #safe(Closure, ExceptionHandler)
+ *
+ *
+ * @see #safeClosure(Closure, ExceptionHandler)
*/
- public static <A> Closure<A> safe(Closure<? super A> closure) {
- return safe(closure, DefaultExceptionHandler.instance());
+ public static <A> Closure<A> safeClosure(Closure<? super A> closure) {
+ return safeClosure(closure, DefaultExceptionHandler.instance());
}
/**
@@ -142,13 +278,43 @@ public final class ClosureTools {
* closure with the specified exception handler. If the
* wrapped closure throws an exception, the safe closure will handle
* the exception and return.
+ *
* @param <A> the type of the object passed to the closure
- * @see #safe(Closure)
+ *
+ * @see #safeClosure(Closure)
*/
- public static <A> Closure<A> safe(Closure<? super A> closure, ExceptionHandler exceptionHandler) {
+ public static <A> Closure<A> safeClosure(Closure<? super A> closure, ExceptionHandler exceptionHandler) {
return new SafeClosureWrapper<>(closure, exceptionHandler);
}
+ /**
+ * Return closure that will handle any exceptions thrown by the specified
+ * closure. If the wrapped closure throws an exception,
+ * the exception's stack trace will be printed to {@link System#err
+ * the "standard" error output stream}.
+ * @param <A> the type of the object passed to the closure
+ *
+ *
+ * @see #safeClosure(InterruptibleClosure, ExceptionHandler)
+ */
+ public static <A> InterruptibleClosure<A> safeClosure(InterruptibleClosure<? super A> closure) {
+ return safeClosure(closure, DefaultExceptionHandler.instance());
+ }
+
+ /**
+ * Return closure that will handle any exceptions thrown by the specified
+ * closure with the specified exception handler. If the
+ * wrapped closure throws an exception, the safe closure will handle
+ * the exception and return.
+ *
+ * @param <A> the type of the object passed to the closure
+ *
+ * @see #safeClosure(InterruptibleClosure)
+ */
+ public static <A> InterruptibleClosure<A> safeClosure(InterruptibleClosure<? super A> closure, ExceptionHandler exceptionHandler) {
+ return new SafeInterruptibleClosureWrapper<>(closure, exceptionHandler);
+ }
+
// ********** reflection **********
@@ -159,10 +325,11 @@ public final class ClosureTools {
* <strong>NB:</strong> The actual method is determined at execution time,
* not construction time. As a result, the closure can be used to emulate
* "duck typing".
+ *
* @param <A> the type of the object passed to the closure
*/
- public static <A> Closure<A> execute(String methodName) {
- return execute(methodName, ClassTools.EMPTY_ARRAY, ObjectTools.EMPTY_OBJECT_ARRAY);
+ public static <A> Closure<A> methodClosure(String methodName) {
+ return methodClosure(methodName, ClassTools.EMPTY_ARRAY, ObjectTools.EMPTY_OBJECT_ARRAY);
}
/**
@@ -172,10 +339,11 @@ public final class ClosureTools {
* <strong>NB:</strong> The actual method is determined at execution time,
* not construction time. As a result, the closure can be used to emulate
* "duck typing".
+ *
* @param <A> the type of the object passed to the closure
*/
- public static <A> Closure<A> execute(String methodName, Class<?> parameterType, Object argument) {
- return execute(methodName, new Class<?>[] { parameterType }, new Object[] { argument });
+ public static <A> Closure<A> methodClosure(String methodName, Class<?> parameterType, Object argument) {
+ return methodClosure(methodName, new Class<?>[] { parameterType }, new Object[] { argument });
}
/**
@@ -185,9 +353,10 @@ public final class ClosureTools {
* <strong>NB:</strong> The actual method is determined at execution time,
* not construction time. As a result, the closure can be used to emulate
* "duck typing".
+ *
* @param <A> the type of the object passed to the closure
*/
- public static <A> Closure<A> execute(String methodName, Class<?>[] parameterTypes, Object[] arguments) {
+ public static <A> Closure<A> methodClosure(String methodName, Class<?>[] parameterTypes, Object[] arguments) {
return new MethodClosure<>(methodName, parameterTypes, arguments);
}
@@ -197,22 +366,59 @@ public final class ClosureTools {
/**
* Return a composite of the specified closures. The composite's argument
* will be passed to each closure, in sequence.
+ *
* @param <A> the type of the object passed to the closure
*/
@SafeVarargs
- public static <A> Closure<A> composite(Closure<? super A>... closures) {
- return composite(ArrayTools.iterable(closures));
+ public static <A> Closure<A> compositeClosure(Closure<? super A>... closures) {
+ return (closures.length != 0) ? compositeClosure_(ArrayTools.iterable(closures)) : nullClosure();
}
/**
* Return a composite of the specified closures. The composite's argument
* will be passed to each closure, in sequence.
+ *
* @param <A> the type of the object passed to the closure
*/
- public static <A> Closure<A> composite(Iterable<Closure<? super A>> closures) {
+ public static <A> Closure<A> compositeClosure(Iterable<? extends Closure<? super A>> closures) {
+ return (closures.iterator().hasNext()) ? compositeClosure_(closures) : nullClosure();
+ }
+
+ /**
+ * assume non-empty
+ */
+ private static <A> Closure<A> compositeClosure_(Iterable<? extends Closure<? super A>> closures) {
return new CompositeClosure<>(closures);
}
+ /**
+ * Return a composite of the specified closures. The composite's argument
+ * will be passed to each closure, in sequence.
+ *
+ * @param <A> the type of the object passed to the closure
+ */
+ @SafeVarargs
+ public static <A> InterruptibleClosure<A> compositeInterruptibleClosure(InterruptibleClosure<? super A>... closures) {
+ return (closures.length != 0) ? compositeInterruptibleClosure_(ArrayTools.iterable(closures)) : nullClosure();
+ }
+
+ /**
+ * Return a composite of the specified closures. The composite's argument
+ * will be passed to each closure, in sequence.
+ *
+ * @param <A> the type of the object passed to the closure
+ */
+ public static <A> InterruptibleClosure<A> compositeInterruptibleClosure(Iterable<? extends InterruptibleClosure<? super A>> closures) {
+ return (closures.iterator().hasNext()) ? compositeInterruptibleClosure_(closures) : nullClosure();
+ }
+
+ /**
+ * assume non-empty
+ */
+ private static <A> InterruptibleClosure<A> compositeInterruptibleClosure_(Iterable<? extends InterruptibleClosure<? super A>> closures) {
+ return new CompositeInterruptibleClosure<>(closures);
+ }
+
// ********** conditional **********
@@ -221,21 +427,45 @@ public final class ClosureTools {
* determine whether to execute the specified closure.
* If the predicate evaluates to <code>false</code>, the closure will do
* nothing.
+ *
* @param <A> the type of the object passed to the closure
*/
public static <A> Closure<A> conditionalClosure(Predicate<? super A> predicate, Closure<? super A> closure) {
- return conditionalClosure(predicate, closure, NullClosure.instance());
+ return conditionalClosure(predicate, closure, nullClosure());
}
/**
* Return a closure that passes its argument to the specified predicate to
* determine which of the two specified closures to execute.
+ *
* @param <A> the type of the object passed to the closure
*/
public static <A> Closure<A> conditionalClosure(Predicate<? super A> predicate, Closure<? super A> trueClosure, Closure<? super A> falseClosure) {
return new ConditionalClosure<>(predicate, trueClosure, falseClosure);
}
+ /**
+ * Return a closure that passes its argument to the specified predicate to
+ * determine whether to execute the specified closure.
+ * If the predicate evaluates to <code>false</code>, the closure will do
+ * nothing.
+ *
+ * @param <A> the type of the object passed to the closure
+ */
+ public static <A> InterruptibleClosure<A> conditionalClosure(Predicate<? super A> predicate, InterruptibleClosure<? super A> closure) {
+ return conditionalClosure(predicate, closure, nullClosure());
+ }
+
+ /**
+ * Return a closure that passes its argument to the specified predicate to
+ * determine which of the two specified closures to execute.
+ *
+ * @param <A> the type of the object passed to the closure
+ */
+ public static <A> InterruptibleClosure<A> conditionalClosure(Predicate<? super A> predicate, InterruptibleClosure<? super A> trueClosure, InterruptibleClosure<? super A> falseClosure) {
+ return new ConditionalInterruptibleClosure<>(predicate, trueClosure, falseClosure);
+ }
+
// ********** switch **********
@@ -247,10 +477,11 @@ public final class ClosureTools {
* predicates would evaluate to <code>true</code>.
* If none of the predicates evaluates to <code>true</code>, the closure
* will do nothing.
+ *
* @param <A> the type of the object passed to the closure
*/
- public static <A> Closure<A> switchClosure(Iterable<Association<Predicate<? super A>, Closure<? super A>>> closures) {
- return switchClosure(closures, NullClosure.instance());
+ public static <A> Closure<A> switchClosure(Iterable<? extends Association<? extends Predicate<? super A>, ? extends Closure<? super A>>> closures) {
+ return switchClosure(closures, nullClosure());
}
/**
@@ -261,12 +492,43 @@ public final class ClosureTools {
* predicates would evaluate to <code>true</code>.
* If none of the predicates evaluates to <code>true</code>, the specified
* default closure is executed.
+ *
* @param <A> the type of the object passed to the closure
*/
- public static <A> Closure<A> switchClosure(Iterable<Association<Predicate<? super A>, Closure<? super A>>> closures, Closure<? super A> defaultClosure) {
+ public static <A> Closure<A> switchClosure(Iterable<? extends Association<? extends Predicate<? super A>, ? extends Closure<? super A>>> closures, Closure<? super A> defaultClosure) {
return new SwitchClosure<>(closures, defaultClosure);
}
+ /**
+ * Return a closure that loops over the specified set of predicate/closure
+ * pairs, passing its argument to each predicate to determine
+ * which of the closures to execute. Only the first closure whose predicate
+ * evaluates to <code>true</code> is executed, even if other, following,
+ * predicates would evaluate to <code>true</code>.
+ * If none of the predicates evaluates to <code>true</code>, the closure
+ * will do nothing.
+ *
+ * @param <A> the type of the object passed to the closure
+ */
+ public static <A> InterruptibleClosure<A> switchInterruptibleClosure(Iterable<? extends Association<? extends Predicate<? super A>, ? extends InterruptibleClosure<? super A>>> closures) {
+ return switchInterruptibleClosure(closures, nullClosure());
+ }
+
+ /**
+ * Return a closure that loops over the specified set of predicate/closure
+ * pairs, passing its argument to each predicate to determine
+ * which of the closures to execute. Only the first closure whose predicate
+ * evaluates to <code>true</code> is executed, even if other, following,
+ * predicates would evaluate to <code>true</code>.
+ * If none of the predicates evaluates to <code>true</code>, the specified
+ * default closure is executed.
+ *
+ * @param <A> the type of the object passed to the closure
+ */
+ public static <A> InterruptibleClosure<A> switchInterruptibleClosure(Iterable<? extends Association<? extends Predicate<? super A>, ? extends InterruptibleClosure<? super A>>> closures, InterruptibleClosure<? super A> defaultClosure) {
+ return new SwitchInterruptibleClosure<>(closures, defaultClosure);
+ }
+
// ********** boolean **********
@@ -303,6 +565,7 @@ public final class ClosureTools {
/**
* Return a closure that will throw an
* {@link UnsupportedOperationException exception} when executed.
+ *
* @param <A> the type of the object passed to the closure
*/
public static <A> Closure<A> disabledClosure() {
@@ -310,27 +573,62 @@ public final class ClosureTools {
}
+ // ********** interrupted **********
+
+ /**
+ * Return a closure that will throw an
+ * {@link InterruptedException exception} when executed.
+ *
+ * @param <A> the type of the object passed to the closure
+ */
+ public static <A> InterruptibleClosure<A> interruptedClosure() {
+ return InterruptedClosure.instance();
+ }
+
+
// ********** looping **********
/**
* Return a closure that executes the specified closure the specified
* number of times.
+ *
* @param <A> the type of the object passed to the closure
*/
- public static <A> Closure<A> repeat(Closure<? super A> closure, int count) {
- return new RepeatingClosure<>(closure, count);
+ public static <A> Closure<A> repeatingClosure(Closure<? super A> closure, int count) {
+ return (count == 0) ? nullClosure() : new RepeatingClosure<>(closure, count);
+ }
+
+ /**
+ * Return a closure that executes the specified closure the specified
+ * number of times.
+ *
+ * @param <A> the type of the object passed to the closure
+ */
+ public static <A> InterruptibleClosure<A> repeatingClosure(InterruptibleClosure<? super A> closure, int count) {
+ return (count == 0) ? nullClosure() : new RepeatingInterruptibleClosure<>(closure, count);
}
/**
* Return a closure that executes the specified closure while the specified
* predicate evaluates to <code>true</code> when passed the argument.
+ *
* @param <A> the type of the object passed to the closure
*/
- public static <A> Closure<A> while_(Predicate<? super A> predicate, Closure<? super A> closure) {
+ public static <A> Closure<A> whileClosure(Predicate<? super A> predicate, Closure<? super A> closure) {
return new WhileClosure<>(predicate, closure);
}
/**
+ * Return a closure that executes the specified closure while the specified
+ * predicate evaluates to <code>true</code> when passed the argument.
+ *
+ * @param <A> the type of the object passed to the closure
+ */
+ public static <A> InterruptibleClosure<A> whileClosure(Predicate<? super A> predicate, InterruptibleClosure<? super A> closure) {
+ return new WhileInterruptibleClosure<>(predicate, closure);
+ }
+
+ /**
* Return a closure that executes the specified closure until the specified
* predicate evaluates to <code>true</code> when passed the argument. The
* specifie closure will always execute at least once.
@@ -339,12 +637,29 @@ public final class ClosureTools {
* statement (i.e. it executes until the predicate evaluates to
* <strong><code>true</code></strong>,
* <em>not</em> <code>false</code>).
+ *
* @param <A> the type of the object passed to the closure
*/
- public static <A> Closure<A> until(Closure<? super A> closure, Predicate<? super A> predicate) {
+ public static <A> Closure<A> untilClosure(Closure<? super A> closure, Predicate<? super A> predicate) {
return new UntilClosure<>(closure, predicate);
}
+ /**
+ * Return a closure that executes the specified closure until the specified
+ * predicate evaluates to <code>true</code> when passed the argument. The
+ * specifie closure will always execute at least once.
+ * <p>
+ * <strong>NB:</strong> This is the inverse of the Java <code>do-while</code>
+ * statement (i.e. it executes until the predicate evaluates to
+ * <strong><code>true</code></strong>,
+ * <em>not</em> <code>false</code>).
+ *
+ * @param <A> the type of the object passed to the closure
+ */
+ public static <A> InterruptibleClosure<A> untilClosure(InterruptibleClosure<? super A> closure, Predicate<? super A> predicate) {
+ return new UntilInterruptibleClosure<>(closure, predicate);
+ }
+
// ********** constructor **********
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/CommandBiClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/CommandBiClosure.java
new file mode 100644
index 0000000000..9be7d10d9f
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/CommandBiClosure.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2013 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.closure;
+
+import org.eclipse.jpt.common.utility.closure.BiClosure;
+import org.eclipse.jpt.common.utility.command.Command;
+import org.eclipse.jpt.common.utility.internal.ObjectTools;
+
+/**
+ * Adapt a {@link Command} to the {@link BiClosure} interface.
+ * The closure's arguments are ignored.
+ *
+ * @param <A1> the type of the first object passed to the closure; ignored
+ * @param <A2> the type of the second object passed to the closure; ignored
+ */
+public class CommandBiClosure<A1, A2>
+ implements BiClosure<A1, A2>
+{
+ private final Command command;
+
+
+ public CommandBiClosure(Command command) {
+ super();
+ if (command == null) {
+ throw new NullPointerException();
+ }
+ this.command = command;
+ }
+
+ public void execute(A1 argument1, A2 argument2) {
+ this.command.execute();
+ }
+
+ @Override
+ public String toString() {
+ return ObjectTools.toString(this, this.command);
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/CompositeBiClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/CompositeBiClosure.java
new file mode 100644
index 0000000000..de8583f962
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/CompositeBiClosure.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2016 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.closure;
+
+import org.eclipse.jpt.common.utility.closure.BiClosure;
+import org.eclipse.jpt.common.utility.internal.ObjectTools;
+import org.eclipse.jpt.common.utility.internal.iterable.IterableTools;
+
+/**
+ * A composite of closures. Pass the composite's arguments to each closure,
+ * in sequence.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ */
+public class CompositeBiClosure<A1, A2>
+ implements BiClosure<A1, A2>
+{
+ private final Iterable<? extends BiClosure<? super A1, ? super A2>> closures;
+
+ public CompositeBiClosure(Iterable<? extends BiClosure<? super A1, ? super A2>> closures) {
+ super();
+ if (IterableTools.isOrContainsNull(closures)) {
+ throw new NullPointerException();
+ }
+ this.closures = closures;
+ }
+
+ public void execute(A1 argument1, A2 argument2) {
+ for (BiClosure<? super A1, ? super A2> closure : this.closures) {
+ closure.execute(argument1, argument2);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return ObjectTools.toString(this, this.closures);
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/CompositeClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/CompositeClosure.java
index 792547aee0..bbeb4bc8c6 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/CompositeClosure.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/CompositeClosure.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 Oracle. All rights reserved.
+ * Copyright (c) 2013, 2016 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.
@@ -22,9 +22,9 @@ import org.eclipse.jpt.common.utility.internal.iterable.IterableTools;
public class CompositeClosure<A>
implements Closure<A>
{
- private final Iterable<Closure<? super A>> closures;
+ private final Iterable<? extends Closure<? super A>> closures;
- public CompositeClosure(Iterable<Closure<? super A>> closures) {
+ public CompositeClosure(Iterable<? extends Closure<? super A>> closures) {
super();
if (IterableTools.isOrContainsNull(closures)) {
throw new NullPointerException();
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/CompositeInterruptibleBiClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/CompositeInterruptibleBiClosure.java
new file mode 100644
index 0000000000..1d83f5515b
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/CompositeInterruptibleBiClosure.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2016 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.closure;
+
+import org.eclipse.jpt.common.utility.closure.InterruptibleBiClosure;
+import org.eclipse.jpt.common.utility.internal.ObjectTools;
+import org.eclipse.jpt.common.utility.internal.iterable.IterableTools;
+
+/**
+ * A composite of closures. Pass the composite's arguments to each closure,
+ * in sequence.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ */
+public class CompositeInterruptibleBiClosure<A1, A2>
+ implements InterruptibleBiClosure<A1, A2>
+{
+ private final Iterable<? extends InterruptibleBiClosure<? super A1, ? super A2>> closures;
+
+ public CompositeInterruptibleBiClosure(Iterable<? extends InterruptibleBiClosure<? super A1, ? super A2>> closures) {
+ super();
+ if (IterableTools.isOrContainsNull(closures)) {
+ throw new NullPointerException();
+ }
+ this.closures = closures;
+ }
+
+ public void execute(A1 argument1, A2 argument2) throws InterruptedException {
+ for (InterruptibleBiClosure<? super A1, ? super A2> closure : this.closures) {
+ closure.execute(argument1, argument2);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return ObjectTools.toString(this, this.closures);
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/CompositeInterruptibleClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/CompositeInterruptibleClosure.java
index 5564a840a2..e1669c766c 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/CompositeInterruptibleClosure.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/CompositeInterruptibleClosure.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 Oracle. All rights reserved.
+ * Copyright (c) 2013, 2016 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.
@@ -19,9 +19,9 @@ import org.eclipse.jpt.common.utility.internal.iterable.IterableTools;
public class CompositeInterruptibleClosure<A>
implements InterruptibleClosure<A>
{
- private final Iterable<InterruptibleClosure<? super A>> closures;
+ private final Iterable<? extends InterruptibleClosure<? super A>> closures;
- public CompositeInterruptibleClosure(Iterable<InterruptibleClosure<? super A>> closures) {
+ public CompositeInterruptibleClosure(Iterable<? extends InterruptibleClosure<? super A>> closures) {
super();
if (IterableTools.isOrContainsNull(closures)) {
throw new NullPointerException();
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ConditionalClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ConditionalClosure.java
index 9e6c6d4680..7dd8ad1605 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ConditionalClosure.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ConditionalClosure.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 Oracle. All rights reserved.
+ * Copyright (c) 2013, 2016 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.
@@ -33,11 +33,17 @@ public class ConditionalClosure<A>
public ConditionalClosure(Predicate<? super A> predicate, Closure<? super A> trueClosure, Closure<? super A> falseClosure) {
super();
- if ((predicate == null) || (trueClosure == null) || (falseClosure == null)) {
+ if (predicate == null) {
throw new NullPointerException();
}
this.predicate = predicate;
+ if (trueClosure == null) {
+ throw new NullPointerException();
+ }
this.trueClosure = trueClosure;
+ if (falseClosure == null) {
+ throw new NullPointerException();
+ }
this.falseClosure = falseClosure;
}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ConditionalInterruptibleClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ConditionalInterruptibleClosure.java
index 64a766ff92..e2f62b5243 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ConditionalInterruptibleClosure.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ConditionalInterruptibleClosure.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 Oracle. All rights reserved.
+ * Copyright (c) 2013, 2016 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.
@@ -29,11 +29,17 @@ public class ConditionalInterruptibleClosure<A>
public ConditionalInterruptibleClosure(Predicate<? super A> predicate, InterruptibleClosure<? super A> trueClosure, InterruptibleClosure<? super A> falseClosure) {
super();
- if ((predicate == null) || (trueClosure == null) || (falseClosure == null)) {
+ if (predicate == null) {
throw new NullPointerException();
}
this.predicate = predicate;
+ if (trueClosure == null) {
+ throw new NullPointerException();
+ }
this.trueClosure = trueClosure;
+ if (falseClosure == null) {
+ throw new NullPointerException();
+ }
this.falseClosure = falseClosure;
}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/DisabledBiClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/DisabledBiClosure.java
new file mode 100644
index 0000000000..e5c3fc5649
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/DisabledBiClosure.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2016 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.closure;
+
+import java.io.Serializable;
+import org.eclipse.jpt.common.utility.closure.BiClosure;
+import org.eclipse.jpt.common.utility.internal.ObjectTools;
+
+/**
+ * Closure that will throw an
+ * {@link UnsupportedOperationException exception} when executed.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ */
+public final class DisabledBiClosure<A1, A2>
+ implements BiClosure<A1, A2>, Serializable
+{
+ @SuppressWarnings("rawtypes")
+ public static final BiClosure INSTANCE = new DisabledBiClosure();
+
+ @SuppressWarnings("unchecked")
+ public static <A1, A2> BiClosure<A1, A2> instance() {
+ return INSTANCE;
+ }
+
+ // ensure single instance
+ private DisabledBiClosure() {
+ super();
+ }
+
+ // throw an exception
+ public void execute(A1 argument1, A2 argument2) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String toString() {
+ return ObjectTools.singletonToString(this);
+ }
+
+ private static final long serialVersionUID = 1L;
+ private Object readResolve() {
+ // replace this object with the singleton
+ return INSTANCE;
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/FactoryBiClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/FactoryBiClosure.java
new file mode 100644
index 0000000000..16b424e8e5
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/FactoryBiClosure.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2016 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.closure;
+
+import org.eclipse.jpt.common.utility.closure.BiClosure;
+import org.eclipse.jpt.common.utility.factory.Factory;
+import org.eclipse.jpt.common.utility.internal.ObjectTools;
+
+/**
+ * Adapt a {@link Factory} to the {@link BiClosure} interface.
+ * The closure's arguments and the factory's output are ignored.
+ * This really only useful for a factory that has side-effects.
+ *
+ * @param <A1> the type of the first object passed to the closure; ignored
+ * @param <A2> the type of the second object passed to the closure; ignored
+ */
+public class FactoryBiClosure<A1, A2>
+ implements BiClosure<A1, A2>
+{
+ private final Factory<?> factory;
+
+
+ public FactoryBiClosure(Factory<?> factory) {
+ super();
+ if (factory == null) {
+ throw new NullPointerException();
+ }
+ this.factory = factory;
+ }
+
+ public void execute(A1 argument1, A2 argument2) {
+ this.factory.create();
+ }
+
+ @Override
+ public String toString() {
+ return ObjectTools.toString(this, this.factory);
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/InterruptedBiClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/InterruptedBiClosure.java
new file mode 100644
index 0000000000..9dba95aa14
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/InterruptedBiClosure.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2016 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.closure;
+
+import java.io.Serializable;
+import org.eclipse.jpt.common.utility.closure.InterruptibleBiClosure;
+import org.eclipse.jpt.common.utility.internal.ObjectTools;
+
+/**
+ * Closure that will throw an {@link InterruptedException exception}
+ * when executed.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ */
+public final class InterruptedBiClosure<A1, A2>
+ implements InterruptibleBiClosure<A1, A2>, Serializable
+{
+ @SuppressWarnings("rawtypes")
+ public static final InterruptibleBiClosure INSTANCE = new InterruptedBiClosure();
+
+ @SuppressWarnings("unchecked")
+ public static <A1, A2> InterruptibleBiClosure<A1, A2> instance() {
+ return INSTANCE;
+ }
+
+ // ensure single instance
+ private InterruptedBiClosure() {
+ super();
+ }
+
+ // throw an exception
+ public void execute(A1 argument1, A2 argument2) throws InterruptedException {
+ throw new InterruptedException();
+ }
+
+ @Override
+ public String toString() {
+ return ObjectTools.singletonToString(this);
+ }
+
+ private static final long serialVersionUID = 1L;
+ private Object readResolve() {
+ // replace this object with the singleton
+ return INSTANCE;
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/InterruptibleBiClosureAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/InterruptibleBiClosureAdapter.java
new file mode 100644
index 0000000000..9d05d7b70c
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/InterruptibleBiClosureAdapter.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2016 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.closure;
+
+import org.eclipse.jpt.common.utility.closure.InterruptibleBiClosure;
+import org.eclipse.jpt.common.utility.internal.ObjectTools;
+
+/**
+ * Convenience interruptible bi-closure that does nothing.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ *
+ * @see BiClosureAdapter
+ * @see NullBiClosure
+ */
+public class InterruptibleBiClosureAdapter<A1, A2>
+ implements InterruptibleBiClosure<A1, A2>
+{
+ public void execute(A1 argument1, A2 argument2) throws InterruptedException {
+ // NOP
+ }
+
+ @Override
+ public String toString() {
+ return ObjectTools.toString(this);
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/InterruptibleBiClosureWrapper.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/InterruptibleBiClosureWrapper.java
new file mode 100644
index 0000000000..fced788030
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/InterruptibleBiClosureWrapper.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2016 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.closure;
+
+import org.eclipse.jpt.common.utility.closure.InterruptibleBiClosure;
+import org.eclipse.jpt.common.utility.internal.ObjectTools;
+
+/**
+ * Closure wrapper that can have its wrapped closure changed,
+ * allowing a client to change a previously-supplied closure's
+ * behavior mid-stream.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ *
+ * @see #setClosure(InterruptibleBiClosure)
+ */
+public class InterruptibleBiClosureWrapper<A1, A2>
+ implements InterruptibleBiClosure<A1, A2>
+{
+ protected volatile InterruptibleBiClosure<? super A1, ? super A2> closure;
+
+ public InterruptibleBiClosureWrapper(InterruptibleBiClosure<? super A1, ? super A2> closure) {
+ super();
+ if (closure == null) {
+ throw new NullPointerException();
+ }
+ this.closure = closure;
+ }
+
+ public void execute(A1 argument1, A2 argument2) throws InterruptedException {
+ this.closure.execute(argument1, argument2);
+ }
+
+ public void setClosure(InterruptibleBiClosure<? super A1, ? super A2> closure) {
+ if (closure == null) {
+ throw new NullPointerException();
+ }
+ this.closure = closure;
+ }
+
+ @Override
+ public String toString() {
+ return ObjectTools.toString(this, this.closure);
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/InterruptibleCommandBiClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/InterruptibleCommandBiClosure.java
new file mode 100644
index 0000000000..a71d62a62c
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/InterruptibleCommandBiClosure.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2013 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.closure;
+
+import org.eclipse.jpt.common.utility.closure.InterruptibleBiClosure;
+import org.eclipse.jpt.common.utility.command.InterruptibleCommand;
+import org.eclipse.jpt.common.utility.internal.ObjectTools;
+
+/**
+ * Adapt an {@link InterruptibleCommand} to the {@link InterruptibleBiClosure} interface.
+ * The closure's arguments are ignored.
+ *
+ * @param <A1> the type of the first object passed to the closure; ignored
+ * @param <A2> the type of the second object passed to the closure; ignored
+ */
+public class InterruptibleCommandBiClosure<A1, A2>
+ implements InterruptibleBiClosure<A1, A2>
+{
+ private final InterruptibleCommand command;
+
+
+ public InterruptibleCommandBiClosure(InterruptibleCommand command) {
+ super();
+ if (command == null) {
+ throw new NullPointerException();
+ }
+ this.command = command;
+ }
+
+ public void execute(A1 argument1, A2 argument2) throws InterruptedException {
+ this.command.execute();
+ }
+
+ @Override
+ public String toString() {
+ return ObjectTools.toString(this, this.command);
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/InterruptibleFactoryBiClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/InterruptibleFactoryBiClosure.java
new file mode 100644
index 0000000000..d36186807c
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/InterruptibleFactoryBiClosure.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2016 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.closure;
+
+import org.eclipse.jpt.common.utility.closure.InterruptibleBiClosure;
+import org.eclipse.jpt.common.utility.factory.InterruptibleFactory;
+import org.eclipse.jpt.common.utility.internal.ObjectTools;
+
+/**
+ * Adapt an {@link InterruptibleFactory} to the {@link InterruptibleBiClosure} interface.
+ * The closure's arguments and the factory's output are ignored.
+ * This really only useful for a factory that has side-effects.
+ *
+ * @param <A1> the type of the first object passed to the closure; ignored
+ * @param <A2> the type of the second object passed to the closure; ignored
+ */
+public class InterruptibleFactoryBiClosure<A1, A2>
+ implements InterruptibleBiClosure<A1, A2>
+{
+ private final InterruptibleFactory<?> factory;
+
+
+ public InterruptibleFactoryBiClosure(InterruptibleFactory<?> factory) {
+ super();
+ if (factory == null) {
+ throw new NullPointerException();
+ }
+ this.factory = factory;
+ }
+
+ public void execute(A1 argument1, A2 argument2) throws InterruptedException {
+ this.factory.create();
+ }
+
+ @Override
+ public String toString() {
+ return ObjectTools.toString(this, this.factory);
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/MethodClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/MethodClosure.java
index bea0748c6f..571388f12a 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/MethodClosure.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/MethodClosure.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 Oracle. All rights reserved.
+ * Copyright (c) 2013, 2016 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.
@@ -40,11 +40,17 @@ public class MethodClosure<A>
public MethodClosure(String methodName, Class<?>[] parameterTypes, Object[] arguments) {
super();
- if ((methodName == null) || ArrayTools.isOrContainsNull(parameterTypes) || (arguments == null)) {
+ if (methodName == null) {
throw new NullPointerException();
}
this.methodName = methodName;
+ if (ArrayTools.isOrContainsNull(parameterTypes)) {
+ throw new NullPointerException();
+ }
this.parameterTypes = parameterTypes;
+ if (arguments == null) {
+ throw new NullPointerException();
+ }
this.arguments = arguments;
}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/NullBiClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/NullBiClosure.java
new file mode 100644
index 0000000000..c1e21e8423
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/NullBiClosure.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2016 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.closure;
+
+import java.io.Serializable;
+import org.eclipse.jpt.common.utility.closure.BiClosure;
+import org.eclipse.jpt.common.utility.internal.ObjectTools;
+
+/**
+ * BiClosure that will do nothing when executed.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ *
+ * @see BiClosureAdapter
+ */
+public final class NullBiClosure<A1, A2>
+ implements BiClosure<A1, A2>, Serializable
+{
+ @SuppressWarnings("rawtypes")
+ public static final BiClosure INSTANCE = new NullBiClosure();
+
+ @SuppressWarnings("unchecked")
+ public static <A1, A2> BiClosure<A1, A2> instance() {
+ return INSTANCE;
+ }
+
+ // ensure single instance
+ private NullBiClosure() {
+ super();
+ }
+
+ public void execute(A1 argument1, A2 argument2) {
+ // NOP
+ }
+
+ @Override
+ public String toString() {
+ return ObjectTools.singletonToString(this);
+ }
+
+ private static final long serialVersionUID = 1L;
+ private Object readResolve() {
+ // replace this object with the singleton
+ return INSTANCE;
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/NullCheckClosureWrapper.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/NullCheckClosureWrapper.java
index 78c1ac3dd8..23ba6f3522 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/NullCheckClosureWrapper.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/NullCheckClosureWrapper.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 Oracle. All rights reserved.
+ * Copyright (c) 2013, 2016 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.
@@ -37,6 +37,9 @@ public class NullCheckClosureWrapper<A>
throw new NullPointerException();
}
this.closure = closure;
+ if (nullCommand == null) {
+ throw new NullPointerException();
+ }
this.nullCommand = nullCommand;
}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/NullCheckInterruptibleClosureWrapper.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/NullCheckInterruptibleClosureWrapper.java
index 9033212fae..ef029729b1 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/NullCheckInterruptibleClosureWrapper.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/NullCheckInterruptibleClosureWrapper.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 Oracle. All rights reserved.
+ * Copyright (c) 2013, 2016 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.
@@ -32,6 +32,9 @@ public class NullCheckInterruptibleClosureWrapper<A>
throw new NullPointerException();
}
this.closure = closure;
+ if (nullCommand == null) {
+ throw new NullPointerException();
+ }
this.nullCommand = nullCommand;
}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/RepeatingBiClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/RepeatingBiClosure.java
new file mode 100644
index 0000000000..6540dddf53
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/RepeatingBiClosure.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2016 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.closure;
+
+import org.eclipse.jpt.common.utility.closure.BiClosure;
+import org.eclipse.jpt.common.utility.internal.ObjectTools;
+
+/**
+ * BiClosure that executes another closure a specified number of times.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ */
+public class RepeatingBiClosure<A1, A2>
+ implements BiClosure<A1, A2>
+{
+ private final int count;
+ private final BiClosure<? super A1, ? super A2> closure;
+
+ public RepeatingBiClosure(BiClosure<? super A1, ? super A2> closure, int count) {
+ super();
+ if (closure == null) {
+ throw new NullPointerException();
+ }
+ this.closure = closure;
+ if (count < 0) {
+ throw new IndexOutOfBoundsException("invalid count: " + count); //$NON-NLS-1$
+ }
+ this.count = count;
+ }
+
+ public void execute(A1 argument1, A2 argument2) {
+ for (int i = this.count; i-- > 0;) {
+ this.closure.execute(argument1, argument2);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return ObjectTools.toString(this, this.closure);
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/RepeatingClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/RepeatingClosure.java
index 2eb80a1421..a1d6e3c995 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/RepeatingClosure.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/RepeatingClosure.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 Oracle. All rights reserved.
+ * Copyright (c) 2013, 2016 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.
@@ -33,10 +33,10 @@ public class RepeatingClosure<A>
if (closure == null) {
throw new NullPointerException();
}
- if (count <= 0) {
+ this.closure = closure;
+ if (count < 0) {
throw new IndexOutOfBoundsException("invalid count: " + count); //$NON-NLS-1$
}
- this.closure = closure;
this.count = count;
}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/RepeatingInterruptibleBiClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/RepeatingInterruptibleBiClosure.java
new file mode 100644
index 0000000000..937d4d5a3a
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/RepeatingInterruptibleBiClosure.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2016 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.closure;
+
+import org.eclipse.jpt.common.utility.closure.InterruptibleBiClosure;
+import org.eclipse.jpt.common.utility.internal.ObjectTools;
+
+/**
+ * BiClosure that executes another closure a specified number of times.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ */
+public class RepeatingInterruptibleBiClosure<A1, A2>
+ implements InterruptibleBiClosure<A1, A2>
+{
+ private final int count;
+ private final InterruptibleBiClosure<? super A1, ? super A2> closure;
+
+ public RepeatingInterruptibleBiClosure(InterruptibleBiClosure<? super A1, ? super A2> closure, int count) {
+ super();
+ if (closure == null) {
+ throw new NullPointerException();
+ }
+ this.closure = closure;
+ if (count < 0) {
+ throw new IndexOutOfBoundsException("invalid count: " + count); //$NON-NLS-1$
+ }
+ this.count = count;
+ }
+
+ public void execute(A1 argument1, A2 argument2) throws InterruptedException {
+ for (int i = this.count; i-- > 0;) {
+ this.closure.execute(argument1, argument2);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return ObjectTools.toString(this, this.closure);
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/RepeatingInterruptibleClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/RepeatingInterruptibleClosure.java
index a401a79a9d..9599946900 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/RepeatingInterruptibleClosure.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/RepeatingInterruptibleClosure.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 Oracle. All rights reserved.
+ * Copyright (c) 2013, 2016 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.
@@ -30,7 +30,7 @@ public class RepeatingInterruptibleClosure<A>
if (closure == null) {
throw new NullPointerException();
}
- if (count <= 0) {
+ if (count < 0) {
throw new IndexOutOfBoundsException("invalid count: " + count); //$NON-NLS-1$
}
this.closure = closure;
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SafeBiClosureWrapper.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SafeBiClosureWrapper.java
new file mode 100644
index 0000000000..aeb4e43d4c
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SafeBiClosureWrapper.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2016 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.closure;
+
+import org.eclipse.jpt.common.utility.closure.BiClosure;
+import org.eclipse.jpt.common.utility.exception.ExceptionHandler;
+import org.eclipse.jpt.common.utility.internal.ObjectTools;
+
+/**
+ * Closure wrapper that will handle any exceptions thrown by the wrapped
+ * closure with an {@link ExceptionHandler exception handler}. If the
+ * wrapped closure throws an exception, the safe closure will handle
+ * the exception and return.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ */
+public class SafeBiClosureWrapper<A1, A2>
+ implements BiClosure<A1, A2>
+{
+ private final BiClosure<? super A1, ? super A2> closure;
+ private final ExceptionHandler exceptionHandler;
+
+
+ public SafeBiClosureWrapper(BiClosure<? super A1, ? super A2> closure, ExceptionHandler exceptionHandler) {
+ super();
+ if (closure == null) {
+ throw new NullPointerException();
+ }
+ this.closure = closure;
+ if (exceptionHandler == null) {
+ throw new NullPointerException();
+ }
+ this.exceptionHandler = exceptionHandler;
+ }
+
+ public void execute(A1 argument1, A2 argument2) {
+ try {
+ this.closure.execute(argument1, argument2);
+ } catch (Throwable ex) {
+ this.exceptionHandler.handleException(ex);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return ObjectTools.toString(this, this.closure);
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SafeClosureWrapper.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SafeClosureWrapper.java
index 0fae6e1ca7..9caa77e632 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SafeClosureWrapper.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SafeClosureWrapper.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 Oracle. All rights reserved.
+ * Copyright (c) 2013, 2016 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.
@@ -30,10 +30,13 @@ public class SafeClosureWrapper<A>
public SafeClosureWrapper(Closure<? super A> closure, ExceptionHandler exceptionHandler) {
super();
- if ((closure == null) || (exceptionHandler == null)) {
+ if (closure == null) {
throw new NullPointerException();
}
this.closure = closure;
+ if (exceptionHandler == null) {
+ throw new NullPointerException();
+ }
this.exceptionHandler = exceptionHandler;
}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SafeInterruptibleBiClosureWrapper.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SafeInterruptibleBiClosureWrapper.java
new file mode 100644
index 0000000000..776ff9552d
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SafeInterruptibleBiClosureWrapper.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2016 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.closure;
+
+import org.eclipse.jpt.common.utility.closure.InterruptibleBiClosure;
+import org.eclipse.jpt.common.utility.exception.ExceptionHandler;
+import org.eclipse.jpt.common.utility.internal.ObjectTools;
+
+/**
+ * Closure wrapper that will handle any exceptions thrown by the wrapped
+ * closure with an {@link ExceptionHandler exception handler}. If the
+ * wrapped closure throws an exception, the safe closure will handle
+ * the exception and return.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ */
+public class SafeInterruptibleBiClosureWrapper<A1, A2>
+ implements InterruptibleBiClosure<A1, A2>
+{
+ private final InterruptibleBiClosure<? super A1, ? super A2> closure;
+ private final ExceptionHandler exceptionHandler;
+
+
+ public SafeInterruptibleBiClosureWrapper(InterruptibleBiClosure<? super A1, ? super A2> closure, ExceptionHandler exceptionHandler) {
+ super();
+ if (closure == null) {
+ throw new NullPointerException();
+ }
+ this.closure = closure;
+ if (exceptionHandler == null) {
+ throw new NullPointerException();
+ }
+ this.exceptionHandler = exceptionHandler;
+ }
+
+ public void execute(A1 argument1, A2 argument2) throws InterruptedException {
+ try {
+ this.closure.execute(argument1, argument2);
+ } catch (InterruptedException ex) {
+ throw ex;
+ } catch (Throwable ex) {
+ this.exceptionHandler.handleException(ex);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return ObjectTools.toString(this, this.closure);
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SafeInterruptibleClosureWrapper.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SafeInterruptibleClosureWrapper.java
index b106b075b8..cc3a317353 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SafeInterruptibleClosureWrapper.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SafeInterruptibleClosureWrapper.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 Oracle. All rights reserved.
+ * Copyright (c) 2013, 2016 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.
@@ -25,10 +25,13 @@ public class SafeInterruptibleClosureWrapper<A>
public SafeInterruptibleClosureWrapper(InterruptibleClosure<? super A> closure, ExceptionHandler exceptionHandler) {
super();
- if ((closure == null) || (exceptionHandler == null)) {
+ if (closure == null) {
throw new NullPointerException();
}
this.closure = closure;
+ if (exceptionHandler == null) {
+ throw new NullPointerException();
+ }
this.exceptionHandler = exceptionHandler;
}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SwitchClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SwitchClosure.java
index c4839d7af7..d62730a374 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SwitchClosure.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SwitchClosure.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 Oracle. All rights reserved.
+ * Copyright (c) 2013, 2016 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.
@@ -34,20 +34,23 @@ import org.eclipse.jpt.common.utility.predicate.Predicate;
public class SwitchClosure<A>
implements Closure<A>
{
- private final Iterable<Association<Predicate<? super A>, Closure<? super A>>> closures;
+ private final Iterable<? extends Association<? extends Predicate<? super A>, ? extends Closure<? super A>>> closures;
private final Closure<? super A> defaultClosure;
- public SwitchClosure(Iterable<Association<Predicate<? super A>, Closure<? super A>>> closures, Closure<? super A> defaultClosure) {
+ public SwitchClosure(Iterable<? extends Association<? extends Predicate<? super A>, ? extends Closure<? super A>>> closures, Closure<? super A> defaultClosure) {
super();
- if (IterableTools.isOrContainsNull(closures) || (defaultClosure == null)) {
+ if (IterableTools.isOrContainsNull(closures)) {
throw new NullPointerException();
}
this.closures = closures;
+ if (defaultClosure == null) {
+ throw new NullPointerException();
+ }
this.defaultClosure = defaultClosure;
}
public void execute(A argument) {
- for (Association<Predicate<? super A>, Closure<? super A>> association : this.closures) {
+ for (Association<? extends Predicate<? super A>, ? extends Closure<? super A>> association : this.closures) {
if (association.getKey().evaluate(argument)) {
association.getValue().execute(argument);
return; // execute only one closure
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SwitchInterruptibleClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SwitchInterruptibleClosure.java
index 086c518f0e..f6640be275 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SwitchInterruptibleClosure.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/SwitchInterruptibleClosure.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 Oracle. All rights reserved.
+ * Copyright (c) 2013, 2016 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.
@@ -25,26 +25,29 @@ import org.eclipse.jpt.common.utility.predicate.Predicate;
public class SwitchInterruptibleClosure<A>
implements InterruptibleClosure<A>
{
- private final Iterable<Association<Predicate<? super A>, InterruptibleClosure<? super A>>> closures;
- private final InterruptibleClosure<? super A> defaultInterruptibleClosure;
+ private final Iterable<? extends Association<? extends Predicate<? super A>, ? extends InterruptibleClosure<? super A>>> closures;
+ private final InterruptibleClosure<? super A> defaultClosure;
- public SwitchInterruptibleClosure(Iterable<Association<Predicate<? super A>, InterruptibleClosure<? super A>>> closures, InterruptibleClosure<? super A> defaultInterruptibleClosure) {
+ public SwitchInterruptibleClosure(Iterable<? extends Association<? extends Predicate<? super A>, ? extends InterruptibleClosure<? super A>>> closures, InterruptibleClosure<? super A> defaultClosure) {
super();
- if (IterableTools.isOrContainsNull(closures) || (defaultInterruptibleClosure == null)) {
+ if (IterableTools.isOrContainsNull(closures)) {
throw new NullPointerException();
}
this.closures = closures;
- this.defaultInterruptibleClosure = defaultInterruptibleClosure;
+ if (defaultClosure == null) {
+ throw new NullPointerException();
+ }
+ this.defaultClosure = defaultClosure;
}
public void execute(A argument) throws InterruptedException {
- for (Association<Predicate<? super A>, InterruptibleClosure<? super A>> association : this.closures) {
+ for (Association<? extends Predicate<? super A>, ? extends InterruptibleClosure<? super A>> association : this.closures) {
if (association.getKey().evaluate(argument)) {
association.getValue().execute(argument);
return; // execute only one closure
}
}
- this.defaultInterruptibleClosure.execute(argument);
+ this.defaultClosure.execute(argument);
}
@Override
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ThreadLocalBiClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ThreadLocalBiClosure.java
new file mode 100644
index 0000000000..e62cb12056
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ThreadLocalBiClosure.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2016 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.closure;
+
+import org.eclipse.jpt.common.utility.closure.BiClosure;
+
+/**
+ * This closure allows the client to specify a different closure for each
+ * thread. If there is no closure for the current thread, the configured default
+ * closure is executed.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ *
+ * @see #set(BiClosure)
+ */
+public class ThreadLocalBiClosure<A1, A2>
+ implements BiClosure<A1, A2>
+{
+ private final ThreadLocal<BiClosure<? super A1, ? super A2>> threadLocal;
+ private final BiClosure<? super A1, ? super A2> defaultClosure;
+
+ public ThreadLocalBiClosure(BiClosure<? super A1, ? super A2> defaultClosure) {
+ super();
+ if (defaultClosure == null) {
+ throw new NullPointerException();
+ }
+ this.defaultClosure = defaultClosure;
+ this.threadLocal = this.buildThreadLocal();
+ }
+
+ private ThreadLocal<BiClosure<? super A1, ? super A2>> buildThreadLocal() {
+ return new ThreadLocal<>();
+ }
+
+ public void execute(A1 argument1, A2 argument2) {
+ this.get().execute(argument1, argument2);
+ }
+
+ private BiClosure<? super A1, ? super A2> get() {
+ BiClosure<? super A1, ? super A2> closure = this.threadLocal.get();
+ return (closure != null) ? closure : this.defaultClosure;
+ }
+
+ /**
+ * Set the current thread's closure to the specified value.
+ */
+ public void set(BiClosure<? super A1, ? super A2> closure) {
+ this.threadLocal.set(closure);
+ }
+
+ /**
+ * Return the string representation of the current thread's closure.
+ */
+ @Override
+ public String toString() {
+ return this.get().toString();
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ThreadLocalClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ThreadLocalClosure.java
index 7d9d93bab0..4857697c81 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ThreadLocalClosure.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ThreadLocalClosure.java
@@ -45,10 +45,7 @@ public class ThreadLocalClosure<A>
private Closure<? super A> get() {
Closure<? super A> closure = this.threadLocal.get();
- if (closure != null) {
- return closure;
- }
- return this.defaultClosure;
+ return (closure != null) ? closure : this.defaultClosure;
}
/**
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ThreadLocalInterruptibleBiClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ThreadLocalInterruptibleBiClosure.java
new file mode 100644
index 0000000000..a722dec737
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ThreadLocalInterruptibleBiClosure.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2016 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.closure;
+
+import org.eclipse.jpt.common.utility.closure.BiClosure;
+import org.eclipse.jpt.common.utility.closure.InterruptibleBiClosure;
+
+/**
+ * This closure allows the client to specify a different closure for each
+ * thread. If there is no closure for the current thread, the configured default
+ * closure is executed.
+ *
+ * @param <A1> the type of the first object passed to the closure
+ * @param <A2> the type of the second object passed to the closure
+ *
+ * @see #set(BiClosure)
+ */
+public class ThreadLocalInterruptibleBiClosure<A1, A2>
+ implements InterruptibleBiClosure<A1, A2>
+{
+ private final ThreadLocal<InterruptibleBiClosure<? super A1, ? super A2>> threadLocal;
+ private final InterruptibleBiClosure<? super A1, ? super A2> defaultClosure;
+
+ public ThreadLocalInterruptibleBiClosure(InterruptibleBiClosure<? super A1, ? super A2> defaultClosure) {
+ super();
+ if (defaultClosure == null) {
+ throw new NullPointerException();
+ }
+ this.defaultClosure = defaultClosure;
+ this.threadLocal = this.buildThreadLocal();
+ }
+
+ private ThreadLocal<InterruptibleBiClosure<? super A1, ? super A2>> buildThreadLocal() {
+ return new ThreadLocal<>();
+ }
+
+ public void execute(A1 argument1, A2 argument2) throws InterruptedException {
+ this.get().execute(argument1, argument2);
+ }
+
+ private InterruptibleBiClosure<? super A1, ? super A2> get() {
+ InterruptibleBiClosure<? super A1, ? super A2> closure = this.threadLocal.get();
+ return (closure != null) ? closure : this.defaultClosure;
+ }
+
+ /**
+ * Set the current thread's closure to the specified value.
+ */
+ public void set(BiClosure<? super A1, ? super A2> closure) {
+ this.threadLocal.set(closure);
+ }
+
+ /**
+ * Return the string representation of the current thread's closure.
+ */
+ @Override
+ public String toString() {
+ return this.get().toString();
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ThreadLocalInterruptibleClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ThreadLocalInterruptibleClosure.java
index f9cca6122b..43616a3894 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ThreadLocalInterruptibleClosure.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/ThreadLocalInterruptibleClosure.java
@@ -18,14 +18,14 @@ public class ThreadLocalInterruptibleClosure<A>
implements InterruptibleClosure<A>
{
private final ThreadLocal<InterruptibleClosure<? super A>> threadLocal;
- private final InterruptibleClosure<? super A> defaultInterruptibleClosure;
+ private final InterruptibleClosure<? super A> defaultClosure;
- public ThreadLocalInterruptibleClosure(InterruptibleClosure<? super A> defaultInterruptibleClosure) {
+ public ThreadLocalInterruptibleClosure(InterruptibleClosure<? super A> defaultClosure) {
super();
- if (defaultInterruptibleClosure == null) {
+ if (defaultClosure == null) {
throw new NullPointerException();
}
- this.defaultInterruptibleClosure = defaultInterruptibleClosure;
+ this.defaultClosure = defaultClosure;
this.threadLocal = this.buildThreadLocal();
}
@@ -39,10 +39,7 @@ public class ThreadLocalInterruptibleClosure<A>
private InterruptibleClosure<? super A> get() {
InterruptibleClosure<? super A> closure = this.threadLocal.get();
- if (closure != null) {
- return closure;
- }
- return this.defaultInterruptibleClosure;
+ return (closure != null) ? closure : this.defaultClosure;
}
/**
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/UntilClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/UntilClosure.java
index 1caa60423b..4632b96ea9 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/UntilClosure.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/UntilClosure.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 Oracle. All rights reserved.
+ * Copyright (c) 2013, 2016 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.
@@ -38,11 +38,14 @@ public class UntilClosure<A>
public UntilClosure(Closure<? super A> closure, Predicate<? super A> predicate) {
super();
- if ((closure == null) || (predicate == null)) {
+ if (closure == null) {
throw new NullPointerException();
}
- this.predicate = predicate;
this.closure = closure;
+ if (predicate == null) {
+ throw new NullPointerException();
+ }
+ this.predicate = predicate;
}
public void execute(A argument) {
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/UntilInterruptibleClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/UntilInterruptibleClosure.java
index a307e8ebac..38b69adaed 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/UntilInterruptibleClosure.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/UntilInterruptibleClosure.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 Oracle. All rights reserved.
+ * Copyright (c) 2013, 2016 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.
@@ -28,11 +28,14 @@ public class UntilInterruptibleClosure<A>
public UntilInterruptibleClosure(InterruptibleClosure<? super A> closure, Predicate<? super A> predicate) {
super();
- if ((closure == null) || (predicate == null)) {
+ if (closure == null) {
throw new NullPointerException();
}
- this.predicate = predicate;
this.closure = closure;
+ if (predicate == null) {
+ throw new NullPointerException();
+ }
+ this.predicate = predicate;
}
public void execute(A argument) throws InterruptedException {
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/WhileClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/WhileClosure.java
index dfbd8c8f2e..147e7e5e27 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/WhileClosure.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/WhileClosure.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 Oracle. All rights reserved.
+ * Copyright (c) 2013, 2016 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.
@@ -32,10 +32,13 @@ public class WhileClosure<A>
public WhileClosure(Predicate<? super A> predicate, Closure<? super A> closure) {
super();
- if ((predicate == null) || (closure == null)) {
+ if (predicate == null) {
throw new NullPointerException();
}
this.predicate = predicate;
+ if (closure == null) {
+ throw new NullPointerException();
+ }
this.closure = closure;
}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/WhileInterruptibleClosure.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/WhileInterruptibleClosure.java
index de0014ab88..06a332f625 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/WhileInterruptibleClosure.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/closure/WhileInterruptibleClosure.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 Oracle. All rights reserved.
+ * Copyright (c) 2013, 2015 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.
@@ -28,10 +28,13 @@ public class WhileInterruptibleClosure<A>
public WhileInterruptibleClosure(Predicate<? super A> predicate, InterruptibleClosure<? super A> closure) {
super();
- if ((predicate == null) || (closure == null)) {
+ if (predicate == null) {
throw new NullPointerException();
}
this.predicate = predicate;
+ if (closure == null) {
+ throw new NullPointerException();
+ }
this.closure = closure;
}
diff --git a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/JptCommonUtilityTests.java b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/JptCommonUtilityTests.java
index ab7b8c52ec..a0e2cd0d9e 100644
--- a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/JptCommonUtilityTests.java
+++ b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/JptCommonUtilityTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2015 Oracle. All rights reserved.
+ * Copyright (c) 2005, 2016 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.
@@ -9,6 +9,7 @@
******************************************************************************/
package org.eclipse.jpt.common.utility.tests.internal;
+import org.eclipse.jpt.common.utility.tests.internal.closure.JptCommonUtilityClosureTests;
import org.eclipse.jpt.common.utility.tests.internal.collection.JptCommonUtilityCollectionTests;
import org.eclipse.jpt.common.utility.tests.internal.command.JptCommonUtilityCommandTests;
import org.eclipse.jpt.common.utility.tests.internal.comparator.JptCommonUtilityComparatorTests;
@@ -38,6 +39,7 @@ public class JptCommonUtilityTests {
public static Test suite() {
TestSuite suite = new TestSuite(JptCommonUtilityTests.class.getPackage().getName());
+ suite.addTest(JptCommonUtilityClosureTests.suite());
suite.addTest(JptCommonUtilityCollectionTests.suite());
suite.addTest(JptCommonUtilityCommandTests.suite());
suite.addTest(JptCommonUtilityComparatorTests.suite());
diff --git a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/closure/BiClosureToolsTests.java b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/closure/BiClosureToolsTests.java
new file mode 100644
index 0000000000..da20ae3efa
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/closure/BiClosureToolsTests.java
@@ -0,0 +1,726 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.tests.internal.closure;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import org.eclipse.jpt.common.utility.closure.BiClosure;
+import org.eclipse.jpt.common.utility.closure.InterruptibleBiClosure;
+import org.eclipse.jpt.common.utility.command.Command;
+import org.eclipse.jpt.common.utility.command.InterruptibleCommand;
+import org.eclipse.jpt.common.utility.factory.Factory;
+import org.eclipse.jpt.common.utility.factory.InterruptibleFactory;
+import org.eclipse.jpt.common.utility.internal.ClassTools;
+import org.eclipse.jpt.common.utility.internal.closure.BiClosureAdapter;
+import org.eclipse.jpt.common.utility.internal.closure.BiClosureTools;
+import org.eclipse.jpt.common.utility.internal.closure.BiClosureWrapper;
+import org.eclipse.jpt.common.utility.internal.closure.InterruptibleBiClosureAdapter;
+import org.eclipse.jpt.common.utility.internal.closure.InterruptibleBiClosureWrapper;
+import org.eclipse.jpt.common.utility.internal.closure.ThreadLocalBiClosure;
+import org.eclipse.jpt.common.utility.internal.closure.ThreadLocalInterruptibleBiClosure;
+import org.eclipse.jpt.common.utility.internal.exception.CollectingExceptionHandler;
+import org.eclipse.jpt.common.utility.internal.iterable.IterableTools;
+import org.eclipse.jpt.common.utility.internal.reference.SimpleIntReference;
+import org.eclipse.jpt.common.utility.reference.ModifiableIntReference;
+import org.eclipse.jpt.common.utility.tests.internal.TestTools;
+import org.eclipse.jpt.common.utility.tests.internal.closure.ClosureToolsTests.LocalCommand;
+import org.eclipse.jpt.common.utility.tests.internal.closure.ClosureToolsTests.LocalFactory;
+import org.eclipse.jpt.common.utility.tests.internal.closure.ClosureToolsTests.LocalInterruptibleCommand;
+import org.eclipse.jpt.common.utility.tests.internal.closure.ClosureToolsTests.LocalInterruptibleFactory;
+import junit.framework.TestCase;
+
+@SuppressWarnings("nls")
+public class BiClosureToolsTests
+ extends TestCase
+{
+ public BiClosureToolsTests(String name) {
+ super(name);
+ }
+
+ public void testAdaptCommand_execute() {
+ LocalCommand command = new LocalCommand();
+ BiClosure<Boolean, Boolean> closure = BiClosureTools.adapt(command);
+ closure.execute(Boolean.FALSE, Boolean.TRUE);
+ assertEquals(1, command.count);
+ }
+
+ public void testAdaptCommand_toString() {
+ LocalCommand command = new LocalCommand();
+ BiClosure<Boolean, Boolean> closure = BiClosureTools.adapt(command);
+ assertTrue(closure.toString().indexOf("CommandBiClosure") != -1);
+ assertTrue(closure.toString().indexOf("LocalCommand") != -1);
+ }
+
+ public void testAdaptCommand_NPE() {
+ boolean exCaught = false;
+ try {
+ BiClosure<Boolean, Boolean> closure = BiClosureTools.adapt((Command) null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testAdaptInterruptibleCommand_execute() throws Exception {
+ LocalInterruptibleCommand command = new LocalInterruptibleCommand();
+ InterruptibleBiClosure<Boolean, Boolean> closure = BiClosureTools.adapt(command);
+ closure.execute(Boolean.FALSE, Boolean.TRUE);
+ assertEquals(1, command.count);
+ }
+
+ public void testAdaptInterruptibleCommand_toString() throws Exception {
+ LocalInterruptibleCommand command = new LocalInterruptibleCommand();
+ InterruptibleBiClosure<Boolean, Boolean> closure = BiClosureTools.adapt(command);
+ assertTrue(closure.toString().indexOf("InterruptibleCommandBiClosure") != -1);
+ assertTrue(closure.toString().indexOf("LocalInterruptibleCommand") != -1);
+ }
+
+ public void testAdaptInterruptibleCommand_NPE() {
+ boolean exCaught = false;
+ try {
+ InterruptibleBiClosure<Boolean, Boolean> closure = BiClosureTools.adapt((InterruptibleCommand) null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testAdaptFactory_execute() throws Exception {
+ LocalFactory<Boolean> factory = new LocalFactory<>();
+ BiClosure<Boolean, Boolean> closure = BiClosureTools.adapt(factory);
+ closure.execute(Boolean.FALSE, Boolean.TRUE);
+ assertEquals(1, factory.count);
+ }
+
+ public void testAdaptFactory_toString() throws Exception {
+ LocalFactory<Boolean> factory = new LocalFactory<>();
+ BiClosure<Boolean, Boolean> closure = BiClosureTools.adapt(factory);
+ assertTrue(closure.toString().indexOf("FactoryBiClosure") != -1);
+ assertTrue(closure.toString().indexOf("LocalFactory") != -1);
+ }
+
+ public void testAdaptFactory_NPE() {
+ boolean exCaught = false;
+ try {
+ BiClosure<Boolean, Boolean> closure = BiClosureTools.adapt((Factory<Boolean>) null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testAdaptInterruptibleFactory_execute() throws Exception {
+ LocalInterruptibleFactory<Boolean> factory = new LocalInterruptibleFactory<>();
+ InterruptibleBiClosure<Boolean, Boolean> closure = BiClosureTools.adapt(factory);
+ closure.execute(Boolean.FALSE, Boolean.TRUE);
+ assertEquals(1, factory.count);
+ }
+
+ public void testAdaptInterruptibleFactory_toString() throws Exception {
+ LocalInterruptibleFactory<Boolean> factory = new LocalInterruptibleFactory<>();
+ InterruptibleBiClosure<Boolean, Boolean> closure = BiClosureTools.adapt(factory);
+ assertTrue(closure.toString().indexOf("InterruptibleFactoryBiClosure") != -1);
+ assertTrue(closure.toString().indexOf("LocalInterruptibleFactory") != -1);
+ }
+
+ public void testAdaptInterruptibleFactory_NPE() {
+ boolean exCaught = false;
+ try {
+ InterruptibleBiClosure<Boolean, Boolean> closure = BiClosureTools.adapt((InterruptibleFactory<Boolean>) null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testNullBiClosure_execute() throws Exception {
+ BiClosure<Boolean, Object> closure = BiClosureTools.nullBiClosure();
+ closure.execute(Boolean.FALSE, null);
+ assertNotNull(closure);
+ }
+
+ public void testNullBiClosure_toString() throws Exception {
+ BiClosure<Boolean, Object> closure = BiClosureTools.nullBiClosure();
+ assertTrue(closure.toString().indexOf("NullBiClosure") != -1);
+ }
+
+ public void testNullBiClosure_serialization() throws Exception {
+ BiClosure<Boolean, Object> closure = BiClosureTools.nullBiClosure();
+ Object clone = TestTools.serialize(closure);
+ assertSame(closure, clone);
+ }
+
+ public void testThreadLocalBiClosure_execute() throws Exception {
+ final ModifiableIntReference ref = new SimpleIntReference();
+ final ThreadLocalBiClosure<Integer, Integer> closure = BiClosureTools.threadLocalBiClosure();
+ closure.execute(Integer.valueOf(3), Integer.valueOf(2));
+ assertEquals(0, ref.getValue());
+ Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ closure.set(new BiClosureAdapter<Integer, Integer>() {
+ @Override
+ public void execute(Integer integer1, Integer integer2) {
+ ref.add(integer1.intValue());
+ ref.add(integer2.intValue());
+ }
+ });
+ closure.execute(Integer.valueOf(3), Integer.valueOf(2));
+ }
+ };
+ Thread thread = new Thread(r);
+ thread.start();
+ thread.join();
+ assertEquals(5, ref.getValue());
+ }
+
+ public void testThreadLocalBiClosure_toString() {
+ ThreadLocalBiClosure<Boolean, Boolean> closure = BiClosureTools.threadLocalBiClosure();
+ assertTrue(closure.toString().indexOf("NullBiClosure") != -1);
+ }
+
+ public void testThreadLocalBiClosure_NPE() {
+ boolean exCaught = false;
+ try {
+ ThreadLocalBiClosure<Boolean, Boolean> closure = BiClosureTools.threadLocalBiClosure(null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testThreadLocalInterruptibleBiClosure_execute() throws Exception {
+ final ModifiableIntReference ref = new SimpleIntReference();
+ final ThreadLocalInterruptibleBiClosure<Integer, Integer> closure = BiClosureTools.threadLocalInterruptibleBiClosure();
+ closure.execute(Integer.valueOf(3), Integer.valueOf(2));
+ assertEquals(0, ref.getValue());
+ Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ closure.set(new BiClosureAdapter<Integer, Integer>() {
+ @Override
+ public void execute(Integer integer1, Integer integer2) {
+ ref.add(integer1.intValue());
+ ref.add(integer2.intValue());
+ }
+ });
+ try {
+ closure.execute(Integer.valueOf(3), Integer.valueOf(2));
+ } catch (InterruptedException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ };
+ Thread thread = new Thread(r);
+ thread.start();
+ thread.join();
+ assertEquals(5, ref.getValue());
+ }
+
+ public void testThreadLocalInterruptibleBiClosure_toString() {
+ ThreadLocalInterruptibleBiClosure<Boolean, Boolean> closure = BiClosureTools.threadLocalInterruptibleBiClosure();
+ assertTrue(closure.toString().indexOf("NullBiClosure") != -1);
+ }
+
+ public void testThreadLocalInterruptibleBiClosure_NPE() {
+ boolean exCaught = false;
+ try {
+ ThreadLocalInterruptibleBiClosure<Boolean, Boolean> closure = BiClosureTools.threadLocalInterruptibleBiClosure(null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testWrap_execute() throws Exception {
+ final ModifiableIntReference ref = new SimpleIntReference();
+ BiClosureWrapper<Integer, Integer> closure = BiClosureTools.wrap(new BiClosureAdapter<Integer, Integer>() {
+ @Override
+ public void execute(Integer argument1, Integer argument2) {
+ ref.add(argument1.intValue());
+ ref.add(argument2.intValue());
+ }
+ });
+ closure.execute(Integer.valueOf(3), Integer.valueOf(2));
+ assertEquals(5, ref.getValue());
+ closure.setClosure(new BiClosureAdapter<Integer, Integer>() {
+ @Override
+ public void execute(Integer argument1, Integer argument2) {
+ ref.add(2 * argument1.intValue());
+ ref.add(2 * argument2.intValue());
+ }
+ });
+ closure.execute(Integer.valueOf(3), Integer.valueOf(2));
+ assertEquals(15, ref.getValue());
+ }
+
+ public void testWrap_toString() {
+ BiClosureWrapper<Integer, Integer> closure = BiClosureTools.wrap(new BiClosureAdapter<Integer, Integer>() {
+ @Override
+ public void execute(Integer argument1, Integer argument2) {
+ // NOP
+ }
+ });
+ assertTrue(closure.toString().indexOf("BiClosureWrapper") != -1);
+ }
+
+ public void testWrap_NPE1() {
+ boolean exCaught = false;
+ try {
+ BiClosure<Integer, Integer> closure = BiClosureTools.wrap((BiClosure<Integer, Integer>) null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testWrap_NPE2() {
+ BiClosureWrapper<Integer, Integer> closure = BiClosureTools.wrap(new BiClosureAdapter<Integer, Integer>());
+ boolean exCaught = false;
+ try {
+ closure.setClosure(null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testWrapInterruptible_execute() throws Exception {
+ final ModifiableIntReference ref = new SimpleIntReference();
+ InterruptibleBiClosureWrapper<Integer, Integer> closure = BiClosureTools.wrap(new InterruptibleBiClosureAdapter<Integer, Integer>() {
+ @Override
+ public void execute(Integer argument1, Integer argument2) throws InterruptedException {
+ ref.add(argument1.intValue());
+ ref.add(argument2.intValue());
+ }
+ });
+ closure.execute(Integer.valueOf(3), Integer.valueOf(2));
+ assertEquals(5, ref.getValue());
+ closure.setClosure(new InterruptibleBiClosureAdapter<Integer, Integer>() {
+ @Override
+ public void execute(Integer argument1, Integer argument2) throws InterruptedException {
+ ref.add(2 * argument1.intValue());
+ ref.add(2 * argument2.intValue());
+ }
+ });
+ closure.execute(Integer.valueOf(3), Integer.valueOf(2));
+ assertEquals(15, ref.getValue());
+ }
+
+ public void testWrapInterruptible_toString() {
+ InterruptibleBiClosureWrapper<Integer, Integer> closure = BiClosureTools.wrap(new InterruptibleBiClosureAdapter<Integer, Integer>() {
+ @Override
+ public void execute(Integer argument1, Integer argument2) throws InterruptedException {
+ // NOP
+ }
+ });
+ assertTrue(closure.toString().indexOf("InterruptibleBiClosureWrapper") != -1);
+ }
+
+ public void testWrapInterruptible_NPE1() {
+ boolean exCaught = false;
+ try {
+ InterruptibleBiClosure<Integer, Integer> closure = BiClosureTools.wrap((InterruptibleBiClosure<Integer, Integer>) null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testWrapInterruptible_NPE2() {
+ InterruptibleBiClosureWrapper<Integer, Integer> closure = BiClosureTools.wrap(new InterruptibleBiClosureAdapter<Integer, Integer>());
+ boolean exCaught = false;
+ try {
+ closure.setClosure(null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testSafeClosure_execute() throws Exception {
+ LocalBiClosure closure1 = new LocalBiClosure();
+ BiClosure<Integer, Integer> closure2 = BiClosureTools.safeBiClosure(closure1);
+ closure2.execute(Integer.valueOf(3), Integer.valueOf(2));
+ assertEquals(5, closure1.count);
+ CollectingExceptionHandler handler = new CollectingExceptionHandler();
+ closure2 = BiClosureTools.safeBiClosure(closure1, handler);
+ closure2.execute(null, null);
+ assertEquals(1, IterableTools.size(handler.getExceptions()));
+ }
+
+ public void testSafeBiClosure_toString() {
+ BiClosure<Integer, Integer> closure = BiClosureTools.safeBiClosure(new LocalBiClosure());
+ assertTrue(closure.toString().indexOf("SafeBiClosureWrapper") != -1);
+ assertTrue(closure.toString().indexOf("LocalBiClosure") != -1);
+ }
+
+ public void testSafeBiClosure_NPE1() {
+ boolean exCaught = false;
+ try {
+ BiClosure<Integer, Integer> closure = BiClosureTools.safeBiClosure((BiClosure<Integer, Integer>) null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testSafeBiClosure_NPE2() {
+ boolean exCaught = false;
+ try {
+ BiClosure<Integer, Integer> closure = BiClosureTools.safeBiClosure(new LocalBiClosure(), null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testSafeInterruptibleClosure_execute() throws Exception {
+ LocalInterruptibleBiClosure closure1 = new LocalInterruptibleBiClosure();
+ InterruptibleBiClosure<Integer, Integer> closure2 = BiClosureTools.safeBiClosure(closure1);
+ closure2.execute(Integer.valueOf(3), Integer.valueOf(2));
+ assertEquals(5, closure1.count);
+ CollectingExceptionHandler handler = new CollectingExceptionHandler();
+ closure2 = BiClosureTools.safeBiClosure(closure1, handler);
+ closure2.execute(null, null);
+ assertEquals(1, IterableTools.size(handler.getExceptions()));
+ }
+
+ public void testSafeInterruptibleBiClosure_toString() {
+ InterruptibleBiClosure<Integer, Integer> closure = BiClosureTools.safeBiClosure(new LocalInterruptibleBiClosure());
+ assertTrue(closure.toString().indexOf("SafeInterruptibleBiClosureWrapper") != -1);
+ assertTrue(closure.toString().indexOf("LocalInterruptibleBiClosure") != -1);
+ }
+
+ public void testSafeInterruptibleBiClosure_NPE1() {
+ boolean exCaught = false;
+ try {
+ InterruptibleBiClosure<Integer, Integer> closure = BiClosureTools.safeBiClosure((InterruptibleBiClosure<Integer, Integer>) null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testSafeInterruptibleBiClosure_NPE2() {
+ boolean exCaught = false;
+ try {
+ InterruptibleBiClosure<Integer, Integer> closure = BiClosureTools.safeBiClosure(new LocalInterruptibleBiClosure(), null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testCompositeClosure_execute1() throws Exception {
+ LocalBiClosure closure1 = new LocalBiClosure();
+ LocalBiClosure closure2 = new LocalBiClosure();
+ BiClosure<Integer, Integer> closure = BiClosureTools.compositeBiClosure(closure1, closure2);
+ closure.execute(Integer.valueOf(3), Integer.valueOf(2));
+ assertEquals(5, closure1.count);
+ assertEquals(5, closure2.count);
+ @SuppressWarnings("unchecked")
+ BiClosure<Integer, Integer>[] closureArray = new BiClosure[0];
+ closure = BiClosureTools.compositeBiClosure(closureArray);
+ closure.execute(Integer.valueOf(3), Integer.valueOf(2));
+ }
+
+ public void testCompositeBiClosure_execute2() throws Exception {
+ LocalBiClosure closure1 = new LocalBiClosure();
+ LocalBiClosure closure2 = new LocalBiClosure();
+ ArrayList<LocalBiClosure> list = new ArrayList<>();
+ list.add(closure1);
+ list.add(closure2);
+ BiClosure<Integer, Integer> closure = BiClosureTools.compositeBiClosure(list);
+ closure.execute(Integer.valueOf(3), Integer.valueOf(2));
+ assertEquals(5, closure1.count);
+ assertEquals(5, closure2.count);
+ list.clear();
+ closure = BiClosureTools.compositeBiClosure(list);
+ closure.execute(Integer.valueOf(3), Integer.valueOf(2));
+ }
+
+ public void testCompositeBiClosure_toString() {
+ LocalBiClosure closure1 = new LocalBiClosure();
+ LocalBiClosure closure2 = new LocalBiClosure();
+ BiClosure<Integer, Integer> closure = BiClosureTools.compositeBiClosure(closure1, closure2);
+ assertTrue(closure.toString().indexOf("CompositeBiClosure") != -1);
+ assertTrue(closure.toString().indexOf("LocalBiClosure") != -1);
+ }
+
+ public void testCompositeBiClosure_NPE1() {
+ LocalBiClosure closure1 = new LocalBiClosure();
+ boolean exCaught = false;
+ try {
+ BiClosure<Integer, Integer> closure = BiClosureTools.compositeBiClosure(closure1, null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testCompositeBiClosure_NPE2() {
+ boolean exCaught = false;
+ try {
+ BiClosure<Integer, Integer> closure = BiClosureTools.compositeBiClosure((Iterable<BiClosure<Integer, Integer>>) null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testCompositeInterruptibleClosure_execute1() throws Exception {
+ LocalInterruptibleBiClosure closure1 = new LocalInterruptibleBiClosure();
+ LocalInterruptibleBiClosure closure2 = new LocalInterruptibleBiClosure();
+ InterruptibleBiClosure<Integer, Integer> closure = BiClosureTools.compositeInterruptibleBiClosure(closure1, closure2);
+ closure.execute(Integer.valueOf(3), Integer.valueOf(2));
+ assertEquals(5, closure1.count);
+ assertEquals(5, closure2.count);
+ @SuppressWarnings("unchecked")
+ InterruptibleBiClosure<Integer, Integer>[] closureArray = new InterruptibleBiClosure[0];
+ closure = BiClosureTools.compositeInterruptibleBiClosure(closureArray);
+ closure.execute(Integer.valueOf(3), Integer.valueOf(2));
+ }
+
+ public void testCompositeInterruptibleBiClosure_execute2() throws Exception {
+ LocalInterruptibleBiClosure closure1 = new LocalInterruptibleBiClosure();
+ LocalInterruptibleBiClosure closure2 = new LocalInterruptibleBiClosure();
+ ArrayList<LocalInterruptibleBiClosure> list = new ArrayList<>();
+ list.add(closure1);
+ list.add(closure2);
+ InterruptibleBiClosure<Integer, Integer> closure = BiClosureTools.compositeInterruptibleBiClosure(list);
+ closure.execute(Integer.valueOf(3), Integer.valueOf(2));
+ assertEquals(5, closure1.count);
+ assertEquals(5, closure2.count);
+ list.clear();
+ closure = BiClosureTools.compositeInterruptibleBiClosure(list);
+ closure.execute(Integer.valueOf(3), Integer.valueOf(2));
+ }
+
+ public void testCompositeInterruptibleBiClosure_toString() {
+ LocalInterruptibleBiClosure closure1 = new LocalInterruptibleBiClosure();
+ LocalInterruptibleBiClosure closure2 = new LocalInterruptibleBiClosure();
+ InterruptibleBiClosure<Integer, Integer> closure = BiClosureTools.compositeInterruptibleBiClosure(closure1, closure2);
+ assertTrue(closure.toString().indexOf("CompositeInterruptibleBiClosure") != -1);
+ assertTrue(closure.toString().indexOf("LocalInterruptibleBiClosure") != -1);
+ }
+
+ public void testCompositeInterruptibleBiClosure_NPE1() {
+ LocalInterruptibleBiClosure closure1 = new LocalInterruptibleBiClosure();
+ boolean exCaught = false;
+ try {
+ InterruptibleBiClosure<Integer, Integer> closure = BiClosureTools.compositeInterruptibleBiClosure(closure1, null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testCompositeInterruptibleBiClosure_NPE2() {
+ boolean exCaught = false;
+ try {
+ InterruptibleBiClosure<Integer, Integer> closure = BiClosureTools.compositeInterruptibleBiClosure((Iterable<InterruptibleBiClosure<Integer, Integer>>) null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testDisabledBiClosure_execute() {
+ BiClosure<Integer, Integer> closure = BiClosureTools.disabledBiClosure();
+ boolean exCaught = false;
+ try {
+ closure.execute(null, null);
+ fail();
+ } catch (UnsupportedOperationException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testDisabledBiClosure_toString() {
+ BiClosure<Integer, Integer> closure = BiClosureTools.disabledBiClosure();
+ assertTrue(closure.toString().indexOf("DisabledBiClosure") != -1);
+ }
+
+ public void testDisabledBiClosure_serialization() throws Exception {
+ BiClosure<Integer, Integer> closure = BiClosureTools.disabledBiClosure();
+ assertSame(closure, TestTools.serialize(closure));
+ }
+
+ public void testInterruptedBiClosure_execute() {
+ InterruptibleBiClosure<Integer, Integer> closure = BiClosureTools.interruptedBiClosure();
+ boolean exCaught = false;
+ try {
+ closure.execute(null, null);
+ fail();
+ } catch (InterruptedException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testInterruptedBiClosure_toString() {
+ InterruptibleBiClosure<Integer, Integer> closure = BiClosureTools.interruptedBiClosure();
+ assertTrue(closure.toString().indexOf("InterruptedBiClosure") != -1);
+ }
+
+ public void testInterruptedBiClosure_serialization() throws Exception {
+ InterruptibleBiClosure<Integer, Integer> closure = BiClosureTools.interruptedBiClosure();
+ assertSame(closure, TestTools.serialize(closure));
+ }
+
+ public void testRepeatingBiClosure_execute1() throws Exception {
+ LocalBiClosure closure1 = new LocalBiClosure();
+ BiClosure<Integer, Integer> closure2 = BiClosureTools.repeatingBiClosure(closure1, 3);
+ closure2.execute(Integer.valueOf(3), Integer.valueOf(2));
+ assertEquals(15, closure1.count);
+ }
+
+ public void testRepeatingBiClosure_execute2() throws Exception {
+ LocalBiClosure closure1 = new LocalBiClosure();
+ BiClosure<Integer, Integer> closure2 = BiClosureTools.repeatingBiClosure(closure1, 0);
+ closure2.execute(Integer.valueOf(3), Integer.valueOf(2));
+ assertEquals(0, closure1.count);
+ }
+
+ public void testRepeatingBiClosure_toString() {
+ LocalBiClosure closure1 = new LocalBiClosure();
+ BiClosure<Integer, Integer> closure2 = BiClosureTools.repeatingBiClosure(closure1, 3);
+ assertTrue(closure2.toString().indexOf("RepeatingBiClosure") != -1);
+ assertTrue(closure2.toString().indexOf("LocalBiClosure") != -1);
+ }
+
+ public void testRepeatingBiClosure_NPE1() {
+ boolean exCaught = false;
+ try {
+ BiClosure<Integer, Integer> closure = BiClosureTools.repeatingBiClosure((BiClosure<Integer, Integer>) null, 3);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testRepeatingBiClosure_NPE2() {
+ LocalBiClosure closure1 = new LocalBiClosure();
+ boolean exCaught = false;
+ try {
+ BiClosure<Integer, Integer> closure2 = BiClosureTools.repeatingBiClosure(closure1, -3);
+ fail("bogus: " + closure2);
+ } catch (IndexOutOfBoundsException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testRepeatingInterruptibleBiClosure_execute1() throws Exception {
+ LocalInterruptibleBiClosure closure1 = new LocalInterruptibleBiClosure();
+ InterruptibleBiClosure<Integer, Integer> closure2 = BiClosureTools.repeatingBiClosure(closure1, 3);
+ closure2.execute(Integer.valueOf(3), Integer.valueOf(2));
+ assertEquals(15, closure1.count);
+ }
+
+ public void testRepeatingInterruptibleBiClosure_execute2() throws Exception {
+ LocalInterruptibleBiClosure closure1 = new LocalInterruptibleBiClosure();
+ InterruptibleBiClosure<Integer, Integer> closure2 = BiClosureTools.repeatingBiClosure(closure1, 0);
+ closure2.execute(Integer.valueOf(3), Integer.valueOf(2));
+ assertEquals(0, closure1.count);
+ }
+
+ public void testRepeatingInterruptibleBiClosure_toString() {
+ LocalInterruptibleBiClosure closure1 = new LocalInterruptibleBiClosure();
+ InterruptibleBiClosure<Integer, Integer> closure2 = BiClosureTools.repeatingBiClosure(closure1, 3);
+ assertTrue(closure2.toString().indexOf("RepeatingInterruptibleBiClosure") != -1);
+ assertTrue(closure2.toString().indexOf("LocalInterruptibleBiClosure") != -1);
+ }
+
+ public void testRepeatingInterruptibleBiClosure_NPE1() {
+ boolean exCaught = false;
+ try {
+ InterruptibleBiClosure<Integer, Integer> closure = BiClosureTools.repeatingBiClosure((InterruptibleBiClosure<Integer, Integer>) null, 3);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testRepeatingInterruptibleBiClosure_NPE2() {
+ LocalInterruptibleBiClosure closure1 = new LocalInterruptibleBiClosure();
+ boolean exCaught = false;
+ try {
+ InterruptibleBiClosure<Integer, Integer> closure2 = BiClosureTools.repeatingBiClosure(closure1, -3);
+ fail("bogus: " + closure2);
+ } catch (IndexOutOfBoundsException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testConstructor() {
+ boolean exCaught = false;
+ try {
+ Object at = ClassTools.newInstance(BiClosureTools.class);
+ fail("bogus: " + at);
+ } catch (RuntimeException ex) {
+ if (ex.getCause() instanceof InvocationTargetException) {
+ if (ex.getCause().getCause() instanceof UnsupportedOperationException) {
+ exCaught = true;
+ }
+ }
+ }
+ assertTrue(exCaught);
+ }
+
+ // ********** test classes **********
+
+ public static class LocalBiClosure
+ extends BiClosureAdapter<Integer, Integer>
+ {
+ public int count = 0;
+
+ @Override
+ public void execute(Integer argument1, Integer argument2) {
+ this.count += argument1.intValue(); // possible NPE
+ this.count += argument2.intValue(); // possible NPE
+ }
+ }
+
+ public static class LocalInterruptibleBiClosure
+ extends InterruptibleBiClosureAdapter<Integer, Integer>
+ {
+ public int count = 0;
+
+ @Override
+ public void execute(Integer argument1, Integer argument2) throws InterruptedException {
+ this.count += argument1.intValue(); // possible NPE
+ this.count += argument2.intValue(); // possible NPE
+ }
+ }
+}
diff --git a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/closure/ClosureToolsTests.java b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/closure/ClosureToolsTests.java
new file mode 100644
index 0000000000..242d28fa84
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/closure/ClosureToolsTests.java
@@ -0,0 +1,1854 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.tests.internal.closure;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.jpt.common.utility.Association;
+import org.eclipse.jpt.common.utility.closure.Closure;
+import org.eclipse.jpt.common.utility.closure.InterruptibleClosure;
+import org.eclipse.jpt.common.utility.command.Command;
+import org.eclipse.jpt.common.utility.command.InterruptibleCommand;
+import org.eclipse.jpt.common.utility.factory.Factory;
+import org.eclipse.jpt.common.utility.factory.InterruptibleFactory;
+import org.eclipse.jpt.common.utility.internal.ClassTools;
+import org.eclipse.jpt.common.utility.internal.SimpleAssociation;
+import org.eclipse.jpt.common.utility.internal.closure.ClosureAdapter;
+import org.eclipse.jpt.common.utility.internal.closure.ClosureTools;
+import org.eclipse.jpt.common.utility.internal.closure.ClosureWrapper;
+import org.eclipse.jpt.common.utility.internal.closure.InterruptibleClosureAdapter;
+import org.eclipse.jpt.common.utility.internal.closure.InterruptibleClosureWrapper;
+import org.eclipse.jpt.common.utility.internal.closure.ThreadLocalClosure;
+import org.eclipse.jpt.common.utility.internal.closure.ThreadLocalInterruptibleClosure;
+import org.eclipse.jpt.common.utility.internal.command.CommandAdapter;
+import org.eclipse.jpt.common.utility.internal.command.CommandTools;
+import org.eclipse.jpt.common.utility.internal.command.InterruptibleCommandAdapter;
+import org.eclipse.jpt.common.utility.internal.exception.CollectingExceptionHandler;
+import org.eclipse.jpt.common.utility.internal.factory.FactoryAdapter;
+import org.eclipse.jpt.common.utility.internal.factory.InterruptibleFactoryAdapter;
+import org.eclipse.jpt.common.utility.internal.iterable.IterableTools;
+import org.eclipse.jpt.common.utility.internal.predicate.PredicateAdapter;
+import org.eclipse.jpt.common.utility.internal.predicate.PredicateTools;
+import org.eclipse.jpt.common.utility.internal.reference.SimpleIntReference;
+import org.eclipse.jpt.common.utility.internal.transformer.InterruptibleTransformerAdapter;
+import org.eclipse.jpt.common.utility.internal.transformer.TransformerAdapter;
+import org.eclipse.jpt.common.utility.predicate.Predicate;
+import org.eclipse.jpt.common.utility.reference.ModifiableIntReference;
+import org.eclipse.jpt.common.utility.tests.internal.TestTools;
+import org.eclipse.jpt.common.utility.transformer.InterruptibleTransformer;
+import org.eclipse.jpt.common.utility.transformer.Transformer;
+import junit.framework.TestCase;
+
+@SuppressWarnings("nls")
+public class ClosureToolsTests
+ extends TestCase
+{
+ public ClosureToolsTests(String name) {
+ super(name);
+ }
+
+ public void testAdaptCommand_execute() {
+ LocalCommand command = new LocalCommand();
+ Closure<Boolean> closure = ClosureTools.adapt(command);
+ closure.execute(Boolean.FALSE);
+ assertEquals(1, command.count);
+ }
+
+ public void testAdaptCommand_toString() {
+ LocalCommand command = new LocalCommand();
+ Closure<Boolean> closure = ClosureTools.adapt(command);
+ assertTrue(closure.toString().indexOf("CommandClosure") != -1);
+ assertTrue(closure.toString().indexOf("LocalCommand") != -1);
+ }
+
+ public void testAdaptCommand_NPE() {
+ boolean exCaught = false;
+ try {
+ Closure<Boolean> closure = ClosureTools.adapt((Command) null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testAdaptInterruptibleCommand_execute() throws Exception {
+ LocalInterruptibleCommand command = new LocalInterruptibleCommand();
+ InterruptibleClosure<Boolean> closure = ClosureTools.adapt(command);
+ closure.execute(Boolean.FALSE);
+ assertEquals(1, command.count);
+ }
+
+ public void testAdaptInterruptibleCommand_toString() {
+ LocalInterruptibleCommand command = new LocalInterruptibleCommand();
+ InterruptibleClosure<Boolean> closure = ClosureTools.adapt(command);
+ assertTrue(closure.toString().indexOf("InterruptibleCommandClosure") != -1);
+ assertTrue(closure.toString().indexOf("LocalInterruptibleCommand") != -1);
+ }
+
+ public void testAdaptInterruptibleCommand_NPE() {
+ boolean exCaught = false;
+ try {
+ InterruptibleClosure<Boolean> closure = ClosureTools.adapt((InterruptibleCommand) null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testAdaptFactory_execute() {
+ LocalFactory<?> factory = new LocalFactory<>();
+ Closure<Boolean> closure = ClosureTools.adapt(factory);
+ closure.execute(Boolean.FALSE);
+ assertEquals(1, factory.count);
+ }
+
+ public void testAdaptFactory_toString() {
+ LocalFactory<?> factory = new LocalFactory<>();
+ Closure<Boolean> closure = ClosureTools.adapt(factory);
+ assertTrue(closure.toString().indexOf("FactoryClosure") != -1);
+ assertTrue(closure.toString().indexOf("LocalFactory") != -1);
+ }
+
+ public void testAdaptFactory_NPE() {
+ boolean exCaught = false;
+ try {
+ Closure<Boolean> closure = ClosureTools.adapt((Factory<?>) null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testAdaptInterruptibleFactory_execute() throws Exception {
+ LocalInterruptibleFactory<?> factory = new LocalInterruptibleFactory<>();
+ InterruptibleClosure<Boolean> closure = ClosureTools.adapt(factory);
+ closure.execute(Boolean.FALSE);
+ assertEquals(1, factory.count);
+ }
+
+ public void testAdaptInterruptibleFactory_toString() {
+ LocalInterruptibleFactory<?> factory = new LocalInterruptibleFactory<>();
+ InterruptibleClosure<Boolean> closure = ClosureTools.adapt(factory);
+ assertTrue(closure.toString().indexOf("InterruptibleFactoryClosure") != -1);
+ assertTrue(closure.toString().indexOf("LocalInterruptibleFactory") != -1);
+ }
+
+ public void testAdaptInterruptibleFactory_NPE() {
+ boolean exCaught = false;
+ try {
+ InterruptibleClosure<Boolean> closure = ClosureTools.adapt((InterruptibleFactory<?>) null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testAdaptTransformer_execute() {
+ LocalTransformer<Boolean, ?> transformer = new LocalTransformer<>();
+ Closure<Boolean> closure = ClosureTools.adapt(transformer);
+ closure.execute(Boolean.FALSE);
+ assertEquals(1, transformer.count);
+ }
+
+ public void testAdaptTransformer_toString() {
+ LocalTransformer<Boolean, ?> transformer = new LocalTransformer<>();
+ Closure<Boolean> closure = ClosureTools.adapt(transformer);
+ assertTrue(closure.toString().indexOf("TransformerClosure") != -1);
+ assertTrue(closure.toString().indexOf("LocalTransformer") != -1);
+ }
+
+ public void testAdaptTransformer_NPE() {
+ boolean exCaught = false;
+ try {
+ Closure<Boolean> closure = ClosureTools.adapt((Transformer<Boolean, ?>) null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testAdaptInterruptibleTransformer_execute() throws Exception {
+ LocalInterruptibleTransformer<Boolean, ?> transformer = new LocalInterruptibleTransformer<>();
+ InterruptibleClosure<Boolean> closure = ClosureTools.adapt(transformer);
+ closure.execute(Boolean.FALSE);
+ assertEquals(1, transformer.count);
+ }
+
+ public void testAdaptInterruptibleTransformer_toString() {
+ LocalInterruptibleTransformer<Boolean, ?> transformer = new LocalInterruptibleTransformer<>();
+ InterruptibleClosure<Boolean> closure = ClosureTools.adapt(transformer);
+ assertTrue(closure.toString().indexOf("InterruptibleTransformerClosure") != -1);
+ assertTrue(closure.toString().indexOf("LocalInterruptibleTransformer") != -1);
+ }
+
+ public void testAdaptInterruptibleTransformer_NPE() {
+ boolean exCaught = false;
+ try {
+ InterruptibleClosure<Boolean> closure = ClosureTools.adapt((InterruptibleTransformer<Boolean, ?>) null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testNullClosure_execute() throws Exception {
+ Closure<Boolean> closure = ClosureTools.nullClosure();
+ closure.execute(Boolean.FALSE);
+ assertNotNull(closure);
+ }
+
+ public void testNullClosure_toString() throws Exception {
+ Closure<Boolean> closure = ClosureTools.nullClosure();
+ assertTrue(closure.toString().indexOf("NullClosure") != -1);
+ }
+
+ public void testNullClosure_serialization() throws Exception {
+ Closure<Boolean> closure = ClosureTools.nullClosure();
+ Object clone = TestTools.serialize(closure);
+ assertSame(closure, clone);
+ }
+
+ public void testThreadLocalClosure_execute() throws Exception {
+ final ModifiableIntReference ref = new SimpleIntReference();
+ final ThreadLocalClosure<Integer> closure = ClosureTools.threadLocalClosure();
+ closure.execute(Integer.valueOf(3));
+ assertEquals(0, ref.getValue());
+ Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ closure.set(new ClosureAdapter<Integer>() {
+ @Override
+ public void execute(Integer integer) {
+ ref.add(integer.intValue());
+ }
+ });
+ closure.execute(Integer.valueOf(3));
+ }
+ };
+ Thread thread = new Thread(r);
+ thread.start();
+ thread.join();
+ assertEquals(3, ref.getValue());
+ }
+
+ public void testThreadLocalClosure_toString() {
+ ThreadLocalClosure<Boolean> closure = ClosureTools.threadLocalClosure();
+ assertTrue(closure.toString().indexOf("NullClosure") != -1);
+ }
+
+ public void testThreadLocalClosure_NPE() {
+ boolean exCaught = false;
+ try {
+ ThreadLocalClosure<Boolean> closure = ClosureTools.threadLocalClosure(null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testThreadLocalInterruptibleClosure_execute() throws Exception {
+ final ModifiableIntReference ref = new SimpleIntReference();
+ final ThreadLocalInterruptibleClosure<Integer> closure = ClosureTools.threadLocalInterruptibleClosure();
+ closure.execute(Integer.valueOf(3));
+ assertEquals(0, ref.getValue());
+ Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ closure.set(new ClosureAdapter<Integer>() {
+ @Override
+ public void execute(Integer integer) {
+ ref.add(integer.intValue());
+ }
+ });
+ try {
+ closure.execute(Integer.valueOf(3));
+ } catch (InterruptedException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ };
+ Thread thread = new Thread(r);
+ thread.start();
+ thread.join();
+ assertEquals(3, ref.getValue());
+ }
+
+ public void testThreadLocalInterruptibleClosure_toString() {
+ ThreadLocalInterruptibleClosure<Boolean> closure = ClosureTools.threadLocalInterruptibleClosure();
+ assertTrue(closure.toString().indexOf("NullClosure") != -1);
+ }
+
+ public void testThreadLocalInterruptibleClosure_NPE() {
+ boolean exCaught = false;
+ try {
+ ThreadLocalInterruptibleClosure<Boolean> closure = ClosureTools.threadLocalInterruptibleClosure(null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testNullCheck_execute() throws Exception {
+ LocalClosure closure1 = new LocalClosure();
+ Closure<Integer> closure2 = ClosureTools.nullCheck(closure1);
+ closure2.execute(null);
+ assertEquals(0, closure1.count);
+ closure2.execute(Integer.valueOf(3));
+ assertEquals(3, closure1.count);
+ }
+
+ public void testNullCheck_toString() {
+ Closure<Integer> closure1 = new LocalClosure();
+ Closure<Integer> closure2 = ClosureTools.nullCheck(closure1);
+ assertTrue(closure2.toString().indexOf("NullCheckClosure") != -1);
+ assertTrue(closure2.toString().indexOf("LocalClosure") != -1);
+ }
+
+ public void testNullCheck_NPE1() {
+ boolean exCaught = false;
+ try {
+ Closure<Integer> closure = ClosureTools.nullCheck((Closure<Integer>) null, CommandTools.nullCommand());
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testNullCheck_NPE2() {
+ Closure<Integer> closure1 = new LocalClosure();
+ boolean exCaught = false;
+ try {
+ Closure<Integer> closure2 = ClosureTools.nullCheck(closure1, null);
+ fail("bogus: " + closure2);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testNullCheckInterruptible_execute() throws Exception {
+ LocalInterruptibleClosure closure1 = new LocalInterruptibleClosure();
+ InterruptibleClosure<Integer> closure2 = ClosureTools.nullCheck(closure1);
+ closure2.execute(null);
+ assertEquals(0, closure1.count);
+ closure2.execute(Integer.valueOf(3));
+ assertEquals(3, closure1.count);
+ }
+
+ public void testNullCheckInterruptible_toString() {
+ InterruptibleClosure<Integer> closure1 = new LocalInterruptibleClosure();
+ InterruptibleClosure<Integer> closure2 = ClosureTools.nullCheck(closure1);
+ assertTrue(closure2.toString().indexOf("NullCheckInterruptibleClosure") != -1);
+ assertTrue(closure2.toString().indexOf("LocalInterruptibleClosure") != -1);
+ }
+
+ public void testNullCheckInterruptible_NPE1() {
+ boolean exCaught = false;
+ try {
+ InterruptibleClosure<Integer> closure = ClosureTools.nullCheck((InterruptibleClosure<Integer>) null, CommandTools.nullCommand());
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testNullCheckInterruptible_NPE2() {
+ InterruptibleClosure<Integer> closure1 = new LocalInterruptibleClosure();
+ boolean exCaught = false;
+ try {
+ InterruptibleClosure<Integer> closure2 = ClosureTools.nullCheck(closure1, null);
+ fail("bogus: " + closure2);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testWrap_execute() throws Exception {
+ final ModifiableIntReference ref = new SimpleIntReference();
+ ClosureWrapper<Integer> closure = ClosureTools.wrap(new ClosureAdapter<Integer>() {
+ @Override
+ public void execute(Integer argument) {
+ ref.add(argument.intValue());
+ }
+ });
+ closure.execute(Integer.valueOf(3));
+ assertEquals(3, ref.getValue());
+ closure.setClosure(new ClosureAdapter<Integer>() {
+ @Override
+ public void execute(Integer argument) {
+ ref.add(2 * argument.intValue());
+ }
+ });
+ closure.execute(Integer.valueOf(3));
+ assertEquals(9, ref.getValue());
+ }
+
+ public void testWrap_toString() {
+ ClosureWrapper<Integer> closure = ClosureTools.wrap(new ClosureAdapter<Integer>() {
+ @Override
+ public void execute(Integer argument) {
+ // NOP
+ }
+ });
+ assertTrue(closure.toString().indexOf("ClosureWrapper") != -1);
+ }
+
+ public void testWrap_NPE1() {
+ boolean exCaught = false;
+ try {
+ Closure<Integer> closure = ClosureTools.wrap((Closure<Integer>) null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testWrap_NPE2() {
+ ClosureWrapper<Integer> closure = ClosureTools.wrap(new LocalClosure());
+ boolean exCaught = false;
+ try {
+ closure.setClosure(null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testWrapInterruptible_execute() throws Exception {
+ final ModifiableIntReference ref = new SimpleIntReference();
+ InterruptibleClosureWrapper<Integer> closure = ClosureTools.wrap(new InterruptibleClosureAdapter<Integer>() {
+ @Override
+ public void execute(Integer argument) throws InterruptedException {
+ ref.add(argument.intValue());
+ }
+ });
+ closure.execute(Integer.valueOf(3));
+ assertEquals(3, ref.getValue());
+ closure.setClosure(new InterruptibleClosureAdapter<Integer>() {
+ @Override
+ public void execute(Integer argument) throws InterruptedException {
+ ref.add(2 * argument.intValue());
+ }
+ });
+ closure.execute(Integer.valueOf(3));
+ assertEquals(9, ref.getValue());
+ }
+
+ public void testWrapInterruptible_toString() {
+ InterruptibleClosureWrapper<Integer> closure = ClosureTools.wrap(new InterruptibleClosureAdapter<Integer>() {
+ @Override
+ public void execute(Integer argument) throws InterruptedException {
+ // NOP
+ }
+ });
+ assertTrue(closure.toString().indexOf("InterruptibleClosureWrapper") != -1);
+ }
+
+ public void testWrapInterruptible_NPE1() {
+ boolean exCaught = false;
+ try {
+ InterruptibleClosure<Integer> closure = ClosureTools.wrap((InterruptibleClosure<Integer>) null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testWrapInterruptible_NPE2() {
+ InterruptibleClosureWrapper<Integer> closure = ClosureTools.wrap(new LocalInterruptibleClosure());
+ boolean exCaught = false;
+ try {
+ closure.setClosure(null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testSafeClosure_execute() throws Exception {
+ LocalClosure closure1 = new LocalClosure();
+ Closure<Integer> closure2 = ClosureTools.safeClosure(closure1);
+ closure2.execute(Integer.valueOf(3));
+ assertEquals(3, closure1.count);
+ CollectingExceptionHandler handler = new CollectingExceptionHandler();
+ closure2 = ClosureTools.safeClosure(closure1, handler);
+ closure2.execute(null);
+ assertEquals(1, IterableTools.size(handler.getExceptions()));
+ }
+
+ public void testSafeClosure_toString() {
+ Closure<Integer> closure = ClosureTools.safeClosure(new LocalClosure());
+ assertTrue(closure.toString().indexOf("SafeClosureWrapper") != -1);
+ assertTrue(closure.toString().indexOf("LocalClosure") != -1);
+ }
+
+ public void testSafeClosure_NPE1() {
+ boolean exCaught = false;
+ try {
+ Closure<Integer> closure = ClosureTools.safeClosure((Closure<Integer>) null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testSafeClosure_NPE2() {
+ boolean exCaught = false;
+ try {
+ Closure<Integer> closure = ClosureTools.safeClosure(new LocalClosure(), null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testSafeInterruptibleClosure_execute() throws Exception {
+ LocalInterruptibleClosure closure1 = new LocalInterruptibleClosure();
+ InterruptibleClosure<Integer> closure2 = ClosureTools.safeClosure(closure1);
+ closure2.execute(Integer.valueOf(3));
+ assertEquals(3, closure1.count);
+ CollectingExceptionHandler handler = new CollectingExceptionHandler();
+ closure2 = ClosureTools.safeClosure(closure1, handler);
+ closure2.execute(null);
+ assertEquals(1, IterableTools.size(handler.getExceptions()));
+ }
+
+ public void testSafeInterruptibleClosure_toString() {
+ InterruptibleClosure<Integer> closure = ClosureTools.safeClosure(new LocalInterruptibleClosure());
+ assertTrue(closure.toString().indexOf("SafeInterruptibleClosureWrapper") != -1);
+ assertTrue(closure.toString().indexOf("LocalInterruptibleClosure") != -1);
+ }
+
+ public void testSafeInterruptibleClosure_NPE1() {
+ boolean exCaught = false;
+ try {
+ InterruptibleClosure<Integer> closure = ClosureTools.safeClosure((InterruptibleClosure<Integer>) null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testSafeInterruptibleClosure_NPE2() {
+ boolean exCaught = false;
+ try {
+ InterruptibleClosure<Integer> closure = ClosureTools.safeClosure(new LocalInterruptibleClosure(), null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testMethodClosure_execute() throws Exception {
+ Closure<Object> closure = ClosureTools.methodClosure("execute");
+ LocalCommand cmd = new LocalCommand();
+ assertEquals(0, cmd.count);
+ closure.execute(cmd);
+ assertEquals(1, cmd.count);
+ }
+
+ public void testMethodClosure_execute_arg() throws Exception {
+ LocalCommand cmd = new LocalCommand();
+ Closure<Object> closure = ClosureTools.methodClosure("equals", Object.class, cmd);
+ assertEquals(0, cmd.count);
+ closure.execute(cmd);
+ assertEquals(0, cmd.count);
+ }
+
+ public void testMethodClosure_equals() throws Exception {
+ Closure<Object> closure1 = ClosureTools.methodClosure("equals", Object.class, "foo");
+ Closure<Object> closure2 = ClosureTools.methodClosure("equals", Object.class, "foo");
+ assertFalse(closure1.equals(null));
+ assertFalse(closure1.equals("foo"));
+ assertTrue(closure1.equals(closure1));
+ assertTrue(closure1.equals(closure2));
+ closure2 = ClosureTools.methodClosure("equals", Object.class, "bar");
+ assertFalse(closure1.equals(closure2));
+ closure2 = ClosureTools.methodClosure("equals", String.class, "foo");
+ assertFalse(closure1.equals(closure2));
+ closure2 = ClosureTools.methodClosure("toString", Object.class, "foo");
+ assertFalse(closure1.equals(closure2));
+ }
+
+ public void testMethodClosure_hashCode() throws Exception {
+ Closure<Object> closure1 = ClosureTools.methodClosure("equals", Object.class, "foo");
+ Closure<Object> closure2 = ClosureTools.methodClosure("equals", Object.class, "foo");
+ assertEquals(closure1.hashCode(), closure1.hashCode());
+ assertEquals(closure1.hashCode(), closure2.hashCode());
+ }
+
+ public void testMethodClosure_toString() {
+ Closure<Object> closure = ClosureTools.methodClosure("execute");
+ assertTrue(closure.toString().indexOf("MethodClosure") != -1);
+ assertTrue(closure.toString().indexOf("execute()") != -1);
+ }
+
+ public void testMethodClosure_NPE1() {
+ boolean exCaught = false;
+ try {
+ Closure<Object> closure = ClosureTools.methodClosure(null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testMethodClosure_NPE2() {
+ boolean exCaught = false;
+ try {
+ Closure<Object> closure = ClosureTools.methodClosure("execute", (Class[]) null, new Object[0]);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testMethodClosure_NPE2a() {
+ boolean exCaught = false;
+ try {
+ Closure<Object> closure = ClosureTools.methodClosure("execute", new Class[] {Object.class, null}, new Object[2]);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testMethodClosure_NPE3() {
+ boolean exCaught = false;
+ try {
+ Closure<Object> closure = ClosureTools.methodClosure("execute", new Class[0], null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testCompositeClosure_execute1() throws Exception {
+ LocalClosure closure1 = new LocalClosure();
+ LocalClosure closure2 = new LocalClosure();
+ Closure<Integer> closure = ClosureTools.compositeClosure(closure1, closure2);
+ closure.execute(Integer.valueOf(3));
+ assertEquals(3, closure1.count);
+ assertEquals(3, closure2.count);
+ @SuppressWarnings("unchecked")
+ Closure<Integer>[] closureArray = new Closure[0];
+ closure = ClosureTools.compositeClosure(closureArray);
+ closure.execute(Integer.valueOf(3));
+ }
+
+ public void testCompositeClosure_execute2() throws Exception {
+ LocalClosure closure1 = new LocalClosure();
+ LocalClosure closure2 = new LocalClosure();
+ ArrayList<LocalClosure> list = new ArrayList<>();
+ list.add(closure1);
+ list.add(closure2);
+ Closure<Integer> closure = ClosureTools.compositeClosure(list);
+ closure.execute(Integer.valueOf(3));
+ assertEquals(3, closure1.count);
+ assertEquals(3, closure2.count);
+ list.clear();
+ closure = ClosureTools.compositeClosure(list);
+ closure.execute(Integer.valueOf(3));
+ }
+
+ public void testCompositeClosure_toString() {
+ LocalClosure closure1 = new LocalClosure();
+ LocalClosure closure2 = new LocalClosure();
+ Closure<Integer> closure = ClosureTools.compositeClosure(closure1, closure2);
+ assertTrue(closure.toString().indexOf("CompositeClosure") != -1);
+ assertTrue(closure.toString().indexOf("LocalClosure") != -1);
+ }
+
+ public void testCompositeClosure_NPE1() {
+ LocalClosure closure1 = new LocalClosure();
+ boolean exCaught = false;
+ try {
+ Closure<Integer> closure = ClosureTools.compositeClosure(closure1, null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testCompositeClosure_NPE2() {
+ boolean exCaught = false;
+ try {
+ Closure<Integer> closure = ClosureTools.compositeClosure((Iterable<Closure<Integer>>) null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testCompositeInterruptibleClosure_execute1() throws Exception {
+ LocalInterruptibleClosure closure1 = new LocalInterruptibleClosure();
+ LocalInterruptibleClosure closure2 = new LocalInterruptibleClosure();
+ InterruptibleClosure<Integer> closure = ClosureTools.compositeInterruptibleClosure(closure1, closure2);
+ closure.execute(Integer.valueOf(3));
+ assertEquals(3, closure1.count);
+ assertEquals(3, closure2.count);
+ @SuppressWarnings("unchecked")
+ InterruptibleClosure<Integer>[] closureArray = new InterruptibleClosure[0];
+ closure = ClosureTools.compositeInterruptibleClosure(closureArray);
+ closure.execute(Integer.valueOf(3));
+ }
+
+ public void testCompositeInterruptibleClosure_execute2() throws Exception {
+ LocalInterruptibleClosure closure1 = new LocalInterruptibleClosure();
+ LocalInterruptibleClosure closure2 = new LocalInterruptibleClosure();
+ ArrayList<LocalInterruptibleClosure> list = new ArrayList<>();
+ list.add(closure1);
+ list.add(closure2);
+ InterruptibleClosure<Integer> closure = ClosureTools.compositeInterruptibleClosure(list);
+ closure.execute(Integer.valueOf(3));
+ assertEquals(3, closure1.count);
+ assertEquals(3, closure2.count);
+ list.clear();
+ closure = ClosureTools.compositeInterruptibleClosure(list);
+ closure.execute(Integer.valueOf(3));
+ }
+
+ public void testCompositeInterruptibleClosure_toString() {
+ LocalInterruptibleClosure closure1 = new LocalInterruptibleClosure();
+ LocalInterruptibleClosure closure2 = new LocalInterruptibleClosure();
+ InterruptibleClosure<Integer> closure = ClosureTools.compositeInterruptibleClosure(closure1, closure2);
+ assertTrue(closure.toString().indexOf("CompositeInterruptibleClosure") != -1);
+ assertTrue(closure.toString().indexOf("LocalInterruptibleClosure") != -1);
+ }
+
+ public void testCompositeInterruptibleClosure_NPE1() {
+ LocalInterruptibleClosure closure1 = new LocalInterruptibleClosure();
+ boolean exCaught = false;
+ try {
+ InterruptibleClosure<Integer> closure = ClosureTools.compositeInterruptibleClosure(closure1, null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testCompositeInterruptibleClosure_NPE2() {
+ boolean exCaught = false;
+ try {
+ InterruptibleClosure<Integer> closure = ClosureTools.compositeInterruptibleClosure((Iterable<InterruptibleClosure<Integer>>) null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testConditionalClosure_execute1() throws Exception {
+ LocalClosure closure1 = new LocalClosure();
+ Predicate<Integer> predicate = new PredicateAdapter<Integer>() {
+ @Override
+ public boolean evaluate(Integer variable) {
+ return variable.intValue() > 3;
+ }
+ };
+ Closure<Integer> closure = ClosureTools.conditionalClosure(predicate, closure1);
+ closure.execute(Integer.valueOf(3));
+ assertEquals(0, closure1.count);
+ closure.execute(Integer.valueOf(4));
+ assertEquals(4, closure1.count);
+ }
+
+ public void testConditionalClosure_execute2() throws Exception {
+ LocalClosure closure1 = new LocalClosure();
+ LocalClosure closure2 = new LocalClosure();
+ Predicate<Integer> predicate = new PredicateAdapter<Integer>() {
+ @Override
+ public boolean evaluate(Integer variable) {
+ return variable.intValue() > 3;
+ }
+ };
+ Closure<Integer> closure = ClosureTools.conditionalClosure(predicate, closure1, closure2);
+ closure.execute(Integer.valueOf(3));
+ assertEquals(0, closure1.count);
+ assertEquals(3, closure2.count);
+ closure.execute(Integer.valueOf(4));
+ assertEquals(4, closure1.count);
+ assertEquals(3, closure2.count);
+ }
+
+ public void testConditionalClosure_toString() {
+ LocalClosure closure1 = new LocalClosure();
+ LocalClosure closure2 = new LocalClosure();
+ Predicate<Integer> predicate = new PredicateAdapter<Integer>() {
+ @Override
+ public boolean evaluate(Integer variable) {
+ return variable.intValue() > 3;
+ }
+ };
+ Closure<Integer> closure = ClosureTools.conditionalClosure(predicate, closure1, closure2);
+ assertTrue(closure.toString().indexOf("ConditionalClosure") != -1);
+ assertTrue(closure.toString().indexOf("Predicate") != -1);
+ }
+
+ public void testConditionalClosure_NPE1() {
+ LocalClosure closure1 = new LocalClosure();
+ LocalClosure closure2 = new LocalClosure();
+ boolean exCaught = false;
+ try {
+ Closure<Integer> closure = ClosureTools.conditionalClosure(null, closure1, closure2);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testConditionalClosure_NPE2() {
+ LocalClosure closure1 = new LocalClosure();
+ boolean exCaught = false;
+ try {
+ Closure<Integer> closure = ClosureTools.conditionalClosure(null, closure1, null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testConditionalClosure_NPE3() {
+ LocalClosure closure2 = new LocalClosure();
+ boolean exCaught = false;
+ try {
+ Closure<Integer> closure = ClosureTools.conditionalClosure(PredicateTools.true_(), null, closure2);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testConditionalInterruptibleClosure_execute1() throws Exception {
+ LocalInterruptibleClosure closure1 = new LocalInterruptibleClosure();
+ Predicate<Integer> predicate = new PredicateAdapter<Integer>() {
+ @Override
+ public boolean evaluate(Integer variable) {
+ return variable.intValue() > 3;
+ }
+ };
+ InterruptibleClosure<Integer> closure = ClosureTools.conditionalClosure(predicate, closure1);
+ closure.execute(Integer.valueOf(3));
+ assertEquals(0, closure1.count);
+ closure.execute(Integer.valueOf(4));
+ assertEquals(4, closure1.count);
+ }
+
+ public void testConditionalInterruptibleClosure_execute2() throws Exception {
+ LocalInterruptibleClosure closure1 = new LocalInterruptibleClosure();
+ LocalInterruptibleClosure closure2 = new LocalInterruptibleClosure();
+ Predicate<Integer> predicate = new PredicateAdapter<Integer>() {
+ @Override
+ public boolean evaluate(Integer variable) {
+ return variable.intValue() > 3;
+ }
+ };
+ InterruptibleClosure<Integer> closure = ClosureTools.conditionalClosure(predicate, closure1, closure2);
+ closure.execute(Integer.valueOf(3));
+ assertEquals(0, closure1.count);
+ assertEquals(3, closure2.count);
+ closure.execute(Integer.valueOf(4));
+ assertEquals(4, closure1.count);
+ assertEquals(3, closure2.count);
+ }
+
+ public void testConditionalInterruptibleClosure_toString() {
+ LocalInterruptibleClosure closure1 = new LocalInterruptibleClosure();
+ LocalInterruptibleClosure closure2 = new LocalInterruptibleClosure();
+ Predicate<Integer> predicate = new PredicateAdapter<Integer>() {
+ @Override
+ public boolean evaluate(Integer variable) {
+ return variable.intValue() > 3;
+ }
+ };
+ InterruptibleClosure<Integer> closure = ClosureTools.conditionalClosure(predicate, closure1, closure2);
+ assertTrue(closure.toString().indexOf("ConditionalInterruptibleClosure") != -1);
+ assertTrue(closure.toString().indexOf("Predicate") != -1);
+ }
+
+ public void testConditionalInterruptibleClosure_NPE1() {
+ LocalInterruptibleClosure closure1 = new LocalInterruptibleClosure();
+ LocalInterruptibleClosure closure2 = new LocalInterruptibleClosure();
+ boolean exCaught = false;
+ try {
+ InterruptibleClosure<Integer> closure = ClosureTools.conditionalClosure(null, closure1, closure2);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testConditionalInterruptibleClosure_NPE2() {
+ LocalInterruptibleClosure closure1 = new LocalInterruptibleClosure();
+ boolean exCaught = false;
+ try {
+ InterruptibleClosure<Integer> closure = ClosureTools.conditionalClosure(null, closure1, null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testConditionalInterruptibleClosure_NPE3() {
+ LocalInterruptibleClosure closure2 = new LocalInterruptibleClosure();
+ boolean exCaught = false;
+ try {
+ InterruptibleClosure<Integer> closure = ClosureTools.conditionalClosure(PredicateTools.true_(), null, closure2);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testSwitchClosure_execute1() throws Exception {
+ List<Association<Predicate<Integer>, LocalClosure>> list = new ArrayList<>();
+
+ Predicate<Integer> predicate1 = PredicateTools.isEqual(Integer.valueOf(1));
+ LocalClosure closure1 = new LocalClosure();
+ Association<Predicate<Integer>, LocalClosure> association1 = new SimpleAssociation<>(predicate1, closure1);
+ list.add(association1);
+
+ Predicate<Integer> predicate2 = PredicateTools.isEqual(Integer.valueOf(2));
+ LocalClosure closure2 = new LocalClosure();
+ Association<Predicate<Integer>, LocalClosure> association2 = new SimpleAssociation<>(predicate2, closure2);
+ list.add(association2);
+
+ Predicate<Integer> predicate3 = PredicateTools.isEqual(Integer.valueOf(3));
+ LocalClosure closure3 = new LocalClosure();
+ Association<Predicate<Integer>, LocalClosure> association3 = new SimpleAssociation<>(predicate3, closure3);
+ list.add(association3);
+
+ Closure<Integer> closure = ClosureTools.switchClosure(list);
+ assertEquals(0, closure1.count);
+ assertEquals(0, closure2.count);
+ assertEquals(0, closure3.count);
+
+ closure.execute(Integer.valueOf(0));
+ assertEquals(0, closure1.count);
+ assertEquals(0, closure2.count);
+ assertEquals(0, closure3.count);
+
+ closure.execute(Integer.valueOf(4));
+ assertEquals(0, closure1.count);
+ assertEquals(0, closure2.count);
+ assertEquals(0, closure3.count);
+
+ closure.execute(Integer.valueOf(1));
+ assertEquals(1, closure1.count);
+ assertEquals(0, closure2.count);
+ assertEquals(0, closure3.count);
+
+ closure.execute(Integer.valueOf(2));
+ assertEquals(1, closure1.count);
+ assertEquals(2, closure2.count);
+ assertEquals(0, closure3.count);
+
+ closure.execute(Integer.valueOf(2));
+ assertEquals(1, closure1.count);
+ assertEquals(4, closure2.count);
+ assertEquals(0, closure3.count);
+
+ closure.execute(Integer.valueOf(3));
+ assertEquals(1, closure1.count);
+ assertEquals(4, closure2.count);
+ assertEquals(3, closure3.count);
+ }
+
+ public void testSwitchClosure_execute2() throws Exception {
+ List<Association<Predicate<Integer>, LocalClosure>> list = new ArrayList<>();
+
+ Predicate<Integer> predicate1 = PredicateTools.isEqual(Integer.valueOf(1));
+ LocalClosure closure1 = new LocalClosure();
+ Association<Predicate<Integer>, LocalClosure> association1 = new SimpleAssociation<>(predicate1, closure1);
+ list.add(association1);
+
+ Predicate<Integer> predicate2 = PredicateTools.isEqual(Integer.valueOf(2));
+ LocalClosure closure2 = new LocalClosure();
+ Association<Predicate<Integer>, LocalClosure> association2 = new SimpleAssociation<>(predicate2, closure2);
+ list.add(association2);
+
+ Predicate<Integer> predicate3 = PredicateTools.isEqual(Integer.valueOf(3));
+ LocalClosure closure3 = new LocalClosure();
+ Association<Predicate<Integer>, LocalClosure> association3 = new SimpleAssociation<>(predicate3, closure3);
+ list.add(association3);
+
+ LocalClosure closureX = new LocalClosure();
+
+ Closure<Integer> closure = ClosureTools.switchClosure(list, closureX);
+ assertEquals(0, closure1.count);
+ assertEquals(0, closure2.count);
+ assertEquals(0, closure3.count);
+ assertEquals(0, closureX.count);
+
+ closure.execute(Integer.valueOf(0));
+ assertEquals(0, closure1.count);
+ assertEquals(0, closure2.count);
+ assertEquals(0, closure3.count);
+ assertEquals(0, closureX.count);
+
+ closure.execute(Integer.valueOf(4));
+ assertEquals(0, closure1.count);
+ assertEquals(0, closure2.count);
+ assertEquals(0, closure3.count);
+ assertEquals(4, closureX.count);
+
+ closure.execute(Integer.valueOf(1));
+ assertEquals(1, closure1.count);
+ assertEquals(0, closure2.count);
+ assertEquals(0, closure3.count);
+ assertEquals(4, closureX.count);
+
+ closure.execute(Integer.valueOf(2));
+ assertEquals(1, closure1.count);
+ assertEquals(2, closure2.count);
+ assertEquals(0, closure3.count);
+ assertEquals(4, closureX.count);
+
+ closure.execute(Integer.valueOf(2));
+ assertEquals(1, closure1.count);
+ assertEquals(4, closure2.count);
+ assertEquals(0, closure3.count);
+ assertEquals(4, closureX.count);
+
+ closure.execute(Integer.valueOf(3));
+ assertEquals(1, closure1.count);
+ assertEquals(4, closure2.count);
+ assertEquals(3, closure3.count);
+ assertEquals(4, closureX.count);
+
+ closure.execute(Integer.valueOf(-7));
+ assertEquals(1, closure1.count);
+ assertEquals(4, closure2.count);
+ assertEquals(3, closure3.count);
+ assertEquals(-3, closureX.count);
+ }
+
+ public void testSwitchClosure_toString() {
+ List<Association<Predicate<Integer>, LocalClosure>> list = new ArrayList<>();
+
+ Predicate<Integer> predicate1 = PredicateTools.isEqual(Integer.valueOf(1));
+ LocalClosure closure1 = new LocalClosure();
+ Association<Predicate<Integer>, LocalClosure> association1 = new SimpleAssociation<>(predicate1, closure1);
+ list.add(association1);
+
+ Predicate<Integer> predicate2 = PredicateTools.isEqual(Integer.valueOf(2));
+ LocalClosure closure2 = new LocalClosure();
+ Association<Predicate<Integer>, LocalClosure> association2 = new SimpleAssociation<>(predicate2, closure2);
+ list.add(association2);
+
+ Predicate<Integer> predicate3 = PredicateTools.isEqual(Integer.valueOf(3));
+ LocalClosure closure3 = new LocalClosure();
+ Association<Predicate<Integer>, LocalClosure> association3 = new SimpleAssociation<>(predicate3, closure3);
+ list.add(association3);
+
+ LocalClosure closureX = new LocalClosure();
+
+ Closure<Integer> closure = ClosureTools.switchClosure(list, closureX);
+
+ assertTrue(closure.toString().indexOf("SwitchClosure") != -1);
+ assertTrue(closure.toString().indexOf("LocalClosure") != -1);
+ }
+
+ public void testSwitchClosure_NPE1() {
+ List<Association<Predicate<Integer>, LocalClosure>> list = new ArrayList<>();
+
+ Predicate<Integer> predicate1 = PredicateTools.isEqual(Integer.valueOf(1));
+ LocalClosure closure1 = new LocalClosure();
+ Association<Predicate<Integer>, LocalClosure> association1 = new SimpleAssociation<>(predicate1, closure1);
+ list.add(association1);
+
+ Predicate<Integer> predicate2 = PredicateTools.isEqual(Integer.valueOf(2));
+ LocalClosure closure2 = new LocalClosure();
+ Association<Predicate<Integer>, LocalClosure> association2 = new SimpleAssociation<>(predicate2, closure2);
+ list.add(association2);
+
+ Predicate<Integer> predicate3 = PredicateTools.isEqual(Integer.valueOf(3));
+ LocalClosure closure3 = new LocalClosure();
+ Association<Predicate<Integer>, LocalClosure> association3 = new SimpleAssociation<>(predicate3, closure3);
+ list.add(association3);
+
+ boolean exCaught = false;
+ try {
+ Closure<Integer> closure = ClosureTools.switchClosure(list, null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testSwitchClosure_NPE2() {
+ List<Association<Predicate<Integer>, LocalClosure>> list = new ArrayList<>();
+
+ Predicate<Integer> predicate1 = PredicateTools.isEqual(Integer.valueOf(1));
+ LocalClosure closure1 = new LocalClosure();
+ Association<Predicate<Integer>, LocalClosure> association1 = new SimpleAssociation<>(predicate1, closure1);
+ list.add(association1);
+
+ Predicate<Integer> predicate2 = PredicateTools.isEqual(Integer.valueOf(2));
+ LocalClosure closure2 = new LocalClosure();
+ Association<Predicate<Integer>, LocalClosure> association2 = new SimpleAssociation<>(predicate2, closure2);
+ list.add(association2);
+
+ Predicate<Integer> predicate3 = PredicateTools.isEqual(Integer.valueOf(3));
+ LocalClosure closure3 = new LocalClosure();
+ Association<Predicate<Integer>, LocalClosure> association3 = new SimpleAssociation<>(predicate3, closure3);
+ list.add(association3);
+ list.add(null);
+
+ boolean exCaught = false;
+ try {
+ Closure<Integer> closure = ClosureTools.switchClosure(list);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testSwitchClosure_NPE3() {
+ boolean exCaught = false;
+ try {
+ Closure<Integer> closure = ClosureTools.switchClosure(null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testSwitchInterruptibleClosure_execute1() throws Exception {
+ List<Association<Predicate<Integer>, LocalInterruptibleClosure>> list = new ArrayList<>();
+
+ Predicate<Integer> predicate1 = PredicateTools.isEqual(Integer.valueOf(1));
+ LocalInterruptibleClosure closure1 = new LocalInterruptibleClosure();
+ Association<Predicate<Integer>, LocalInterruptibleClosure> association1 = new SimpleAssociation<>(predicate1, closure1);
+ list.add(association1);
+
+ Predicate<Integer> predicate2 = PredicateTools.isEqual(Integer.valueOf(2));
+ LocalInterruptibleClosure closure2 = new LocalInterruptibleClosure();
+ Association<Predicate<Integer>, LocalInterruptibleClosure> association2 = new SimpleAssociation<>(predicate2, closure2);
+ list.add(association2);
+
+ Predicate<Integer> predicate3 = PredicateTools.isEqual(Integer.valueOf(3));
+ LocalInterruptibleClosure closure3 = new LocalInterruptibleClosure();
+ Association<Predicate<Integer>, LocalInterruptibleClosure> association3 = new SimpleAssociation<>(predicate3, closure3);
+ list.add(association3);
+
+ InterruptibleClosure<Integer> closure = ClosureTools.switchInterruptibleClosure(list);
+ assertEquals(0, closure1.count);
+ assertEquals(0, closure2.count);
+ assertEquals(0, closure3.count);
+
+ closure.execute(Integer.valueOf(0));
+ assertEquals(0, closure1.count);
+ assertEquals(0, closure2.count);
+ assertEquals(0, closure3.count);
+
+ closure.execute(Integer.valueOf(4));
+ assertEquals(0, closure1.count);
+ assertEquals(0, closure2.count);
+ assertEquals(0, closure3.count);
+
+ closure.execute(Integer.valueOf(1));
+ assertEquals(1, closure1.count);
+ assertEquals(0, closure2.count);
+ assertEquals(0, closure3.count);
+
+ closure.execute(Integer.valueOf(2));
+ assertEquals(1, closure1.count);
+ assertEquals(2, closure2.count);
+ assertEquals(0, closure3.count);
+
+ closure.execute(Integer.valueOf(2));
+ assertEquals(1, closure1.count);
+ assertEquals(4, closure2.count);
+ assertEquals(0, closure3.count);
+
+ closure.execute(Integer.valueOf(3));
+ assertEquals(1, closure1.count);
+ assertEquals(4, closure2.count);
+ assertEquals(3, closure3.count);
+ }
+
+ public void testSwitchInterruptibleClosure_execute2() throws Exception {
+ List<Association<Predicate<Integer>, LocalInterruptibleClosure>> list = new ArrayList<>();
+
+ Predicate<Integer> predicate1 = PredicateTools.isEqual(Integer.valueOf(1));
+ LocalInterruptibleClosure closure1 = new LocalInterruptibleClosure();
+ Association<Predicate<Integer>, LocalInterruptibleClosure> association1 = new SimpleAssociation<>(predicate1, closure1);
+ list.add(association1);
+
+ Predicate<Integer> predicate2 = PredicateTools.isEqual(Integer.valueOf(2));
+ LocalInterruptibleClosure closure2 = new LocalInterruptibleClosure();
+ Association<Predicate<Integer>, LocalInterruptibleClosure> association2 = new SimpleAssociation<>(predicate2, closure2);
+ list.add(association2);
+
+ Predicate<Integer> predicate3 = PredicateTools.isEqual(Integer.valueOf(3));
+ LocalInterruptibleClosure closure3 = new LocalInterruptibleClosure();
+ Association<Predicate<Integer>, LocalInterruptibleClosure> association3 = new SimpleAssociation<>(predicate3, closure3);
+ list.add(association3);
+
+ LocalInterruptibleClosure closureX = new LocalInterruptibleClosure();
+
+ InterruptibleClosure<Integer> closure = ClosureTools.switchInterruptibleClosure(list, closureX);
+ assertEquals(0, closure1.count);
+ assertEquals(0, closure2.count);
+ assertEquals(0, closure3.count);
+ assertEquals(0, closureX.count);
+
+ closure.execute(Integer.valueOf(0));
+ assertEquals(0, closure1.count);
+ assertEquals(0, closure2.count);
+ assertEquals(0, closure3.count);
+ assertEquals(0, closureX.count);
+
+ closure.execute(Integer.valueOf(4));
+ assertEquals(0, closure1.count);
+ assertEquals(0, closure2.count);
+ assertEquals(0, closure3.count);
+ assertEquals(4, closureX.count);
+
+ closure.execute(Integer.valueOf(1));
+ assertEquals(1, closure1.count);
+ assertEquals(0, closure2.count);
+ assertEquals(0, closure3.count);
+ assertEquals(4, closureX.count);
+
+ closure.execute(Integer.valueOf(2));
+ assertEquals(1, closure1.count);
+ assertEquals(2, closure2.count);
+ assertEquals(0, closure3.count);
+ assertEquals(4, closureX.count);
+
+ closure.execute(Integer.valueOf(2));
+ assertEquals(1, closure1.count);
+ assertEquals(4, closure2.count);
+ assertEquals(0, closure3.count);
+ assertEquals(4, closureX.count);
+
+ closure.execute(Integer.valueOf(3));
+ assertEquals(1, closure1.count);
+ assertEquals(4, closure2.count);
+ assertEquals(3, closure3.count);
+ assertEquals(4, closureX.count);
+
+ closure.execute(Integer.valueOf(-7));
+ assertEquals(1, closure1.count);
+ assertEquals(4, closure2.count);
+ assertEquals(3, closure3.count);
+ assertEquals(-3, closureX.count);
+ }
+
+ public void testSwitchInterruptibleClosure_toString() {
+ List<Association<Predicate<Integer>, LocalInterruptibleClosure>> list = new ArrayList<>();
+
+ Predicate<Integer> predicate1 = PredicateTools.isEqual(Integer.valueOf(1));
+ LocalInterruptibleClosure closure1 = new LocalInterruptibleClosure();
+ Association<Predicate<Integer>, LocalInterruptibleClosure> association1 = new SimpleAssociation<>(predicate1, closure1);
+ list.add(association1);
+
+ Predicate<Integer> predicate2 = PredicateTools.isEqual(Integer.valueOf(2));
+ LocalInterruptibleClosure closure2 = new LocalInterruptibleClosure();
+ Association<Predicate<Integer>, LocalInterruptibleClosure> association2 = new SimpleAssociation<>(predicate2, closure2);
+ list.add(association2);
+
+ Predicate<Integer> predicate3 = PredicateTools.isEqual(Integer.valueOf(3));
+ LocalInterruptibleClosure closure3 = new LocalInterruptibleClosure();
+ Association<Predicate<Integer>, LocalInterruptibleClosure> association3 = new SimpleAssociation<>(predicate3, closure3);
+ list.add(association3);
+
+ LocalInterruptibleClosure closureX = new LocalInterruptibleClosure();
+
+ InterruptibleClosure<Integer> closure = ClosureTools.switchInterruptibleClosure(list, closureX);
+
+ assertTrue(closure.toString().indexOf("SwitchInterruptibleClosure") != -1);
+ assertTrue(closure.toString().indexOf("LocalInterruptibleClosure") != -1);
+ }
+
+ public void testSwitchInterruptibleClosure_NPE1() {
+ List<Association<Predicate<Integer>, LocalInterruptibleClosure>> list = new ArrayList<>();
+
+ Predicate<Integer> predicate1 = PredicateTools.isEqual(Integer.valueOf(1));
+ LocalInterruptibleClosure closure1 = new LocalInterruptibleClosure();
+ Association<Predicate<Integer>, LocalInterruptibleClosure> association1 = new SimpleAssociation<>(predicate1, closure1);
+ list.add(association1);
+
+ Predicate<Integer> predicate2 = PredicateTools.isEqual(Integer.valueOf(2));
+ LocalInterruptibleClosure closure2 = new LocalInterruptibleClosure();
+ Association<Predicate<Integer>, LocalInterruptibleClosure> association2 = new SimpleAssociation<>(predicate2, closure2);
+ list.add(association2);
+
+ Predicate<Integer> predicate3 = PredicateTools.isEqual(Integer.valueOf(3));
+ LocalInterruptibleClosure closure3 = new LocalInterruptibleClosure();
+ Association<Predicate<Integer>, LocalInterruptibleClosure> association3 = new SimpleAssociation<>(predicate3, closure3);
+ list.add(association3);
+
+ boolean exCaught = false;
+ try {
+ InterruptibleClosure<Integer> closure = ClosureTools.switchInterruptibleClosure(list, null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testSwitchInterruptibleClosure_NPE2() {
+ List<Association<Predicate<Integer>, LocalInterruptibleClosure>> list = new ArrayList<>();
+
+ Predicate<Integer> predicate1 = PredicateTools.isEqual(Integer.valueOf(1));
+ LocalInterruptibleClosure closure1 = new LocalInterruptibleClosure();
+ Association<Predicate<Integer>, LocalInterruptibleClosure> association1 = new SimpleAssociation<>(predicate1, closure1);
+ list.add(association1);
+
+ Predicate<Integer> predicate2 = PredicateTools.isEqual(Integer.valueOf(2));
+ LocalInterruptibleClosure closure2 = new LocalInterruptibleClosure();
+ Association<Predicate<Integer>, LocalInterruptibleClosure> association2 = new SimpleAssociation<>(predicate2, closure2);
+ list.add(association2);
+
+ Predicate<Integer> predicate3 = PredicateTools.isEqual(Integer.valueOf(3));
+ LocalInterruptibleClosure closure3 = new LocalInterruptibleClosure();
+ Association<Predicate<Integer>, LocalInterruptibleClosure> association3 = new SimpleAssociation<>(predicate3, closure3);
+ list.add(association3);
+ list.add(null);
+
+ boolean exCaught = false;
+ try {
+ InterruptibleClosure<Integer> closure = ClosureTools.switchInterruptibleClosure(list);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testSwitchInterruptibleClosure_NPE3() {
+ boolean exCaught = false;
+ try {
+ InterruptibleClosure<Integer> closure = ClosureTools.switchInterruptibleClosure(null);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testDisabledClosure_execute() {
+ Closure<Integer> closure = ClosureTools.disabledClosure();
+ boolean exCaught = false;
+ try {
+ closure.execute(null);
+ fail();
+ } catch (UnsupportedOperationException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testDisabledClosure_toString() {
+ Closure<Integer> closure = ClosureTools.disabledClosure();
+ assertTrue(closure.toString().indexOf("DisabledClosure") != -1);
+ }
+
+ public void testDisabledClosure_serialization() throws Exception {
+ Closure<Integer> closure = ClosureTools.disabledClosure();
+ assertSame(closure, TestTools.serialize(closure));
+ }
+
+ public void testInterruptedClosure_execute() throws Exception {
+ InterruptibleClosure<Integer> closure = ClosureTools.interruptedClosure();
+ boolean exCaught = false;
+ try {
+ closure.execute(null);
+ fail();
+ } catch (InterruptedException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testInterruptedClosure_toString() {
+ InterruptibleClosure<Integer> closure = ClosureTools.interruptedClosure();
+ assertTrue(closure.toString().indexOf("InterruptedClosure") != -1);
+ }
+
+ public void testInterruptedClosure_serialization() throws Exception {
+ InterruptibleClosure<Integer> closure = ClosureTools.interruptedClosure();
+ assertSame(closure, TestTools.serialize(closure));
+ }
+
+ public void testRepeatingClosure_execute1() throws Exception {
+ LocalClosure closure1 = new LocalClosure();
+ Closure<Integer> closure2 = ClosureTools.repeatingClosure(closure1, 3);
+ closure2.execute(Integer.valueOf(3));
+ assertEquals(9, closure1.count);
+ }
+
+ public void testRepeatingClosure_execute2() throws Exception {
+ LocalClosure closure1 = new LocalClosure();
+ Closure<Integer> closure2 = ClosureTools.repeatingClosure(closure1, 0);
+ closure2.execute(Integer.valueOf(3));
+ assertEquals(0, closure1.count);
+ }
+
+ public void testRepeatingClosure_toString() {
+ LocalClosure closure1 = new LocalClosure();
+ Closure<Integer> closure2 = ClosureTools.repeatingClosure(closure1, 3);
+ assertTrue(closure2.toString().indexOf("RepeatingClosure") != -1);
+ assertTrue(closure2.toString().indexOf("LocalClosure") != -1);
+ }
+
+ public void testRepeatingClosure_NPE1() {
+ boolean exCaught = false;
+ try {
+ Closure<Integer> closure = ClosureTools.repeatingClosure((Closure<Integer>) null, 3);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testRepeatingClosure_NPE2() {
+ LocalClosure closure1 = new LocalClosure();
+ boolean exCaught = false;
+ try {
+ Closure<Integer> closure2 = ClosureTools.repeatingClosure(closure1, -3);
+ fail("bogus: " + closure2);
+ } catch (IndexOutOfBoundsException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testRepeatingInterruptibleClosure_execute1() throws Exception {
+ LocalInterruptibleClosure closure1 = new LocalInterruptibleClosure();
+ InterruptibleClosure<Integer> closure2 = ClosureTools.repeatingClosure(closure1, 3);
+ closure2.execute(Integer.valueOf(3));
+ assertEquals(9, closure1.count);
+ }
+
+ public void testRepeatingInterruptibleClosure_execute2() throws Exception {
+ LocalInterruptibleClosure closure1 = new LocalInterruptibleClosure();
+ InterruptibleClosure<Integer> closure2 = ClosureTools.repeatingClosure(closure1, 0);
+ closure2.execute(Integer.valueOf(3));
+ assertEquals(0, closure1.count);
+ }
+
+ public void testRepeatingInterruptibleClosure_toString() {
+ LocalInterruptibleClosure closure1 = new LocalInterruptibleClosure();
+ InterruptibleClosure<Integer> closure2 = ClosureTools.repeatingClosure(closure1, 3);
+ assertTrue(closure2.toString().indexOf("RepeatingInterruptibleClosure") != -1);
+ assertTrue(closure2.toString().indexOf("LocalInterruptibleClosure") != -1);
+ }
+
+ public void testRepeatingInterruptibleClosure_NPE1() {
+ boolean exCaught = false;
+ try {
+ InterruptibleClosure<Integer> closure = ClosureTools.repeatingClosure((InterruptibleClosure<Integer>) null, 3);
+ fail("bogus: " + closure);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testRepeatingInterruptibleClosure_NPE2() {
+ LocalInterruptibleClosure closure1 = new LocalInterruptibleClosure();
+ boolean exCaught = false;
+ try {
+ InterruptibleClosure<Integer> closure2 = ClosureTools.repeatingClosure(closure1, -3);
+ fail("bogus: " + closure2);
+ } catch (IndexOutOfBoundsException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testWhileClosure_execute() throws Exception {
+ ModifiableIntReference ref = new SimpleIntReference(0);
+ IntRefClosure closure1 = new IntRefClosure();
+ Predicate<ModifiableIntReference> predicate = new IntRefValueNotEqualPredicate(3);
+ Closure<ModifiableIntReference> closure2 = ClosureTools.whileClosure(predicate, closure1);
+ closure2.execute(ref);
+ assertEquals(6, closure1.count);
+ ref.setValue(-6);
+ closure2.execute(ref);
+ assertEquals(24, closure1.count);
+ }
+
+ public void testWhileClosure_toString() {
+ IntRefClosure closure1 = new IntRefClosure();
+ Predicate<ModifiableIntReference> predicate = new IntRefValueNotEqualPredicate(3);
+ Closure<ModifiableIntReference> closure2 = ClosureTools.whileClosure(predicate, closure1);
+ assertTrue(closure2.toString().indexOf("WhileClosure") != -1);
+ assertTrue(closure2.toString().indexOf("IntRefValueNotEqualPredicate") != -1);
+ }
+
+ public void testWhileClosure_NPE1() {
+ IntRefClosure closure1 = new IntRefClosure();
+ boolean exCaught = false;
+ try {
+ Closure<ModifiableIntReference> closure2 = ClosureTools.whileClosure(null, closure1);
+ fail("bogus: " + closure2);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testWhileClosure_NPE2() {
+ Predicate<ModifiableIntReference> predicate = new IntRefValueNotEqualPredicate(3);
+ boolean exCaught = false;
+ try {
+ Closure<ModifiableIntReference> closure2 = ClosureTools.whileClosure(predicate, (IntRefClosure) null);
+ fail("bogus: " + closure2);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public static class IntRefClosure
+ extends ClosureAdapter<ModifiableIntReference>
+ {
+ public int count = 0;
+ @Override
+ public void execute(ModifiableIntReference argument) {
+ this.count += 2;
+ argument.increment();
+ }
+ }
+
+ public void testWhileInterruptibleClosure_execute() throws Exception {
+ ModifiableIntReference ref = new SimpleIntReference(0);
+ IntRefInterruptibleClosure closure1 = new IntRefInterruptibleClosure();
+ Predicate<ModifiableIntReference> predicate = new IntRefValueNotEqualPredicate(3);
+ InterruptibleClosure<ModifiableIntReference> closure2 = ClosureTools.whileClosure(predicate, closure1);
+ closure2.execute(ref);
+ assertEquals(6, closure1.count);
+ ref.setValue(-6);
+ closure2.execute(ref);
+ assertEquals(24, closure1.count);
+ }
+
+ public void testWhileInterruptibleClosure_toString() {
+ IntRefInterruptibleClosure closure1 = new IntRefInterruptibleClosure();
+ Predicate<ModifiableIntReference> predicate = new IntRefValueNotEqualPredicate(3);
+ InterruptibleClosure<ModifiableIntReference> closure2 = ClosureTools.whileClosure(predicate, closure1);
+ assertTrue(closure2.toString().indexOf("WhileInterruptibleClosure") != -1);
+ assertTrue(closure2.toString().indexOf("IntRefValueNotEqualPredicate") != -1);
+ }
+
+ public void testWhileInterruptibleClosure_NPE1() {
+ IntRefInterruptibleClosure closure1 = new IntRefInterruptibleClosure();
+ boolean exCaught = false;
+ try {
+ InterruptibleClosure<ModifiableIntReference> closure2 = ClosureTools.whileClosure(null, closure1);
+ fail("bogus: " + closure2);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testWhileInterruptibleClosure_NPE2() {
+ Predicate<ModifiableIntReference> predicate = new IntRefValueNotEqualPredicate(3);
+ boolean exCaught = false;
+ try {
+ InterruptibleClosure<ModifiableIntReference> closure2 = ClosureTools.whileClosure(predicate, (IntRefInterruptibleClosure) null);
+ fail("bogus: " + closure2);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public static class IntRefInterruptibleClosure
+ extends InterruptibleClosureAdapter<ModifiableIntReference>
+ {
+ public int count = 0;
+ @Override
+ public void execute(ModifiableIntReference argument) throws InterruptedException {
+ this.count += 2;
+ argument.increment();
+ }
+ }
+
+ public static class IntRefValueNotEqualPredicate
+ extends PredicateAdapter<ModifiableIntReference>
+ {
+ private final int count;
+ public IntRefValueNotEqualPredicate(int count) {
+ super();
+ this.count = count;
+ }
+ @Override
+ public boolean evaluate(ModifiableIntReference variable) {
+ return variable.notEqual(this.count);
+ }
+ }
+
+ public void testUntilClosure_execute() throws Exception {
+ ModifiableIntReference ref = new SimpleIntReference(0);
+ IntRefClosure closure1 = new IntRefClosure();
+ Predicate<ModifiableIntReference> predicate = new IntRefValueEqualPredicate(3);
+ Closure<ModifiableIntReference> closure2 = ClosureTools.untilClosure(closure1, predicate);
+ closure2.execute(ref);
+ assertEquals(6, closure1.count);
+ ref.setValue(-6);
+ closure2.execute(ref);
+ assertEquals(24, closure1.count);
+ }
+
+ public void testUntilClosure_toString() {
+ IntRefClosure closure1 = new IntRefClosure();
+ Predicate<ModifiableIntReference> predicate = new IntRefValueEqualPredicate(3);
+ Closure<ModifiableIntReference> closure2 = ClosureTools.untilClosure(closure1, predicate);
+ assertTrue(closure2.toString().indexOf("UntilClosure") != -1);
+ assertTrue(closure2.toString().indexOf("IntRefValueEqualPredicate") != -1);
+ }
+
+ public void testUntilClosure_NPE1() {
+ IntRefClosure closure1 = new IntRefClosure();
+ boolean exCaught = false;
+ try {
+ Closure<ModifiableIntReference> closure2 = ClosureTools.untilClosure(closure1, null);
+ fail("bogus: " + closure2);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testUntilClosure_NPE2() {
+ Predicate<ModifiableIntReference> predicate = new IntRefValueEqualPredicate(3);
+ boolean exCaught = false;
+ try {
+ Closure<ModifiableIntReference> closure2 = ClosureTools.untilClosure((IntRefClosure) null, predicate);
+ fail("bogus: " + closure2);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testUntilInterruptibleClosure_execute() throws Exception {
+ ModifiableIntReference ref = new SimpleIntReference(0);
+ IntRefInterruptibleClosure closure1 = new IntRefInterruptibleClosure();
+ Predicate<ModifiableIntReference> predicate = new IntRefValueEqualPredicate(3);
+ InterruptibleClosure<ModifiableIntReference> closure2 = ClosureTools.untilClosure(closure1, predicate);
+ closure2.execute(ref);
+ assertEquals(6, closure1.count);
+ ref.setValue(-6);
+ closure2.execute(ref);
+ assertEquals(24, closure1.count);
+ }
+
+ public void testUntilInterruptibleClosure_toString() {
+ IntRefInterruptibleClosure closure1 = new IntRefInterruptibleClosure();
+ Predicate<ModifiableIntReference> predicate = new IntRefValueEqualPredicate(3);
+ InterruptibleClosure<ModifiableIntReference> closure2 = ClosureTools.untilClosure(closure1, predicate);
+ assertTrue(closure2.toString().indexOf("UntilInterruptibleClosure") != -1);
+ assertTrue(closure2.toString().indexOf("IntRefValueEqualPredicate") != -1);
+ }
+
+ public void testUntilInterruptibleClosure_NPE1() {
+ IntRefInterruptibleClosure closure1 = new IntRefInterruptibleClosure();
+ boolean exCaught = false;
+ try {
+ InterruptibleClosure<ModifiableIntReference> closure2 = ClosureTools.untilClosure(closure1, null);
+ fail("bogus: " + closure2);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testUntilInterruptibleClosure_NPE2() {
+ Predicate<ModifiableIntReference> predicate = new IntRefValueEqualPredicate(3);
+ boolean exCaught = false;
+ try {
+ InterruptibleClosure<ModifiableIntReference> closure2 = ClosureTools.untilClosure((IntRefInterruptibleClosure) null, predicate);
+ fail("bogus: " + closure2);
+ } catch (NullPointerException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public static class IntRefValueEqualPredicate
+ extends PredicateAdapter<ModifiableIntReference>
+ {
+ private final int count;
+ public IntRefValueEqualPredicate(int count) {
+ super();
+ this.count = count;
+ }
+ @Override
+ public boolean evaluate(ModifiableIntReference variable) {
+ return variable.equals(this.count);
+ }
+ }
+
+ public void testConstructor() {
+ boolean exCaught = false;
+ try {
+ Object at = ClassTools.newInstance(ClosureTools.class);
+ fail("bogus: " + at);
+ } catch (RuntimeException ex) {
+ if (ex.getCause() instanceof InvocationTargetException) {
+ if (ex.getCause().getCause() instanceof UnsupportedOperationException) {
+ exCaught = true;
+ }
+ }
+ }
+ assertTrue(exCaught);
+ }
+
+ // ********** test classes **********
+
+ public static class LocalClosure
+ extends ClosureAdapter<Integer>
+ {
+ public int count = 0;
+
+ @Override
+ public void execute(Integer argument) {
+ this.count += argument.intValue(); // possible NPE
+ }
+ }
+
+ public static class LocalClosure2
+ extends ClosureAdapter<Integer>
+ {
+ public int count = 0;
+
+ @Override
+ public void execute(Integer argument) {
+ this.count += (2 * argument.intValue()); // possible NPE
+ }
+ }
+
+ public static class LocalInterruptibleClosure
+ extends InterruptibleClosureAdapter<Integer>
+ {
+ public int count = 0;
+
+ @Override
+ public void execute(Integer argument) throws InterruptedException {
+ this.count += argument.intValue(); // possible NPE
+ }
+ }
+
+ public static class LocalCommand
+ extends CommandAdapter
+ {
+ public int count = 0;
+
+ @Override
+ public void execute() {
+ this.count++;
+ }
+ }
+
+ public static class LocalInterruptibleCommand
+ extends InterruptibleCommandAdapter
+ {
+ public int count = 0;
+
+ @Override
+ public void execute() {
+ this.count++;
+ }
+ }
+
+ public static class LocalFactory<T>
+ extends FactoryAdapter<T>
+ {
+ public int count = 0;
+
+ @Override
+ public T create() {
+ this.count++;
+ return null;
+ }
+ }
+
+ public static class LocalInterruptibleFactory<T>
+ extends InterruptibleFactoryAdapter<T>
+ {
+ public int count = 0;
+
+ @Override
+ public T create() throws InterruptedException {
+ this.count++;
+ return null;
+ }
+ }
+
+ public static class LocalTransformer<I, O>
+ extends TransformerAdapter<I, O>
+ {
+ public int count = 0;
+
+ @Override
+ public O transform(I input) {
+ this.count++;
+ return null;
+ }
+ }
+
+ public static class LocalInterruptibleTransformer<I, O>
+ extends InterruptibleTransformerAdapter<I, O>
+ {
+ public int count = 0;
+
+ @Override
+ public O transform(I input) throws InterruptedException {
+ this.count++;
+ return null;
+ }
+ }
+}
diff --git a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/closure/JptCommonUtilityClosureTests.java b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/closure/JptCommonUtilityClosureTests.java
index 40f8b348ec..cf0c333f35 100644
--- a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/closure/JptCommonUtilityClosureTests.java
+++ b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/closure/JptCommonUtilityClosureTests.java
@@ -20,7 +20,9 @@ public class JptCommonUtilityClosureTests {
public static Test suite() {
TestSuite suite = new TestSuite(JptCommonUtilityClosureTests.class.getPackage().getName());
+ suite.addTestSuite(BiClosureToolsTests.class);
suite.addTestSuite(BooleanClosureTests.class);
+ suite.addTestSuite(ClosureToolsTests.class);
suite.addTestSuite(NullableBooleanClosureTests.class);
return suite;

Back to the top