org.junit.jupiter.engine.execution.ExtensionValuesStore Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of junit-jupiter-engine Show documentation
Show all versions of junit-jupiter-engine Show documentation
Module "junit-jupiter-engine" of JUnit 5.
/*
* Copyright 2015-2021 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
* accompanies this distribution and is available at
*
* https://www.eclipse.org/legal/epl-v20.html
*/
package org.junit.jupiter.engine.execution;
import static org.apiguardian.api.API.Status.INTERNAL;
import static org.junit.jupiter.engine.support.JupiterThrowableCollectorFactory.createThrowableCollector;
import static org.junit.platform.commons.util.ReflectionUtils.getWrapperType;
import static org.junit.platform.commons.util.ReflectionUtils.isAssignableTo;
import java.util.Comparator;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Function;
import java.util.function.Supplier;
import org.apiguardian.api.API;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
import org.junit.jupiter.api.extension.ExtensionContext.Store.CloseableResource;
import org.junit.jupiter.api.extension.ExtensionContextException;
import org.junit.platform.engine.support.hierarchical.ThrowableCollector;
/**
* {@code ExtensionValuesStore} is used inside implementations of
* {@link ExtensionContext} to store and retrieve values.
*
* @since 5.0
*/
@API(status = INTERNAL, since = "5.0")
public class ExtensionValuesStore {
private static final Comparator REVERSE_INSERT_ORDER = Comparator. comparing(
it -> it.order).reversed();
private final AtomicInteger insertOrderSequence = new AtomicInteger();
private final ConcurrentMap storedValues = new ConcurrentHashMap<>(4);
private final ExtensionValuesStore parentStore;
public ExtensionValuesStore(ExtensionValuesStore parentStore) {
this.parentStore = parentStore;
}
/**
* Close all values that implement {@link CloseableResource}.
*
* @implNote Only close values stored in this instance. This implementation
* does not close values in parent stores.
*/
public void closeAllStoredCloseableValues() {
ThrowableCollector throwableCollector = createThrowableCollector();
storedValues.values().stream() //
.filter(storedValue -> storedValue.evaluateSafely() instanceof CloseableResource) //
.sorted(REVERSE_INSERT_ORDER) //
.map(storedValue -> (CloseableResource) storedValue.evaluate()) //
.forEach(resource -> throwableCollector.execute(resource::close));
throwableCollector.assertEmpty();
}
Object get(Namespace namespace, Object key) {
StoredValue storedValue = getStoredValue(new CompositeKey(namespace, key));
return (storedValue != null ? storedValue.evaluate() : null);
}
T get(Namespace namespace, Object key, Class requiredType) {
Object value = get(namespace, key);
return castToRequiredType(key, value, requiredType);
}
Object getOrComputeIfAbsent(Namespace namespace, K key, Function defaultCreator) {
CompositeKey compositeKey = new CompositeKey(namespace, key);
StoredValue storedValue = getStoredValue(compositeKey);
if (storedValue == null) {
StoredValue newValue = storedValue(new MemoizingSupplier(() -> defaultCreator.apply(key)));
storedValue = Optional.ofNullable(storedValues.putIfAbsent(compositeKey, newValue)).orElse(newValue);
}
return storedValue.evaluate();
}
V getOrComputeIfAbsent(Namespace namespace, K key, Function defaultCreator, Class requiredType) {
Object value = getOrComputeIfAbsent(namespace, key, defaultCreator);
return castToRequiredType(key, value, requiredType);
}
void put(Namespace namespace, Object key, Object value) {
storedValues.put(new CompositeKey(namespace, key), storedValue(() -> value));
}
private StoredValue storedValue(Supplier
© 2015 - 2024 Weber Informatics LLC | Privacy Policy