/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 *
 */

/**
 * <pre>
 * <p>
 * Contains interfaces and classes used for bootstrap schema object loading and
 * configuration.
 * </p>
 * <p>
 * Briefly, before delving into the reasons behind our choices, we would like to
 * summarize what is here.  First off each schema entity of significance whether
 * defined by the protocol or not is introduced into the system using a bootstrap
 * configuration set class.  This is a class that implements a specific interface
 * for creating all the needed schema objects to establish a baseline within the
 * system.  All such schema objects generated will be owned by the directory
 * administrator.  Furthermore these objects are temporary and can be overridden
 * in the solid state using altered versions that are authoritative definitions
 * within the system backend.
 * </p>
 * <p>
 * Just what does all this mean?  Hard coded schema objects in Java classes
 * which implement a configuration set interface can be loaded into the system
 * and used while bootstrapping it.  If this is the first time bootstrapping,
 * meaning these objects are NOT found within the system backend, they will
 * be persisted into the system backend at the very end of the bootstrap stage so
 * they can be resolved in the solid state.  Changes to these objects via LDAP
 * within the system backend by the admin persist across bootstrap sessions.  They
 * persist because the bootstrap object is never stored in the system backend
 * if a record for that object already exists.
 * </p>
 * <p>
 * Why are we storing a configuration directly in Java code?  First off the
 * likelihood of altering schema object fields to bootstrap the system is highly
 * unlikely.  Secondly most of these objects are published static entities and
 * changing them would have serious repercussions.  Hence its highly unlikely
 * that these objects will change and there is no need to get complex to try
 * to have an external representation for these schema objects.  The
 * representation of these objects as entries and attributes within the directory
 * is enough of an external representation.  Schema manipulation tools already
 * exist for making changes so why have another additional
 * mechanism/representation as well.
 * </p>
 * <hr>
 * <h3>Notes:</h3>
 * <ul>
 * <li>
 * Baseline schema configuration sets are loaded first.
 * </li>
 * <li>
 * Within a logical schema (e.g. krb5-kdc) the ConfigurationSets of that
 * schema will be loaded in an order consistent with datatype dependencies.
 * For example a ConfigurationSet (CS) for SyntaxCheckers will be loaded
 * before the one for Syntaxes within the same schema.  This is because
 * Syntaxes depend upon SyntaxCheckers and the proper SyntaxChecker must be
 * resolvable via the SyntaxChecker registry.
 * </li>
 * <li>
 * A CS shall contain schema objects associated with a specific owner, and a
 * specific logical schema.  The set of CS schema objects may depend on
 * Schema objects within other logic schemas, hence other CS objects.  These
 * dependencies on other logical schemas are exposed by the CS interface.
 * </li>
 * <li>
 * Other user defined CS classes can be loaded by the system as well.  The
 * system can search on the classpath for classes implementing the CS
 * interface.  It would then need to analyze dependencies to determine which
 * schema object sets to process/load first.  This is the most rudimentary
 * of mechanisms for users to introduce new schema objects into the system.
 * The other means is during the solid state through LDAP itself.  Changes
 * can be made along with new schema object introductions via schemaSubentry
 * changes in the usual LDAP manager where schema objects are attributes in
 * a massive entry.  Another means is through the alteration of easier to
 * manage entries for schema objects through the system namespace.  Changes
 * to either schemaSubEntry attributes or system namespace schema entries both
 * mirror one another.  A change to one propagates to the other: the same
 * entity is being manipulated through two different views.  One is a heck of
 * a lot more manageable.
 * </li>
 * <li>
 * We can add a resolver interface so a resolver can be registered after
 * bootstrapping with a registry.  In the case of a registry miss we ask the
 * resolver for the object.  If it cannot find it then well we're out of luck.
 * Once the resolver is set for solid state operation, registry misses make
 * the resolver go to disk on the system backend for authoritative copies.
 * </li>
 * <li>
 * The resolver concept mentioned above can itself be another registry.  It's
 * just a secondary disk registry used when the first misses disk.  So hence
 * other registries should be able to be registerable with others to allow for
 * registry delegation like the way classloaders delegate.  This way there is
 * no need to replace bootstrap registries.  Once they have enough info to
 * enable disk access, they can tap secondary schema information on disk to
 * override the bootstrap objects first of all.  Secondly in the solid state
 * schema objects can be brought into memory from disk.
 * </li>
 * </ul>
 * </hr>
 * </pre>
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$, $Date$
 */

package org.apache.directory.server.schema.bootstrap;
