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