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