001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2009 Sun Microsystems, Inc. 015 */ 016 017package org.forgerock.opendj.ldap; 018 019/** 020 * The result of a tri-state logical expression. Condition results are used to 021 * represent the result of a conditional evaluation that can yield three 022 * possible values: {@code FALSE} (i.e. "no"), {@code TRUE} (i.e. "yes"), or 023 * {@code UNDEFINED} (i.e. "maybe"). A result of {@code UNDEFINED} indicates 024 * that further investigation may be required. 025 */ 026public enum ConditionResult { 027 /** 028 * Indicates that the condition evaluated to {@code false}. 029 */ 030 FALSE("false"), 031 032 /** 033 * Indicates that the condition could not be evaluated and its result is 034 * undefined. 035 */ 036 UNDEFINED("undefined"), 037 038 /** 039 * Indicates that the condition evaluated to {@code true}. 040 */ 041 TRUE("true"); 042 043 /** Boolean -> ConditionResult map. */ 044 private static final boolean[] BOOLEAN_MAP = { false, false, true }; 045 046 /** AND truth table. */ 047 private static final ConditionResult[][] LOGICAL_AND = { { FALSE, FALSE, FALSE }, 048 { FALSE, UNDEFINED, UNDEFINED }, { FALSE, UNDEFINED, TRUE }, }; 049 050 /** NOT truth table. */ 051 private static final ConditionResult[] LOGICAL_NOT = { TRUE, UNDEFINED, FALSE }; 052 053 /** OR truth table. */ 054 private static final ConditionResult[][] LOGICAL_OR = { { FALSE, UNDEFINED, TRUE }, 055 { UNDEFINED, UNDEFINED, TRUE }, { TRUE, TRUE, TRUE }, }; 056 057 /** 058 * Returns the logical AND of zero condition results, which is always 059 * {@code TRUE}. 060 * 061 * @return The logical OR of zero condition results, which is always 062 * {@code TRUE}. 063 */ 064 public static ConditionResult and() { 065 return TRUE; 066 } 067 068 /** 069 * Returns the logical AND of the provided condition result, which is always 070 * {@code r}. 071 * 072 * @param r 073 * The condition result. 074 * @return The logical AND of the provided condition result, which is always 075 * {@code r}. 076 */ 077 public static ConditionResult and(final ConditionResult r) { 078 return r; 079 } 080 081 /** 082 * Returns the logical AND of the provided condition results, which is 083 * {@code TRUE} if all of the provided condition results are {@code TRUE}, 084 * {@code FALSE} if at least one of them is {@code FALSE}, and 085 * {@code UNDEFINED} otherwise. Note that {@code TRUE} is returned if the 086 * provided list of results is empty. 087 * 088 * @param results 089 * The condition results to be compared. 090 * @return The logical AND of the provided condition results. 091 */ 092 public static ConditionResult and(final ConditionResult... results) { 093 ConditionResult finalResult = TRUE; 094 for (final ConditionResult result : results) { 095 finalResult = and(finalResult, result); 096 if (finalResult == FALSE) { 097 break; 098 } 099 } 100 return finalResult; 101 } 102 103 /** 104 * Returns the logical AND of the provided condition results, which is 105 * {@code TRUE} if both of the provided condition results are {@code TRUE}, 106 * {@code FALSE} if at least one of them is {@code FALSE} , and 107 * {@code UNDEFINED} otherwise. 108 * 109 * @param r1 110 * The first condition result to be compared. 111 * @param r2 112 * The second condition result to be compared. 113 * @return The logical AND of the provided condition results. 114 */ 115 public static ConditionResult and(final ConditionResult r1, final ConditionResult r2) { 116 return LOGICAL_AND[r1.ordinal()][r2.ordinal()]; 117 } 118 119 /** 120 * Returns the logical NOT of the provided condition result, which is 121 * {@code TRUE} if the provided condition result is {@code FALSE}, 122 * {@code TRUE} if it is {@code FALSE}, and {@code UNDEFINED} otherwise. 123 * 124 * @param r 125 * The condition result to invert. 126 * @return The logical NOT of the provided condition result. 127 */ 128 public static ConditionResult not(final ConditionResult r) { 129 return LOGICAL_NOT[r.ordinal()]; 130 } 131 132 /** 133 * Returns the logical OR of zero condition results, which is always 134 * {@code FALSE}. 135 * 136 * @return The logical OR of zero condition results, which is always 137 * {@code FALSE}. 138 */ 139 public static ConditionResult or() { 140 return FALSE; 141 } 142 143 /** 144 * Returns the logical OR of the provided condition result, which is always 145 * {@code r}. 146 * 147 * @param r 148 * The condition result. 149 * @return The logical OR of the provided condition result, which is always 150 * {@code r}. 151 */ 152 public static ConditionResult or(final ConditionResult r) { 153 return r; 154 } 155 156 /** 157 * Returns the logical OR of the provided condition results, which is 158 * {@code FALSE} if all of the provided condition results are {@code FALSE}, 159 * {@code TRUE} if at least one of them is {@code TRUE}, and 160 * {@code UNDEFINED} otherwise. Note that {@code FALSE} is returned if the 161 * provided list of results is empty. 162 * 163 * @param results 164 * The condition results to be compared. 165 * @return The logical OR of the provided condition results. 166 */ 167 public static ConditionResult or(final ConditionResult... results) { 168 ConditionResult finalResult = FALSE; 169 for (final ConditionResult result : results) { 170 finalResult = or(finalResult, result); 171 if (finalResult == TRUE) { 172 break; 173 } 174 } 175 return finalResult; 176 } 177 178 /** 179 * Returns the logical OR of the provided condition results, which is 180 * {@code FALSE} if both of the provided condition results are {@code FALSE} 181 * , {@code TRUE} if at least one of them is {@code TRUE} , and 182 * {@code UNDEFINED} otherwise. 183 * 184 * @param r1 185 * The first condition result to be compared. 186 * @param r2 187 * The second condition result to be compared. 188 * @return The logical OR of the provided condition results. 189 */ 190 public static ConditionResult or(final ConditionResult r1, final ConditionResult r2) { 191 return LOGICAL_OR[r1.ordinal()][r2.ordinal()]; 192 } 193 194 /** 195 * Returns the condition result which is equivalent to the provided boolean 196 * value. 197 * 198 * @param b 199 * The boolean value. 200 * @return {@code TRUE} if {@code b} was {@code true}, otherwise 201 * {@code FALSE} . 202 */ 203 public static ConditionResult valueOf(final boolean b) { 204 return b ? TRUE : FALSE; 205 } 206 207 /** The human-readable name for this result. */ 208 private final String resultName; 209 210 /** Prevent instantiation. */ 211 private ConditionResult(final String resultName) { 212 this.resultName = resultName; 213 } 214 215 /** 216 * Converts this condition result to a boolean value. {@code FALSE} and 217 * {@code UNDEFINED} are both converted to {@code false}, and {@code TRUE} 218 * is converted to {@code true}. 219 * 220 * @return The boolean equivalent of this condition result. 221 */ 222 public boolean toBoolean() { 223 return BOOLEAN_MAP[ordinal()]; 224 } 225 226 /** 227 * Returns the string representation of this condition result. 228 * 229 * @return The string representation of his condition result. 230 */ 231 @Override 232 public String toString() { 233 return resultName; 234 } 235}