JDK 13 Compatibility (#116)
* Add jdk 13 to build matrix * Adjust indentation * Adjust indentation * Bump kemitix-maven-tiles from 1.2.0 to 2.4.1 * Fix TypeAlias.equals(Object) does not check for null argument net.kemitix.mon.TypeAlias.equals(Object) does not check for null argument [net.kemitix.mon.TypeAlias] At TypeAlias.java:[lines 82-88] NP_EQUALS_SHOULD_HANDLE_NULL_ARGUMENT * Fix TypeAlias.flatMap(Function) declares unbound method template parameter [ERROR] Method net.kemitix.mon.TypeAlias.flatMap(Function) declares unbound method template parameter(s) [net.kemitix.mon.TypeAlias] At TypeAlias.java:[line 72] UMTP_UNBOUND_METHOD_TEMPLATE_PARAMETER * Fix Lazy has a circular dependency with other classes [ERROR] Class net.kemitix.mon.lazy.Lazy has a circular dependency with other classes [net.kemitix.mon.lazy.Lazy] At Lazy.java:[lines 36-46] FCCD_FIND_CLASS_CIRCULAR_DEPENDENCY * Fix Synchronization performed on AtomicReference [ERROR] Synchronization performed on java.util.concurrent.atomic.AtomicReference in net.kemitix.mon.lazy.LazySupplier.value() [net.kemitix.mon.lazy.LazySupplier] At LazySupplier.java:[line 61] JLM_JSR166_UTILCONCURRENT_MONITORENTER * Fix Just.orElseThrow(Supplier) declares throwing an exception that isn't thrown [ERROR] Non derivable method net.kemitix.mon.maybe.Just.orElseThrow(Supplier) declares throwing an exception that isn't thrown [net.kemitix.mon.maybe.Just] At Just.java:[line 102] BED_BOGUS_EXCEPTION_DECLARATION * Fix Maybe has a circular dependency with other classes [ERROR] Class net.kemitix.mon.maybe.Maybe has a circular dependency with other classes [net.kemitix.mon.maybe.Maybe] At Maybe.java:[lines 40-94] FCCD_FIND_CLASS_CIRCULAR_DEPENDENCY * Fix Maybe.findFirst(Stream) uses immediate execution of a block [ERROR] Method net.kemitix.mon.maybe.Maybe.findFirst(Stream) uses immediate execution of a block of code that is often not used [net.kemitix.mon.maybe.Maybe] At Maybe.java:[line 94] OI_OPTIONAL_ISSUES_USES_IMMEDIATE_EXECUTION * Fix Success/Result/Err has a circular dependency [ERROR] Class net.kemitix.mon.result.Err has a circular dependency with other classes [net.kemitix.mon.result.Err] At Err.java: FCCD_FIND_CLASS_CIRCULAR_DEPENDENCY * Fix GeneralisedTree has a circular dependency [ERROR] Class net.kemitix.mon.tree.GeneralisedTree has a circular dependency with other classes [net.kemitix.mon.tree.GeneralisedTree] At GeneralisedTree.java:[lines 39-80] FCCD_FIND_CLASS_CIRCULAR_DEPENDENCY * Supress warning about boxing a boolean NAB_NEEDLESS_BOOLEAN_CONSTANT_CONVERSION Without creating a whole reimplemention of Maybe/Just/Nothing purely for `boolean` primitives, we can’t avoid this boxing. * Supress store before return warnings in Lombok generate hashCode USBR_UNNECESSARY_STORE_BEFORE_RETURN The annotation has to be used at the class level, which unfortunately means we have no store-before-return checks for the rest of the class. * Suppress warning about unused parameter The type parameter for `Tree.builder(type)` is used to specify the parameterised type of the return value. * Checkstyle fixups * [changelog] updated
This commit is contained in:
parent
86d3a214ed
commit
830b312d9e
17 changed files with 120 additions and 45 deletions
16
.github/workflows/maven-build.yml
vendored
16
.github/workflows/maven-build.yml
vendored
|
@ -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
|
||||
|
|
28
.github/workflows/sonatype-deploy.yml
vendored
28
.github/workflows/sonatype-deploy.yml
vendored
|
@ -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 }}
|
||||
|
|
|
@ -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)
|
||||
|
|
9
pom.xml
9
pom.xml
|
@ -38,11 +38,12 @@
|
|||
<assertj.version>3.15.0</assertj.version>
|
||||
<lombok.version>1.18.12</lombok.version>
|
||||
<tiles-maven-plugin.version>2.16</tiles-maven-plugin.version>
|
||||
<kemitix-maven-tiles.version>1.2.0</kemitix-maven-tiles.version>
|
||||
<kemitix-maven-tiles.version>2.4.1</kemitix-maven-tiles.version>
|
||||
<digraph-dependency.basePackage>net.kemitix.mon</digraph-dependency.basePackage>
|
||||
<kemitix-checkstyle.version>5.0.0</kemitix-checkstyle.version>
|
||||
<pitest-maven-plugin.version>1.5.0</pitest-maven-plugin.version>
|
||||
<pitest-junit5-plugin.version>0.12</pitest-junit5-plugin.version>
|
||||
<spotbugs.version>4.0.1</spotbugs.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
@ -75,6 +76,12 @@
|
|||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.spotbugs</groupId>
|
||||
<artifactId>spotbugs-annotations</artifactId>
|
||||
<version>${spotbugs.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<dependencyManagement>
|
||||
|
|
|
@ -64,11 +64,10 @@ public abstract class TypeAlias<T> {
|
|||
* Map the TypeAlias into another TypeAlias.
|
||||
*
|
||||
* @param f the function to create the new value
|
||||
* @param <R> the type of the new value within a TypeAlias
|
||||
* @param <U> the type of the TypeAlias superclass containing the new value
|
||||
* @return a TypeAlias
|
||||
*/
|
||||
public final <R, U extends TypeAlias<R>> U flatMap(final Function<T, U> f) {
|
||||
public final <U extends TypeAlias<?>> U flatMap(final Function<T, U> f) {
|
||||
return f.apply(value);
|
||||
}
|
||||
|
||||
|
@ -85,7 +84,7 @@ public abstract class TypeAlias<T> {
|
|||
return otherValueClass.equals(getValue().getClass())
|
||||
&& other.value.equals(getValue());
|
||||
}
|
||||
return map(o::equals);
|
||||
return o != null && map(o::equals);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -38,6 +38,7 @@ class LazySupplier<T> implements Lazy<T> {
|
|||
private final Supplier<T> supplier;
|
||||
private final AtomicBoolean evaluated = new AtomicBoolean(false);
|
||||
private final AtomicReference<T> value = new AtomicReference<>();
|
||||
private final Object lock = new Object();
|
||||
|
||||
/**
|
||||
* Creates a new Lazy wrapper for the Supplier.
|
||||
|
@ -58,7 +59,7 @@ class LazySupplier<T> implements Lazy<T> {
|
|||
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<T> implements Lazy<T> {
|
|||
|
||||
@Override
|
||||
public <R> Lazy<R> map(final Function<T, R> f) {
|
||||
return Lazy.of(() -> f.apply(value()));
|
||||
return new LazySupplier<R>(() -> f.apply(value()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -85,11 +85,12 @@ final class Just<T> implements Maybe<T> {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Maybe<T> filter(final Predicate<T> predicate) {
|
||||
if (predicate.test(value)) {
|
||||
return this;
|
||||
}
|
||||
return Maybe.nothing();
|
||||
return (Maybe<T>) Nothing.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -98,7 +99,7 @@ final class Just<T> implements Maybe<T> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public <X extends Throwable> T orElseThrow(final Supplier<? extends X> e) throws X {
|
||||
public <X extends Throwable> T orElseThrow(final Supplier<? extends X> e) {
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ public interface Maybe<T> extends Functor<T, Maybe<?>> {
|
|||
public static <T> Maybe<T> findFirst(Stream<T> stream) {
|
||||
return stream.findFirst()
|
||||
.map(Maybe::just)
|
||||
.orElse(Maybe.nothing());
|
||||
.orElseGet(Maybe::nothing);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -50,8 +50,9 @@ final class Nothing<T> implements Maybe<T> {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <R> Maybe<R> flatMap(final Function<T, Maybe<R>> f) {
|
||||
return Maybe.nothing();
|
||||
return (Maybe<R>) INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -54,12 +54,12 @@ class Err<T> implements Result<T> {
|
|||
|
||||
@Override
|
||||
public <R> Result<R> flatMap(final Function<T, Result<R>> f) {
|
||||
return Result.error(error);
|
||||
return err(error);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> Result<R> map(final Function<T, R> f) {
|
||||
return Result.error(error);
|
||||
return err(error);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -69,7 +69,7 @@ class Err<T> implements Result<T> {
|
|||
|
||||
@Override
|
||||
public Result<Maybe<T>> maybe(final Predicate<T> predicate) {
|
||||
return Result.error(error);
|
||||
return err(error);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -108,7 +108,7 @@ class Err<T> implements Result<T> {
|
|||
|
||||
@Override
|
||||
public <R> Result<R> andThen(final Function<T, Callable<R>> f) {
|
||||
return Result.error(error);
|
||||
return err(error);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -118,7 +118,7 @@ class Err<T> implements Result<T> {
|
|||
|
||||
@Override
|
||||
public Result<T> reduce(final Result<T> identify, final BinaryOperator<T> operator) {
|
||||
return Result.error(error);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -49,6 +49,17 @@ public interface Result<T> extends Functor<T, Result<?>> {
|
|||
.orElseGet(() -> Result.error(error.get()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Result for an error.
|
||||
*
|
||||
* @param error the error (Throwable)
|
||||
* @param <T> the type had the result been a success
|
||||
* @return an error Result
|
||||
*/
|
||||
public default <T> Result<T> err(final Throwable error) {
|
||||
return new Err<>(error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Result for an error.
|
||||
*
|
||||
|
@ -60,6 +71,22 @@ public interface Result<T> extends Functor<T, Result<?>> {
|
|||
return new Err<>(error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Result for a output of the Callable.
|
||||
*
|
||||
* @param callable the callable to produce the result
|
||||
* @param <T> the type of the value
|
||||
* @return a Result
|
||||
*/
|
||||
@SuppressWarnings("illegalcatch")
|
||||
public default <T> Result<T> result(final Callable<T> 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<T> extends Functor<T, Result<?>> {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Result for a success.
|
||||
*
|
||||
* @param value the value
|
||||
* @param <T> the type of the value
|
||||
* @return a successful Result
|
||||
*/
|
||||
public default <T> Result<T> success(final T value) {
|
||||
return new Success<>(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Result for a success.
|
||||
*
|
||||
|
|
|
@ -54,7 +54,7 @@ class Success<T> implements Result<T> {
|
|||
|
||||
@Override
|
||||
public <R> Result<R> map(final Function<T, R> f) {
|
||||
return Result.ok(f.apply(value));
|
||||
return success(f.apply(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -65,9 +65,9 @@ class Success<T> implements Result<T> {
|
|||
@Override
|
||||
public Result<Maybe<T>> maybe(final Predicate<T> 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<T> implements Result<T> {
|
|||
|
||||
@Override
|
||||
public <R> Result<R> andThen(final Function<T, Callable<R>> f) {
|
||||
return Result.of(f.apply(value));
|
||||
return result(f.apply(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -113,7 +113,7 @@ class Success<T> implements Result<T> {
|
|||
|
||||
@Override
|
||||
public Result<T> reduce(final Result<T> identity, final BinaryOperator<T> 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
|
||||
|
|
|
@ -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<T> implements Tree<T>, TreeMapper<T> {
|
||||
|
||||
|
@ -62,7 +64,7 @@ class GeneralisedTree<T> implements Tree<T>, TreeMapper<T> {
|
|||
*/
|
||||
@Override
|
||||
public <R> Tree<R> map(final Function<T, R> f) {
|
||||
return Tree.of(f.apply(item), mapTrees(f, subTrees()));
|
||||
return new GeneralisedTree<>(f.apply(item), mapTrees(f, subTrees()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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<T> implements Tree<T>, TreeMapper<T> {
|
||||
|
|
|
@ -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<T> implements TreeBuilder<T> {
|
|||
.map(Tree::builder));
|
||||
}
|
||||
|
||||
private Boolean matchesItem(final T childItem, final MutableTree<T> tree) {
|
||||
return tree.item().map(childItem::equals).orElse(false);
|
||||
@SuppressFBWarnings("NAB_NEEDLESS_BOOLEAN_CONSTANT_CONVERSION")
|
||||
private boolean matchesItem(
|
||||
final T childItem,
|
||||
final MutableTree<T> tree
|
||||
) {
|
||||
return tree.item()
|
||||
.map(childItem::equals)
|
||||
.orElse(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<T> extends Functor<T, Tree<?>> {
|
|||
*
|
||||
* @return a TreeBuilder
|
||||
*/
|
||||
@SuppressFBWarnings(value = "UP_UNUSED_PARAMETER",
|
||||
justification = "Use the type parameter to fingerprint the return type")
|
||||
public static <B> TreeBuilder<B> builder(final Class<B> type) {
|
||||
return new MutableTreeBuilder<>();
|
||||
}
|
||||
|
|
|
@ -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<String> {
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue