001/*
002 * Copyright 2023 the original author or authors.
003 * <p>
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * <p>
008 * https://www.apache.org/licenses/LICENSE-2.0
009 * <p>
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package de.cuioss.tools.base;
017
018import lombok.experimental.UtilityClass;
019
020/**
021 * Utility Class providing some boolean operations. In essence, it simplifies
022 * 'or' and 'and' operations. Some examples from the unit-tests:
023 *
024 * <pre>
025 *
026 * &#64;Test
027 * void shouldDetectAnyTrue() {
028 *     assertTrue(BooleanOperations.isAnyTrue(true));
029 *     assertTrue(BooleanOperations.isAnyTrue(true, true));
030 *     assertTrue(BooleanOperations.isAnyTrue(true, false));
031 *     assertFalse(BooleanOperations.isAnyTrue(false, false));
032 *     // Not really sensible, but defined contract -> Corner Case
033 *     assertFalse(BooleanOperations.isAnyTrue());
034 *     assertFalse(BooleanOperations.isAnyTrue(null));
035 * }
036 *
037 * &#64;Test
038 * void shouldDetectAnyFalse() {
039 *     assertFalse(BooleanOperations.isAnyFalse(true));
040 *     assertTrue(BooleanOperations.isAnyFalse(true, false));
041 *     assertTrue(BooleanOperations.isAnyFalse(false, false));
042 *     // Not really sensible, but defined contract -> Corner Case
043 *     assertFalse(BooleanOperations.isAnyFalse());
044 *     assertFalse(BooleanOperations.isAnyFalse(null));
045 * }
046 *
047 * &#64;Test
048 * void shouldDetectAllFalse() {
049 *     assertFalse(BooleanOperations.areAllFalse(true));
050 *     assertFalse(BooleanOperations.areAllFalse(true, false));
051 *     assertFalse(BooleanOperations.areAllFalse(true, true));
052 *     assertTrue(BooleanOperations.areAllFalse(false, false));
053 *     // Not really sensible, but defined contract -> Corner Case
054 *     assertFalse(BooleanOperations.areAllFalse());
055 *     assertFalse(BooleanOperations.areAllFalse(null));
056 * }
057 *
058 * &#64;Test
059 * void shouldDetectAllTrue() {
060 *     assertTrue(BooleanOperations.areAllTrue(true));
061 *     assertFalse(BooleanOperations.areAllTrue(true, false));
062 *     assertTrue(BooleanOperations.areAllTrue(true, true));
063 *     assertFalse(BooleanOperations.areAllTrue(false, false));
064 *     // Not really sensible, but defined contract -> Corner Case
065 *     assertTrue(BooleanOperations.areAllTrue());
066 *     assertTrue(BooleanOperations.areAllTrue(null));
067 * }
068 * </pre>
069 *
070 *
071 *
072 * @author Eugen Fischer
073 * @author Oliver Wolff
074 */
075@UtilityClass
076public final class BooleanOperations {
077
078    private static boolean containsTrue(final boolean... parameter) {
079        if (isEmpty(parameter)) {
080            return false;
081        }
082        for (boolean element : parameter) {
083            if (element) {
084                return true;
085            }
086        }
087        return false;
088    }
089
090    private static boolean isEmpty(boolean[] parameter) {
091        return null == parameter || 0 == parameter.length;
092    }
093
094    private static boolean containsFalse(final boolean... parameter) {
095        if (isEmpty(parameter)) {
096            return false;
097        }
098        for (boolean element : parameter) {
099            if (!element) {
100                return true;
101            }
102        }
103        return false;
104    }
105
106    /**
107     * Shorthand for checking if at least one of the given booleans is {@code true}
108     *
109     * @param parameter ellipsis of boolean values
110     * @return {@code true} if one of parameters is {@code true}, {@code false}
111     *         otherwise
112     */
113    public static boolean isAnyTrue(final boolean... parameter) {
114        return containsTrue(parameter);
115    }
116
117    /**
118     * Shorthand for checking if all the given booleans are {@code true}
119     *
120     * @param parameter ellipsis of boolean values
121     * @return {@code true} if all parameters are {@code true} or no parameter is
122     *         given ratio: no given false, {@code false} otherwise
123     */
124    public static boolean areAllTrue(final boolean... parameter) {
125        if (isEmpty(parameter)) {
126            return true;
127        }
128        return !containsFalse(parameter);
129    }
130
131    /**
132     * Shorthand for checking if all given booleans are {@code false}
133     *
134     * @param parameter ellipsis of boolean values
135     * @return {@code true} if all parameters are {@code false}, {@code true}
136     *         otherwise. {@code false} if no parameter is passed, ratio: no given
137     *         false
138     */
139    public static boolean areAllFalse(final boolean... parameter) {
140        if (isEmpty(parameter)) {
141            return false;
142        }
143        return !containsTrue(parameter);
144    }
145
146    /**
147     * Shorthand for checking if at least one of the given booleans is {@code false}
148     *
149     * @param parameter ellipsis of boolean values
150     * @return {@code true} if one of parameters is {@code false}, {@code true}
151     *         otherwise
152     */
153    public static boolean isAnyFalse(final boolean... parameter) {
154        return containsFalse(parameter);
155    }
156
157    /**
158     * @param value to be checked
159     * @return true, if the given value represents a boolean value i.e. "true" or
160     *         "false" ignoring case.
161     */
162    public static boolean isValidBoolean(String value) {
163        return Boolean.TRUE.toString().equalsIgnoreCase(value) || Boolean.FALSE.toString().equalsIgnoreCase(value);
164    }
165}