001/* 002 * Copyright 2008-2020 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2008-2020 Ping Identity Corporation 007 * 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020/* 021 * Copyright (C) 2008-2020 Ping Identity Corporation 022 * 023 * This program is free software; you can redistribute it and/or modify 024 * it under the terms of the GNU General Public License (GPLv2 only) 025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 026 * as published by the Free Software Foundation. 027 * 028 * This program is distributed in the hope that it will be useful, 029 * but WITHOUT ANY WARRANTY; without even the implied warranty of 030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 031 * GNU General Public License for more details. 032 * 033 * You should have received a copy of the GNU General Public License 034 * along with this program; if not, see <http://www.gnu.org/licenses>. 035 */ 036package com.unboundid.ldap.matchingrules; 037 038 039 040import com.unboundid.asn1.ASN1OctetString; 041import com.unboundid.ldap.sdk.LDAPException; 042import com.unboundid.ldap.sdk.ResultCode; 043import com.unboundid.util.StaticUtils; 044import com.unboundid.util.ThreadSafety; 045import com.unboundid.util.ThreadSafetyLevel; 046 047import static com.unboundid.ldap.matchingrules.MatchingRuleMessages.*; 048 049 050 051/** 052 * This class provides an implementation of a matching rule that allows strings 053 * consisting of numeric digits and spaces. Spaces will be considered 054 * insignificant for matching purposes. 055 */ 056@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 057public final class NumericStringMatchingRule 058 extends SimpleMatchingRule 059{ 060 /** 061 * The singleton instance that will be returned from the {@code getInstance} 062 * method. 063 */ 064 private static final NumericStringMatchingRule INSTANCE = 065 new NumericStringMatchingRule(); 066 067 068 069 /** 070 * The name for the numericStringMatch equality matching rule. 071 */ 072 public static final String EQUALITY_RULE_NAME = "numericStringMatch"; 073 074 075 076 /** 077 * The name for the numericStringMatch equality matching rule, formatted in 078 * all lowercase characters. 079 */ 080 static final String LOWER_EQUALITY_RULE_NAME = 081 StaticUtils.toLowerCase(EQUALITY_RULE_NAME); 082 083 084 085 /** 086 * The OID for the numericStringMatch equality matching rule. 087 */ 088 public static final String EQUALITY_RULE_OID = "2.5.13.8"; 089 090 091 092 /** 093 * The name for the numericStringOrderingMatch ordering matching rule. 094 */ 095 public static final String ORDERING_RULE_NAME = "numericStringOrderingMatch"; 096 097 098 099 /** 100 * The name for the numericStringOrderingMatch ordering matching rule, 101 * formatted in all lowercase characters. 102 */ 103 static final String LOWER_ORDERING_RULE_NAME = 104 StaticUtils.toLowerCase(ORDERING_RULE_NAME); 105 106 107 108 /** 109 * The OID for the numericStringOrderingMatch ordering matching rule. 110 */ 111 public static final String ORDERING_RULE_OID = "2.5.13.9"; 112 113 114 115 /** 116 * The name for the numericStringSubstringsMatch substring matching rule. 117 */ 118 public static final String SUBSTRING_RULE_NAME = 119 "numericStringSubstringsMatch"; 120 121 122 123 /** 124 * The name for the numericStringSubstringsMatch substring matching rule, 125 * formatted in all lowercase characters. 126 */ 127 static final String LOWER_SUBSTRING_RULE_NAME = 128 StaticUtils.toLowerCase(SUBSTRING_RULE_NAME); 129 130 131 132 /** 133 * The OID for the numericStringSubstringsMatch substring matching rule. 134 */ 135 public static final String SUBSTRING_RULE_OID = "2.5.13.10"; 136 137 138 139 /** 140 * The serial version UID for this serializable class. 141 */ 142 private static final long serialVersionUID = -898484312052746321L; 143 144 145 146 /** 147 * Creates a new instance of this numeric string matching rule. 148 */ 149 public NumericStringMatchingRule() 150 { 151 // No implementation is required. 152 } 153 154 155 156 /** 157 * Retrieves a singleton instance of this matching rule. 158 * 159 * @return A singleton instance of this matching rule. 160 */ 161 public static NumericStringMatchingRule getInstance() 162 { 163 return INSTANCE; 164 } 165 166 167 168 /** 169 * {@inheritDoc} 170 */ 171 @Override() 172 public String getEqualityMatchingRuleName() 173 { 174 return EQUALITY_RULE_NAME; 175 } 176 177 178 179 /** 180 * {@inheritDoc} 181 */ 182 @Override() 183 public String getEqualityMatchingRuleOID() 184 { 185 return EQUALITY_RULE_OID; 186 } 187 188 189 190 /** 191 * {@inheritDoc} 192 */ 193 @Override() 194 public String getOrderingMatchingRuleName() 195 { 196 return ORDERING_RULE_NAME; 197 } 198 199 200 201 /** 202 * {@inheritDoc} 203 */ 204 @Override() 205 public String getOrderingMatchingRuleOID() 206 { 207 return ORDERING_RULE_OID; 208 } 209 210 211 212 /** 213 * {@inheritDoc} 214 */ 215 @Override() 216 public String getSubstringMatchingRuleName() 217 { 218 return SUBSTRING_RULE_NAME; 219 } 220 221 222 223 /** 224 * {@inheritDoc} 225 */ 226 @Override() 227 public String getSubstringMatchingRuleOID() 228 { 229 return SUBSTRING_RULE_OID; 230 } 231 232 233 234 /** 235 * {@inheritDoc} 236 */ 237 @Override() 238 public ASN1OctetString normalize(final ASN1OctetString value) 239 throws LDAPException 240 { 241 // The value may already be normalized, so optimize behavior for that 242 // possibility. 243 int numSpaces = 0; 244 final byte[] valueBytes = value.getValue(); 245 for (int i=0; i < valueBytes.length; i++) 246 { 247 if (valueBytes[i] == ' ') 248 { 249 numSpaces++; 250 } 251 else if ((valueBytes[i] < '0') || (valueBytes[i] > '9')) 252 { 253 throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX, 254 ERR_NUMERIC_STRING_INVALID_CHARACTER.get(i)); 255 } 256 } 257 258 if (numSpaces == 0) 259 { 260 return value; 261 } 262 263 int pos = 0; 264 final byte[] returnBytes = new byte[valueBytes.length-numSpaces]; 265 for (final byte b : valueBytes) 266 { 267 if (b != ' ') 268 { 269 returnBytes[pos++] = b; 270 } 271 } 272 273 return new ASN1OctetString(returnBytes); 274 } 275 276 277 278 /** 279 * {@inheritDoc} 280 */ 281 @Override() 282 public ASN1OctetString normalizeSubstring(final ASN1OctetString value, 283 final byte substringType) 284 throws LDAPException 285 { 286 return normalize(value); 287 } 288}