SchemaBackend.java revision af53bf9d654793177a14fb00231c6da12707e407
/*
* 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
* 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
* trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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
*
*
* Portions Copyright 2006-2007 Sun Microsystems, Inc.
*/
/**
* This class defines a backend to hold the Directory Server schema information.
* It is a kind of meta-backend in that it doesn't actually hold any data but
* rather dynamically generates the schema entry whenever it is requested.
*/
public class SchemaBackend
extends Backend
{
/**
* The tracer object for the debug logger.
*/
/**
* The fully-qualified name of this class.
*/
private static final String CLASS_NAME =
"org.opends.server.backends.SchemaBackend";
// The set of user-defined attributes that will be included in the schema
// entry.
// The attribute type that will be used to include the defined attribute
// types.
private AttributeType attributeTypesType;
// The attribute type that will be used to hold the schema creation timestamp.
private AttributeType createTimestampType;
// The attribute type that will be used to hold the schema creator's name.
private AttributeType creatorsNameType;
// The attribute type that will be used to include the defined DIT content
// rules.
private AttributeType ditContentRulesType;
// The attribute type that will be used to include the defined DIT structure
// rules.
private AttributeType ditStructureRulesType;
// The attribute type that will be used to include the defined attribute
// syntaxes.
private AttributeType ldapSyntaxesType;
// The attribute type that will be used to include the defined matching rules.
private AttributeType matchingRulesType;
// The attribute type that will be used to include the defined matching rule
// uses.
private AttributeType matchingRuleUsesType;
// The attribute that will be used to hold the schema modifier's name.
private AttributeType modifiersNameType;
// The attribute type that will be used to hold the schema modification
// timestamp.
private AttributeType modifyTimestampType;
// The attribute type that will be used to include the defined object classes.
private AttributeType objectClassesType;
// The attribute type that will be used to include the defined name forms.
private AttributeType nameFormsType;
// The attribute type that will be used to save the synchronization state.
private AttributeType synchronizationStateType;
// The attribute type that will be used to save the synchronization
// generationId.
// The value containing DN of the user we'll say created the configuration.
private AttributeValue creatorsName;
// The value containing the DN of the last user to modify the configuration.
private AttributeValue modifiersName;
// The timestamp that will be used for the schema creation time.
private AttributeValue createTimestamp;
// The timestamp that will be used for the latest schema modification time.
private AttributeValue modifyTimestamp;
// Indicates whether the attributes of the schema entry should always be
// treated as user attributes even if they are defined as operational.
private boolean showAllAttributes;
// The DN of the configuration entry for this backend.
private DN configEntryDN;
// The current configuration state.
private SchemaBackendCfg currentConfig;
// The set of base DNs for this backend.
// The set of objectclasses that will be used in the schema entry.
// The set of supported controls for this backend.
// The set of supported features for this backend.
// The time that the schema was last modified.
private long modifyTime;
//Regular expression used to strip minimum upper bound value from
//syntax Attribute Type Description. The value looks like: {count}.
/**
* Creates a new backend with the provided information. All backend
* implementations must implement a default constructor that use
* <CODE>super()</CODE> to invoke this constructor.
*/
public SchemaBackend()
{
super();
// Perform all initialization in initializeBackend.
}
/**
* {@inheritDoc}
*/
@Override()
throws ConfigException
{
// Make sure that a configuration entry was provided. If not, then we will
// not be able to complete initialization.
{
throw new ConfigException(message);
}
// Get all of the attribute types that we will use for schema elements.
true);
// Initialize the lastmod attributes.
// Construct the set of objectclasses to include in the schema entry.
true);
true);
// Define empty sets for the supported controls and features.
// Get the set of user-defined attributes for the configuration entry. Any
// attributes that we don't recognize will be included directly in the
// schema entry.
{
{
if (! isSchemaConfigAttribute(a))
{
}
}
}
{
{
if (! isSchemaConfigAttribute(a))
{
}
}
}
// Determine whether to show all attributes.
currentConfig = cfg;
}
/**
* {@inheritDoc}
*/
@Override()
public void initializeBackend()
{
// Register each of the suffixes with the Directory Server. Also, register
// the first one as the schema base.
{
try
{
}
catch (Exception e)
{
if (debugEnabled())
{
}
throw new InitializationException(message, e);
}
}
// Identify any differences that may exist between the concatenated schema
// file from the last online modification and the current schema files. If
// there are any differences, then they should be from making changes to the
// schema files with the server offline.
try
{
// First, generate lists of elements from the current schema.
newMRUs);
// Next, generate lists of elements from the previous concatenated schema.
// If there isn't a previous concatenated schema, then use the base
// schema for the current revision.
if (concatFile.exists())
{
}
else
{
if (concatFile.exists())
{
}
else
{
if ((runningUnitTestsStr != null) &&
{
}
else
{
concatFile.getName());
throw new InitializationException(message);
}
}
}
// Create a list of modifications and add any differences between the old
// and new schema into them.
mods);
mods);
mods);
mods);
{
// Write a new concatenated schema file with the most recent information
// so we don't re-find these same changes on the next startup.
}
}
catch (InitializationException ie)
{
throw ie;
}
catch (Exception e)
{
if (debugEnabled())
{
}
getExceptionMessage(e));
}
// Register with the Directory Server as a configurable component.
}
/**
* {@inheritDoc}
*/
@Override()
public void finalizeBackend()
{
{
try
{
}
catch (Exception e)
{
if (debugEnabled())
{
}
}
}
}
/**
* Indicates whether the provided attribute is one that is used in the
* configuration of this backend.
*
* @param attribute The attribute for which to make the determination.
*
* @return <CODE>true</CODE> if the provided attribute is one that is used in
* the configuration of this backend, <CODE>false</CODE> if not.
*/
{
{
return true;
}
return false;
}
/**
* {@inheritDoc}
*/
@Override()
public DN[] getBaseDNs()
{
return baseDNs;
}
/**
* {@inheritDoc}
*/
@Override()
public long getEntryCount()
{
// There is always only a single entry in this backend.
return 1;
}
/**
* {@inheritDoc}
*/
@Override()
public boolean isLocal()
{
// For the purposes of this method, this is a local backend.
return true;
}
/**
* {@inheritDoc}
*/
@Override()
{
// All searches in this backend will always be considered indexed.
return true;
}
/**
* {@inheritDoc}
*/
@Override()
throws DirectoryException
{
return ConditionResult.FALSE;
}
/**
* {@inheritDoc}
*/
@Override()
throws DirectoryException
{
return 0L;
}
/**
* {@inheritDoc}
*/
@Override()
throws DirectoryException
{
// If the requested entry was one of the schema entries, then create and
// return it.
{
{
return getSchemaEntry(entryDN);
}
}
// There is never anything below the schema entries, so we will return null.
return null;
}
/**
* Generates and returns a schema entry for the Directory Server.
*
* @param entryDN The DN to use for the generated entry.
*
* @return The schema entry that was generated.
*/
{
// Add the RDN attribute(s) for the provided entry.
{
for (int i=0; i < numAVAs; i++)
{
if (attrType.isOperational())
{
}
else
{
}
}
}
// Add the "attributeTypes" attribute.
else
valueSet);
{
}
else
{
}
// Add the "objectClasses" attribute.
{
}
else
{
}
// Add the "matchingRules" attribute.
{
}
else
{
}
// Add the "ldapSyntaxes" attribute.
// Note that we intentionally ignore showAllAttributes for attribute
// syntaxes, name forms, matching rule uses, DIT content rules, and DIT
// structure rules because those attributes aren't allowed in the subschema
// objectclass, and treating them as user attributes would cause schema
// updates to fail. This means that you'll always have to explicitly
// request these attributes in order to be able to see them.
if (ldapSyntaxesType.isOperational())
{
}
else
{
}
// If there are any name forms defined, then add them.
{
if (nameFormsType.isOperational())
{
}
else
{
}
}
// If there are any DIT content rules defined, then add them.
{
valueSet);
if (ditContentRulesType.isOperational())
{
}
else
{
}
}
// If there are any DIT structure rules defined, then add them.
{
valueSet);
{
}
else
{
}
}
// If there are any matching rule uses defined, then add them.
{
valueSet);
{
}
else
{
}
}
// Add the lastmod attributes.
valueSet));
valueSet));
{
synchronized (this)
{
}
}
valueSet));
valueSet));
// Add the synchronization State attribute.
// Add the synchronization GenerationId attribute.
// Add all the user-defined attributes.
for (Attribute a : userDefinedAttributes)
{
if (type.isOperational())
{
{
}
else
{
}
}
else
{
{
}
else
{
}
}
}
// Construct and return the entry.
return e;
}
/**
* {@inheritDoc}
*/
@Override()
throws DirectoryException
{
// The specified DN must be one of the specified schema DNs.
{
{
return true;
}
}
return false;
}
/**
* {@inheritDoc}
*/
@Override()
throws DirectoryException
{
}
/**
* {@inheritDoc}
*/
@Override()
throws DirectoryException
{
}
/**
* {@inheritDoc}
*/
@Override()
throws DirectoryException
{
// Make sure that the authenticated user has the necessary UPDATE_SCHEMA
// privilege.
{
message);
}
{
// There aren't any modifications, so we don't need to do anything.
return;
}
int pos = -1;
{
pos++;
if (m.isInternal())
{
// We don't need to do anything for internal modifications (e.g., like
// those that set modifiersName and modifyTimestamp).
continue;
}
// Determine the type of modification to perform. We will support add and
// delete operations in the schema, and we will also support the ability
// to add a schema element that already exists and treat it as a
// replacement of that existing element.
Attribute a = m.getAttribute();
switch (m.getModificationType())
{
case ADD:
{
continue;
}
{
for (AttributeValue v : values)
{
try
{
newSchema, false);
}
catch (DirectoryException de)
{
if (debugEnabled())
{
}
throw new DirectoryException(
de);
}
}
}
{
for (AttributeValue v : values)
{
try
{
newSchema, false);
}
catch (DirectoryException de)
{
if (debugEnabled())
{
}
throw new DirectoryException(
de);
}
}
}
{
for (AttributeValue v : values)
{
try
{
false);
}
catch (DirectoryException de)
{
if (debugEnabled())
{
}
throw new DirectoryException(
de);
}
}
}
{
for (AttributeValue v : values)
{
try
{
newSchema, false);
}
catch (DirectoryException de)
{
if (debugEnabled())
{
}
throw new DirectoryException(
de);
}
}
}
{
for (AttributeValue v : values)
{
try
{
}
catch (DirectoryException de)
{
if (debugEnabled())
{
}
throw new DirectoryException(
de);
}
}
}
{
for (AttributeValue v : values)
{
try
{
newSchema, false);
}
catch (DirectoryException de)
{
if (debugEnabled())
{
}
throw new DirectoryException(
de);
}
}
}
else
{
message);
}
break;
case DELETE:
{
message);
}
{
for (AttributeValue v : values)
{
try
{
newSchema, false);
}
catch (DirectoryException de)
{
if (debugEnabled())
{
}
throw new DirectoryException(
de);
}
}
}
{
for (AttributeValue v : values)
{
try
{
newSchema, false);
}
catch (DirectoryException de)
{
if (debugEnabled())
{
}
throw new DirectoryException(
de);
}
}
}
{
for (AttributeValue v : values)
{
try
{
false);
}
catch (DirectoryException de)
{
if (debugEnabled())
{
}
throw new DirectoryException(
de);
}
}
}
{
for (AttributeValue v : values)
{
try
{
newSchema, false);
}
catch (DirectoryException de)
{
if (debugEnabled())
{
}
throw new DirectoryException(
de);
}
}
}
{
for (AttributeValue v : values)
{
try
{
}
catch (DirectoryException de)
{
if (debugEnabled())
{
}
throw new DirectoryException(
de);
}
}
}
{
for (AttributeValue v : values)
{
try
{
newSchema, false);
}
catch (DirectoryException de)
{
if (debugEnabled())
{
}
throw new DirectoryException(
de);
}
}
}
else
{
message);
}
break;
default:
{
message);
}
else
{
}
}
}
// If we've gotten here, then everything looks OK. We'll re-write all
// impacted schema files by first creating them in a temporary location
// and then replacing the existing schema files with the new versions.
// If all that goes successfully, then activate the new schema.
try
{
{
}
}
catch (DirectoryException de)
{
if (debugEnabled())
{
}
throw de;
}
catch (Exception e)
{
if (debugEnabled())
{
}
message, e);
}
finally
{
}
// Create a single file with all of the concatenated schema information
// that we can use on startup to detect whether the schema files have been
// edited with the server offline.
{
}
}
/**
* Handles all processing required for adding the provided attribute type to
* the given schema, replacing an existing type if necessary, and ensuring all
* other metadata is properly updated.
*
* @param attributeType The attribute type to add or replace in the
* server schema.
* @param schema The schema to which the attribute type should
* be added.
* @param modifiedSchemaFiles The names of the schema files containing
* schema elements that have been updated as part
* of the schema modification.
*
* @throws DirectoryException If a problem occurs while attempting to add
* the provided attribute type to the server
* schema.
*/
throws DirectoryException
{
// First, see if the specified attribute type already exists. We'll check
// the OID and all of the names, which means that it's possible there could
// be more than one match (although if there is, then we'll refuse the
// operation).
{
if (t == null)
{
continue;
}
else if (existingType == null)
{
existingType = t;
}
else if (existingType != t)
{
// NOTE: We really do want to use "!=" instead of "! t.equals()"
// because we want to check whether it's the same object instance, not
// just a logical equivalent.
t.getNameOrOID());
}
}
// Make sure that the new attribute type doesn't reference an undefined
// or OBSOLETE superior attribute type.
if (superiorType != null)
{
{
}
else if (superiorType.isObsolete())
{
}
}
// Make sure that none of the associated matching rules are marked OBSOLETE.
{
}
{
}
{
}
{
}
// If there is no existing type, then we're adding a new attribute.
// Otherwise, we're replacing an existing one.
if (existingType == null)
{
{
}
}
else
{
{
{
}
}
else
{
{
}
else
{
}
}
}
}
/**
* Handles all processing required to remove the provided attribute type from
* the server schema, ensuring all other metadata is properly updated. Note
* that this method will first check to see whether the same attribute type
* will be later added to the server schema with an updated definition, and if
* so then the removal will be ignored because the later add will be handled
* as a replace. If the attribute type will not be replaced with a new
* definition, then this method will ensure that there are no other schema
* elements that depend on the attribute type before allowing it to be
* removed.
*
* @param attributeType The attribute type to remove from the server
* schema.
* @param schema The schema from which the attribute type
* should be removed.
* @param modifications The full set of modifications to be processed
* against the server schema.
* @param currentPosition The position of the modification currently
* being performed.
* @param modifiedSchemaFiles The names of the schema files containing
* schema elements that have been updated as part
* of the schema modification.
*
* @throws DirectoryException If a problem occurs while attempting to remove
* the provided attribute type from the server
* schema.
*/
int currentPosition,
throws DirectoryException
{
// See if the specified attribute type is actually defined in the server
// schema. If not, then fail.
{
}
// See if there is another modification later to add the attribute type back
// into the schema. If so, then it's a replace and we should ignore the
// remove because adding it back will handle the replace.
{
Attribute a = m.getAttribute();
{
continue;
}
for (AttributeValue v : a.getValues())
{
try
{
true);
}
catch (DirectoryException de)
{
if (debugEnabled())
{
}
throw new DirectoryException(
de);
}
{
// We found a match where the attribute type is added back later, so
// we don't need to do anything else here.
return;
}
}
}
// Make sure that the attribute type isn't used as the superior type for
// any other attributes.
{
{
}
}
// Make sure that the attribute type isn't used as a required or optional
// attribute type in any objectclass.
{
{
}
}
// Make sure that the attribute type isn't used as a required or optional
// attribute type in any name form.
{
{
}
}
// Make sure that the attribute type isn't used as a required, optional, or
// prohibited attribute type in any DIT content rule.
{
{
}
}
// Make sure that the attribute type isn't referenced by any matching rule
// use.
{
{
}
}
// If we've gotten here, then it's OK to remove the attribute type from
// the schema.
if (schemaFile != null)
{
}
}
/**
* Handles all processing required for adding the provided objectclass to the
* given schema, replacing an existing class if necessary, and ensuring
* all other metadata is properly updated.
*
* @param objectClass The objectclass to add or replace in the
* server schema.
* @param schema The schema to which the objectclass should be
* added.
* @param modifiedSchemaFiles The names of the schema files containing
* schema elements that have been updated as part
* of the schema modification.
*
* @throws DirectoryException If a problem occurs while attempting to add
* the provided objectclass to the server schema.
*/
throws DirectoryException
{
// First, see if the specified objectclass already exists. We'll check the
// OID and all of the names, which means that it's possible there could be
// more than one match (although if there is, then we'll refuse the
// operation).
{
{
continue;
}
else if (existingClass == null)
{
existingClass = oc;
}
else if (existingClass != oc)
{
// NOTE: We really do want to use "!=" instead of "! t.equals()"
// because we want to check whether it's the same object instance, not
// just a logical equivalent.
oc.getNameOrOID());
}
}
// Make sure that the new objectclass doesn't reference an undefined
// superior class, or an undefined required or optional attribute type,
// and that none of them are OBSOLETE.
if (superiorClass != null)
{
{
}
else if (superiorClass.isObsolete())
{
}
}
{
{
}
else if (at.isObsolete())
{
}
}
{
{
}
else if (at.isObsolete())
{
}
}
// If there is no existing class, then we're adding a new objectclass.
// Otherwise, we're replacing an existing one.
if (existingClass == null)
{
{
}
}
else
{
{
{
}
}
else
{
{
}
else
{
}
}
}
}
/**
* Handles all processing required to remove the provided objectclass from the
* server schema, ensuring all other metadata is properly updated. Note that
* this method will first check to see whether the same objectclass will be
* later added to the server schema with an updated definition, and if so then
* the removal will be ignored because the later add will be handled as a
* replace. If the objectclass will not be replaced with a new definition,
* then this method will ensure that there are no other schema elements that
* depend on the objectclass before allowing it to be removed.
*
* @param objectClass The objectclass to remove from the server
* schema.
* @param schema The schema from which the objectclass should
* be removed.
* @param modifications The full set of modifications to be processed
* against the server schema.
* @param currentPosition The position of the modification currently
* being performed.
* @param modifiedSchemaFiles The names of the schema files containing
* schema elements that have been updated as part
* of the schema modification.
*
* @throws DirectoryException If a problem occurs while attempting to remove
* the provided objectclass from the server
* schema.
*/
int currentPosition,
throws DirectoryException
{
// See if the specified objectclass is actually defined in the server
// schema. If not, then fail.
{
}
// See if there is another modification later to add the objectclass back
// into the schema. If so, then it's a replace and we should ignore the
// remove because adding it back will handle the replace.
{
Attribute a = m.getAttribute();
{
continue;
}
for (AttributeValue v : a.getValues())
{
try
{
}
catch (DirectoryException de)
{
if (debugEnabled())
{
}
throw new DirectoryException(
de);
}
{
// We found a match where the objectClass is added back later, so we
// don't need to do anything else here.
return;
}
}
}
// Make sure that the objectclass isn't used as the superior class for any
// other objectclass.
{
{
}
}
// Make sure that the objectclass isn't used as the structural class for
// any name form.
{
}
// Make sure that the objectclass isn't used as a structural or auxiliary
// class for any DIT content rule.
{
{
}
}
// If we've gotten here, then it's OK to remove the objectclass from the
// schema.
if (schemaFile != null)
{
}
}
/**
* Handles all processing required for adding the provided name form to the
* the given schema, replacing an existing name form if necessary, and
* ensuring all other metadata is properly updated.
*
* @param nameForm The name form to add or replace in the server
* schema.
* @param schema The schema to which the name form should be
* added.
* @param modifiedSchemaFiles The names of the schema files containing
* schema elements that have been updated as part
* of the schema modification.
*
* @throws DirectoryException If a problem occurs while attempting to add
* the provided name form to the server schema.
*/
throws DirectoryException
{
// First, see if the specified name form already exists. We'll check the
// OID and all of the names, which means that it's possible there could be
// more than one match (although if there is, then we'll refuse the
// operation).
{
{
continue;
}
else if (existingNF == null)
{
existingNF = nf;
}
else if (existingNF != nf)
{
// NOTE: We really do want to use "!=" instead of "! t.equals()"
// because we want to check whether it's the same object instance, not
// just a logical equivalent.
nf.getNameOrOID());
}
}
// Make sure that the new name form doesn't reference an undefined
// structural class, or an undefined required or optional attribute type, or
// that any of them are marked OBSOLETE.
{
}
{
}
if (structuralClass.isObsolete())
{
}
{
}
{
{
}
else if (at.isObsolete())
{
}
}
{
{
}
else if (at.isObsolete())
{
}
}
// If there is no existing class, then we're adding a new name form.
// Otherwise, we're replacing an existing one.
if (existingNF == null)
{
{
}
}
else
{
{
{
}
}
else
{
{
}
else
{
}
}
}
}
/**
* Handles all processing required to remove the provided name form from the
* server schema, ensuring all other metadata is properly updated. Note that
* this method will first check to see whether the same name form will be
* later added to the server schema with an updated definition, and if so then
* the removal will be ignored because the later add will be handled as a
* replace. If the name form will not be replaced with a new definition, then
* this method will ensure that there are no other schema elements that depend
* on the name form before allowing it to be removed.
*
* @param nameForm The name form to remove from the server
* schema.
* @param schema The schema from which the name form should be
* be removed.
* @param modifications The full set of modifications to be processed
* against the server schema.
* @param currentPosition The position of the modification currently
* being performed.
* @param modifiedSchemaFiles The names of the schema files containing
* schema elements that have been updated as part
* of the schema modification.
*
* @throws DirectoryException If a problem occurs while attempting to remove
* the provided name form from the server schema.
*/
int currentPosition,
throws DirectoryException
{
// See if the specified name form is actually defined in the server schema.
// If not, then fail.
{
nameForm.getNameOrOID());
}
// See if there is another modification later to add the name form back
// into the schema. If so, then it's a replace and we should ignore the
// remove because adding it back will handle the replace.
{
Attribute a = m.getAttribute();
{
continue;
}
for (AttributeValue v : a.getValues())
{
try
{
}
catch (DirectoryException de)
{
if (debugEnabled())
{
}
throw new DirectoryException(
de);
}
{
// We found a match where the name form is added back later, so we
// don't need to do anything else here.
return;
}
}
}
// Make sure that the name form isn't referenced by any DIT structure
// rule.
{
}
// If we've gotten here, then it's OK to remove the name form from the
// schema.
if (schemaFile != null)
{
}
}
/**
* Handles all processing required for adding the provided DIT content rule to
* the given schema, replacing an existing rule if necessary, and ensuring
* all other metadata is properly updated.
*
* @param ditContentRule The DIT content rule to add or replace in the
* server schema.
* @param schema The schema to which the DIT content rule
* should be be added.
* @param modifiedSchemaFiles The names of the schema files containing
* schema elements that have been updated as part
* of the schema modification.
*
* @throws DirectoryException If a problem occurs while attempting to add
* the provided DIT content rule to the server
* schema.
*/
throws DirectoryException
{
// First, see if the specified DIT content rule already exists. We'll check
// all of the names, which means that it's possible there could be more than
// one match (although if there is, then we'll refuse the operation).
{
{
{
if (existingDCR == null)
{
existingDCR = dcr;
break;
}
else
{
message);
}
}
}
}
// Get the structural class for the new DIT content rule and see if there's
// already an existing rule that is associated with that class. If there
// is, then it will only be acceptable if it's the DIT content rule that we
// are replacing (in which case we really do want to use the "!=" operator).
{
}
// Make sure that the new DIT content rule doesn't reference an undefined
// structural or auxiliaryclass, or an undefined required, optional, or
// prohibited attribute type.
{
}
{
}
if (structuralClass.isObsolete())
{
}
{
{
}
{
}
if (oc.isObsolete())
{
}
}
{
{
}
else if (at.isObsolete())
{
}
}
{
{
}
else if (at.isObsolete())
{
}
}
{
{
}
else if (at.isObsolete())
{
}
}
// If there is no existing rule, then we're adding a new DIT content rule.
// Otherwise, we're replacing an existing one.
if (existingDCR == null)
{
{
}
}
else
{
{
{
}
}
else
{
{
}
else
{
}
}
}
}
/**
* Handles all processing required to remove the provided DIT content rule
* from the server schema, ensuring all other metadata is properly updated.
* Note that this method will first check to see whether the same rule will be
* later added to the server schema with an updated definition, and if so then
* the removal will be ignored because the later add will be handled as a
* replace. If the DIT content rule will not be replaced with a new
* definition, then this method will ensure that there are no other schema
* elements that depend on the rule before allowing it to be removed.
*
* @param ditContentRule The DIT content rule to remove from the server
* schema.
* @param schema The schema from which the DIT content rule
* should be removed.
* @param modifications The full set of modifications to be processed
* against the server schema.
* @param currentPosition The position of the modification currently
* being performed.
* @param modifiedSchemaFiles The names of the schema files containing
* schema elements that have been updated as part
* of the schema modification.
*
* @throws DirectoryException If a problem occurs while attempting to remove
* the provided DIT content rule from the server
* schema.
*/
int currentPosition,
throws DirectoryException
{
// See if the specified DIT content rule is actually defined in the server
// schema. If not, then fail.
{
}
// Since DIT content rules don't have any dependencies, then we don't need
// to worry about the difference between a remove or a replace. We can
// just remove the DIT content rule now, and if it is added back later then
// there still won't be any conflict.
if (schemaFile != null)
{
}
}
/**
* Handles all processing required for adding the provided DIT structure rule
* to the given schema, replacing an existing rule if necessary, and ensuring
* all other metadata is properly updated.
*
* @param ditStructureRule The DIT structure rule to add or replace in
* the server schema.
* @param schema The schema to which the DIT structure rule
* should be be added.
* @param modifiedSchemaFiles The names of the schema files containing
* schema elements that have been updated as part
* of the schema modification.
*
* @throws DirectoryException If a problem occurs while attempting to add
* the provided DIT structure rule to the server
* schema.
*/
throws DirectoryException
{
// First, see if the specified DIT structure rule already exists. We'll
// check the rule ID and all of the names, which means that it's possible
// there could be more than one match (although if there is, then we'll
// refuse the operation).
{
{
{
// We really do want to use the "!=" operator here because it's
// acceptable if we find match for the same object instance.
{
message);
}
}
}
}
// Get the name form for the new DIT structure rule and see if there's
// already an existing rule that is associated with that name form. If
// there is, then it will only be acceptable if it's the DIT structure rule
// that we are replacing (in which case we really do want to use the "!="
// operator).
if ((existingRuleForNameForm != null) &&
{
}
// Make sure that the new DIT structure rule doesn't reference an undefined
// name form or superior DIT structure rule.
{
}
if (nameForm.isObsolete())
{
}
// If there are any superior rules, then make sure none of them are marked
// OBSOLETE.
{
if (dsr.isObsolete())
{
}
}
// If there is no existing rule, then we're adding a new DIT structure rule.
// Otherwise, we're replacing an existing one.
if (existingDSR == null)
{
{
}
}
else
{
{
{
}
}
else
{
{
}
else
{
}
}
}
}
/**
* Handles all processing required to remove the provided DIT structure rule
* from the server schema, ensuring all other metadata is properly updated.
* Note that this method will first check to see whether the same rule will be
* later added to the server schema with an updated definition, and if so then
* the removal will be ignored because the later add will be handled as a
* replace. If the DIT structure rule will not be replaced with a new
* definition, then this method will ensure that there are no other schema
* elements that depend on the rule before allowing it to be removed.
*
* @param ditStructureRule The DIT structure rule to remove from the
* server schema.
* @param schema The schema from which the DIT structure rule
* should be removed.
* @param modifications The full set of modifications to be processed
* against the server schema.
* @param currentPosition The position of the modification currently
* being performed.
* @param modifiedSchemaFiles The names of the schema files containing
* schema elements that have been updated as part
* of the schema modification.
*
* @throws DirectoryException If a problem occurs while attempting to remove
* the provided DIT structure rule from the
* server schema.
*/
int currentPosition,
throws DirectoryException
{
// See if the specified DIT structure rule is actually defined in the server
// schema. If not, then fail.
{
}
// See if there is another modification later to add the DIT structure rule
// back into the schema. If so, then it's a replace and we should ignore
// the remove because adding it back will handle the replace.
{
Attribute a = m.getAttribute();
{
continue;
}
for (AttributeValue v : a.getValues())
{
try
{
}
catch (DirectoryException de)
{
if (debugEnabled())
{
}
throw new DirectoryException(
de);
}
{
// We found a match where the DIT structure rule is added back later,
// so we don't need to do anything else here.
return;
}
}
}
// Make sure that the DIT structure rule isn't the superior for any other
// DIT structure rule.
{
{
}
}
// If we've gotten here, then it's OK to remove the DIT structure rule from
// the schema.
if (schemaFile != null)
{
}
}
/**
* Handles all processing required for adding the provided matching rule use
* to the given schema, replacing an existing use if necessary, and ensuring
* all other metadata is properly updated.
*
* @param matchingRuleUse The matching rule use to add or replace in the
* server schema.
* @param schema The schema to which the matching rule use
* should be added.
* @param modifiedSchemaFiles The names of the schema files containing
* schema elements that have been updated as part
* of the schema modification.
*
* @throws DirectoryException If a problem occurs while attempting to add
* the provided matching rule use to the server
* schema.
*/
throws DirectoryException
{
// First, see if the specified matching rule use already exists. We'll
// check all of the names, which means that it's possible that there could
// be more than one match (although if there is, then we'll refuse the
// operation).
{
{
{
if (existingMRU == null)
{
existingMRU = mru;
break;
}
else
{
message);
}
}
}
}
// Get the matching rule for the new matching rule use and see if there's
// already an existing matching rule use that is associated with that
// matching rule. If there is, then it will only be acceptable if it's the
// matching rule use that we are replacing (in which case we really do want
// to use the "!=" operator).
{
}
if (matchingRule.isObsolete())
{
}
// Make sure that the new matching rule use doesn't reference an undefined
// attribute type.
{
{
}
else if (at.isObsolete())
{
}
}
// If there is no existing matching rule use, then we're adding a new one.
// Otherwise, we're replacing an existing matching rule use.
if (existingMRU == null)
{
{
}
}
else
{
{
{
}
}
else
{
{
}
else
{
}
}
}
}
/**
* Handles all processing required to remove the provided matching rule use
* from the server schema, ensuring all other metadata is properly updated.
* Note that this method will first check to see whether the same matching
* rule use will be later added to the server schema with an updated
* definition, and if so then the removal will be ignored because the later
* add will be handled as a replace. If the matching rule use will not be
* replaced with a new definition, then this method will ensure that there are
* no other schema elements that depend on the matching rule use before
* allowing it to be removed.
*
* @param matchingRuleUse The matching rule use to remove from the
* server schema.
* @param schema The schema from which the matching rule use
* should be removed.
* @param modifications The full set of modifications to be processed
* against the server schema.
* @param currentPosition The position of the modification currently
* being performed.
* @param modifiedSchemaFiles The names of the schema files containing
* schema elements that have been updated as part
* of the schema modification.
*
* @throws DirectoryException If a problem occurs while attempting to remove
* the provided matching rule use from the server
* schema.
*/
int currentPosition,
throws DirectoryException
{
// See if the specified DIT content rule is actually defined in the server
// schema. If not, then fail.
{
}
// Since matching rule uses don't have any dependencies, then we don't need
// to worry about the difference between a remove or a replace. We can
// just remove the DIT content rule now, and if it is added back later then
// there still won't be any conflict.
if (schemaFile != null)
{
}
}
/**
* Creates an empty entry that may be used as the basis for a new schema file.
*
* @return An empty entry that may be used as the basis for a new schema
* file.
*/
private Entry createEmptySchemaEntry()
{
{
if (type.isOperational())
{
}
else
{
}
}
}
/**
* Writes a temporary version of the specified schema file.
*
* @param schema The schema from which to take the definitions to be
* written.
* @param schemaFile The name of the schema file to be written.
*
* @throws DirectoryException If an unexpected problem occurs while
* identifying the schema definitions to include
* in the schema file.
*
* @throws IOException If an unexpected error occurs while attempting to
* write the temporary schema file.
*
* @throws LDIFException If an unexpected problem occurs while generating
* the LDIF representation of the schema entry.
*/
{
// Start with an empty schema entry.
// Add all of the appropriate attribute types to the schema entry. We need
// to be careful of the ordering to ensure that any superior types in the
// same file are written before the subordinate types.
{
{
}
}
{
}
// Add all of the appropriate objectclasses to the schema entry. We need
// to be careful of the ordering to ensure that any superior classes in the
// same file are written before the subordinate classes.
{
{
0);
}
}
{
}
// Add all of the appropriate name forms to the schema entry. Since there
// is no hierarchical relationship between name forms, we don't need to
// worry about ordering.
{
{
}
}
{
}
// Add all of the appropriate DIT content rules to the schema entry. Since
// there is no hierarchical relationship between DIT content rules, we don't
// need to worry about ordering.
{
{
dcr.getDefinition()));
}
}
{
}
// Add all of the appropriate DIT structure rules to the schema entry. We
// need to be careful of the ordering to ensure that any superior rules in
// the same file are written before the subordinate rules.
{
{
addedDSRs, 0);
}
}
{
values));
}
// Add all of the appropriate matching rule uses to the schema entry. Since
// there is no hierarchical relationship between matching rule uses, we
// don't need to worry about ordering.
{
{
mru.getDefinition()));
}
}
{
values));
}
{
{
values));
}
}
// Create a temporary file to which we can write the schema entry.
ldifWriter.close();
return tempFile;
}
/**
* Adds the definition for the specified attribute type to the provided set of
* attribute values, recursively adding superior types as appropriate.
*
* @param schema The schema containing the attribute type.
* @param schemaFile The schema file with which the attribute type is
* associated.
* @param attributeType The attribute type whose definition should be added
* to the value set.
* @param values The set of values for attribute type definitions
* already added.
* @param addedTypes The set of attribute types whose definitions have
* already been added to the set of values.
* @param depth A depth counter to use in an attempt to detect
* circular references.
*/
int depth)
throws DirectoryException
{
if (depth > 20)
{
}
{
return;
}
if ((superiorType != null) &&
{
}
}
/**
* Adds the definition for the specified objectclass to the provided set of
* attribute values, recursively adding superior classes as appropriate.
*
* @param schema The schema containing the objectclass.
* @param schemaFile The schema file with which the objectclass is
* associated.
* @param objectClass The objectclass whose definition should be added to
* the value set.
* @param values The set of values for objectclass definitions
* already added.
* @param addedClasses The set of objectclasses whose definitions have
* already been added to the set of values.
* @param depth A depth counter to use in an attempt to detect
* circular references.
*/
int depth)
throws DirectoryException
{
if (depth > 20)
{
}
{
return;
}
if ((superiorClass != null) &&
{
}
objectClass.getDefinition()));
}
/**
* Adds the definition for the specified DIT structure rule to the provided
* set of attribute values, recursively adding superior rules as appropriate.
*
* @param schema The schema containing the DIT structure rule.
* @param schemaFile The schema file with which the DIT structure rule
* is associated.
* @param ditStructureRule The DIT structure rule whose definition should be
* added to the value set.
* @param values The set of values for DIT structure rule
* definitions already added.
* @param addedDSRs The set of DIT structure rules whose definitions
* have already been added added to the set of
* values.
* @param depth A depth counter to use in an attempt to detect
* circular references.
*/
throws DirectoryException
{
if (depth > 20)
{
}
{
return;
}
{
{
}
}
}
/**
* Moves the specified temporary schema files in place of the active versions.
* If an error occurs in the process, then this method will attempt to restore
* the original schema files if possible.
*
* @param tempSchemaFiles The set of temporary schema files to be activated.
*
* @throws DirectoryException If a problem occurs while attempting to
* install the temporary schema files.
*/
throws DirectoryException
{
// Create lists that will hold the three types of files we'll be dealing
// with (the temporary files that will be installed, the installed schema
// files, and the previously-installed schema files).
{
}
// If there are any old ".orig" files laying around from a previous
// attempt, then try to clean them up.
for (File f : origFileList)
{
if (f.exists())
{
f.delete();
}
}
// Copy all of the currently-installed files with a ".orig" extension. If
// this fails, then try to clean up the copies.
try
{
{
if (installedFile.exists())
{
}
}
}
catch (Exception e)
{
if (debugEnabled())
{
}
boolean allCleaned = true;
for (File f : origFileList)
{
try
{
if (f.exists())
{
if (! f.delete())
{
allCleaned = false;
}
}
}
{
if (debugEnabled())
{
}
allCleaned = false;
}
}
if (allCleaned)
{
getExceptionMessage(e));
message, e);
}
else
{
.get(getExceptionMessage(e));
message);
message, e);
}
}
// Try to copy all of the temporary files into place over the installed
// files. If this fails, then try to restore the originals.
try
{
{
}
}
catch (Exception e)
{
if (debugEnabled())
{
}
for (File f : installedFileList)
{
try
{
if (f.exists())
{
f.delete();
}
}
{
if (debugEnabled())
{
}
}
}
boolean allRestored = true;
{
try
{
{
{
allRestored = false;
}
}
}
{
if (debugEnabled())
{
}
allRestored = false;
}
}
if (allRestored)
{
getExceptionMessage(e));
message, e);
}
else
{
.get(getExceptionMessage(e));
message);
message, e);
}
}
// At this point, we're committed to the schema change, so we can't throw
// any more exceptions, but all we have left is to clean up the original and
// temporary files.
for (File f : origFileList)
{
try
{
if (f.exists())
{
f.delete();
}
}
catch (Exception e)
{
if (debugEnabled())
{
}
}
}
for (File f : tempFileList)
{
try
{
if (f.exists())
{
f.delete();
}
}
catch (Exception e)
{
if (debugEnabled())
{
}
}
}
}
/**
* Creates a copy of the specified file.
*
* @param from The source file to be copied.
* @param to The destination file to be created.
*
* @throws IOException If a problem occurs.
*/
throws IOException
{
byte[] buffer = new byte[4096];
try
{
while (bytesRead > 0)
{
}
}
finally
{
if (inputStream != null)
{
try
{
inputStream.close();
}
catch (Exception e)
{
if (debugEnabled())
{
}
}
}
if (outputStream != null)
{
}
}
}
/**
* Performs any necessary cleanup in an attempt to delete any temporary schema
* files that may have been left over after trying to install the new schema.
*
* @param tempSchemaFiles The set of temporary schema files that have been
* created and are candidates for cleanup.
*/
{
{
return;
}
{
try
{
if (f.exists())
{
f.delete();
}
}
catch (Exception e)
{
if (debugEnabled())
{
}
}
}
}
/**
* {@inheritDoc}
*/
@Override()
throws DirectoryException
{
}
/**
* {@inheritDoc}
*/
@Override()
throws DirectoryException
{
boolean found = false;
{
{
found = true;
break;
}
{
break;
}
}
if (! found)
{
}
// If it's a onelevel or subordinate subtree search, then we will never
// match anything since there isn't anything below the schema.
{
return;
}
// Get the schema entry and see if it matches the filter. If so, then send
// it to the client.
{
}
}
/**
* {@inheritDoc}
*/
@Override()
{
return supportedControls;
}
/**
* {@inheritDoc}
*/
@Override()
{
return supportedFeatures;
}
/**
* {@inheritDoc}
*/
@Override()
public boolean supportsLDIFExport()
{
// We will only export the DSE entry itself.
return true;
}
/**
* {@inheritDoc}
*/
@Override()
throws DirectoryException
{
// Create the LDIF writer.
try
{
}
catch (Exception e)
{
if (debugEnabled())
{
}
message);
}
// Write the root schema entry to it. Make sure to close the LDIF
// writer when we're done.
try
{
}
catch (Exception e)
{
if (debugEnabled())
{
}
message);
}
finally
{
try
{
ldifWriter.close();
}
catch (Exception e)
{
if (debugEnabled())
{
}
}
}
}
/**
* {@inheritDoc}
*/
@Override()
public boolean supportsLDIFImport()
{
// This backend does not support LDIF imports.
// FIXME -- Should we support them?
return false;
}
/**
* {@inheritDoc}
*/
@Override()
throws DirectoryException
{
// This backend does not support LDIF imports.
}
/**
* {@inheritDoc}
*/
@Override()
public boolean supportsBackup()
{
// We do support an online backup mechanism for the schema.
return true;
}
/**
* {@inheritDoc}
*/
@Override()
{
// We should support online backup for the schema in any form. This
// implementation does not support incremental backups, but in this case
// even if we're asked to do an incremental we'll just do a full backup
// instead. So the answer to this should always be "true".
return true;
}
/**
* {@inheritDoc}
*/
@Override()
throws DirectoryException
{
// Get the properties to use for the backup. We don't care whether or not
// it's incremental, so there's no need to get that.
// Create a hash map that will hold the extra backup property information
// for this backup.
// Get the crypto manager and use it to obtain references to the message
if (hash)
{
if (signHash)
{
try
{
}
catch (Exception e)
{
if (debugEnabled())
{
}
throw new DirectoryException(
e);
}
}
else
{
try
{
}
catch (Exception e)
{
if (debugEnabled())
{
}
throw new DirectoryException(
e);
}
}
}
// Create an output stream that will be used to write the archive file. At
// its core, it will be a file output stream to put a file on the disk. If
// we are to encrypt the data, then that file output stream will be wrapped
// in a cipher output stream. The resulting output stream will then be
// wrapped by a zip output stream (which may or may not actually use
// compression).
try
{
filename);
if (archiveFile.exists())
{
int i=1;
while (true)
{
filename + "." + i);
if (archiveFile.exists())
{
i++;
}
else
{
break;
}
}
}
}
catch (Exception e)
{
if (debugEnabled())
{
}
getExceptionMessage(e));
message, e);
}
// If we should encrypt the data, then wrap the output stream in a cipher
// output stream.
if (encrypt)
{
try
{
}
catch (CryptoManagerException e)
{
if (debugEnabled())
{
}
message, e);
}
}
// Wrap the file output stream in a zip output stream.
backupID);
if (compress)
{
}
else
{
}
// Get the path to the directory in which the schema files reside and
// then get a list of all the files in that directory.
File[] schemaFiles;
try
{
}
catch (Exception e)
{
if (debugEnabled())
{
}
message, e);
}
// Iterate through the schema files and write them to the zip stream. If
// we're using a hash or MAC, then calculate that as well.
byte[] buffer = new byte[8192];
{
if (! schemaFile.isFile())
{
// If there are any non-file items in the directory (e.g., one or more
// subdirectories), then we'll skip them.
continue;
}
// We'll put the name in the hash, too.
if (hash)
{
if (signHash)
{
}
else
{
}
}
try
{
while (true)
{
if (bytesRead < 0)
{
break;
}
if (hash)
{
if (signHash)
{
}
else
{
}
}
}
inputStream.close();
}
catch (Exception e)
{
if (debugEnabled())
{
}
try
{
inputStream.close();
try
{
message, e);
}
}
// We're done writing the file, so close the zip stream (which should also
// close the underlying stream).
try
{
}
catch (Exception e)
{
if (debugEnabled())
{
}
message, e);
}
// Get the digest or MAC bytes if appropriate.
byte[] digestBytes = null;
if (hash)
{
if (signHash)
{
}
else
{
}
}
// Create the backup info structure for this backup and add it to the backup
// directory.
// FIXME -- Should I use the date from when I started or finished?
try
{
}
catch (Exception e)
{
if (debugEnabled())
{
}
message, e);
}
}
/**
* {@inheritDoc}
*/
@Override()
throws DirectoryException
{
}
/**
* {@inheritDoc}
*/
@Override()
public boolean supportsRestore()
{
// We will provide a restore, but only for offline operations.
return true;
}
/**
* {@inheritDoc}
*/
@Override()
throws DirectoryException
{
// First, make sure that the requested backup exists.
if (backupInfo == null)
{
message);
}
// Read the backup info structure to determine the name of the file that
// contains the archive. Then make sure that file exists.
if (backupFilename == null)
{
message);
}
try
{
if (! backupFile.exists())
{
message);
}
}
catch (DirectoryException de)
{
throw de;
}
catch (Exception e)
{
message, e);
}
// If the backup is hashed, then we need to get the message digest to use
// to verify it.
if (unsignedHash != null)
{
if (digestAlgorithm == null)
{
message);
}
try
{
}
catch (Exception e)
{
message, e);
}
}
// If the backup is signed, then we need to get the MAC to use to verify it.
if (signedHash != null)
{
{
message);
}
try
{
}
catch (Exception e)
{
message, e);
}
}
// Create the input stream that will be used to read the backup file. At
// its core, it will be a file input stream.
try
{
}
catch (Exception e)
{
message, e);
}
// If the backup is encrypted, then we need to wrap the file input stream
// in a cipher input stream.
if (backupInfo.isEncrypted())
{
try
{
}
catch (CryptoManagerException e)
{
message, e);
}
}
// Now wrap the resulting input stream in a zip stream so that we can read
// its contents. We don't need to worry about whether to use compression or
// not because it will be handled automatically.
// Determine whether we should actually do the restore, or if we should just
// try to verify the archive. If we are not going to verify only, then
// move the current schema directory out of the way so we can keep it around
// to restore if a problem occurs.
if (! verifyOnly)
{
// Rename the current schema directory if it exists.
try
{
{
if (schemaBackupDir.exists())
{
int i=2;
while (true)
{
backupDirPath = schemaBackupDirPath + i;
if (schemaBackupDir.exists())
{
i++;
}
else
{
break;
}
}
}
}
}
catch (Exception e)
{
message, e);
}
// Create a new directory to hold the restored schema files.
try
{
}
catch (Exception e)
{
// Try to restore the previous schema directory if possible. This will
// probably fail in this case, but try anyway.
if (schemaBackupDir != null)
{
try
{
}
{
}
}
message, e);
}
}
// Read through the archive file an entry at a time. For each entry, update
// the digest or MAC if necessary, and if we're actually doing the restore,
// then write the files out into the schema directory.
byte[] buffer = new byte[8192];
while (true)
{
try
{
}
catch (Exception e)
{
// Tell the user where the previous schema was archived.
if (schemaBackupDir != null)
{
}
message, e);
}
{
break;
}
// Get the filename for the zip entry and update the digest or MAC as
// necessary.
{
}
{
}
// If we're doing the restore, then create the output stream to write the
// file.
if (! verifyOnly)
{
try
{
}
catch (Exception e)
{
// Tell the user where the previous schema was archived.
if (schemaBackupDir != null)
{
}
throw new DirectoryException(
e);
}
}
// Read the contents of the file and update the digest or MAC as
// necessary. If we're actually restoring it, then write it into the
// new schema directory.
try
{
while (true)
{
if (bytesRead < 0)
{
// We've reached the end of the entry.
break;
}
// Update the digest or MAC if appropriate.
{
}
{
}
// Write the data to the output stream if appropriate.
if (outputStream != null)
{
}
}
// We're at the end of the file so close the output stream if we're
// writing it.
if (outputStream != null)
{
}
}
catch (Exception e)
{
// Tell the user where the previous schema was archived.
if (schemaBackupDir != null)
{
}
message, e);
}
}
// Close the zip stream since we don't need it anymore.
try
{
}
catch (Exception e)
{
message, e);
}
// At this point, we should be done with the contents of the ZIP file and
// the restore should be complete. If we were generating a digest or MAC,
// then make sure it checks out.
{
{
}
else
{
// Tell the user where the previous schema was archived.
if (schemaBackupDir != null)
{
}
message);
}
}
{
{
}
else
{
// Tell the user where the previous schema was archived.
if (schemaBackupDir != null)
{
}
message);
}
}
// If we are just verifying the archive, then we're done.
if (verifyOnly)
{
return;
}
// If we've gotten here, then the archive was restored successfully. Get
// rid of the temporary copy we made of the previous schema directory and
// exit.
if (schemaBackupDir != null)
{
}
}
/**
* {@inheritDoc}
*/
public boolean isConfigurationChangeAcceptable(
{
return true;
}
/**
* {@inheritDoc}
*/
{
boolean adminActionRequired = false;
// Check to see if we should apply a new set of base DNs.
try
{
if (newBaseDNs.isEmpty())
{
}
}
catch (Exception e)
{
if (debugEnabled())
{
}
getExceptionMessage(e)));
newBaseDNs = null;
}
// Check to see if we should change the behavior regarding whether to show
// all schema attributes.
// Check to see if there is a new set of user-defined attributes.
try
{
{
{
if (! isSchemaConfigAttribute(a))
{
newUserAttrs.add(a);
}
}
}
{
{
if (! isSchemaConfigAttribute(a))
{
newUserAttrs.add(a);
}
}
}
}
catch (ConfigException e)
{
if (debugEnabled())
{
}
}
{
// Get an array containing the new base DNs to use.
// Determine the set of DNs to add and delete. When this is done, the
// deleteBaseDNs will contain the set of DNs that should no longer be used
// and should be deregistered from the server, and the newBaseDNs set will
// just contain the set of DNs to add.
{
{
}
}
{
try
{
}
catch (Exception e)
{
if (debugEnabled())
{
}
getExceptionMessage(e)));
}
}
{
try
{
}
catch (Exception e)
{
if (debugEnabled())
{
}
getExceptionMessage(e)));
}
}
}
}
/**
* Indicates whether to treat common schema attributes like user attributes
* rather than operational attributes.
*
* @return {@code true} if common attributes should be treated like user
* attributes, or {@code false} if not.
*/
boolean showAllAttributes()
{
return showAllAttributes;
}
/**
* Specifies whether to treat common schema attributes like user attributes
* rather than operational attributes.
*
* @param showAllAttributes Specifies whether to treat common schema
* attributes like user attributes rather than
* operational attributes.
*/
void setShowAllAttributes(boolean showAllAttributes)
{
this.showAllAttributes = showAllAttributes;
}
/**
* {@inheritDoc}
*/
public DN getComponentEntryDN()
{
return configEntryDN;
}
/**
* {@inheritDoc}
*/
public String getClassName()
{
return CLASS_NAME;
}
/**
* {@inheritDoc}
*/
{
return alerts;
}
/**
* Returns an attribute that has the minimum upper bound value removed from
* all of its attribute values.
*
* @param valueSet The original valueset containing the
* attribute type definitions.
*
* @return Attribute that with all of the minimum upper bound values removed
* from its attribute values.
*/
private Attribute
new LinkedHashSet<AttributeValue>();
for(AttributeValue v : valueSet) {
//If it exists, strip the minimum upper bound value from the
//attribute value.
//Create an attribute value from the stripped string and add it to the
//valueset.
} else
valueSetCopy.add(v);
}
return
}
}