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}