Skip to content

πŸͺ Inspectable Wrappers Specification, provides the interfaces to make wrapper instances as an inspectable wrapper chain.

License

Notifications You must be signed in to change notification settings

foldright/inspectable-wrappers

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸͺ Inspectable Wrappers

GH Workflow Build Status Codecov Qodana - GH Workflow Build Status Java support License Javadocs Maven Central GitHub Releases GitHub Stars GitHub Forks GitHub Issues GitHub Contributors GitHub repo size gitpod: Ready to Code

inspectable-wrappers

The purpose of Inspectable Wrappers is to provide a standard for wrapper chain with the inspection ability.



🍑 Files

  • 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 ability
    • WrapperAdapter interface is used to adapt an existed wrapper instance to type Wrapper without modifying it
  • The Inspector class is used to inspect the wrapper chain
  • The utility classes:
    • AttachableDelegate class provides a simple Attachable delegate implementation
    • WrapperAdapterUtils class provides utility methods for creating WrapperAdapter instances without writing boilerplate codes of creating new adapter classes

🌰 Usage Demo

Below use the Executor Wrapper to demonstrate the usage.

demo wrapper implementations in your application code

// 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); } }

inspection of the wrapper chain

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

🌰 Integration Demo

Integrate an existed wrapper instance to type Wrapper without modifying it.

the demo existed wrapper which cannot be modified

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); } }

the integration code

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

🌰 Integration Demo using WrapperAdapterUtils

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

🍼 Java API Docs

The current version Java API documentation: https://foldright.io/inspectable-wrappers/apidocs/

πŸͺ Dependency

For Maven projects:

<dependency> <groupId>io.foldright</groupId> <artifactId>inspectable-wrappers</artifactId> <version>0.5.6</version> </dependency>

For Gradle projects:

// Gradle Kotlin DSL implementation("io.foldright:inspectable-wrappers:0.5.6")
// Gradle Groovy DSL implementation 'io.foldright:inspectable-wrappers:0.5.6'

inspectable-wrappers has published to maven central, find the latest version at central.sonatype.com.

About

πŸͺ Inspectable Wrappers Specification, provides the interfaces to make wrapper instances as an inspectable wrapper chain.

Topics

Resources

License

Stars

Watchers

Forks

Contributors 5