/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at legal-notices/CDDLv1_0.txt.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2006-2010 Sun Microsystems, Inc.
* Portions Copyright 2011-2015 ForgeRock AS
*/
/**
* This class defines a utility that will be used to manage the interaction with
* the Directory Server schema. It will be used to initially load all of the
* matching rules and attribute syntaxes that have been defined in the
* configuration, and will then read the actual schema definitions. At present,
* only attribute types and objectclasses are supported in the schema config
* files. Other components like DIT content rules, DIT structure rules, name
* forms, and matching rule use definitions will be ignored.
*/
public class SchemaConfigManager
{
/** The schema that has been parsed from the server configuration. */
/**
* Creates a new instance of this schema config manager.
*
* @param serverContext
* The server context.
*/
{
this.serverContext = serverContext;
}
/**
* Retrieves the path to the directory containing the server schema files.
*
* @return The path to the directory containing the server schema files.
*/
{
return schemaDir.getAbsolutePath();
}
return null;
}
/**
* Retrieves a reference to the schema information that has been read from the
* server configuration. Note that this information will not be complete
* until the <CODE>initializeMatchingRules</CODE>,
* <CODE>initializeAttributeSyntaxes</CODE>, and
* <CODE>initializeAttributeTypesAndObjectClasses</CODE> methods have been
* called.
*
* @return A reference to the schema information that has been read from the
* server configuration.
*/
{
return schema;
}
/**
* Initializes all the matching rules defined in the Directory Server
* configuration. This should only be called at Directory Server startup.
*
* @throws ConfigException If a configuration problem causes the matching
* rule initialization process to fail.
*
* @throws InitializationException If a problem occurs while initializing
* the matching rules that is not related to
* the server configuration.
*/
public void initializeMatchingRules()
{
new MatchingRuleConfigManager();
}
/**
* Initializes all the attribute syntaxes defined in the Directory Server
* configuration. This should only be called at Directory Server startup.
*
* @throws ConfigException If a configuration problem causes the syntax
* initialization process to fail.
*
* @throws InitializationException If a problem occurs while initializing
* the syntaxes that is not related to the
* server configuration.
*/
public void initializeAttributeSyntaxes()
{
}
/**
* Filter implementation that accepts only ldif files.
*/
{
/** {@inheritDoc} */
{
}
}
/**
* Initializes all the attribute type, object class, name form, DIT content
* rule, DIT structure rule, and matching rule use definitions by reading the
* server schema files. These files will be located in a single directory and
* will be processed in lexicographic order. However, to make the order
* easier to understand, they may be prefixed with a two digit number (with a
* leading zero if necessary) so that they will be read in numeric order.
* This should only be called at Directory Server startup.
*
* @throws ConfigException If a configuration problem causes the schema
* element initialization to fail.
*
* @throws InitializationException If a problem occurs while initializing
* the schema elements that is not related
* to the server configuration.
*/
public void initializeSchemaFromFiles()
{
// Construct the path to the directory that should contain the schema files
// and make sure that it exists and is a directory. Get a list of the files
// in that directory sorted in alphabetic order.
try
{
if (schemaInstanceDirPath != null)
{
}
} catch (Exception e)
{
}
long oldestModificationTime = -1L;
long youngestModificationTime = -1L;
try
{
{
throw new InitializationException(message);
}
if (! schemaInstanceDir.isDirectory())
{
throw new InitializationException(message);
}
for (File f : schemaInstanceDirFiles)
{
if (f.isFile())
{
}
long modificationTime = f.lastModified();
if (oldestModificationTime <= 0L ||
{
}
if (youngestModificationTime <= 0 ||
{
}
}
}
catch (InitializationException ie)
{
throw ie;
}
catch (Exception e)
{
logger.traceException(e);
throw new InitializationException(message, e);
}
// If the oldest and youngest modification timestamps didn't get set for
// some reason, then set them to the current time.
if (oldestModificationTime <= 0)
{
}
if (youngestModificationTime <= 0)
{
}
// Iterate through the schema files and read them as an LDIF file containing
// a single entry. Then get the attributeTypes and objectClasses attributes
// from that entry and parse them to initialize the server schema.
{
}
}
/**
* Loads the contents of the specified schema file into the provided schema.
*
* @param serverContext
* The server context.
*
* @param schema The schema in which the contents of the schema file are
* to be loaded.
* @param schemaFile The name of the schema file to be loaded into the
* provided schema.
*
* @return A list of the modifications that could be performed in order to
* obtain the contents of the file.
*
* @throws ConfigException If a configuration problem causes the schema
* element initialization to fail.
*
* @throws InitializationException If a problem occurs while initializing
* the schema elements that is not related
* to the server configuration.
*/
public static List<Modification> loadSchemaFile(ServerContext serverContext, Schema schema, String schemaFile)
{
}
/**
* Loads the contents of the specified schema file into the provided schema.
*
* @param schema The schema in which the contents of the schema file
* are to be loaded.
* @param schemaFile The name of the schema file to be loaded into the
* provided schema.
* @param failOnError If {@code true}, indicates that this method should
* throw an exception if certain kinds of errors occur.
* If {@code false}, indicates that this method should
* log an error message and return without an exception.
* This should only be {@code false} when called from
* {@code initializeSchemaFromFiles}.
*
* @return A list of the modifications that could be performed in order to
* obtain the contents of the file, or {@code null} if a problem
* occurred and {@code failOnError} is {@code false}.
*
* @throws ConfigException If a configuration problem causes the schema
* element initialization to fail.
*
* @throws InitializationException If a problem occurs while initializing
* the schema elements that is not related
* to the server configuration.
*/
private static List<Modification> loadSchemaFile(ServerContext serverContext, Schema schema, String schemaFile,
{
// Create an LDIF reader to use when reading the files.
try
{
}
catch (Exception e)
{
logger.traceException(e);
if (failOnError)
{
throw new ConfigException(message);
}
else
{
return null;
}
}
// Read the LDIF entry from the file and close the file.
try
{
{
// The file was empty -- skip it.
return new LinkedList<>();
}
}
catch (Exception e)
{
logger.traceException(e);
if (failOnError)
{
throw new InitializationException(message, e);
}
else
{
return null;
}
}
// If there are any more entries in the file, then print a warning message.
try
{
if (e != null)
{
}
}
catch (Exception e)
{
logger.traceException(e);
logger.warn(WARN_CONFIG_SCHEMA_UNPARSEABLE_EXTRA_DATA_IN_FILE, schemaFile, schemaDirPath, getExceptionMessage(e));
}
finally
{
}
// Get the attributeTypes attribute from the entry.
//parse the syntaxes first because attributes rely on these.
// Loop on all the attribute of the schema entry to
// find the extra attribute that should be loaded in the Schema.
{
if (!isSchemaAttribute(attribute))
{
}
}
return mods;
}
{
{
}
AttributeType ldapSyntaxAttrType = getAttributeType(schema, ATTR_LDAP_SYNTAXES, ATTR_LDAP_SYNTAXES_LC, syntax);
}
{
{
}
}
/** Get the objectClasses attribute from the entry. */
{
{
}
AttributeType objectclassAttrType = getAttributeType(schema, ATTR_OBJECTCLASSES, ATTR_OBJECTCLASSES_LC, syntax);
}
/** Get the name forms attribute from the entry. */
{
{
}
}
/** Get the DIT content rules attribute from the entry. */
{
{
}
}
/** Get the DIT structure rules attribute from the entry. */
{
{
}
AttributeType dsrAttrType = getAttributeType(schema, ATTR_DIT_STRUCTURE_RULES, ATTR_DIT_STRUCTURE_RULES_LC, syntax);
}
/** Get the matching rule uses attribute from the entry. */
{
{
}
AttributeType mruAttrType = getAttributeType(schema, ATTR_MATCHING_RULE_USE, ATTR_MATCHING_RULE_USE_LC, syntax);
}
{
{
return attrType;
}
}
{
{
for (Attribute a : attributes)
{
}
}
return attributes;
}
/** Parse the ldapsyntaxes definitions if there are any. */
throws ConfigException
{
if (ldapSyntaxList != null)
{
for (Attribute a : ldapSyntaxList)
{
for (ByteString v : a)
{
try
{
syntaxDescription = LDAPSyntaxDescriptionSyntax.decodeLDAPSyntax(v, serverContext, schema, false, false);
}
catch (DirectoryException de)
{
de.getMessageObject());
continue;
}
catch (Exception e)
{
logger.traceException(e);
continue;
}
// Register it with the schema. We will allow duplicates, with the
// later definition overriding any earlier definition, but we want
// to trap them and log a warning.
try
{
}
catch (DirectoryException de)
{
try
{
}
catch (Exception e)
{
// This should never happen.
logger.traceException(e);
}
}
}
}
}
}
private static void registerLdapSyntaxInSchemaNG(ServerContext serverContext, LDAPSyntaxDescription syntaxDescription,
boolean overwrite)
{
// The server context may be null when this code is reached through non-server code (e.g. gui tools)
if (serverContext != null)
{
Syntax.Builder builder = schemaUpdater.getSchemaBuilder().buildSyntax(syntaxDescription.getSyntax());
}
}
/** Parse the attribute type definitions if there are any. */
throws ConfigException
{
{
{
for (ByteString v : a)
{
// Parse the attribute type.
try
{
}
catch (DirectoryException de)
{
continue;
}
catch (Exception e)
{
logger.traceException(e);
continue;
}
// Register it with the schema. We will allow duplicates, with the
// later definition overriding any earlier definition, but we want
// to trap them and log a warning.
try
{
}
catch (DirectoryException de)
{
try
{
}
catch (Exception e)
{
// This should never happen.
logger.traceException(e);
}
}
}
}
}
}
/** Parse the objectclass definitions if there are any. */
throws ConfigException
{
{
{
for (ByteString v : a)
{
// Parse the objectclass.
try
{
}
catch (DirectoryException de)
{
de.getMessageObject());
continue;
}
catch (Exception e)
{
logger.traceException(e);
continue;
}
// Register it with the schema. We will allow duplicates, with the
// later definition overriding any earlier definition, but we want
// to trap them and log a warning.
try
{
}
catch (DirectoryException de)
{
try
{
}
catch (Exception e)
{
// This should never happen.
logger.traceException(e);
}
}
}
}
}
}
/** Parse the name form definitions if there are any. */
throws ConfigException
{
{
{
for (ByteString v : a)
{
// Parse the name form.
try
{
}
catch (DirectoryException de)
{
continue;
}
catch (Exception e)
{
logger.traceException(e);
continue;
}
// Register it with the schema. We will allow duplicates, with the
// later definition overriding any earlier definition, but we want
// to trap them and log a warning.
try
{
}
catch (DirectoryException de)
{
try
{
}
catch (Exception e)
{
// This should never happen.
logger.traceException(e);
}
}
}
}
}
}
/** Parse the DIT content rule definitions if there are any. */
throws ConfigException
{
{
{
for (ByteString v : a)
{
// Parse the DIT content rule.
try
{
}
catch (DirectoryException de)
{
continue;
}
catch (Exception e)
{
logger.traceException(e);
continue;
}
// Register it with the schema. We will allow duplicates, with the
// later definition overriding any earlier definition, but we want
// to trap them and log a warning.
try
{
}
catch (DirectoryException de)
{
try
{
}
catch (Exception e)
{
// This should never happen.
logger.traceException(e);
}
}
}
}
}
}
{
if (failOnError)
{
throw new ConfigException(message, e);
}
}
/** Parse the DIT structure rule definitions if there are any. */
throws ConfigException
{
{
{
for (ByteString v : a)
{
// Parse the DIT content rule.
try
{
}
catch (DirectoryException de)
{
continue;
}
catch (Exception e)
{
logger.traceException(e);
continue;
}
// Register it with the schema. We will allow duplicates, with the
// later definition overriding any earlier definition, but we want
// to trap them and log a warning.
try
{
}
catch (DirectoryException de)
{
try
{
}
catch (Exception e)
{
// This should never happen.
logger.traceException(e);
}
}
}
}
}
}
/** Parse the matching rule use definitions if there are any. */
throws ConfigException
{
{
{
for (ByteString v : a)
{
// Parse the matching rule use definition.
try
{
}
catch (DirectoryException de)
{
continue;
}
catch (Exception e)
{
logger.traceException(e);
continue;
}
// Register it with the schema. We will allow duplicates, with the
// later definition overriding any earlier definition, but we want
// to trap them and log a warning.
try
{
}
catch (DirectoryException de)
{
try
{
}
catch (Exception e)
{
// This should never happen.
logger.traceException(e);
}
}
}
}
}
}
/**
* This method checks if a given attribute is an attribute that
* is used by the definition of the schema.
*
* @param attribute The attribute to be checked.
* @return true if the attribute is part of the schema definition,
* false if the attribute is not part of the schema
* definition.
*/
{
}
}