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