Skip to content

Commit

Permalink
refactor(Inspector): move util methods to Inspector, remove `Inte…
Browse files Browse the repository at this point in the history
…rnalUtils` class
  • Loading branch information
oldratlee committed Mar 27, 2024
1 parent c963093 commit cf77e0e
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 44 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ The purpose of **Inspectable Wrappers** is to provide a standard for wrapper cha

- Core interfaces:
- [`Wrapper`](src/main/java/io/foldright/inspectablewrappers/Wrapper.java) interface is core interface, used to
be implemented by wrapper classes, make an **inspectable wrapper chain**(linked list).
be implemented by wrapper classes, make an **inspectable wrapper chain**(linked list)
- [`Attachable`](src/main/java/io/foldright/inspectablewrappers/Attachable.java) interface is used to
enhance the wrapper instances with the attachment storage ability
- [`WrapperAdapter`](src/main/java/io/foldright/inspectablewrappers/WrapperAdapter.java) interface is used to
Expand Down
62 changes: 46 additions & 16 deletions src/main/java/io/foldright/inspectablewrappers/Inspector.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,32 @@
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

import static io.foldright.inspectablewrappers.InternalUtils.unwrapNonNull;
import static java.util.Objects.requireNonNull;


/**
* This {@code Inspector} class is used to inspect the wrapper chain.
* <p>
* Common usages:
*
* <h2>Common simple usages</h2>
* <ul>
* <li>Reports whether any instance on the wrapper chain matches the given type
* by static method {@link #isInstanceOf(Object, Class)}
* <li>Retrieve the attachment from wrapper chain(wrapper instances implement interface {@link Wrapper})
* by static method {@link #getAttachment(Object, Object)}
* </ul>
*
* <h2>Advanced usages</h2>
* <ul>
* <li>Reports whether any instance on the wrapper chain satisfy the given {@link Predicate}
* by static method {@link #inspect(Object, Predicate)}
* <li>Traverses the wrapper chain, and applies the given {@link Function} to each instance on the wrapper chain,
* by static method {@link #travel(Object, Function)}
* </ul>
* <p>
* You can implement your own inspection logic using above advanced methods.
*
* @author Jerry Lee (oldratlee at gmail dot com)
* @author Zava (zava dot kid at gmail dot com)
* @see Wrapper
Expand Down Expand Up @@ -112,9 +122,9 @@ public static <W> boolean inspect(final W wrapper, final Predicate<? super W> pr
}

/**
* Traverses the wrapper chain, and apply the given {@code process} function to each instances on the wrapper chain,
* and returns the first non-empty({@link Optional#empty()}) result of the process function,
* otherwise returns {@link Optional#empty()}.
* Traverses the wrapper chain, and applies the given {@code process} function to
* each instance on the wrapper chain, and returns the first non-empty({@link Optional#empty()}) result
* of the process function, otherwise returns {@link Optional#empty()}.
* <p>
* The wrapper chain consists of wrapper itself, followed by the wrappers
* obtained by repeatedly calling {@link Wrapper#unwrap()}.
Expand All @@ -130,7 +140,7 @@ public static <W> boolean inspect(final W wrapper, final Predicate<? super W> pr
*/
@NonNull
@SuppressWarnings("unchecked")
public static <W, T> Optional<T> travel(final W wrapper, final Function<W, Optional<T>> process) {
public static <W, T> Optional<T> travel(final W wrapper, final Function<? super W, Optional<T>> process) {
requireNonNull(wrapper, "wrapper is null");
requireNonNull(process, "process is null");

Expand All @@ -142,14 +152,7 @@ public static <W, T> Optional<T> travel(final W wrapper, final Function<W, Optio

// also process the adaptee if it's a WrapperAdapter
if (w instanceof WrapperAdapter) {
final Object adaptee = ((WrapperAdapter<?>) w).adaptee();
if (adaptee instanceof Wrapper) {
throw new IllegalStateException("adaptee(" + adaptee.getClass().getName() +
") of WrapperAdapter(" + w.getClass().getName() +
") is type Wrapper, adapting a Wrapper to a Wrapper is unnecessary!");
}

Optional<T> r = process.apply((W) adaptee);
Optional<T> r = process.apply((W) adapteeNonWrapper(w));
if (r.isPresent()) return r;
}

Expand All @@ -158,7 +161,34 @@ public static <W, T> Optional<T> travel(final W wrapper, final Function<W, Optio
}
}

// no need to create instance at all
/**
* Gets adaptee of the given WrapperAdapter instance with {@code null} check and non-{@link Wrapper} type check.
*/
private static Object adapteeNonWrapper(Object w) {
final Object adaptee = ((WrapperAdapter<?>) w).adaptee();
Supplier<String> msg = () -> "adaptee of WrapperAdapter(" + w.getClass().getName() + ") is null";
requireNonNull(adaptee, msg);

if (adaptee instanceof Wrapper) {
throw new IllegalStateException("adaptee(" + adaptee.getClass().getName() +
") of WrapperAdapter(" + w.getClass().getName() +
") is type Wrapper, adapting a Wrapper to a Wrapper is unnecessary!");
}
return adaptee;
}

/**
* Unwraps the given wrapper instance with {@code null} check.
*/
private static Object unwrapNonNull(final Object wrapper) {
Object unwrap = ((Wrapper<?>) wrapper).unwrap();
Supplier<String> msg = () -> "unwrap of Wrapper(" + wrapper.getClass().getName() + ") is null";
return requireNonNull(unwrap, msg);
}

/**
* no need to create instance at all
*/
private Inspector() {
}
}
23 changes: 0 additions & 23 deletions src/main/java/io/foldright/inspectablewrappers/InternalUtils.java

This file was deleted.

4 changes: 2 additions & 2 deletions src/main/java/io/foldright/inspectablewrappers/Wrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

/**
* This {@code Wrapper} interface is used to be implemented by wrapper classes,
* make an <b>inspectable wrapper chain</b>(linked list).
* make an <strong>inspectable wrapper chain</strong>(linked list).
* <p>
* <b><i>Note about wrapper chain:<br></i></b>
* <strong>Note about wrapper chain:</strong>
* <ul>
* <li>The wrapper chain consists of wrapper itself, followed by the wrappers
* obtained by repeatedly calling {@link Wrapper#unwrap()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public interface WrapperAdapter<T> extends Wrapper<T> {
/**
* Returns the adapted/existed wrapper.
* <p>
* <b><i>Note:<br></i></b>
* <strong>Note:</strong>
* <ul>
* <li>The adaptee MUST not a {@link Wrapper},
* since adapting a {@link Wrapper} to a {@link Wrapper} is unnecessary.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* <ul>
* <li>{@link io.foldright.inspectablewrappers.Wrapper} is core interface, used to
* be implemented by wrapper classes, make an <b>inspectable wrapper chain</b>(linked list).
* be implemented by wrapper classes, make an <strong>inspectable wrapper chain</strong>(linked list).
* <li>{@link io.foldright.inspectablewrappers.Attachable} interface is used to
* enhance the wrapper instances with the attachment storage ability
* <li>{@link io.foldright.inspectablewrappers.WrapperAdapter} interface is used to
Expand Down

0 comments on commit cf77e0e

Please sign in to comment.