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 may be used for
038 * telephone numbers.  It will accept values with any ASCII printable character.
039 * When making comparisons, spaces and dashes will be ignored.
040 */
041@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
042public final class TelephoneNumberMatchingRule
043       extends SimpleMatchingRule
044{
045  /**
046   * The singleton instance that will be returned from the {@code getInstance}
047   * method.
048   */
049  private static final TelephoneNumberMatchingRule INSTANCE =
050       new TelephoneNumberMatchingRule();
051
052
053
054  /**
055   * The name for the telephoneNumberMatch equality matching rule.
056   */
057  public static final String EQUALITY_RULE_NAME = "telephoneNumberMatch";
058
059
060
061  /**
062   * The name for the telephoneNumberMatch equality matching rule, formatted in
063   * all lowercase characters.
064   */
065  static final String LOWER_EQUALITY_RULE_NAME =
066       toLowerCase(EQUALITY_RULE_NAME);
067
068
069
070  /**
071   * The OID for the telephoneNumberMatch equality matching rule.
072   */
073  public static final String EQUALITY_RULE_OID = "2.5.13.20";
074
075
076
077  /**
078   * The name for the telephoneNumberSubstringsMatch substring matching rule.
079   */
080  public static final String SUBSTRING_RULE_NAME =
081       "telephoneNumberSubstringsMatch";
082
083
084
085  /**
086   * The name for the telephoneNumberSubstringsMatch substring matching rule,
087   * formatted in all lowercase characters.
088   */
089  static final String LOWER_SUBSTRING_RULE_NAME =
090       toLowerCase(SUBSTRING_RULE_NAME);
091
092
093
094  /**
095   * The OID for the telephoneNumberSubstringsMatch substring matching rule.
096   */
097  public static final String SUBSTRING_RULE_OID = "2.5.13.21";
098
099
100
101  /**
102   * The serial version UID for this serializable class.
103   */
104  private static final long serialVersionUID = -5463096544849211252L;
105
106
107
108  /**
109   * Creates a new instance of this telephone number matching rule.
110   */
111  public TelephoneNumberMatchingRule()
112  {
113    // No implementation is required.
114  }
115
116
117
118  /**
119   * Retrieves a singleton instance of this matching rule.
120   *
121   * @return  A singleton instance of this matching rule.
122   */
123  public static TelephoneNumberMatchingRule getInstance()
124  {
125    return INSTANCE;
126  }
127
128
129
130  /**
131   * {@inheritDoc}
132   */
133  @Override()
134  public String getEqualityMatchingRuleName()
135  {
136    return EQUALITY_RULE_NAME;
137  }
138
139
140
141  /**
142   * {@inheritDoc}
143   */
144  @Override()
145  public String getEqualityMatchingRuleOID()
146  {
147    return EQUALITY_RULE_OID;
148  }
149
150
151
152  /**
153   * {@inheritDoc}
154   */
155  @Override()
156  public String getOrderingMatchingRuleName()
157  {
158    return null;
159  }
160
161
162
163  /**
164   * {@inheritDoc}
165   */
166  @Override()
167  public String getOrderingMatchingRuleOID()
168  {
169    return null;
170  }
171
172
173
174  /**
175   * {@inheritDoc}
176   */
177  @Override()
178  public String getSubstringMatchingRuleName()
179  {
180    return SUBSTRING_RULE_NAME;
181  }
182
183
184
185  /**
186   * {@inheritDoc}
187   */
188  @Override()
189  public String getSubstringMatchingRuleOID()
190  {
191    return SUBSTRING_RULE_OID;
192  }
193
194
195
196  /**
197   * {@inheritDoc}
198   */
199  @Override()
200  public int compareValues(final ASN1OctetString value1,
201                           final ASN1OctetString value2)
202         throws LDAPException
203  {
204    throw new LDAPException(ResultCode.INAPPROPRIATE_MATCHING,
205         ERR_TELEPHONE_NUMBER_ORDERING_MATCHING_NOT_SUPPORTED.get());
206  }
207
208
209
210  /**
211   * {@inheritDoc}
212   */
213  @Override()
214  public ASN1OctetString normalize(final ASN1OctetString value)
215         throws LDAPException
216  {
217    final byte[] valueBytes = value.getValue();
218    final StringBuilder buffer = new StringBuilder();
219    for (int i=0; i < valueBytes.length; i++)
220    {
221      switch (valueBytes[i])
222      {
223        case ' ':
224        case '-':
225          // These should be ignored.
226          break;
227
228        case '\'':
229        case '(':
230        case ')':
231        case '+':
232        case ',':
233        case '.':
234        case '=':
235        case '/':
236        case ':':
237        case '?':
238          // These should be retained.
239          buffer.append((char) valueBytes[i]);
240          break;
241
242        default:
243          final byte b = valueBytes[i];
244          if (((b >= '0') && (b <= '9')) ||
245              ((b >= 'a') && (b <= 'z')) ||
246              ((b >= 'A') && (b <= 'Z')))
247          {
248            // These should be retained.
249            buffer.append((char) valueBytes[i]);
250            break;
251          }
252
253          throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
254               ERR_TELEPHONE_NUMBER_INVALID_CHARACTER.get(i));
255      }
256    }
257
258    return new ASN1OctetString(buffer.toString());
259  }
260
261
262
263  /**
264   * {@inheritDoc}
265   */
266  @Override()
267  public ASN1OctetString normalizeSubstring(final ASN1OctetString value,
268                                            final byte substringType)
269         throws LDAPException
270  {
271    return normalize(value);
272  }
273}