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 */ 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 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) 042public 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}