001/*
002 * Copyright 2008-2018 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2008-2018 Ping Identity Corporation
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.DN;
027import com.unboundid.ldap.sdk.LDAPException;
028import com.unboundid.ldap.sdk.ResultCode;
029import com.unboundid.util.Debug;
030import com.unboundid.util.StaticUtils;
031import com.unboundid.util.ThreadSafety;
032import com.unboundid.util.ThreadSafetyLevel;
033
034import static com.unboundid.ldap.matchingrules.MatchingRuleMessages.*;
035
036
037
038/**
039 * This class provides an implementation of a matching rule that performs
040 * equality comparisons against values that should be distinguished names.
041 * Substring and ordering matching are not supported.
042 */
043@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
044public final class DistinguishedNameMatchingRule
045       extends MatchingRule
046{
047  /**
048   * The singleton instance that will be returned from the {@code getInstance}
049   * method.
050   */
051  private static final DistinguishedNameMatchingRule INSTANCE =
052       new DistinguishedNameMatchingRule();
053
054
055
056  /**
057   * The name for the distinguishedNameMatch equality matching rule.
058   */
059  public static final String EQUALITY_RULE_NAME = "distinguishedNameMatch";
060
061
062
063  /**
064   * The name for the distinguishedNameMatch equality matching rule, formatted
065   * in all lowercase characters.
066   */
067  static final String LOWER_EQUALITY_RULE_NAME =
068       StaticUtils.toLowerCase(EQUALITY_RULE_NAME);
069
070
071
072  /**
073   * The OID for the distinguishedNameMatch equality matching rule.
074   */
075  public static final String EQUALITY_RULE_OID = "2.5.13.1";
076
077
078
079  /**
080   * The serial version UID for this serializable class.
081   */
082  private static final long serialVersionUID = -2617356571703597868L;
083
084
085
086  /**
087   * Creates a new instance of this distinguished name matching rule.
088   */
089  public DistinguishedNameMatchingRule()
090  {
091    // No implementation is required.
092  }
093
094
095
096  /**
097   * Retrieves a singleton instance of this matching rule.
098   *
099   * @return  A singleton instance of this matching rule.
100   */
101  public static DistinguishedNameMatchingRule getInstance()
102  {
103    return INSTANCE;
104  }
105
106
107
108  /**
109   * {@inheritDoc}
110   */
111  @Override()
112  public String getEqualityMatchingRuleName()
113  {
114    return EQUALITY_RULE_NAME;
115  }
116
117
118
119  /**
120   * {@inheritDoc}
121   */
122  @Override()
123  public String getEqualityMatchingRuleOID()
124  {
125    return EQUALITY_RULE_OID;
126  }
127
128
129
130  /**
131   * {@inheritDoc}
132   */
133  @Override()
134  public String getOrderingMatchingRuleName()
135  {
136    return null;
137  }
138
139
140
141  /**
142   * {@inheritDoc}
143   */
144  @Override()
145  public String getOrderingMatchingRuleOID()
146  {
147    return null;
148  }
149
150
151
152  /**
153   * {@inheritDoc}
154   */
155  @Override()
156  public String getSubstringMatchingRuleName()
157  {
158    return null;
159  }
160
161
162
163  /**
164   * {@inheritDoc}
165   */
166  @Override()
167  public String getSubstringMatchingRuleOID()
168  {
169    return null;
170  }
171
172
173
174  /**
175   * {@inheritDoc}
176   */
177  @Override()
178  public boolean valuesMatch(final ASN1OctetString value1,
179                             final ASN1OctetString value2)
180         throws LDAPException
181  {
182    final DN dn1;
183    try
184    {
185      dn1 = new DN(value1.stringValue());
186    }
187    catch (final LDAPException le)
188    {
189      Debug.debugException(le);
190      throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
191                              le.getMessage(), le);
192    }
193
194    final DN dn2;
195    try
196    {
197      dn2 = new DN(value2.stringValue());
198    }
199    catch (final LDAPException le)
200    {
201      Debug.debugException(le);
202      throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
203                              le.getMessage(), le);
204    }
205
206    return dn1.equals(dn2);
207  }
208
209
210
211  /**
212   * {@inheritDoc}
213   */
214  @Override()
215  public boolean matchesAnyValue(final ASN1OctetString assertionValue,
216                                 final ASN1OctetString[] attributeValues)
217         throws LDAPException
218  {
219    if ((assertionValue == null) || (attributeValues == null) ||
220        (attributeValues.length == 0))
221    {
222      return false;
223    }
224
225    final DN assertionValueDN;
226    try
227    {
228      assertionValueDN = new DN(assertionValue.stringValue());
229    }
230    catch (final LDAPException le)
231    {
232      Debug.debugException(le);
233      throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
234           le.getMessage(), le);
235    }
236
237    for (final ASN1OctetString attributeValue : attributeValues)
238    {
239      try
240      {
241        if (assertionValueDN.equals(new DN(attributeValue.stringValue())))
242        {
243          return true;
244        }
245      }
246      catch (final Exception e)
247      {
248        Debug.debugException(e);
249      }
250    }
251
252    return false;
253  }
254
255
256
257  /**
258   * {@inheritDoc}
259   */
260  @Override()
261  public boolean matchesSubstring(final ASN1OctetString value,
262                                  final ASN1OctetString subInitial,
263                                  final ASN1OctetString[] subAny,
264                                  final ASN1OctetString subFinal)
265         throws LDAPException
266  {
267    throw new LDAPException(ResultCode.INAPPROPRIATE_MATCHING,
268                            ERR_DN_SUBSTRING_MATCHING_NOT_SUPPORTED.get());
269  }
270
271
272
273  /**
274   * {@inheritDoc}
275   */
276  @Override()
277  public int compareValues(final ASN1OctetString value1,
278                           final ASN1OctetString value2)
279         throws LDAPException
280  {
281    throw new LDAPException(ResultCode.INAPPROPRIATE_MATCHING,
282                            ERR_DN_ORDERING_MATCHING_NOT_SUPPORTED.get());
283  }
284
285
286
287  /**
288   * {@inheritDoc}
289   */
290  @Override()
291  public ASN1OctetString normalize(final ASN1OctetString value)
292         throws LDAPException
293  {
294    try
295    {
296      final DN dn = new DN(value.stringValue());
297      return new ASN1OctetString(dn.toNormalizedString());
298    }
299    catch (final LDAPException le)
300    {
301      Debug.debugException(le);
302      throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
303                              le.getMessage(), le);
304    }
305  }
306
307
308
309  /**
310   * {@inheritDoc}
311   */
312  @Override()
313  public ASN1OctetString normalizeSubstring(final ASN1OctetString value,
314                                            final byte substringType)
315         throws LDAPException
316  {
317    throw new LDAPException(ResultCode.INAPPROPRIATE_MATCHING,
318                            ERR_DN_SUBSTRING_MATCHING_NOT_SUPPORTED.get());
319  }
320}