001/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*- 002 * 003 * Copyright © 2023–2024 microBean™. 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 006 * the License. You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 011 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 012 * specific language governing permissions and limitations under the License. 013 */ 014package org.microbean.bean; 015 016/** 017 * A reigstry of {@link AutoCloseable} instances that itself is {@link AutoCloseable}. 018 * 019 * <p>{@linkplain #close() Closing} an {@link AutoCloseableRegistry} {@linkplain AutoCloseable#close() closes} its 020 * registrants.</p> 021 * 022 * @author <a href="https://about.me/lairdnelson/" target="_top">Laird Nelson</a> 023 * 024 * @see #register(AutoCloseable) 025 */ 026public interface AutoCloseableRegistry extends AutoCloseable { 027 028 /** 029 * Returns a new {@link AutoCloseableRegistry} instance that is not {@linkplain #closed() closed}, has no {@linkplain 030 * #register(AutoCloseable) registrations} yet, and is {@linkplain #register(AutoCloseable) registered} with this 031 * {@link AutoCloseableRegistry}. 032 * 033 * <p>The new {@link AutoCloseableRegistry} child therefore functions as an intermediate or leaf node in a tree of 034 * {@link AutoCloseable} implementations, such that if any node of the tree is {@linkplain AutoCloseable#close() 035 * closed}, all of its descendants will be {@linkplain AutoCloseable#close() closed} as well.</p> 036 * 037 * @return a new, {@linkplain #closed() unclosed} {@link AutoCloseableRegistry} {@linkplain #register(AutoCloseable) 038 * registered} with this {@link AutoCloseableRegistry} that functions as an intermediate or leaf node in a tree of 039 * such nodes 040 * 041 * @exception IllegalStateException if this {@link AutoCloseableRegistry} is {@linkplain #closed() closed} 042 * 043 * @nullability Implementations of this method must not return {@code null}. 044 * 045 * @idempotency All successful invocations of implementations of this method must return new, distinct {@link 046 * AutoCloseableRegistry} instances. 047 * 048 * @threadsafety Implementations of this method must be safe for concurrent use by multiple threads. 049 * 050 * @see #register(AutoCloseable) 051 */ 052 public AutoCloseableRegistry newChild(); 053 054 /** 055 * Closes this {@link AutoCloseableRegistry} and {@linkplain AutoCloseable#close() closes} its {@linkplain 056 * #register(AutoCloseable) registrants}. 057 * 058 * <p>After any successful invocation of this method, an invocation of the {@link #closed()} method must forever after 059 * return {@code true}.</p> 060 * 061 * @idempotency Implementations of this method must be idempotent. 062 * 063 * @threadsafety Implementations of this method must be safe for concurrent use by multiple threads. 064 * 065 * @see #closed() 066 */ 067 @Override // AutoCloseable 068 public void close(); 069 070 /** 071 * Returns {@code true} if and only if this {@link AutoCloseableRegistry} is {@linkplain #close() closed}. 072 * 073 * <p>Once an invocation of this method has returned {@code true}, on any thread, subsequent invocations must also 074 * return {@code true}, on any thread.</p> 075 * 076 * <p>An implementation of this method must return {@code false} until an invocation of the {@link #close()} method 077 * has successfully completed, and must return {@code true} thereafter.</p> 078 * 079 * @return {@code true} if and only if this {@link AutoCloseableRegistry} is {@linkplain #close() closed} 080 * 081 * @idempotency Implementations of this method must be idempotent. 082 * 083 * @threadsafety Implementations of this method must be safe for concurrent use by multiple threads. 084 * 085 * @see #close() 086 */ 087 public boolean closed(); 088 089 /** 090 * If this {@link AutoCloseableRegistry} is not {@linkplain #closed() closed}, and if the supplied {@link 091 * AutoCloseable} has not yet been registered, registers it such that it will be {@linkplain AutoCloseable#close() 092 * closed} when this {@link AutoCloseableRegistry} is {@linkplain #close() closed}, and returns {@code true}. 093 * 094 * <p>This method takes no action and returns {@code false} in all other cases.</p> 095 * 096 * @param closeable the {@link AutoCloseable} to register; must not be {@code null} 097 * 098 * @return {@code true} if and only if this {@link AutoCloseableRegistry} is not {@linkplain #closed() closed} and the 099 * supplied {@link AutoCloseable} is not already registered and registration completed successfully; {@code false} in 100 * all other cases 101 * 102 * @exception NullPointerException if {@code closeable} is {@code null} 103 * 104 * @idempotency Implementations of this method must be idempotent. 105 * 106 * @threadsafety Implementations of this method must be safe for concurrent use by multiple threads. 107 */ 108 public boolean register(final AutoCloseable closeable); 109 110}