package xapi.api; import xapi.fu.In1Out1; import java.util.Optional; import java.util.function.Predicate; /** * @author James X. Nelson (james@wetheinter.net) * Created on 2/14/16. */ public interface Scope { interface GlobalScope <UserType> extends Scope { <RequestType> SessionScope<UserType, RequestType> getSessionScope(UserType user); } interface SessionScope <UserType, RequestType> extends Scope { UserType getUser(); RequestScope getRequestScope(RequestType request); } interface RequestScope extends Scope { } interface LocalScope extends Scope {} boolean isReleased(); <T, C extends Class<? extends T>> T get(C cls); <T, C extends Class<? extends T>> T set(C cls, T value); void release(); Scope getParent(); default <S extends Scope> Optional<S> findParent(Class<S> type, boolean exactMatch) { Scope current = this; Predicate<Class> matcher = exactMatch ? type::equals : type::isAssignableFrom; while (current != null) { if (matcher.test(current.getClass())) { return Optional.of((S)current); } current = current.getParent(); } return Optional.empty(); } <K, T> T getOrCreate(K key, In1Out1<K, String> keyProvider, In1Out1<K, T> factory); default <T> T getOrCreate(String key, In1Out1<String, T> factory) { return getOrCreate(key, String::toString, factory); } }