001/*
002 * Copyright 2008-2024 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2008-2024 Ping Identity Corporation
007 *
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *    http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 */
020/*
021 * Copyright (C) 2008-2024 Ping Identity Corporation
022 *
023 * This program is free software; you can redistribute it and/or modify
024 * it under the terms of the GNU General Public License (GPLv2 only)
025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
026 * as published by the Free Software Foundation.
027 *
028 * This program is distributed in the hope that it will be useful,
029 * but WITHOUT ANY WARRANTY; without even the implied warranty of
030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
031 * GNU General Public License for more details.
032 *
033 * You should have received a copy of the GNU General Public License
034 * along with this program; if not, see <http://www.gnu.org/licenses>.
035 */
036package com.unboundid.ldap.matchingrules;
037
038
039
040import com.unboundid.asn1.ASN1OctetString;
041import com.unboundid.ldap.sdk.LDAPException;
042import com.unboundid.ldap.sdk.ResultCode;
043import com.unboundid.util.NotNull;
044import com.unboundid.util.Nullable;
045import com.unboundid.util.StaticUtils;
046import com.unboundid.util.ThreadSafety;
047import com.unboundid.util.ThreadSafetyLevel;
048
049import static com.unboundid.ldap.matchingrules.MatchingRuleMessages.*;
050
051
052
053/**
054 * This class provides an implementation of a matching rule that performs
055 * equality comparisons against Boolean values, which should be either "TRUE" or
056 * "FALSE".  Substring and ordering matching are not supported.
057 */
058@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
059public final class BooleanMatchingRule
060       extends MatchingRule
061{
062  /**
063   * The singleton instance that will be returned from the {@code getInstance}
064   * method.
065   */
066  @NotNull private static final BooleanMatchingRule INSTANCE =
067       new BooleanMatchingRule();
068
069
070
071  /**
072   * The pre-defined value that will be used as the normalized representation
073   * of a "TRUE" value.
074   */
075  @NotNull private static final ASN1OctetString TRUE_VALUE =
076       new ASN1OctetString("TRUE");
077
078
079
080  /**
081   * The pre-defined value that will be used as the normalized representation
082   * of a "FALSE" value.
083   */
084  @NotNull private static final ASN1OctetString FALSE_VALUE =
085       new ASN1OctetString("FALSE");
086
087
088
089  /**
090   * The name for the booleanMatch equality matching rule.
091   */
092  @NotNull public static final String EQUALITY_RULE_NAME = "booleanMatch";
093
094
095
096  /**
097   * The name for the booleanMatch equality matching rule, formatted in all
098   * lowercase characters.
099   */
100  @NotNull static final String LOWER_EQUALITY_RULE_NAME =
101       StaticUtils.toLowerCase(EQUALITY_RULE_NAME);
102
103
104
105  /**
106   * The OID for the booleanMatch equality matching rule.
107   */
108  @NotNull public static final String EQUALITY_RULE_OID = "2.5.13.13";
109
110
111
112  /**
113   * The serial version UID for this serializable class.
114   */
115  private static final long serialVersionUID = 5137725892611277972L;
116
117
118
119  /**
120   * Creates a new instance of this Boolean matching rule.
121   */
122  public BooleanMatchingRule()
123  {
124    // No implementation is required.
125  }
126
127
128
129  /**
130   * Retrieves a singleton instance of this matching rule.
131   *
132   * @return  A singleton instance of this matching rule.
133   */
134  @NotNull()
135  public static BooleanMatchingRule getInstance()
136  {
137    return INSTANCE;
138  }
139
140
141
142  /**
143   * {@inheritDoc}
144   */
145  @Override()
146  @NotNull()
147  public String getEqualityMatchingRuleName()
148  {
149    return EQUALITY_RULE_NAME;
150  }
151
152
153
154  /**
155   * {@inheritDoc}
156   */
157  @Override()
158  @NotNull()
159  public String getEqualityMatchingRuleOID()
160  {
161    return EQUALITY_RULE_OID;
162  }
163
164
165
166  /**
167   * {@inheritDoc}
168   */
169  @Override()
170  @Nullable()
171  public String getOrderingMatchingRuleName()
172  {
173    return null;
174  }
175
176
177
178  /**
179   * {@inheritDoc}
180   */
181  @Override()
182  @Nullable()
183  public String getOrderingMatchingRuleOID()
184  {
185    return null;
186  }
187
188
189
190  /**
191   * {@inheritDoc}
192   */
193  @Override()
194  @Nullable()
195  public String getSubstringMatchingRuleName()
196  {
197    return null;
198  }
199
200
201
202  /**
203   * {@inheritDoc}
204   */
205  @Override()
206  @Nullable()
207  public String getSubstringMatchingRuleOID()
208  {
209    return null;
210  }
211
212
213
214  /**
215   * {@inheritDoc}
216   */
217  @Override()
218  public boolean valuesMatch(@NotNull final ASN1OctetString value1,
219                             @NotNull final ASN1OctetString value2)
220         throws LDAPException
221  {
222    return normalize(value1).equals(normalize(value2));
223  }
224
225
226
227  /**
228   * {@inheritDoc}
229   */
230  @Override()
231  public boolean matchesSubstring(@NotNull final ASN1OctetString value,
232                                  @Nullable final ASN1OctetString subInitial,
233                                  @Nullable final ASN1OctetString[] subAny,
234                                  @Nullable final ASN1OctetString subFinal)
235         throws LDAPException
236  {
237    throw new LDAPException(ResultCode.INAPPROPRIATE_MATCHING,
238                            ERR_BOOLEAN_SUBSTRING_MATCHING_NOT_SUPPORTED.get());
239  }
240
241
242
243  /**
244   * {@inheritDoc}
245   */
246  @Override()
247  public int compareValues(@NotNull final ASN1OctetString value1,
248                           @NotNull final ASN1OctetString value2)
249         throws LDAPException
250  {
251    throw new LDAPException(ResultCode.INAPPROPRIATE_MATCHING,
252                            ERR_BOOLEAN_ORDERING_MATCHING_NOT_SUPPORTED.get());
253  }
254
255
256
257  /**
258   * {@inheritDoc}
259   */
260  @Override()
261  @NotNull()
262  public ASN1OctetString normalize(@NotNull final ASN1OctetString value)
263         throws LDAPException
264  {
265    final byte[] valueBytes = value.getValue();
266
267    if ((valueBytes.length == 4) &&
268        ((valueBytes[0] == 'T') || (valueBytes[0] == 't')) &&
269        ((valueBytes[1] == 'R') || (valueBytes[1] == 'r')) &&
270        ((valueBytes[2] == 'U') || (valueBytes[2] == 'u')) &&
271        ((valueBytes[3] == 'E') || (valueBytes[3] == 'e')))
272    {
273      return TRUE_VALUE;
274    }
275    else if ((valueBytes.length == 5) &&
276             ((valueBytes[0] == 'F') || (valueBytes[0] == 'f')) &&
277             ((valueBytes[1] == 'A') || (valueBytes[1] == 'a')) &&
278             ((valueBytes[2] == 'L') || (valueBytes[2] == 'l')) &&
279             ((valueBytes[3] == 'S') || (valueBytes[3] == 's')) &&
280             ((valueBytes[4] == 'E') || (valueBytes[4] == 'e')))
281    {
282      return FALSE_VALUE;
283    }
284    else
285    {
286      throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
287                              ERR_BOOLEAN_INVALID_VALUE.get());
288    }
289  }
290
291
292
293  /**
294   * {@inheritDoc}
295   */
296  @Override()
297  @NotNull()
298  public ASN1OctetString normalizeSubstring(
299                              @NotNull final ASN1OctetString value,
300                              final byte substringType)
301         throws LDAPException
302  {
303    throw new LDAPException(ResultCode.INAPPROPRIATE_MATCHING,
304                            ERR_BOOLEAN_SUBSTRING_MATCHING_NOT_SUPPORTED.get());
305  }
306}