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