The purpose of Inspectable Wrappers is to provide a standard for wrapper chain with the inspection ability.
- π‘ Files
- π° Usage Demo
- π° Integration Demo
- π° Integration Demo using
WrapperAdapterUtils
- πΌ Java API Docs
- πͺ Dependency
- The core interfaces/specification interfaces:
Wrapper
interface is used to be implemented by wrapper classes, make an inspectable wrapper chain(linked list)Attachable
interface is used to enhance the wrapper instances with the attachment storage abilityWrapperAdapter
interface is used to adapt an existed wrapper instance to typeWrapper
without modifying it
- The
Inspector
class is used to inspect the wrapper chain - The utility classes:
AttachableDelegate
class provides a simpleAttachable
delegate implementationWrapperAdapterUtils
class provides utility methods for creatingWrapperAdapter
instances without writing boilerplate codes of creating new adapter classes
Below use the Executor Wrapper
to demonstrate the usage.
// a wrapper implementation
public class ChattyExecutorWrapper implements Executor, Wrapper<Executor> {
private final Executor executor;
public ChattyExecutorWrapper(Executor executor) {
this.executor = executor;
}
@Override
public void execute(Runnable command) {
System.out.println("BlaBlaBla...");
executor.execute(command);
}
@Override
public Executor unwrap_() {
return executor;
}
}
// another wrapper implementation
public class LazyExecutorWrapper implements Executor, Wrapper<Executor>, Attachable<String, String> {
private final Executor executor;
public LazyExecutorWrapper(Executor executor) {
this.executor = executor;
}
@Override
public void execute(Runnable command) {
System.out.println("I'm lazy, sleep before work.");
sleep();
executor.execute(command);
}
@Override
public Executor unwrap_() {
return executor;
}
private final Attachable<String, String> attachable = new AttachableDelegate<>();
@Override
public void setAttachment_(String key, String value) {
attachable.setAttachment_(key, value);
}
@Override
public String getAttachment_(String key) {
return attachable.getAttachment_(key);
}
}
public class Demo {
public static void main(String[] args) {
final Executor executor = buildExecutorChain();
////////////////////////////////////////
// inspect the executor(wrapper chain)
////////////////////////////////////////
System.out.println("Is executor lazy? " +
containsInstanceTypeOnWrapperChain(executor, LazyExecutorWrapper.class));
// print true
String busy = getAttachmentFromWrapperChain(executor, "busy");
System.out.println("Is executor busy? " + busy);
// print "very, very busy!"
////////////////////////////////////////
// call executor(wrapper chain)
////////////////////////////////////////
System.out.println();
executor.execute(() -> System.out.println("I'm working."));
}
/**
* prepare executor instances/wrappers, build the executor/wrapper chain
**/
private static Executor buildExecutorChain() {
final Executor base = Runnable::run;
final LazyExecutorWrapper lazy = new LazyExecutorWrapper(base);
lazy.setAttachment_("busy", "very, very busy!");
return new ChattyExecutorWrapper(lazy);
}
}
/*
demo output:
Is executor lazy? true
Is executor busy? very, very busy!
BlaBlaBla...
I'm lazy, sleep before work.
I'm working.
*/
Runnable demo codes in project:
Demo.java
Integrate an existed wrapper instance to type Wrapper
without modifying it.
public class ExistedExecutorWrapper implements Executor {
private final Executor executor;
public ExistedExecutorWrapper(Executor executor) {
this.executor = executor;
}
@Override
public void execute(Runnable command) {
System.out.println("I'm existed executor, have nothing to do with ~inspectable~wrappers~.");
executor.execute(command);
}
}
public class IntegrationDemo {
public static void main(String[] args) {
final Executor executor = buildExecutorChain();
////////////////////////////////////////
// inspect the executor(wrapper chain)
////////////////////////////////////////
System.out.println("Is executor ExistedExecutorWrapper? " +
containsInstanceTypeOnWrapperChain(executor, ExistedExecutorWrapper.class));
// print true
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~."
////////////////////////////////////////
// call executor(wrapper chain)
////////////////////////////////////////
System.out.println();
executor.execute(() -> System.out.println("I'm working."));
}
private static Executor buildExecutorChain() {
final Executor base = Runnable::run;
final ExistedExecutorWrapperAdapter adapter = createExistedExecutorWrapperAdapter(base);
return new ChattyExecutorWrapper(adapter);
}
private static ExistedExecutorWrapperAdapter createExistedExecutorWrapperAdapter(Executor base) {
final ExistedExecutorWrapper existed = new ExistedExecutorWrapper(base);
final ExistedExecutorWrapperAdapter adapter = new ExistedExecutorWrapperAdapter(base, existed);
adapter.setAttachment_("adapted-existed-executor-wrapper-msg", "I'm an adapter of an existed executor which have nothing to do with ~inspectable~wrappers~.");
return adapter;
}
/**
* Adaption an existed wrapper(`ExistedExecutorWrapper`) without modifying it.
*/
private static class ExistedExecutorWrapperAdapter implements Executor, WrapperAdapter<Executor>, Attachable<String, String> {
private final Executor base;
private final Executor adaptee;
public ExistedExecutorWrapperAdapter(Executor base, Executor adaptee) {
this.base = base;
this.adaptee = adaptee;
}
@Override
public Executor unwrap_() {
return base;
}
@Override
public Executor adaptee_() {
return adaptee;
}
@Override
public void execute(Runnable command) {
adaptee.execute(command);
}
private final Attachable<String, String> attachable = new AttachableDelegate<>();
@Override
public void setAttachment_(String key, String value) {
attachable.setAttachment_(key, value);
}
@Nullable
@Override
public String getAttachment_(String key) {
return attachable.getAttachment_(key);
}
}
}
/*
demo output:
Is executor ExistedExecutorWrapper? true
Adapted existed executor wrapper msg: I'm an adapter of an existed executor which have nothing to do with ~inspectable~wrappers~.
BlaBlaBla...
I'm an adapter of an existed executor which have nothing to do with ~inspectable~wrappers~.
I'm working.
*/
Runnable demo codes in project:
IntegrationDemo.java
Uses WrapperAdapterUtils
to create WrapperAdapter
instances without writing boilerplate codes of creating new adapter classes.
public class IntegrationDemoUsingWrapperAdapterUtils {
public static void main(String[] args) {
final Executor executor = buildExecutorChain();
////////////////////////////////////////
// inspect the executor(wrapper chain)
////////////////////////////////////////
System.out.println("Is executor ExistedExecutorWrapper? " +
containsInstanceTypeOnWrapperChain(executor, ExistedExecutorWrapper.class));
// print true
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~."
////////////////////////////////////////
// call executor(wrapper chain)
////////////////////////////////////////
System.out.println();
executor.execute(() -> System.out.println("I'm working."));
}
private static Executor buildExecutorChain() {
final Executor base = Runnable::run;
final Executor adapter = createExistedExecutorWrapperAdapter(base);
return new ChattyExecutorWrapper(adapter);
}
private static Executor createExistedExecutorWrapperAdapter(Executor base) {
final Executor existed = new ExistedExecutorWrapper(base);
Attachable<String, String> attachable = new AttachableDelegate<>();
attachable.setAttachment_("adapted-existed-executor-wrapper-msg", "I'm an adapter of an existed executor which have nothing to do with ~inspectable~wrappers~.");
return WrapperAdapterUtils.createWrapperAdapter(Executor.class, base, existed, attachable);
}
}
/*
demo output:
Is executor ExistedExecutorWrapper? true
Adapted existed executor wrapper msg: I'm an adapter of an existed executor which have nothing to do with ~inspectable~wrappers~.
BlaBlaBla...
I'm an adapter of an existed executor which have nothing to do with ~inspectable~wrappers~.
I'm working.
*/
Runnable demo codes in project:
IntegrationDemoUsingWrapperAdapterUtils.java
The current version Java API documentation: https://foldright.io/inspectable-wrappers/apidocs/
For Maven
projects:
<dependency>
<groupId>io.foldright</groupId>
<artifactId>inspectable-wrappers</artifactId>
<version>0.5.5</version>
</dependency>
For Gradle
projects:
// Gradle Kotlin DSL
implementation("io.foldright:inspectable-wrappers:0.5.5")
// Gradle Groovy DSL
implementation 'io.foldright:inspectable-wrappers:0.5.5'
inspectable-wrappers
has published to maven central, find the latest version at central.sonatype.com.