001 /*
002 * Copyright 2008-2016 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2008-2016 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 allows strings
038 * consisting of numeric digits and spaces. Spaces will be considered
039 * insignificant for matching purposes.
040 */
041 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
042 public final class NumericStringMatchingRule
043 extends SimpleMatchingRule
044 {
045 /**
046 * The singleton instance that will be returned from the {@code getInstance}
047 * method.
048 */
049 private static final NumericStringMatchingRule INSTANCE =
050 new NumericStringMatchingRule();
051
052
053
054 /**
055 * The name for the numericStringMatch equality matching rule.
056 */
057 public static final String EQUALITY_RULE_NAME = "numericStringMatch";
058
059
060
061 /**
062 * The name for the numericStringMatch 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 numericStringMatch equality matching rule.
072 */
073 public static final String EQUALITY_RULE_OID = "2.5.13.8";
074
075
076
077 /**
078 * The name for the numericStringOrderingMatch ordering matching rule.
079 */
080 public static final String ORDERING_RULE_NAME = "numericStringOrderingMatch";
081
082
083
084 /**
085 * The name for the numericStringOrderingMatch ordering matching rule,
086 * formatted in all lowercase characters.
087 */
088 static final String LOWER_ORDERING_RULE_NAME =
089 toLowerCase(ORDERING_RULE_NAME);
090
091
092
093 /**
094 * The OID for the numericStringOrderingMatch ordering matching rule.
095 */
096 public static final String ORDERING_RULE_OID = "2.5.13.9";
097
098
099
100 /**
101 * The name for the numericStringSubstringsMatch substring matching rule.
102 */
103 public static final String SUBSTRING_RULE_NAME =
104 "numericStringSubstringsMatch";
105
106
107
108 /**
109 * The name for the numericStringSubstringsMatch substring matching rule,
110 * formatted in all lowercase characters.
111 */
112 static final String LOWER_SUBSTRING_RULE_NAME =
113 toLowerCase(SUBSTRING_RULE_NAME);
114
115
116
117 /**
118 * The OID for the numericStringSubstringsMatch substring matching rule.
119 */
120 public static final String SUBSTRING_RULE_OID = "2.5.13.10";
121
122
123
124 /**
125 * The serial version UID for this serializable class.
126 */
127 private static final long serialVersionUID = -898484312052746321L;
128
129
130
131 /**
132 * Creates a new instance of this numeric string matching rule.
133 */
134 public NumericStringMatchingRule()
135 {
136 // No implementation is required.
137 }
138
139
140
141 /**
142 * Retrieves a singleton instance of this matching rule.
143 *
144 * @return A singleton instance of this matching rule.
145 */
146 public static NumericStringMatchingRule getInstance()
147 {
148 return INSTANCE;
149 }
150
151
152
153 /**
154 * {@inheritDoc}
155 */
156 @Override()
157 public String getEqualityMatchingRuleName()
158 {
159 return EQUALITY_RULE_NAME;
160 }
161
162
163
164 /**
165 * {@inheritDoc}
166 */
167 @Override()
168 public String getEqualityMatchingRuleOID()
169 {
170 return EQUALITY_RULE_OID;
171 }
172
173
174
175 /**
176 * {@inheritDoc}
177 */
178 @Override()
179 public String getOrderingMatchingRuleName()
180 {
181 return ORDERING_RULE_NAME;
182 }
183
184
185
186 /**
187 * {@inheritDoc}
188 */
189 @Override()
190 public String getOrderingMatchingRuleOID()
191 {
192 return ORDERING_RULE_OID;
193 }
194
195
196
197 /**
198 * {@inheritDoc}
199 */
200 @Override()
201 public String getSubstringMatchingRuleName()
202 {
203 return SUBSTRING_RULE_NAME;
204 }
205
206
207
208 /**
209 * {@inheritDoc}
210 */
211 @Override()
212 public String getSubstringMatchingRuleOID()
213 {
214 return SUBSTRING_RULE_OID;
215 }
216
217
218
219 /**
220 * {@inheritDoc}
221 */
222 @Override()
223 public ASN1OctetString normalize(final ASN1OctetString value)
224 throws LDAPException
225 {
226 // The value may already be normalized, so optimize behavior for that
227 // possibility.
228 int numSpaces = 0;
229 final byte[] valueBytes = value.getValue();
230 for (int i=0; i < valueBytes.length; i++)
231 {
232 if (valueBytes[i] == ' ')
233 {
234 numSpaces++;
235 }
236 else if ((valueBytes[i] < '0') || (valueBytes[i] > '9'))
237 {
238 throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
239 ERR_NUMERIC_STRING_INVALID_CHARACTER.get(i));
240 }
241 }
242
243 if (numSpaces == 0)
244 {
245 return value;
246 }
247
248 int pos = 0;
249 final byte[] returnBytes = new byte[valueBytes.length-numSpaces];
250 for (final byte b : valueBytes)
251 {
252 if (b != ' ')
253 {
254 returnBytes[pos++] = b;
255 }
256 }
257
258 return new ASN1OctetString(returnBytes);
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 }