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.api;
028 import org.opends.messages.Message;
029
030
031
032 import java.util.List;
033
034 import org.opends.server.admin.std.server.MatchingRuleCfg;
035 import org.opends.server.config.ConfigException;
036 import org.opends.server.types.ByteString;
037 import org.opends.server.types.ConditionResult;
038 import org.opends.server.types.DirectoryException;
039 import org.opends.server.types.InitializationException;
040
041
042
043 /**
044 * This class defines the set of methods and structures that must be
045 * implemented by a Directory Server module that implements a matching
046 * rule.
047 *
048 * @param <T> The type of configuration handled by this matching
049 * rule.
050 */
051 @org.opends.server.types.PublicAPI(
052 stability=org.opends.server.types.StabilityLevel.VOLATILE,
053 mayInstantiate=false,
054 mayExtend=true,
055 mayInvoke=false)
056 public abstract class MatchingRule<T extends MatchingRuleCfg>
057 {
058 /**
059 * Initializes this matching rule based on the information in the
060 * provided configuration entry.
061 *
062 * @param configuration The configuration to use to intialize this
063 * matching rule.
064 *
065 * @throws ConfigException If an unrecoverable problem arises in
066 * the process of performing the
067 * initialization.
068 *
069 * @throws InitializationException If a problem that is not
070 * configuration-related occurs
071 * during initialization.
072 */
073 public abstract void initializeMatchingRule(T configuration)
074 throws ConfigException, InitializationException;
075
076
077
078 /**
079 * Indicates whether the provided configuration is acceptable for
080 * this matching rule. It should be possible to call this method on
081 * an uninitialized matching rule instance in order to determine
082 * whether the matching rule would be able to use the provided
083 * configuration.
084 * <BR><BR>
085 * Note that implementations which use a subclass of the provided
086 * configuration class will likely need to cast the configuration
087 * to the appropriate subclass type.
088 *
089 * @param configuration The matching rule configuration for
090 * which to make the determination.
091 * @param unacceptableReasons A list that may be used to hold the
092 * reasons that the provided
093 * configuration is not acceptable.
094 *
095 * @return {@code true} if the provided configuration is acceptable
096 * for this matching rule, or {@code false} if not.
097 */
098 public boolean isConfigurationAcceptable(
099 MatchingRuleCfg configuration,
100 List<Message> unacceptableReasons)
101 {
102 // This default implementation does not perform any special
103 // validation. It should be overridden by matching rule
104 // implementations that wish to perform more detailed validation.
105 return true;
106 }
107
108
109
110 /**
111 * Performs any finalization that may be needed whenever this
112 * matching rule is taken out of service.
113 */
114 public void finalizeMatchingRule()
115 {
116 // No implementation is required by default.
117 }
118
119
120
121 /**
122 * Retrieves the common name for this matching rule.
123 *
124 * @return The common name for this matching rule, or {@code null}
125 * if it does not have a name.
126 */
127 public abstract String getName();
128
129
130
131 /**
132 * Retrieves the OID for this matching rule.
133 *
134 * @return The OID for this matching rule.
135 */
136 public abstract String getOID();
137
138
139
140 /**
141 * Retrieves the name or OID for this matching rule. If it has a
142 * name, then it will be returned. Otherwise, the OID will be
143 * returned.
144 *
145 * @return The name or OID for this matching rule.
146 */
147 public final String getNameOrOID()
148 {
149 String name = getName();
150 if ((name == null) || (name.length() == 0))
151 {
152 return getOID();
153 }
154 else
155 {
156 return name;
157 }
158 }
159
160
161
162 /**
163 * Retrieves the description for this matching rule.
164 *
165 * @return The description for this matching rule, or {@code null}
166 * if there is none.
167 */
168 public abstract String getDescription();
169
170
171
172 /**
173 * Retrieves the OID of the syntax with which this matching rule is
174 * associated.
175 *
176 * @return The OID of the syntax with which this matching rule is
177 * associated.
178 */
179 public abstract String getSyntaxOID();
180
181
182
183 /**
184 * Indicates whether this matching rule is declared "OBSOLETE".
185 * The default implementation will always return {@code false}. If
186 * that is not acceptable for a particular matching rule
187 * implementation, then it should override this method and perform
188 * the appropriate processing to return the correct value.
189 *
190 * @return {@code true} if this matching rule is declared
191 * "OBSOLETE", or {@code false} if not.
192 */
193 public boolean isObsolete()
194 {
195 return false;
196 }
197
198
199
200 /**
201 * Retrieves the normalized form of the provided value, which is
202 * best suite for efficiently performing matching operations on that
203 * value.
204 *
205 * @param value The value to be normalized.
206 *
207 * @return The normalized version of the provided value.
208 *
209 * @throws DirectoryException If the provided value is invalid
210 * according to the associated
211 * attribute syntax.
212 */
213 public abstract ByteString normalizeValue(ByteString value)
214 throws DirectoryException;
215
216
217
218 /**
219 * Indicates whether the provided attribute value should be
220 * considered a match for the given assertion value. This will only
221 * be used for the purpose of extensible matching. Subclasses
222 * should define more specific methods that are appropriate to the
223 * matching rule type.
224 *
225 * @param attributeValue The attribute value in a form that has
226 * been normalized according to this
227 * matching rule.
228 * @param assertionValue The assertion value in a form that has
229 * been normalized according to this
230 * matching rule.
231 *
232 * @return {@code TRUE} if the attribute value should be considered
233 * a match for the provided assertion value, {@code FALSE}
234 * if it does not match, or {@code UNDEFINED} if the result
235 * is undefined.
236 */
237 public abstract ConditionResult
238 valuesMatch(ByteString attributeValue,
239 ByteString assertionValue);
240
241
242
243 /**
244 * Retrieves the hash code for this matching rule. It will be
245 * calculated as the sum of the characters in the OID.
246 *
247 * @return The hash code for this matching rule.
248 */
249 public final int hashCode()
250 {
251 int hashCode = 0;
252
253 String oidString = getOID();
254 int oidLength = oidString.length();
255 for (int i=0; i < oidLength; i++)
256 {
257 hashCode += oidString.charAt(i);
258 }
259
260 return hashCode;
261 }
262
263
264
265 /**
266 * Indicates whether the provided object is equal to this matching
267 * rule. The provided object will be considered equal to this
268 * matching rule only if it is a matching rule with the same OID.
269 *
270 * @param o The object for which to make the determination.
271 *
272 * @return {@code true} if the provided object is equal to this
273 * matching rule, or {@code false} if it is not.
274 */
275 public final boolean equals(Object o)
276 {
277 if (o == null)
278 {
279 return false;
280 }
281
282 if (this == o)
283 {
284 return true;
285 }
286
287 if (! (o instanceof MatchingRule))
288 {
289 return false;
290 }
291
292 return getOID().equals(((MatchingRule) o).getOID());
293 }
294
295
296
297 /**
298 * Retrieves a string representation of this matching rule in the
299 * format defined in RFC 2252.
300 *
301 * @return A string representation of this matching rule in the
302 * format defined in RFC 2252.
303 */
304 public final String toString()
305 {
306 StringBuilder buffer = new StringBuilder();
307 toString(buffer);
308 return buffer.toString();
309 }
310
311
312
313 /**
314 * Appends a string representation of this matching rule in the
315 * format defined in RFC 2252 to the provided buffer.
316 *
317 * @param buffer The buffer to which the information should be
318 * appended.
319 */
320 public final void toString(StringBuilder buffer)
321 {
322 buffer.append("( ");
323 buffer.append(getOID());
324 buffer.append(" NAME '");
325 buffer.append(getName());
326
327 String description = getDescription();
328 if ((description != null) && (description.length() > 0))
329 {
330 buffer.append("' DESC '");
331 buffer.append(description);
332 }
333
334 if (isObsolete())
335 {
336 buffer.append("' OBSOLETE SYNTAX ");
337 }
338 else
339 {
340 buffer.append("' SYNTAX ");
341 }
342
343 buffer.append(getSyntaxOID());
344 buffer.append(" )");
345 }
346 }
347