Skip to content

About

馃獝 Inspectable Wrappers Specification, provides the interfaces to make wrapper instances as an inspectable wrapper chain.

Topics

Resources

Stars

7 stars

Watchers

2 watching

Forks

Latest commit

聽

History

103 Commits

Folders and files

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

Stars

7 stars

Watchers

2 watching

Forks

Releases

Used by

Contributors

Languages