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-2010 Sun Microsystems, Inc.
015 * Portions Copyright 2011-2016 ForgeRock AS.
016 */
017package org.opends.server.schema;
018
019import static org.opends.server.schema.SchemaConstants.*;
020
021import org.forgerock.i18n.LocalizableMessageBuilder;
022import org.forgerock.i18n.slf4j.LocalizedLogger;
023import org.forgerock.opendj.config.server.ConfigException;
024import org.forgerock.opendj.ldap.ByteSequence;
025import org.forgerock.opendj.ldap.schema.Schema;
026import org.forgerock.opendj.ldap.schema.SchemaBuilder;
027import org.forgerock.opendj.ldap.schema.Syntax;
028import org.forgerock.opendj.server.config.server.AttributeSyntaxCfg;
029import org.opends.server.api.AttributeSyntax;
030import org.opends.server.core.ServerContext;
031import org.forgerock.opendj.ldap.DN;
032import org.opends.server.types.DirectoryException;
033import org.opends.server.types.Schema.SchemaUpdater;
034import org.opends.server.types.SubtreeSpecification;
035
036/**
037 * This class defines the subtree specification attribute syntax,
038 * which is used to specify the scope of sub-entries (RFC 3672).
039 */
040public final class SubtreeSpecificationSyntax
041       extends AttributeSyntax<AttributeSyntaxCfg>
042{
043
044  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
045
046  /**
047   * Creates a new instance of this syntax. Note that the only thing
048   * that should be done here is to invoke the default constructor for
049   * the superclass. All initialization should be performed in the
050   * <CODE>initializeSyntax</CODE> method.
051   */
052  public SubtreeSpecificationSyntax() {
053    // No implementation required.
054  }
055
056  @Override
057  public void initializeSyntax(AttributeSyntaxCfg configuration, ServerContext serverContext)
058      throws ConfigException, DirectoryException
059  {
060    // Add the subtree specification syntax to the "new" schema
061    serverContext.getSchema().updateSchema(new SchemaUpdater()
062    {
063      @Override
064      public Schema update(SchemaBuilder builder)
065      {
066        return addSubtreeSpecificationSyntax(builder).toSchema();
067      }
068    });
069  }
070
071  /**
072   * Adds the subtree specification syntax to the provided schema builder.
073   *
074   * @param builder
075   *          where to add the subtree specification syntax
076   * @return the provided builder
077   */
078  public static SchemaBuilder addSubtreeSpecificationSyntax(SchemaBuilder builder)
079  {
080    return builder
081        .buildSyntax(SYNTAX_SUBTREE_SPECIFICATION_OID)
082        .description(SYNTAX_SUBTREE_SPECIFICATION_DESCRIPTION)
083        .implementation(new SubtreeSpecificationSyntaxImpl())
084        .addToSchema();
085  }
086
087  @Override
088  public Syntax getSDKSyntax(Schema schema)
089  {
090    return schema.getSyntax(SchemaConstants.SYNTAX_SUBTREE_SPECIFICATION_OID);
091  }
092
093  @Override
094  public String getName() {
095    return SYNTAX_SUBTREE_SPECIFICATION_NAME;
096  }
097
098  @Override
099  public String getOID() {
100    return SYNTAX_SUBTREE_SPECIFICATION_OID;
101  }
102
103  @Override
104  public String getDescription() {
105    return SYNTAX_SUBTREE_SPECIFICATION_DESCRIPTION;
106  }
107
108  @Override
109  public boolean valueIsAcceptable(ByteSequence value,
110                                   LocalizableMessageBuilder invalidReason) {
111    // Use the subtree specification code to make this determination.
112    try {
113      SubtreeSpecification.valueOf(DN.rootDN(), value.toString());
114
115      return true;
116    } catch (DirectoryException e) {
117      logger.traceException(e);
118
119      invalidReason.append(e.getMessageObject());
120      return false;
121    }
122  }
123
124  @Override
125  public boolean isBEREncodingRequired()
126  {
127    return false;
128  }
129
130  @Override
131  public boolean isHumanReadable()
132  {
133    return true;
134  }
135}