diff --git a/README.md b/README.md
index e2a3332..75bb778 100644
--- a/README.md
+++ b/README.md
@@ -48,7 +48,8 @@ The purpose of **Inspectable Wrappers** is to provide a standard for wrapper cha
enhance the wrapper instances with the attachment storage ability
- [`WrapperAdapter`](src/main/java/io/foldright/inspectablewrappers/WrapperAdapter.java) interface is used to
adapt an existed wrapper instance to type `Wrapper` without modifying it
-- The [`Inspector`](src/main/java/io/foldright/inspectablewrappers/Inspector.java) class is used to inspect the **wrapper
+- The [`Inspector`](src/main/java/io/foldright/inspectablewrappers/Inspector.java) class is used to inspect the *
+ *wrapper
chain**
## 🌰 Usage Demo
@@ -125,10 +126,10 @@ public class Demo {
////////////////////////////////////////
System.out.println("Is executor lazy? " +
- Inspector.isInstanceOf(executor, LazyExecutorWrapper.class));
+ containsInstanceOnWrapperChain(executor, LazyExecutorWrapper.class));
// print true
- String busy = Inspector.getAttachment(executor, "busy");
+ String busy = getAttachmentFromWrapperChain(executor, "busy");
System.out.println("Is executor busy? " + busy);
// print "very, very busy!"
@@ -205,9 +206,9 @@ public class IntegrationDemo {
////////////////////////////////////////
System.out.println("Is executor ExistedExecutorWrapper? " +
- Inspector.isInstanceOf(executor, ExistedExecutorWrapper.class));
+ containsInstanceOnWrapperChain(executor, ExistedExecutorWrapper.class));
// print true
- String adaptAttachment = Inspector.getAttachment(executor, "adapted-existed-executor-wrapper-msg");
+ String adaptAttachment = getAttachmentFromWrapperChain(executor, "adapted-existed-executor-wrapper-msg");
System.out.println("Adapted existed executor wrapper msg: " + adaptAttachment);
// print "I'm an adapter of an existed executor which have nothing to do with ~inspectable~wrappers~."
diff --git a/src/main/java/io/foldright/inspectablewrappers/Attachable.java b/src/main/java/io/foldright/inspectablewrappers/Attachable.java
index 28ac45b..5445713 100644
--- a/src/main/java/io/foldright/inspectablewrappers/Attachable.java
+++ b/src/main/java/io/foldright/inspectablewrappers/Attachable.java
@@ -8,7 +8,8 @@
* This {@code Attachable} interface is used to be implemented by wrapper classes,
* provide the attachment storage ability.
*
- * Retrieves the attachment from wrapper chain the static method {@link Inspector#getAttachment(Object, Object)}.
+ * Retrieves the attachment from wrapper chain
+ * by method {@link Inspector#getAttachmentFromWrapperChain(Object, Object)}.
*
* Provided {@link io.foldright.inspectablewrappers.utils.AttachableDelegate AttachableDelegate}
* as a simple delegate implementation.
@@ -17,7 +18,7 @@
* @param the value type to be stored
* @author Jerry Lee (oldratlee at gmail dot com)
* @author Yang Fang (snoop dot fy at gmail dot com)
- * @see Inspector#getAttachment(Object, Object)
+ * @see Inspector#getAttachmentFromWrapperChain(Object, Object)
* @see io.foldright.inspectablewrappers.utils.AttachableDelegate
*/
public interface Attachable {
@@ -37,7 +38,7 @@ public interface Attachable {
* @return return the attachment value, or {@code null} if contains no attachment for the key
* @throws NullPointerException if key argument is null
* @throws ClassCastException if the return value is not type {@code }
- * @see Inspector#getAttachment(Object, Object)
+ * @see Inspector#getAttachmentFromWrapperChain(Object, Object)
*/
@Nullable
V getAttachment(@NonNull K key);
diff --git a/src/main/java/io/foldright/inspectablewrappers/Inspector.java b/src/main/java/io/foldright/inspectablewrappers/Inspector.java
index 7c1f172..43c6829 100644
--- a/src/main/java/io/foldright/inspectablewrappers/Inspector.java
+++ b/src/main/java/io/foldright/inspectablewrappers/Inspector.java
@@ -18,21 +18,29 @@
* Common simple usages
*
* - Reports whether any instance on the wrapper chain matches the given type
- * by static method {@link #isInstanceOf(Object, Class)}
+ * by static method {@link #containsInstanceOnWrapperChain(Object, Class)}
*
- Retrieves the attachment of instance on the wrapper chain
- * by static method {@link #getAttachment(Object, Object)}
+ * by static method {@link #getAttachmentFromWrapperChain(Object, Object)}
*
*
* Advanced usages
*
* - Reports whether any instance on the wrapper chain satisfy the given {@link Predicate}
- * by static method {@link #inspect(Object, Predicate)}
+ * by static method {@link #testWrapperChain(Object, Predicate)}
*
- Traverses the wrapper chain and applies the given {@link Function} to each instance on the wrapper chain
- * by static method {@link #travel(Object, Function)}
+ * by static method {@link #travelWrapperChain(Object, Function)}
*
*
* You can implement your own inspection logic using above advanced methods.
*
+ *
Note about usage and methods naming
+ *
+ * All method names contain the word "wrapper chain",
+ * so the usage code is easily recognizable as related to {@code inspectable wrappers}.
+ *
+ * Because the method names are long and informative,
+ * it's recommended to {@code static import} these methods.
+ *
* @author Jerry Lee (oldratlee at gmail dot com)
* @author Zava Xu (zava dot kid at gmail dot com)
* @see Wrapper
@@ -47,19 +55,26 @@ public final class Inspector {
* The wrapper chain consists of wrapper itself, followed by the wrappers
* obtained by repeatedly calling {@link Wrapper#unwrap()}.
*
- * @param wrapper wrapper instance/wrapper chain
- * @param clazz target type
- * @param the type of instances that be wrapped
+ * @param wrapper wrapper instance/wrapper chain
+ * @param instanceType target type
+ * @param the type of instances that be wrapped
* @return return {@code false} if no wrapper on the wrapper chain matches the given type,
* otherwise return {@code true}
- * @throws NullPointerException if any arguments is null or any wrapper {@link Wrapper#unwrap()} returns null
+ * @throws NullPointerException if any arguments is null,
+ * or any wrapper {@link Wrapper#unwrap()} returns null,
+ * or the adaptee of {@link WrapperAdapter} is null
* @throws IllegalStateException if the adaptee of {@link WrapperAdapter} is type {@link Wrapper}
+ * @see Wrapper#unwrap()
* @see WrapperAdapter#adaptee()
*/
- public static boolean isInstanceOf(final W wrapper, final Class> clazz) {
+ public static boolean containsInstanceOnWrapperChain(final W wrapper, final Class> instanceType) {
requireNonNull(wrapper, "wrapper is null");
- requireNonNull(clazz, "clazz is null");
- return inspect(wrapper, w -> clazz.isAssignableFrom(w.getClass()));
+ requireNonNull(instanceType, "instanceType is null");
+ return testWrapperChain(wrapper, w -> isInstanceOf(w, instanceType));
+ }
+
+ private static boolean isInstanceOf(final Object o, final Class> clazz) {
+ return clazz.isAssignableFrom(o.getClass());
}
/**
@@ -78,17 +93,19 @@ public static boolean isInstanceOf(final W wrapper, final Class> clazz) {
* @param the type of attachment value
* @return the attachment value of wrapper for given key on the wrapper chain,
* or null if the attachment is absent
- * @throws NullPointerException if any arguments is null or any wrapper {@link Wrapper#unwrap()} returns null
+ * @throws NullPointerException if any arguments is null,
+ * or any wrapper {@link Wrapper#unwrap()} returns null,
+ * or the adaptee of {@link WrapperAdapter} is null
* @throws ClassCastException if the return value is not type {@code }
* @throws IllegalStateException if the adaptee of {@link WrapperAdapter} is type {@link Wrapper}
* @see Attachable#getAttachment(Object)
*/
@Nullable
@SuppressWarnings("unchecked")
- public static V getAttachment(final W wrapper, final K key) {
+ public static V getAttachmentFromWrapperChain(final W wrapper, final K key) {
requireNonNull(wrapper, "wrapper is null");
requireNonNull(key, "key is null");
- return travel(wrapper, w -> {
+ return travelWrapperChain(wrapper, w -> {
if (w instanceof Attachable) {
V value = ((Attachable) w).getAttachment(key);
return Optional.ofNullable(value);
@@ -109,13 +126,15 @@ public static V getAttachment(final W wrapper, final K key) {
* @param the type of instances that be wrapped
* @return return {@code false} if no wrapper on the wrapper chain satisfy the given {@code predicate},
* otherwise return {@code true}
- * @throws NullPointerException if any arguments is null or any wrapper {@link Wrapper#unwrap()} returns null
+ * @throws NullPointerException if any arguments is null,
+ * or any wrapper {@link Wrapper#unwrap()} returns null,
+ * or the adaptee of {@link WrapperAdapter} is null
* @throws IllegalStateException if the adaptee of {@link WrapperAdapter} is type {@link Wrapper}
*/
- public static boolean inspect(final W wrapper, final Predicate super W> predicate) {
+ public static boolean testWrapperChain(final W wrapper, final Predicate super W> predicate) {
requireNonNull(wrapper, "wrapper is null");
requireNonNull(predicate, "predicate is null");
- return travel(wrapper, w -> {
+ return travelWrapperChain(wrapper, w -> {
if (predicate.test(w)) return Optional.of(true);
else return Optional.empty();
}).orElse(false);
@@ -135,12 +154,14 @@ public static boolean inspect(final W wrapper, final Predicate super W> pr
* @param the return data type of process function
* @return the first non-empty({@link Optional#empty()}) result of the process function,
* otherwise returns {@link Optional#empty()}
- * @throws NullPointerException if any arguments is null or any wrapper {@link Wrapper#unwrap()} returns null
+ * @throws NullPointerException if any arguments is null,
+ * or any wrapper {@link Wrapper#unwrap()} returns null,
+ * or the adaptee of {@link WrapperAdapter} is null
* @throws IllegalStateException if the adaptee of {@link WrapperAdapter} is type {@link Wrapper}
*/
@NonNull
@SuppressWarnings("unchecked")
- public static Optional travel(final W wrapper, final Function super W, Optional> process) {
+ public static Optional travelWrapperChain(final W wrapper, final Function super W, Optional> process) {
requireNonNull(wrapper, "wrapper is null");
requireNonNull(process, "process is null");
diff --git a/src/test/java/io/foldright/demo/Demo.java b/src/test/java/io/foldright/demo/Demo.java
index 578284d..6bc4901 100644
--- a/src/test/java/io/foldright/demo/Demo.java
+++ b/src/test/java/io/foldright/demo/Demo.java
@@ -4,6 +4,9 @@
import java.util.concurrent.Executor;
+import static io.foldright.inspectablewrappers.Inspector.containsInstanceOnWrapperChain;
+import static io.foldright.inspectablewrappers.Inspector.getAttachmentFromWrapperChain;
+
public class Demo {
public static void main(String[] args) {
@@ -14,10 +17,10 @@ public static void main(String[] args) {
////////////////////////////////////////
System.out.println("Is executor lazy? " +
- Inspector.isInstanceOf(executor, LazyExecutorWrapper.class));
+ containsInstanceOnWrapperChain(executor, LazyExecutorWrapper.class));
// print true
- String busy = Inspector.getAttachment(executor, "busy");
+ String busy = getAttachmentFromWrapperChain(executor, "busy");
System.out.println("Is executor busy? " + busy);
// print "very, very busy!"
diff --git a/src/test/java/io/foldright/demo/integration/ExistedExecutorWrapper.java b/src/test/java/io/foldright/demo/integration/ExistedExecutorWrapper.java
index 458eed8..7524247 100644
--- a/src/test/java/io/foldright/demo/integration/ExistedExecutorWrapper.java
+++ b/src/test/java/io/foldright/demo/integration/ExistedExecutorWrapper.java
@@ -21,7 +21,7 @@ public Executor getExecutor() {
@Override
public void execute(Runnable command) {
- System.out.println("I'm a adapter of an existed executor which have nothing to do with ~inspectable~wrappers~.");
+ System.out.println("I'm existed executor, have nothing to do with ~inspectable~wrappers~.");
executor.execute(command);
}
}
diff --git a/src/test/java/io/foldright/demo/integration/IntegrationDemo.java b/src/test/java/io/foldright/demo/integration/IntegrationDemo.java
index 53d0983..b8ca703 100644
--- a/src/test/java/io/foldright/demo/integration/IntegrationDemo.java
+++ b/src/test/java/io/foldright/demo/integration/IntegrationDemo.java
@@ -4,13 +4,15 @@
import edu.umd.cs.findbugs.annotations.ReturnValuesAreNonnullByDefault;
import io.foldright.demo.ChattyExecutorWrapper;
import io.foldright.inspectablewrappers.Attachable;
-import io.foldright.inspectablewrappers.Inspector;
import io.foldright.inspectablewrappers.WrapperAdapter;
import io.foldright.inspectablewrappers.utils.AttachableDelegate;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.concurrent.Executor;
+import static io.foldright.inspectablewrappers.Inspector.containsInstanceOnWrapperChain;
+import static io.foldright.inspectablewrappers.Inspector.getAttachmentFromWrapperChain;
+
@ParametersAreNonnullByDefault
@ReturnValuesAreNonnullByDefault
@@ -23,9 +25,9 @@ public static void main(String[] args) {
////////////////////////////////////////
System.out.println("Is executor ExistedExecutorWrapper? " +
- Inspector.isInstanceOf(executor, ExistedExecutorWrapper.class));
+ containsInstanceOnWrapperChain(executor, ExistedExecutorWrapper.class));
// print true
- String adaptAttachment = Inspector.getAttachment(executor, "adapted-existed-executor-wrapper-msg");
+ String adaptAttachment = getAttachmentFromWrapperChain(executor, "adapted-existed-executor-wrapper-msg");
System.out.println("Adapted existed executor wrapper msg: " + adaptAttachment);
// print "I'm an adapter of an existed executor which have nothing to do with ~inspectable~wrappers~."
diff --git a/src/test/java/io/foldright/inspectablewrappers/WrapperAdapterTest.kt b/src/test/java/io/foldright/inspectablewrappers/WrapperAdapterTest.kt
index f519bea..154e48e 100644
--- a/src/test/java/io/foldright/inspectablewrappers/WrapperAdapterTest.kt
+++ b/src/test/java/io/foldright/inspectablewrappers/WrapperAdapterTest.kt
@@ -1,5 +1,7 @@
package io.foldright.inspectablewrappers
+import io.foldright.inspectablewrappers.Inspector.containsInstanceOnWrapperChain
+import io.foldright.inspectablewrappers.Inspector.getAttachmentFromWrapperChain
import io.foldright.inspectablewrappers.utils.AttachableDelegate
import io.kotest.assertions.fail
import io.kotest.assertions.throwables.shouldThrow
@@ -25,20 +27,20 @@ class WrapperAdapterTest : FunSpec({
}.let(::ChattyExecutorWrapper)
test("WrapperAdapter") {
- Inspector.isInstanceOf(executorChain, ExistedExecutorWrapper::class.java).shouldBeTrue()
- Inspector.isInstanceOf(executorChain, ExistedExecutorWrapperAdapter::class.java).shouldBeTrue()
- Inspector.isInstanceOf(executorChain, ChattyExecutorWrapper::class.java).shouldBeTrue()
- Inspector.isInstanceOf(executorChain, ExecutorService::class.java).shouldBeFalse()
+ containsInstanceOnWrapperChain(executorChain, ExistedExecutorWrapper::class.java).shouldBeTrue()
+ containsInstanceOnWrapperChain(executorChain, ExistedExecutorWrapperAdapter::class.java).shouldBeTrue()
+ containsInstanceOnWrapperChain(executorChain, ChattyExecutorWrapper::class.java).shouldBeTrue()
+ containsInstanceOnWrapperChain(executorChain, ExecutorService::class.java).shouldBeFalse()
- val value: String? = Inspector.getAttachment(executorChain, ADAPTED_MSG_KEY)
+ val value: String? = getAttachmentFromWrapperChain(executorChain, ADAPTED_MSG_KEY)
value shouldBe ADAPTED_MSG_VALUE
- Inspector.getAttachment(executorChain, "not existed").shouldBeNull()
+ getAttachmentFromWrapperChain(executorChain, "not existed").shouldBeNull()
}
test("ClassCastException") {
shouldThrow {
- val value = Inspector.getAttachment(executorChain, ADAPTED_MSG_KEY)
+ val value = getAttachmentFromWrapperChain(executorChain, ADAPTED_MSG_KEY)
fail(value.toString())
}
}
@@ -46,15 +48,15 @@ class WrapperAdapterTest : FunSpec({
@Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
test("argument null") {
shouldThrow {
- Inspector.getAttachment(null, ADAPTED_MSG_KEY)
+ getAttachmentFromWrapperChain(null, ADAPTED_MSG_KEY)
}.message shouldBe "wrapper is null"
shouldThrow {
- Inspector.getAttachment(executorChain, null)
+ getAttachmentFromWrapperChain(executorChain, null)
}.message shouldBe "key is null"
}
- test("travel IllegalStateException - the adaptee of WrapperAdapter is a wrapper instance") {
+ test("travelWrapperChain IllegalStateException - the adaptee of WrapperAdapter is type wrapper") {
val chain: Executor = ChattyExecutorWrapper { runnable -> runnable.run() }
.let(::ChattyExecutorWrapperAdapter)
@@ -63,15 +65,15 @@ class WrapperAdapterTest : FunSpec({
" is type Wrapper, adapting a Wrapper to a Wrapper is unnecessary!"
shouldThrow {
- Inspector.isInstanceOf(chain, ExecutorService::class.java)
+ containsInstanceOnWrapperChain(chain, ExecutorService::class.java)
}.message shouldBe errMsg
// first instance is ok, not trigger the check logic yet...
- Inspector.isInstanceOf(chain, Executor::class.java).shouldBeTrue()
- Inspector.isInstanceOf(chain, ChattyExecutorWrapperAdapter::class.java).shouldBeTrue()
+ containsInstanceOnWrapperChain(chain, Executor::class.java).shouldBeTrue()
+ containsInstanceOnWrapperChain(chain, ChattyExecutorWrapperAdapter::class.java).shouldBeTrue()
shouldThrow {
- Inspector.getAttachment(chain, "k1")
+ getAttachmentFromWrapperChain(chain, "k1")
}.message shouldBe errMsg
}
})
diff --git a/src/test/java/io/foldright/inspectablewrappers/WrapperTest.kt b/src/test/java/io/foldright/inspectablewrappers/WrapperTest.kt
index e160a41..1adff05 100644
--- a/src/test/java/io/foldright/inspectablewrappers/WrapperTest.kt
+++ b/src/test/java/io/foldright/inspectablewrappers/WrapperTest.kt
@@ -1,5 +1,7 @@
package io.foldright.inspectablewrappers
+import io.foldright.inspectablewrappers.Inspector.containsInstanceOnWrapperChain
+import io.foldright.inspectablewrappers.Inspector.getAttachmentFromWrapperChain
import io.foldright.inspectablewrappers.utils.AttachableDelegate
import io.kotest.assertions.fail
import io.kotest.assertions.throwables.shouldThrow
@@ -19,19 +21,19 @@ class WrapperTest : FunSpec({
.let(::ChattyExecutorWrapper)
test("wrapper") {
- Inspector.isInstanceOf(executorChain, LazyExecutorWrapper::class.java).shouldBeTrue()
- Inspector.isInstanceOf(executorChain, ChattyExecutorWrapper::class.java).shouldBeTrue()
- Inspector.isInstanceOf(executorChain, ExecutorService::class.java).shouldBeFalse()
+ containsInstanceOnWrapperChain(executorChain, LazyExecutorWrapper::class.java).shouldBeTrue()
+ containsInstanceOnWrapperChain(executorChain, ChattyExecutorWrapper::class.java).shouldBeTrue()
+ containsInstanceOnWrapperChain(executorChain, ExecutorService::class.java).shouldBeFalse()
- val value: String? = Inspector.getAttachment(executorChain, "busy")
+ val value: String? = getAttachmentFromWrapperChain(executorChain, "busy")
value shouldBe "very, very busy!"
- Inspector.getAttachment(executorChain, "not existed").shouldBeNull()
+ getAttachmentFromWrapperChain(executorChain, "not existed").shouldBeNull()
}
test("ClassCastException") {
shouldThrow {
- val value = Inspector.getAttachment(executorChain, "busy")
+ val value = getAttachmentFromWrapperChain(executorChain, "busy")
fail(value.toString())
}
}
@@ -39,25 +41,25 @@ class WrapperTest : FunSpec({
@Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
test("argument null") {
shouldThrow {
- Inspector.getAttachment(null, "busy")
+ getAttachmentFromWrapperChain(null, "busy")
}.message shouldBe "wrapper is null"
shouldThrow {
- Inspector.getAttachment(executorChain, null)
+ getAttachmentFromWrapperChain(executorChain, null)
}.message shouldBe "key is null"
}
- test("inspect last instance - isInstanceOf") {
+ test("inspect last instance - containsInstanceOnWrapperChain") {
val pool = Executors.newCachedThreadPool()
- Inspector.isInstanceOf(pool, ExecutorService::class.java).shouldBeTrue()
+ containsInstanceOnWrapperChain(pool, ExecutorService::class.java).shouldBeTrue()
val chatty = ChattyExecutorWrapper(pool)
- Inspector.isInstanceOf(chatty, ExecutorService::class.java).shouldBeTrue()
+ containsInstanceOnWrapperChain(chatty, ExecutorService::class.java).shouldBeTrue()
}
- test("inspect last instance - getAttachment") {
+ test("inspect last instance - getAttachmentFromWrapperChain") {
val attachable = AttachableDelegate().apply { setAttachment("k1", "v1") }
- Inspector.getAttachment(attachable, "k1") shouldBe "v1"
+ getAttachmentFromWrapperChain(attachable, "k1") shouldBe "v1"
val base = object : Executor, Attachable by AttachableDelegate() {
override fun execute(command: Runnable) {
@@ -65,10 +67,10 @@ class WrapperTest : FunSpec({
}
}
base.setAttachment("k1", "v1")
- Inspector.getAttachment(base, "k1") shouldBe "v1"
+ getAttachmentFromWrapperChain(base, "k1") shouldBe "v1"
val c2 = ChattyExecutorWrapper(base)
- Inspector.getAttachment(c2, "k1") shouldBe "v1"
+ getAttachmentFromWrapperChain(c2, "k1") shouldBe "v1"
}
})