diff --git a/README.md b/README.md
index 55c7d24..f381bbe 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[](https://search.maven.org/search?q=g:com.github.cowwoc.pouch) [](http://cowwoc.github.io/pouch/5.3/docs/api/) [](docs/Changelog.md)
+[](https://search.maven.org/search?q=g:com.github.cowwoc.pouch) [](http://cowwoc.github.io/pouch/5.4/docs/api/) [](docs/Changelog.md)
[](../../actions?query=workflow%3ABuild)
#
Pouch: Inversion of Control for the Masses
@@ -20,7 +20,7 @@ To get started, add this Maven dependency:
com.github.cowwoc.pouch
core
- 5.3
+ 5.4
```
@@ -50,7 +50,9 @@ public enum RunMode
```
```java
-public interface JvmScope extends AutoCloseable
+import com.github.cowwoc.pouch.core.Scope;
+
+public interface JvmScope extends Scope
{
RunMode getRunMode();
}
@@ -101,7 +103,7 @@ import org.eclipse.jetty.client.HttpClient;
import java.net.URI;
-public interface ClientScope
+public interface ClientScope extends Scope
{
URI getServer();
@@ -135,10 +137,10 @@ For example, notice how `AbstractDatabaseScope.getRunMode()` delegates to `JvmSc
### Waiting for Child Scopes to Shut Down
-When running in a multi-threaded environment, such as a web server, you might want to wait for ongoing HTTP
+When running in a multithreaded environment, such as a web server, you might want to wait for ongoing HTTP
requests to complete before shutting down the server.
You can use the
-[ConcurrentChildScopes](https://cowwoc.github.io/pouch/5.3/docs/api/com.github.cowwoc.pouch.core/com/github/cowwoc/pouch/core/ConcurrentChildScopes.html)
+[ConcurrentChildScopes](https://cowwoc.github.io/pouch/5.4/docs/api/com.github.cowwoc.pouch.core/com/github/cowwoc/pouch/core/ConcurrentChildScopes.html)
class to implement this as follows:
```java
@@ -588,9 +590,9 @@ The scope approach makes it easier to look up multiple values, or pass the scope
The library contains two types of classes: ones that are thread-safe and ones that are not.
For example,
-[ConcurrentLazyFactory](https://cowwoc.github.io/pouch/5.3/docs/api/com.github.cowwoc.pouch.core/com/github/cowwoc/pouch/core/ConcurrentLazyFactory.html)
+[ConcurrentLazyFactory](https://cowwoc.github.io/pouch/5.4/docs/api/com.github.cowwoc.pouch.core/com/github/cowwoc/pouch/core/ConcurrentLazyFactory.html)
is the thread-safe equivalent
-of [LazyFactory](https://cowwoc.github.io/pouch/5.3/docs/api/com.github.cowwoc.pouch.core/com/github/cowwoc/pouch/core/LazyFactory.html).
+of [LazyFactory](https://cowwoc.github.io/pouch/5.4/docs/api/com.github.cowwoc.pouch.core/com/github/cowwoc/pouch/core/LazyFactory.html).
`LazyFactory` is faster than `ConcurrentLazyFactory`, but doesn't support access from multiple threads.
Classes that are required to support multithreaded access
(such as the application scope) must use the thread-safe classes.
diff --git a/core/src/main/java/com/github/cowwoc/pouch/core/AbstractScope.java b/core/src/main/java/com/github/cowwoc/pouch/core/AbstractScope.java
new file mode 100644
index 0000000..c353bd8
--- /dev/null
+++ b/core/src/main/java/com/github/cowwoc/pouch/core/AbstractScope.java
@@ -0,0 +1,44 @@
+package com.github.cowwoc.pouch.core;
+
+/**
+ * The default implementation of {@link Scope}.
+ */
+public abstract class AbstractScope implements Scope
+{
+ /**
+ * The child scopes.
+ */
+ protected final ConcurrentChildScopes children = new ConcurrentChildScopes();
+
+ /**
+ * Creates new scope.
+ */
+ protected AbstractScope()
+ {
+ }
+
+ @Override
+ public void addChild(Scope child)
+ {
+ ensureOpen();
+ children.add(child);
+ }
+
+ @Override
+ public void removeChild(Scope child)
+ {
+ ensureOpen();
+ children.remove(child);
+ }
+
+ /**
+ * Ensures that the scope is open.
+ *
+ * @throws IllegalStateException if the scope is closed
+ */
+ protected void ensureOpen()
+ {
+ if (isClosed())
+ throw new IllegalStateException("Scope is closed");
+ }
+}
\ No newline at end of file
diff --git a/docs/changelog.md b/docs/changelog.md
index bbb47a5..e17fd68 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -1,9 +1,13 @@
Minor updates involving cosmetic changes have been omitted from this list. See [commits](../../commits/master)
for a full list.
+## Version 5.4 - 2024/12/29
+
+* Added `AbstractScope`.
+
## Version 5.3 - 2024/12/29
-* Added a common definition of a `Scope`.
+* Added `Scope`.
## Version 5.2 - 2024/12/12
diff --git a/docs/frequently_asked_questions.md b/docs/frequently_asked_questions.md
index 415a7d9..fc471e0 100644
--- a/docs/frequently_asked_questions.md
+++ b/docs/frequently_asked_questions.md
@@ -156,12 +156,12 @@ Ease of use and substantially reduced size.
Guava provides comparable functionality:
-* [Reference](https://cowwoc.github.io/pouch/5.3/docs/api/com.github.cowwoc.pouch.core/com/github/cowwoc/pouch/core/Reference.html) <->
+* [Reference](https://cowwoc.github.io/pouch/5.4/docs/api/com.github.cowwoc.pouch.core/com/github/cowwoc/pouch/core/Reference.html) <->
[Supplier](https://guava.dev/releases/32.1.1-jre/api/docs/com/google/common/base/Supplier.html)
-* [ConstantReference](https://cowwoc.github.io/pouch/5.3/docs/api/com.github.cowwoc.pouch.core/com/github/cowwoc/pouch/core/ConstantReference.html)
+* [ConstantReference](https://cowwoc.github.io/pouch/5.4/docs/api/com.github.cowwoc.pouch.core/com/github/cowwoc/pouch/core/ConstantReference.html)
<->
[Suppliers.ofInstance()](https://guava.dev/releases/32.1.1-jre/api/docs/com/google/common/base/Suppliers.html#ofInstance-T-)
-* [LazyReference](https://cowwoc.github.io/pouch/5.3/docs/api/com.github.cowwoc.pouch.core/com/github/cowwoc/pouch/core/LazyReference.html) <->
+* [LazyReference](https://cowwoc.github.io/pouch/5.4/docs/api/com.github.cowwoc.pouch.core/com/github/cowwoc/pouch/core/LazyReference.html) <->
[Suppliers.memoize()](https://guava.dev/releases/32.1.1-jre/api/docs/com/google/common/base/Suppliers.html#memoize-com.google.common.base.Supplier-)
While it is true
@@ -175,12 +175,12 @@ For example:
1. [Suppliers.memoize()](https://guava.dev/releases/32.1.1-jre/api/docs/com/google/common/base/Suppliers.html#memoize-com.google.common.base.Supplier-)
doesn't provide a mechanism for checking whether the underlying value has been initialized.
This is important because, when implementing
- [Factory.close()](https://cowwoc.github.io/pouch/5.3/docs/api/com.github.cowwoc.pouch.core/com/github/cowwoc/pouch/core/Factory.html#close()),
+ [Factory.close()](https://cowwoc.github.io/pouch/5.4/docs/api/com.github.cowwoc.pouch.core/com/github/cowwoc/pouch/core/Factory.html#close()),
you'll want to avoid initializing values that have never been initialized before.
2. This library provides convenience classes such as
- [LazyFactory](https://cowwoc.github.io/pouch/5.3/docs/api/com.github.cowwoc.pouch.core/com/github/cowwoc/pouch/core/LazyFactory.html)
+ [LazyFactory](https://cowwoc.github.io/pouch/5.4/docs/api/com.github.cowwoc.pouch.core/com/github/cowwoc/pouch/core/LazyFactory.html)
which unifies classes
- [LazyReference](https://cowwoc.github.io/pouch/5.3/docs/api/com.github.cowwoc.pouch.core/com/github/cowwoc/pouch/core/LazyReference.html)
+ [LazyReference](https://cowwoc.github.io/pouch/5.4/docs/api/com.github.cowwoc.pouch.core/com/github/cowwoc/pouch/core/LazyReference.html)
and [Closeable](http://docs.oracle.com/javase/8/docs/api/java/io/Closeable.html) into a single class.
The size of the Guava library is 2.8MB.