001 /* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.schema; 028 import org.opends.messages.Message; 029 030 031 032 import java.util.Arrays; 033 034 import org.opends.server.admin.std.server.EqualityMatchingRuleCfg; 035 import org.opends.server.api.EqualityMatchingRule; 036 import org.opends.server.config.ConfigException; 037 import org.opends.server.core.DirectoryServer; 038 import org.opends.server.protocols.asn1.ASN1OctetString; 039 import org.opends.server.types.ByteString; 040 import org.opends.server.types.DirectoryException; 041 import org.opends.server.types.InitializationException; 042 import org.opends.server.types.ResultCode; 043 044 import static org.opends.messages.SchemaMessages.*; 045 import static org.opends.server.schema.SchemaConstants.*; 046 import static org.opends.server.util.StaticUtils.*; 047 import org.opends.server.loggers.ErrorLogger; 048 049 050 /** 051 * This class implements the numericStringMatch matching rule defined in X.520 052 * and referenced in RFC 2252. It allows for values with numeric digits and 053 * spaces, but ignores spaces when performing matching. 054 */ 055 public class NumericStringEqualityMatchingRule 056 extends EqualityMatchingRule 057 { 058 /** 059 * Creates a new instance of this caseExactMatch matching rule. 060 */ 061 public NumericStringEqualityMatchingRule() 062 { 063 super(); 064 } 065 066 067 068 /** 069 * {@inheritDoc} 070 */ 071 public void initializeMatchingRule(EqualityMatchingRuleCfg configuration) 072 throws ConfigException, InitializationException 073 { 074 // No initialization is required. 075 } 076 077 078 079 /** 080 * Retrieves the common name for this matching rule. 081 * 082 * @return The common name for this matching rule, or <CODE>null</CODE> if 083 * it does not have a name. 084 */ 085 public String getName() 086 { 087 return EMR_NUMERIC_STRING_NAME; 088 } 089 090 091 092 /** 093 * Retrieves the OID for this matching rule. 094 * 095 * @return The OID for this matching rule. 096 */ 097 public String getOID() 098 { 099 return EMR_NUMERIC_STRING_OID; 100 } 101 102 103 104 /** 105 * Retrieves the description for this matching rule. 106 * 107 * @return The description for this matching rule, or <CODE>null</CODE> if 108 * there is none. 109 */ 110 public String getDescription() 111 { 112 // There is no standard description for this matching rule. 113 return null; 114 } 115 116 117 118 /** 119 * Retrieves the OID of the syntax with which this matching rule is 120 * associated. 121 * 122 * @return The OID of the syntax with which this matching rule is associated. 123 */ 124 public String getSyntaxOID() 125 { 126 return SYNTAX_NUMERIC_STRING_OID; 127 } 128 129 130 131 /** 132 * Retrieves the normalized form of the provided value, which is best suited 133 * for efficiently performing matching operations on that value. 134 * 135 * @param value The value to be normalized. 136 * 137 * @return The normalized version of the provided value. 138 * 139 * @throws DirectoryException If the provided value is invalid according to 140 * the associated attribute syntax. 141 */ 142 public ByteString normalizeValue(ByteString value) 143 throws DirectoryException 144 { 145 String valueString = value.stringValue(); 146 int valueLength = valueString.length(); 147 StringBuilder valueBuffer = new StringBuilder(valueLength); 148 149 boolean logged = false; 150 for (int i=0; i < valueLength; i++) 151 { 152 char c = valueString.charAt(i); 153 if (isDigit(c)) 154 { 155 valueBuffer.append(c); 156 } 157 else if (c != ' ') 158 { 159 // This is an illegal character. Either log it or reject it. 160 161 Message message = WARN_ATTR_SYNTAX_NUMERIC_STRING_ILLEGAL_CHAR.get( 162 valueString, String.valueOf(c), i); 163 164 switch (DirectoryServer.getSyntaxEnforcementPolicy()) 165 { 166 case REJECT: 167 throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX, 168 message); 169 case WARN: 170 if (! logged) 171 { 172 ErrorLogger.logError(message); 173 logged = true; 174 } 175 } 176 } 177 } 178 179 return new ASN1OctetString(getBytes(valueBuffer.toString())); 180 } 181 182 183 184 /** 185 * Indicates whether the two provided normalized values are equal to each 186 * other. 187 * 188 * @param value1 The normalized form of the first value to compare. 189 * @param value2 The normalized form of the second value to compare. 190 * 191 * @return <CODE>true</CODE> if the provided values are equal, or 192 * <CODE>false</CODE> if not. 193 */ 194 public boolean areEqual(ByteString value1, ByteString value2) 195 { 196 // Since the values are already normalized, we just need to compare the 197 // associated byte arrays. 198 return Arrays.equals(value1.value(), value2.value()); 199 } 200 } 201