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