/* * Copyright (c) 2017 OBiBa. All rights reserved. * * This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.obiba.magma.lang; import javax.annotation.Nullable; /** * Boolean helper methods. * <p/> * This class provides <a href="http://en.wikipedia.org/wiki/Ternary_logic"/>Ternary Logic</a> operations which allow * operating on {@code null} boolean values. The following truth table is implemented by these methods. * <table> * <tbody> * <tr> * <th><i>A</i></th> * <th><i>B</i></th> * <th><i>A</i> OR <i>B</i></th> * <th><i>A</i> AND <i>B</i></th> * <th>NOT <i>A</i></th> * </tr> * <tr> * <td>true</td> * <td>true</td> * <td>true</td> * <td>true</td> * <td>false</td> * </tr> * <tr> * <td>true</td> * <td>null</td> * <td>true</td> * <td>null</td> * <td>false</td> * </tr> * <tr> * <td>true</td> * <td>false</td> * <td>true</td> * <td>false</td> * <td>false</td> * </tr> * <tr> * <td>null</td> * <td>true</td> * <td>true</td> * <td>null</td> * <td>null</td> * </tr> * <tr> * <td>null</td> * <td>null</td> * <td>null</td> * <td>null</td> * <td>null</td> * </tr> * <tr> * <td>null</td> * <td>false</td> * <td>null</td> * <td>false</td> * <td>null</td> * </tr> * <tr> * <td>false</td> * <td>true</td> * <td>true</td> * <td>false</td> * <td>true</td> * </tr> * <tr> * <td>false</td> * <td>null</td> * <td>null</td> * <td>false</td> * <td>true</td> * </tr> * <tr> * <td>false</td> * <td>false</td> * <td>false</td> * <td>false</td> * <td>true</td> * </tr> * </tbody> * </table> */ public final class Booleans { private Booleans() { } /** * Implements ternary logic {@code AND} operation * * @param op1 first operand * @param op2 second operand * @return true, false or null (see truth table) */ @SuppressWarnings("ConstantConditions") @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "NP_BOOLEAN_RETURN_NULL", justification = "Clients expect ternaryAnd to return null as a valid value.") public static Boolean ternaryAnd(@Nullable Boolean op1, @Nullable Boolean op2) { // If either operands is null, then the outcome is either null or false. if(isNull(op1) || isNull(op2)) { // The outcome is false if either operand is false if(isFalse(op1) || isFalse(op2)) return false; return null; } return op1 && op2; } /** * Implements ternary logic {@code OR} operation * * @param op1 first operand * @param op2 second operand * @return true, false or null (see truth table) */ @SuppressWarnings("ConstantConditions") @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "NP_BOOLEAN_RETURN_NULL", justification = "Clients expect ternaryOr to return null as a valid value.") public static Boolean ternaryOr(@Nullable Boolean op1, @Nullable Boolean op2) { // If either operands is null, then the outcome is either null or true. if(isNull(op1) || isNull(op2)) { // The outcome is true if either operand is true if(isTrue(op1) || isTrue(op2)) return true; return null; } return op1 || op2; } /** * Implements ternary logic {@code NOT} operation * * @param op operand * @return true, false or null (see truth table) */ @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "NP_BOOLEAN_RETURN_NULL", justification = "Clients expect ternaryNot to return null as a valid value.") public static Boolean ternaryNot(Boolean op) { // If operand is null, then the outcome is null. if(isNull(op)) return null; return !op; } /** * Returns true when {@code op} is {@code false}. This method returns false when {@code op} is {@code null} or {@code * true}. * * @param op value to test * @return true when {@code op} is {@code false} */ public static boolean isFalse(Boolean op) { return op != null && !op; } /** * Returns true when {@code op} is {@code true}. This method returns false when {@code op} is {@code null} or {@code * false}. * * @param op value to test * @return true when {@code op} is {@code true} */ public static boolean isTrue(Boolean op) { return op != null && op; } /** * Returns true when {@code op} is {@code null}. * * @param op value to test * @return true when {@code op} is {@code null} */ private static boolean isNull(Boolean op) { return op == null; } }