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 legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2006-2009 Sun Microsystems, Inc. 025 * Portions Copyright 2012-2015 ForgeRock AS. 026 */ 027package org.opends.server.api; 028 029import org.forgerock.i18n.LocalizableMessage; 030 031import java.util.List; 032 033import org.opends.server.admin.std.server.AttributeSyntaxCfg; 034import org.opends.server.core.ServerContext; 035import org.forgerock.opendj.config.server.ConfigException; 036import org.opends.server.types.InitializationException; 037import org.opends.server.util.RemoveOnceSDKSchemaIsUsed; 038import org.forgerock.opendj.ldap.ByteSequence; 039import org.forgerock.opendj.ldap.schema.MatchingRule; 040import org.forgerock.opendj.ldap.schema.Schema; 041import org.forgerock.opendj.ldap.schema.Syntax; 042import org.forgerock.i18n.LocalizableMessageBuilder; 043 044/** 045 * This class defines the set of methods and structures that must be 046 * implemented by a Directory Server module that implements an 047 * attribute syntax. 048 * 049 * @param <T> The type of configuration handled by this attribute 050 * syntax. 051 */ 052@org.opends.server.types.PublicAPI( 053 stability=org.opends.server.types.StabilityLevel.VOLATILE, 054 mayInstantiate=false, 055 mayExtend=true, 056 mayInvoke=false) 057@RemoveOnceSDKSchemaIsUsed("All descendants classes can be removed as well") 058public abstract class AttributeSyntax<T extends AttributeSyntaxCfg> 059{ 060 /** 061 * Initializes this attribute syntax based on the information in the 062 * provided configuration entry. 063 * 064 * @param configuration The configuration to use to initialize 065 * this attribute syntax. 066 * @param serverContext 067 * The server context. 068 * 069 * @throws ConfigException If an unrecoverable problem arises in 070 * the process of performing the 071 * initialization. 072 * 073 * @throws InitializationException If a problem occurs during 074 * initialization that is not 075 * related to the server 076 * configuration. 077 */ 078 public void initializeSyntax(T configuration, ServerContext serverContext) 079 throws ConfigException, InitializationException 080 { 081 // not implemented 082 } 083 084 /** 085 * Returns the SDK Syntax equivalent to this syntax. 086 * <p> 087 * This method allow smooth migration to SDK syntax. It will disappear 088 * once the the migration to SDK schema is complete, together with 089 * this class and all its implementation. 090 * 091 * @param schema 092 * Schema to use to retrieve the syntax 093 * 094 * @return the equivalent SDK syntax. 095 */ 096 public abstract Syntax getSDKSyntax(Schema schema); 097 098 /** 099 * Indicates whether the provided configuration is acceptable for 100 * this attribute syntax. It should be possible to call this method 101 * on an uninitialized attribute syntax instance in order to 102 * determine whether the syntax would be able to use the provided 103 * configuration. 104 * <BR><BR> 105 * Note that implementations which use a subclass of the provided 106 * configuration class will likely need to cast the configuration 107 * to the appropriate subclass type. 108 * 109 * @param configuration The attribute syntax configuration 110 * for which to make the determination. 111 * @param unacceptableReasons A list that may be used to hold the 112 * reasons that the provided 113 * configuration is not acceptable. 114 * 115 * @return {@code true} if the provided configuration is acceptable 116 * for this attribute syntax, or {@code false} if not. 117 */ 118 public boolean isConfigurationAcceptable( 119 AttributeSyntaxCfg configuration, 120 List<LocalizableMessage> unacceptableReasons) 121 { 122 // This default implementation does not perform any special 123 // validation. It should be overridden by attribute syntax 124 // implementations that wish to perform more detailed validation. 125 return true; 126 } 127 128 129 130 /** 131 * Performs any finalization that may be necessary for this 132 * attribute syntax. By default, no finalization is performed. 133 */ 134 public void finalizeSyntax() 135 { 136 // No implementation required. 137 } 138 139 140 141 /** 142 * Retrieves the common name for this attribute syntax. 143 * 144 * @return The common name for this attribute syntax. 145 */ 146 public abstract String getName(); 147 148 149 150 /** 151 * Retrieves the OID for this attribute syntax. 152 * 153 * @return The OID for this attribute syntax. 154 */ 155 public abstract String getOID(); 156 157 158 159 /** 160 * Retrieves a description for this attribute syntax. 161 * 162 * @return A description for this attribute syntax. 163 */ 164 public abstract String getDescription(); 165 166 167 168 /** 169 * Retrieves the default equality matching rule that will be used 170 * for attributes with this syntax. 171 * 172 * @return The default equality matching rule that will be used for 173 * attributes with this syntax, or {@code null} if equality 174 * matches will not be allowed for this type by default. 175 */ 176 public MatchingRule getEqualityMatchingRule() 177 { 178 return null; 179 } 180 181 182 183 /** 184 * Retrieves the default ordering matching rule that will be used 185 * for attributes with this syntax. 186 * 187 * @return The default ordering matching rule that will be used for 188 * attributes with this syntax, or {@code null} if ordering 189 * matches will not be allowed for this type by default. 190 */ 191 public MatchingRule getOrderingMatchingRule() 192 { 193 return null; 194 } 195 196 197 /** 198 * Retrieves the default substring matching rule that will be used 199 * for attributes with this syntax. 200 * 201 * @return The default substring matching rule that will be used 202 * for attributes with this syntax, or {@code null} if 203 * substring matches will not be allowed for this type by 204 * default. 205 */ 206 public MatchingRule getSubstringMatchingRule() 207 { 208 return null; 209 } 210 211 212 /** 213 * Retrieves the default approximate matching rule that will be used 214 * for attributes with this syntax. 215 * 216 * @return The default approximate matching rule that will be used 217 * for attributes with this syntax, or {@code null} if 218 * approximate matches will not be allowed for this type by 219 * default. 220 */ 221 public MatchingRule getApproximateMatchingRule() 222 { 223 return null; 224 } 225 226 227 228 /** 229 * Indicates whether the provided value is acceptable for use in an 230 * attribute with this syntax. If it is not, then the reason may be 231 * appended to the provided buffer. 232 * 233 * @param value The value for which to make the 234 * determination. 235 * @param invalidReason The buffer to which the invalid reason 236 * should be appended. 237 * 238 * @return {@code true} if the provided value is acceptable for use 239 * with this syntax, or {@code false} if not. 240 */ 241 public boolean valueIsAcceptable(ByteSequence value, 242 LocalizableMessageBuilder invalidReason) 243 { 244 return true; 245 } 246 247 248 249 /** 250 * Indicates whether this attribute syntax requires BER encoding. 251 * 252 * @return {@code true} if this syntax required BER encoding. 253 */ 254 public boolean isBEREncodingRequired() 255 { 256 return true; 257 } 258 259 260 261 /** 262 * Indicates whether this attribute syntax is human readable. 263 * 264 * @return {@code true} if this syntax is human readable. 265 */ 266 public boolean isHumanReadable() 267 { 268 return true; 269 } 270 271 272 /** 273 * Retrieves the hash code for this attribute syntax. It will be 274 * calculated as the sum of the characters in the OID. 275 * 276 * @return The hash code for this attribute syntax. 277 */ 278 @Override 279 public final int hashCode() 280 { 281 int hashCode = 0; 282 283 String oidString = getOID(); 284 int oidLength = oidString.length(); 285 for (int i=0; i < oidLength; i++) 286 { 287 hashCode += oidString.charAt(i); 288 } 289 290 return hashCode; 291 } 292 293 294 295 /** 296 * Indicates whether the provided object is equal to this attribute 297 * syntax. The provided object will be considered equal to this 298 * attribute syntax only if it is an attribute syntax with the same 299 * OID. 300 * 301 * @param o The object for which to make the determination. 302 * 303 * @return {@code true} if the provided object is equal to this 304 * attribute syntax, or {@code false} if it is not. 305 */ 306 @Override 307 public final boolean equals(Object o) 308 { 309 if (this == o) 310 { 311 return true; 312 } 313 if (!(o instanceof AttributeSyntax)) 314 { 315 return false; 316 } 317 return getOID().equals(((AttributeSyntax<?>) o).getOID()); 318 } 319 320 321 322 /** 323 * Retrieves a string representation of this attribute syntax in the 324 * format defined in RFC 2252. 325 * 326 * @return A string representation of this attribute syntax in the 327 * format defined in RFC 2252. 328 */ 329 @Override 330 public String toString() 331 { 332 StringBuilder buffer = new StringBuilder(); 333 toString(buffer); 334 return buffer.toString(); 335 } 336 337 338 339 /** 340 * Appends a string representation of this attribute syntax in the 341 * format defined in RFC 2252 to the provided buffer. 342 * 343 * @param buffer The buffer to which the information should be 344 * appended. 345 */ 346 public final void toString(StringBuilder buffer) 347 { 348 buffer.append("( "); 349 buffer.append(getOID()); 350 351 String description = getDescription(); 352 if (description != null && description.length() != 0) 353 { 354 buffer.append(" DESC '").append(description).append("'"); 355 } 356 buffer.append(" )"); 357 } 358}