Skip to content

Commit

Permalink
Make creating LauncherSessionListeners interceptable
Browse files Browse the repository at this point in the history
  • Loading branch information
marcphilipp committed Jan 10, 2023
1 parent d65913c commit 27b738f
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
package org.junit.platform.launcher;

import static org.apiguardian.api.API.Status.EXPERIMENTAL;
import static org.apiguardian.api.API.Status.INTERNAL;

import java.util.List;

import org.apiguardian.api.API;

Expand All @@ -28,6 +31,18 @@
@API(status = EXPERIMENTAL, since = "1.10")
public interface LauncherInterceptor {

LauncherInterceptor NOOP = new LauncherInterceptor() {
@Override
public <T> T intercept(Invocation<T> invocation) {
return invocation.proceed();
}

@Override
public void close() {
// do nothing
}
};

/**
* Intercept the supplied invocation.
*
Expand All @@ -54,4 +69,29 @@ public interface LauncherInterceptor {
interface Invocation<T> {
T proceed();
}

@API(status = INTERNAL, since = "1.10")
static LauncherInterceptor composite(List<LauncherInterceptor> interceptors) {
if (interceptors.isEmpty()) {
return NOOP;
}
return interceptors.stream() //
.skip(1) //
.reduce(interceptors.get(0), (a, b) -> new LauncherInterceptor() {
@Override
public void close() {
try {
a.close();
}
finally {
b.close();
}
}

@Override
public <T> T intercept(Invocation<T> invocation) {
return a.intercept(() -> b.intercept(invocation));
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ class DefaultLauncherSession implements LauncherSession {

DefaultLauncherSession(List<LauncherInterceptor> interceptors, Supplier<Launcher> launcherSupplier,
Supplier<LauncherSessionListener> listenerSupplier) {
this.listener = listenerSupplier.get();
CloseableLauncher closeableLauncher = InterceptingClosableLauncher.decorate(launcherSupplier, interceptors);
LauncherInterceptor interceptor = LauncherInterceptor.composite(interceptors);
this.listener = interceptor.intercept(listenerSupplier::get);
Launcher launcher = interceptor.intercept(launcherSupplier::get);
CloseableLauncher closeableLauncher = new InterceptingClosableLauncher(launcher, interceptor);
this.launcher = new DelegatingCloseableLauncher<>(closeableLauncher, delegate -> {
delegate.close();
return ClosedLauncher.INSTANCE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,6 @@

package org.junit.platform.launcher.core;

import static java.util.function.Function.identity;

import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;

import org.junit.platform.launcher.Launcher;
import org.junit.platform.launcher.LauncherDiscoveryRequest;
import org.junit.platform.launcher.LauncherInterceptor;
Expand All @@ -27,42 +21,9 @@
*/
class InterceptingClosableLauncher extends DelegatingCloseableLauncher<Launcher> {

static CloseableLauncher decorate(Supplier<Launcher> launcherSupplier, List<LauncherInterceptor> interceptors) {
Optional<LauncherInterceptor> combinedInterceptor = composite(interceptors);
Launcher launcher = combinedInterceptor.map(it -> it.intercept(launcherSupplier::get)).orElseGet(
launcherSupplier);
return combinedInterceptor //
.map(it -> (CloseableLauncher) new InterceptingClosableLauncher(launcher, it)) //
.orElse(new DelegatingCloseableLauncher<>(launcher, identity()));
}

private static Optional<LauncherInterceptor> composite(List<LauncherInterceptor> interceptors) {
if (interceptors.isEmpty()) {
return Optional.empty();
}
return Optional.of(interceptors.stream() //
.skip(1) //
.reduce(interceptors.get(0), (a, b) -> new LauncherInterceptor() {
@Override
public void close() {
try {
a.close();
}
finally {
b.close();
}
}

@Override
public <T> T intercept(Invocation<T> invocation) {
return a.intercept(() -> b.intercept(invocation));
}
}));
}

private final LauncherInterceptor interceptor;

private InterceptingClosableLauncher(Launcher delegate, LauncherInterceptor interceptor) {
InterceptingClosableLauncher(Launcher delegate, LauncherInterceptor interceptor) {
super(delegate, it -> {
interceptor.close();
return it;
Expand Down

0 comments on commit 27b738f

Please sign in to comment.