diff --git a/.github/workflows/maven-build.yml b/.github/workflows/maven-build.yml index 367d5d2..470baeb 100644 --- a/.github/workflows/maven-build.yml +++ b/.github/workflows/maven-build.yml @@ -14,12 +14,12 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - java: [ 8, 11 ] + java: [ 8, 11, 13 ] steps: - - uses: actions/checkout@v2 - - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@v1 - with: - java-version: ${{ matrix.java }} - - name: Build with Maven - run: mvn -B install + - uses: actions/checkout@v2 + - name: Set up JDK ${{ matrix.java }} + uses: actions/setup-java@v1 + with: + java-version: ${{ matrix.java }} + - name: Build with Maven + run: mvn -B install diff --git a/.github/workflows/sonatype-deploy.yml b/.github/workflows/sonatype-deploy.yml index 0db51e7..192bf3c 100644 --- a/.github/workflows/sonatype-deploy.yml +++ b/.github/workflows/sonatype-deploy.yml @@ -8,17 +8,17 @@ jobs: deploy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Set up JDK 1.8 - uses: actions/setup-java@v1 - with: - java-version: 1.8 - - name: Build with Maven - run: mvn -B install - - name: Nexus Repo Publish - run: sh .github/deploy.sh - env: - NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }} - NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }} - GPG_KEYNAME: ${{ secrets.GPG_KEYNAME }} - GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + - uses: actions/checkout@v2 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Build with Maven + run: mvn -B install + - name: Nexus Repo Publish + run: sh .github/deploy.sh + env: + NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }} + NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }} + GPG_KEYNAME: ${{ secrets.GPG_KEYNAME }} + GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} diff --git a/CHANGELOG.org b/CHANGELOG.org index 3794191..7e3348b 100644 --- a/CHANGELOG.org +++ b/CHANGELOG.org @@ -10,9 +10,11 @@ The format is based on [[https://keepachangelog.com/en/1.0.0/][Keep a Changelog] ** Added * Add github actions config (#113) + * Add JDK 13 compatibility (#116) ** Dependencies + * Bump kemitix-maven-tiles from 1.2.0 to 2.4.1 (#116) * Bump assertj-core from 3.13.2 to 3.15.0 (#106) * Bump junit-bom from 5.5.2 to 5.6.0 (#105) * Bump tiles-maven-plugin from 2.15 to 2.16 (#101) diff --git a/pom.xml b/pom.xml index 7af215d..132493f 100644 --- a/pom.xml +++ b/pom.xml @@ -38,11 +38,12 @@ 3.15.0 1.18.12 2.16 - 1.2.0 + 2.4.1 net.kemitix.mon 5.0.0 1.5.0 0.12 + 4.0.1 @@ -75,6 +76,12 @@ ${assertj.version} test + + com.github.spotbugs + spotbugs-annotations + ${spotbugs.version} + provided + diff --git a/src/main/java/net/kemitix/mon/TypeAlias.java b/src/main/java/net/kemitix/mon/TypeAlias.java index eb8ea26..4422b4d 100644 --- a/src/main/java/net/kemitix/mon/TypeAlias.java +++ b/src/main/java/net/kemitix/mon/TypeAlias.java @@ -64,11 +64,10 @@ public abstract class TypeAlias { * Map the TypeAlias into another TypeAlias. * * @param f the function to create the new value - * @param the type of the new value within a TypeAlias * @param the type of the TypeAlias superclass containing the new value * @return a TypeAlias */ - public final > U flatMap(final Function f) { + public final > U flatMap(final Function f) { return f.apply(value); } @@ -85,7 +84,7 @@ public abstract class TypeAlias { return otherValueClass.equals(getValue().getClass()) && other.value.equals(getValue()); } - return map(o::equals); + return o != null && map(o::equals); } @Override diff --git a/src/main/java/net/kemitix/mon/lazy/LazySupplier.java b/src/main/java/net/kemitix/mon/lazy/LazySupplier.java index 061c61b..7460dcd 100644 --- a/src/main/java/net/kemitix/mon/lazy/LazySupplier.java +++ b/src/main/java/net/kemitix/mon/lazy/LazySupplier.java @@ -38,6 +38,7 @@ class LazySupplier implements Lazy { private final Supplier supplier; private final AtomicBoolean evaluated = new AtomicBoolean(false); private final AtomicReference value = new AtomicReference<>(); + private final Object lock = new Object(); /** * Creates a new Lazy wrapper for the Supplier. @@ -58,7 +59,7 @@ class LazySupplier implements Lazy { if (evaluated.get()) { return value.get(); } - synchronized (value) { + synchronized (lock) { if (!evaluated.get()) { value.set(supplier.get()); evaluated.set(true); @@ -69,7 +70,7 @@ class LazySupplier implements Lazy { @Override public Lazy map(final Function f) { - return Lazy.of(() -> f.apply(value())); + return new LazySupplier(() -> f.apply(value())); } } diff --git a/src/main/java/net/kemitix/mon/maybe/Just.java b/src/main/java/net/kemitix/mon/maybe/Just.java index 9a7c96b..b16cbd8 100644 --- a/src/main/java/net/kemitix/mon/maybe/Just.java +++ b/src/main/java/net/kemitix/mon/maybe/Just.java @@ -85,11 +85,12 @@ final class Just implements Maybe { } @Override + @SuppressWarnings("unchecked") public Maybe filter(final Predicate predicate) { if (predicate.test(value)) { return this; } - return Maybe.nothing(); + return (Maybe) Nothing.INSTANCE; } @Override @@ -98,7 +99,7 @@ final class Just implements Maybe { } @Override - public T orElseThrow(final Supplier e) throws X { + public T orElseThrow(final Supplier e) { return value; } diff --git a/src/main/java/net/kemitix/mon/maybe/Maybe.java b/src/main/java/net/kemitix/mon/maybe/Maybe.java index 3041bdc..1808e99 100644 --- a/src/main/java/net/kemitix/mon/maybe/Maybe.java +++ b/src/main/java/net/kemitix/mon/maybe/Maybe.java @@ -91,7 +91,7 @@ public interface Maybe extends Functor> { public static Maybe findFirst(Stream stream) { return stream.findFirst() .map(Maybe::just) - .orElse(Maybe.nothing()); + .orElseGet(Maybe::nothing); } /** diff --git a/src/main/java/net/kemitix/mon/maybe/Nothing.java b/src/main/java/net/kemitix/mon/maybe/Nothing.java index 2d4791c..47f651c 100644 --- a/src/main/java/net/kemitix/mon/maybe/Nothing.java +++ b/src/main/java/net/kemitix/mon/maybe/Nothing.java @@ -50,8 +50,9 @@ final class Nothing implements Maybe { } @Override + @SuppressWarnings("unchecked") public Maybe flatMap(final Function> f) { - return Maybe.nothing(); + return (Maybe) INSTANCE; } @Override diff --git a/src/main/java/net/kemitix/mon/result/Err.java b/src/main/java/net/kemitix/mon/result/Err.java index e2c0a67..a6d0f04 100644 --- a/src/main/java/net/kemitix/mon/result/Err.java +++ b/src/main/java/net/kemitix/mon/result/Err.java @@ -54,12 +54,12 @@ class Err implements Result { @Override public Result flatMap(final Function> f) { - return Result.error(error); + return err(error); } @Override public Result map(final Function f) { - return Result.error(error); + return err(error); } @Override @@ -69,7 +69,7 @@ class Err implements Result { @Override public Result> maybe(final Predicate predicate) { - return Result.error(error); + return err(error); } @Override @@ -108,7 +108,7 @@ class Err implements Result { @Override public Result andThen(final Function> f) { - return Result.error(error); + return err(error); } @Override @@ -118,7 +118,7 @@ class Err implements Result { @Override public Result reduce(final Result identify, final BinaryOperator operator) { - return Result.error(error); + return this; } @Override diff --git a/src/main/java/net/kemitix/mon/result/Result.java b/src/main/java/net/kemitix/mon/result/Result.java index 76d852b..d0942c0 100644 --- a/src/main/java/net/kemitix/mon/result/Result.java +++ b/src/main/java/net/kemitix/mon/result/Result.java @@ -49,6 +49,17 @@ public interface Result extends Functor> { .orElseGet(() -> Result.error(error.get())); } + /** + * Create a Result for an error. + * + * @param error the error (Throwable) + * @param the type had the result been a success + * @return an error Result + */ + public default Result err(final Throwable error) { + return new Err<>(error); + } + /** * Create a Result for an error. * @@ -60,6 +71,22 @@ public interface Result extends Functor> { return new Err<>(error); } + /** + * Create a Result for a output of the Callable. + * + * @param callable the callable to produce the result + * @param the type of the value + * @return a Result + */ + @SuppressWarnings("illegalcatch") + public default Result result(final Callable callable) { + try { + return Result.ok(callable.call()); + } catch (final Exception e) { + return Result.error(e); + } + } + /** * Create a Result for a output of the Callable. * @@ -76,6 +103,17 @@ public interface Result extends Functor> { } } + /** + * Create a Result for a success. + * + * @param value the value + * @param the type of the value + * @return a successful Result + */ + public default Result success(final T value) { + return new Success<>(value); + } + /** * Create a Result for a success. * diff --git a/src/main/java/net/kemitix/mon/result/Success.java b/src/main/java/net/kemitix/mon/result/Success.java index ce49401..ee8a49e 100644 --- a/src/main/java/net/kemitix/mon/result/Success.java +++ b/src/main/java/net/kemitix/mon/result/Success.java @@ -54,7 +54,7 @@ class Success implements Result { @Override public Result map(final Function f) { - return Result.ok(f.apply(value)); + return success(f.apply(value)); } @Override @@ -65,9 +65,9 @@ class Success implements Result { @Override public Result> maybe(final Predicate predicate) { if (predicate.test(value)) { - return Result.ok(Maybe.just(value)); + return success(Maybe.just(value)); } - return Result.ok(Maybe.nothing()); + return success(Maybe.nothing()); } @Override @@ -103,7 +103,7 @@ class Success implements Result { @Override public Result andThen(final Function> f) { - return Result.of(f.apply(value)); + return result(f.apply(value)); } @Override @@ -113,7 +113,7 @@ class Success implements Result { @Override public Result reduce(final Result identity, final BinaryOperator operator) { - return flatMap(a -> identity.flatMap(b -> Result.of(() -> operator.apply(a, b)))); + return flatMap(a -> identity.flatMap(b -> result(() -> operator.apply(a, b)))); } @Override diff --git a/src/main/java/net/kemitix/mon/tree/GeneralisedTree.java b/src/main/java/net/kemitix/mon/tree/GeneralisedTree.java index d0cb9cb..e833b49 100644 --- a/src/main/java/net/kemitix/mon/tree/GeneralisedTree.java +++ b/src/main/java/net/kemitix/mon/tree/GeneralisedTree.java @@ -21,6 +21,7 @@ package net.kemitix.mon.tree; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import lombok.EqualsAndHashCode; import net.kemitix.mon.maybe.Maybe; @@ -36,6 +37,7 @@ import java.util.function.Function; * * @author Paul Campbell (pcampbell@kemitix.net) */ +@SuppressFBWarnings("USBR_UNNECESSARY_STORE_BEFORE_RETURN") @EqualsAndHashCode class GeneralisedTree implements Tree, TreeMapper { @@ -62,7 +64,7 @@ class GeneralisedTree implements Tree, TreeMapper { */ @Override public Tree map(final Function f) { - return Tree.of(f.apply(item), mapTrees(f, subTrees())); + return new GeneralisedTree<>(f.apply(item), mapTrees(f, subTrees())); } @Override diff --git a/src/main/java/net/kemitix/mon/tree/MutableTree.java b/src/main/java/net/kemitix/mon/tree/MutableTree.java index e4be977..9948ba8 100644 --- a/src/main/java/net/kemitix/mon/tree/MutableTree.java +++ b/src/main/java/net/kemitix/mon/tree/MutableTree.java @@ -21,6 +21,7 @@ package net.kemitix.mon.tree; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import lombok.EqualsAndHashCode; import net.kemitix.mon.maybe.Maybe; @@ -37,6 +38,7 @@ import java.util.stream.Collectors; * * @author Paul Campbell (pcampbell@kemitix.net) */ +@SuppressFBWarnings("USBR_UNNECESSARY_STORE_BEFORE_RETURN") @EqualsAndHashCode @SuppressWarnings("methodcount") class MutableTree implements Tree, TreeMapper { diff --git a/src/main/java/net/kemitix/mon/tree/MutableTreeBuilder.java b/src/main/java/net/kemitix/mon/tree/MutableTreeBuilder.java index da07431..0ce7ef4 100644 --- a/src/main/java/net/kemitix/mon/tree/MutableTreeBuilder.java +++ b/src/main/java/net/kemitix/mon/tree/MutableTreeBuilder.java @@ -21,6 +21,7 @@ package net.kemitix.mon.tree; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import net.kemitix.mon.maybe.Maybe; import java.util.function.Function; @@ -84,8 +85,14 @@ class MutableTreeBuilder implements TreeBuilder { .map(Tree::builder)); } - private Boolean matchesItem(final T childItem, final MutableTree tree) { - return tree.item().map(childItem::equals).orElse(false); + @SuppressFBWarnings("NAB_NEEDLESS_BOOLEAN_CONSTANT_CONVERSION") + private boolean matchesItem( + final T childItem, + final MutableTree tree + ) { + return tree.item() + .map(childItem::equals) + .orElse(false); } } diff --git a/src/main/java/net/kemitix/mon/tree/Tree.java b/src/main/java/net/kemitix/mon/tree/Tree.java index e7933c9..66ce89c 100644 --- a/src/main/java/net/kemitix/mon/tree/Tree.java +++ b/src/main/java/net/kemitix/mon/tree/Tree.java @@ -21,6 +21,7 @@ package net.kemitix.mon.tree; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import net.kemitix.mon.Functor; import net.kemitix.mon.maybe.Maybe; @@ -70,6 +71,8 @@ public interface Tree extends Functor> { * * @return a TreeBuilder */ + @SuppressFBWarnings(value = "UP_UNUSED_PARAMETER", + justification = "Use the type parameter to fingerprint the return type") public static TreeBuilder builder(final Class type) { return new MutableTreeBuilder<>(); } diff --git a/src/test/java/net/kemitix/mon/TypeAliasTest.java b/src/test/java/net/kemitix/mon/TypeAliasTest.java index 7c89ad3..2073386 100644 --- a/src/test/java/net/kemitix/mon/TypeAliasTest.java +++ b/src/test/java/net/kemitix/mon/TypeAliasTest.java @@ -1,6 +1,7 @@ package net.kemitix.mon; import org.assertj.core.util.Strings; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.Arrays; @@ -116,6 +117,17 @@ class TypeAliasTest { assertThat(value).isEqualTo("'text'"); } + @Test + @DisplayName("equals other is null then not equals") + void whenOtherNullEqualsIsFalse() { + //given + final AnAlias anAlias = AnAlias.of("text"); + //then + boolean result = anAlias.equals(null); + //then + assertThat(result).isFalse(); + } + private static class AnAlias extends TypeAlias { /**