001    /*
002     * Copyright 2008-2015 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2008-2015 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     */
021    package com.unboundid.ldap.matchingrules;
022    
023    
024    
025    import com.unboundid.asn1.ASN1OctetString;
026    import com.unboundid.ldap.sdk.LDAPException;
027    import com.unboundid.ldap.sdk.ResultCode;
028    import com.unboundid.util.ThreadSafety;
029    import com.unboundid.util.ThreadSafetyLevel;
030    
031    import static com.unboundid.ldap.matchingrules.MatchingRuleMessages.*;
032    import 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)
042    public 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    }