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