From 62e4d56c9a311cf1c58f5426f50b6994dac32707 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Sat, 26 Aug 2017 19:13:36 +0100 Subject: [PATCH] Condition: avoid danger of JVM-level deadlock during initialisation --- CHANGELOG | 1 + .../net/kemitix/conditional/Condition.java | 72 +------------------ .../kemitix/conditional/FalseCondition.java | 53 ++++++++++++++ .../kemitix/conditional/TrueCondition.java | 54 ++++++++++++++ 4 files changed, 110 insertions(+), 70 deletions(-) create mode 100644 src/main/java/net/kemitix/conditional/FalseCondition.java create mode 100644 src/main/java/net/kemitix/conditional/TrueCondition.java diff --git a/CHANGELOG b/CHANGELOG index 9a5f6a7..4e439cd 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,7 @@ CHANGELOG 0.3.0 ----- +* Avoid danger of JVM-level deadlock during `Condition` initialisation * Upgrade `kemitix-parent` to 3.2.0 * Upgrade `kemitix-checkstyle-parent` to 3.2.0 * Upgrade `assertj` to 3.8.0 diff --git a/src/main/java/net/kemitix/conditional/Condition.java b/src/main/java/net/kemitix/conditional/Condition.java index 9f1f497..7129574 100644 --- a/src/main/java/net/kemitix/conditional/Condition.java +++ b/src/main/java/net/kemitix/conditional/Condition.java @@ -21,12 +21,6 @@ package net.kemitix.conditional; -import java.util.AbstractMap.SimpleEntry; -import java.util.Collections; -import java.util.Map; -import java.util.stream.Collectors; -import java.util.stream.Stream; - /** * If-then-else in a functional-style. * @@ -34,14 +28,6 @@ import java.util.stream.Stream; */ public interface Condition { - Condition TRUE = new TrueCondition(); - - Condition FALSE = new FalseCondition(); - - Map CONDITIONS = Collections.unmodifiableMap( - Stream.of(new SimpleEntry<>(true, TRUE), new SimpleEntry<>(false, FALSE)) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))); - /** * Create a new {@code Condition} for the clause. * @@ -49,8 +35,9 @@ public interface Condition { * * @return the Condition */ + @SuppressWarnings("avoidinlineconditionals") static Condition where(final boolean clause) { - return CONDITIONS.get(clause); + return clause ? TrueCondition.TRUE : FalseCondition.FALSE; } /** @@ -131,59 +118,4 @@ public interface Condition { return where(clause); } - /** - * A {@code Condition} that has evaluated to {@code true}. - */ - class TrueCondition implements Condition { - - @Override - public Condition and(final boolean clause) { - return where(clause); - } - - @Override - public Condition or(final boolean secondClause) { - return TRUE; - } - - @Override - public Condition then(final Runnable response) { - response.run(); - return TRUE; - } - - @Override - public void otherwise(final Runnable response) { - // do nothing - } - - } - - /** - * A {@code Condition} that has evaluated to {@code false}. - */ - class FalseCondition implements Condition { - - @Override - public Condition and(final boolean clause) { - return FALSE; - } - - @Override - public Condition or(final boolean secondClause) { - return where(secondClause); - } - - @Override - public Condition then(final Runnable response) { - return FALSE; - } - - @Override - public void otherwise(final Runnable response) { - response.run(); - } - - } - } diff --git a/src/main/java/net/kemitix/conditional/FalseCondition.java b/src/main/java/net/kemitix/conditional/FalseCondition.java new file mode 100644 index 0000000..8695649 --- /dev/null +++ b/src/main/java/net/kemitix/conditional/FalseCondition.java @@ -0,0 +1,53 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2017 Paul Campbell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies + * or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package net.kemitix.conditional; + +/** + * A {@code Condition} that has evaluated to {@code false}. + * + * @author Paul Campbell (pcampbell@kemitix.net). + */ +public final class FalseCondition implements Condition { + + protected static final Condition FALSE = new net.kemitix.conditional.FalseCondition(); + + @Override + public Condition and(final boolean clause) { + return FALSE; + } + + @Override + public Condition or(final boolean secondClause) { + return Condition.where(secondClause); + } + + @Override + public Condition then(final Runnable response) { + return FALSE; + } + + @Override + public void otherwise(final Runnable response) { + response.run(); + } + +} diff --git a/src/main/java/net/kemitix/conditional/TrueCondition.java b/src/main/java/net/kemitix/conditional/TrueCondition.java new file mode 100644 index 0000000..ba15c80 --- /dev/null +++ b/src/main/java/net/kemitix/conditional/TrueCondition.java @@ -0,0 +1,54 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2017 Paul Campbell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies + * or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package net.kemitix.conditional; + +/** + * A {@code Condition} that has evaluated to {@code true}. + * + * @author Paul Campbell (pcampbell@kemitix.net). + */ +public final class TrueCondition implements Condition { + + protected static final Condition TRUE = new net.kemitix.conditional.TrueCondition(); + + @Override + public Condition and(final boolean clause) { + return Condition.where(clause); + } + + @Override + public Condition or(final boolean secondClause) { + return TRUE; + } + + @Override + public Condition then(final Runnable response) { + response.run(); + return TRUE; + } + + @Override + public void otherwise(final Runnable response) { + // do nothing + } + +}