001/*
002 * Copyright 2008-2020 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2008-2020 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-2020 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.StaticUtils;
044import com.unboundid.util.ThreadSafety;
045import com.unboundid.util.ThreadSafetyLevel;
046
047import static com.unboundid.ldap.matchingrules.MatchingRuleMessages.*;
048
049
050
051/**
052 * This class provides an implementation of a matching rule that performs
053 * equality comparisons against Boolean values, which should be either "TRUE" or
054 * "FALSE".  Substring and ordering matching are not supported.
055 */
056@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
057public final class BooleanMatchingRule
058       extends MatchingRule
059{
060  /**
061   * The singleton instance that will be returned from the {@code getInstance}
062   * method.
063   */
064  private static final BooleanMatchingRule INSTANCE =
065       new BooleanMatchingRule();
066
067
068
069  /**
070   * The pre-defined value that will be used as the normalized representation
071   * of a "TRUE" value.
072   */
073  private static final ASN1OctetString TRUE_VALUE = new ASN1OctetString("TRUE");
074
075
076
077  /**
078   * The pre-defined value that will be used as the normalized representation
079   * of a "FALSE" value.
080   */
081  private static final ASN1OctetString FALSE_VALUE =
082       new ASN1OctetString("FALSE");
083
084
085
086  /**
087   * The name for the booleanMatch equality matching rule.
088   */
089  public static final String EQUALITY_RULE_NAME = "booleanMatch";
090
091
092
093  /**
094   * The name for the booleanMatch equality matching rule, formatted in all
095   * lowercase characters.
096   */
097  static final String LOWER_EQUALITY_RULE_NAME =
098       StaticUtils.toLowerCase(EQUALITY_RULE_NAME);
099
100
101
102  /**
103   * The OID for the booleanMatch equality matching rule.
104   */
105  public static final String EQUALITY_RULE_OID = "2.5.13.13";
106
107
108
109  /**
110   * The serial version UID for this serializable class.
111   */
112  private static final long serialVersionUID = 5137725892611277972L;
113
114
115
116  /**
117   * Creates a new instance of this Boolean matching rule.
118   */
119  public BooleanMatchingRule()
120  {
121    // No implementation is required.
122  }
123
124
125
126  /**
127   * Retrieves a singleton instance of this matching rule.
128   *
129   * @return  A singleton instance of this matching rule.
130   */
131  public static BooleanMatchingRule getInstance()
132  {
133    return INSTANCE;
134  }
135
136
137
138  /**
139   * {@inheritDoc}
140   */
141  @Override()
142  public String getEqualityMatchingRuleName()
143  {
144    return EQUALITY_RULE_NAME;
145  }
146
147
148
149  /**
150   * {@inheritDoc}
151   */
152  @Override()
153  public String getEqualityMatchingRuleOID()
154  {
155    return EQUALITY_RULE_OID;
156  }
157
158
159
160  /**
161   * {@inheritDoc}
162   */
163  @Override()
164  public String getOrderingMatchingRuleName()
165  {
166    return null;
167  }
168
169
170
171  /**
172   * {@inheritDoc}
173   */
174  @Override()
175  public String getOrderingMatchingRuleOID()
176  {
177    return null;
178  }
179
180
181
182  /**
183   * {@inheritDoc}
184   */
185  @Override()
186  public String getSubstringMatchingRuleName()
187  {
188    return null;
189  }
190
191
192
193  /**
194   * {@inheritDoc}
195   */
196  @Override()
197  public String getSubstringMatchingRuleOID()
198  {
199    return null;
200  }
201
202
203
204  /**
205   * {@inheritDoc}
206   */
207  @Override()
208  public boolean valuesMatch(final ASN1OctetString value1,
209                             final ASN1OctetString value2)
210         throws LDAPException
211  {
212    return normalize(value1).equals(normalize(value2));
213  }
214
215
216
217  /**
218   * {@inheritDoc}
219   */
220  @Override()
221  public boolean matchesSubstring(final ASN1OctetString value,
222                                  final ASN1OctetString subInitial,
223                                  final ASN1OctetString[] subAny,
224                                  final ASN1OctetString subFinal)
225         throws LDAPException
226  {
227    throw new LDAPException(ResultCode.INAPPROPRIATE_MATCHING,
228                            ERR_BOOLEAN_SUBSTRING_MATCHING_NOT_SUPPORTED.get());
229  }
230
231
232
233  /**
234   * {@inheritDoc}
235   */
236  @Override()
237  public int compareValues(final ASN1OctetString value1,
238                           final ASN1OctetString value2)
239         throws LDAPException
240  {
241    throw new LDAPException(ResultCode.INAPPROPRIATE_MATCHING,
242                            ERR_BOOLEAN_ORDERING_MATCHING_NOT_SUPPORTED.get());
243  }
244
245
246
247  /**
248   * {@inheritDoc}
249   */
250  @Override()
251  public ASN1OctetString normalize(final ASN1OctetString value)
252         throws LDAPException
253  {
254    final byte[] valueBytes = value.getValue();
255
256    if ((valueBytes.length == 4) &&
257        ((valueBytes[0] == 'T') || (valueBytes[0] == 't')) &&
258        ((valueBytes[1] == 'R') || (valueBytes[1] == 'r')) &&
259        ((valueBytes[2] == 'U') || (valueBytes[2] == 'u')) &&
260        ((valueBytes[3] == 'E') || (valueBytes[3] == 'e')))
261    {
262      return TRUE_VALUE;
263    }
264    else if ((valueBytes.length == 5) &&
265             ((valueBytes[0] == 'F') || (valueBytes[0] == 'f')) &&
266             ((valueBytes[1] == 'A') || (valueBytes[1] == 'a')) &&
267             ((valueBytes[2] == 'L') || (valueBytes[2] == 'l')) &&
268             ((valueBytes[3] == 'S') || (valueBytes[3] == 's')) &&
269             ((valueBytes[4] == 'E') || (valueBytes[4] == 'e')))
270    {
271      return FALSE_VALUE;
272    }
273    else
274    {
275      throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
276                              ERR_BOOLEAN_INVALID_VALUE.get());
277    }
278  }
279
280
281
282  /**
283   * {@inheritDoc}
284   */
285  @Override()
286  public ASN1OctetString normalizeSubstring(final ASN1OctetString value,
287                                            final byte substringType)
288         throws LDAPException
289  {
290    throw new LDAPException(ResultCode.INAPPROPRIATE_MATCHING,
291                            ERR_BOOLEAN_SUBSTRING_MATCHING_NOT_SUPPORTED.get());
292  }
293}