blob: b76308fd6ab49307fb232a1a0b94b409231731ab [file] [log] [blame]
/*
* 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.
*
*/
package org.apache.directory.server.config;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.naming.directory.SearchControls;
import org.apache.directory.server.config.beans.AdsBaseBean;
import org.apache.directory.server.config.beans.ConfigBean;
import org.apache.directory.server.core.partition.impl.btree.BTreePartition;
import org.apache.directory.server.i18n.I18n;
import org.apache.directory.server.xdbm.ForwardIndexEntry;
import org.apache.directory.server.xdbm.IndexCursor;
import org.apache.directory.server.xdbm.search.SearchEngine;
import org.apache.directory.shared.ldap.model.constants.SchemaConstants;
import org.apache.directory.shared.ldap.model.entry.Entry;
import org.apache.directory.shared.ldap.model.entry.EntryAttribute;
import org.apache.directory.shared.ldap.model.entry.StringValue;
import org.apache.directory.shared.ldap.model.entry.Value;
import org.apache.directory.shared.ldap.model.exception.LdapException;
import org.apache.directory.shared.ldap.model.exception.LdapInvalidDnException;
import org.apache.directory.shared.ldap.model.filter.EqualityNode;
import org.apache.directory.shared.ldap.model.filter.SearchScope;
import org.apache.directory.shared.ldap.model.message.AliasDerefMode;
import org.apache.directory.shared.ldap.model.name.Dn;
import org.apache.directory.shared.ldap.model.name.Rdn;
import org.apache.directory.shared.ldap.model.schema.MutableAttributeTypeImpl;
import org.apache.directory.shared.ldap.model.schema.ObjectClass;
import org.apache.directory.shared.ldap.model.schema.SchemaManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A class used for reading the configuration present in a Partition
* and instantiate the necessary objects like DirectoryService, Interceptors etc.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public class ConfigPartitionReader
{
/** The logger for this class */
private static final Logger LOG = LoggerFactory.getLogger( ConfigPartitionReader.class );
/** the partition which holds the configuration data */
private BTreePartition<Long> configPartition;
/** the search engine of the partition */
private SearchEngine<Entry, Long> se;
/** the schema manager set in the config partition */
private SchemaManager schemaManager;
/** The prefix for all the configuration ObjectClass names */
private static final String ADS_PREFIX = "ads-";
/** The suffix for the bean */
private static final String ADS_SUFFIX = "Bean";
/** Those two flags are used to tell the reader if an element of configuration is mandatory or not */
private static final boolean MANDATORY = true;
private static final boolean OPTIONNAL = false;
/**
*
* Creates a new instance of ConfigPartitionReader.
*
* @param configPartition the non null config partition
*/
public ConfigPartitionReader( BTreePartition<Long> configPartition )
{
if ( configPartition == null )
{
throw new IllegalArgumentException( I18n.err( I18n.ERR_503 ) );
}
if ( !configPartition.isInitialized() )
{
throw new IllegalStateException( I18n.err( I18n.ERR_504 ) );
}
this.configPartition = configPartition;
se = configPartition.getSearchEngine();
this.schemaManager = configPartition.getSchemaManager();
}
/**
* Fnd the upper objectclass in a hierarchy. All the inherited ObjectClasses
* will be removed.
*/
private ObjectClass findObjectClass( EntryAttribute objectClass ) throws Exception
{
Set<ObjectClass> candidates = new HashSet<ObjectClass>();
try
{
// Create the set of candidates
for ( Value<?> ocValue : objectClass )
{
String ocName = ocValue.getString();
String ocOid = schemaManager.getObjectClassRegistry().getOidByName( ocName );
ObjectClass oc = ( ObjectClass ) schemaManager.getObjectClassRegistry().get( ocOid );
if ( oc.isStructural() )
{
candidates.add( oc );
}
}
}
catch ( Exception e )
{
e.printStackTrace();
throw e;
}
// Now find the parent OC
for ( Value<?> ocValue : objectClass )
{
String ocName = ocValue.getString();
String ocOid = schemaManager.getObjectClassRegistry().getOidByName( ocName );
ObjectClass oc = ( ObjectClass ) schemaManager.getObjectClassRegistry().get( ocOid );
for ( ObjectClass superior : oc.getSuperiors() )
{
if ( oc.isStructural() )
{
if ( candidates.contains( superior ) )
{
candidates.remove( superior );
}
}
}
}
// The remaining OC in the candidates set is the one we are looking for
ObjectClass result = candidates.toArray( new ObjectClass[]
{} )[0];
LOG.debug( "The top level object class is {}", result.getName() );
return result;
}
/**
* Create the base Bean from the ObjectClass name.
* The bean name is constructed using the OjectClass name, by
* removing the ADS prefix, upper casing the first letter and adding "Bean" at the end.
*
* For instance, ads-directoryService wil become DirectoryServiceBean
*/
private AdsBaseBean createBean( ObjectClass objectClass ) throws ConfigurationException
{
// The remaining OC in the candidates set is the one we are looking for
String objectClassName = objectClass.getName();
// Now, let's instanciate the associated bean. Get rid of the 'ads-' in front of the name,
// and uppercase the first letter. Finally add "Bean" at the end and add the package.
//String beanName = this.getClass().getPackage().getName() + "org.apache.directory.server.config.beans." + Character.toUpperCase( objectClassName.charAt( 4 ) ) + objectClassName.substring( 5 ) + "Bean";
String beanName = this.getClass().getPackage().getName() + ".beans." +
Character.toUpperCase( objectClassName.charAt( ADS_PREFIX.length() ) ) +
objectClassName.substring( ADS_PREFIX.length() + 1 ) + ADS_SUFFIX;
try
{
Class<?> clazz = Class.forName( beanName );
Constructor<?> constructor = clazz.getConstructor();
AdsBaseBean bean = ( AdsBaseBean ) constructor.newInstance();
LOG.debug( "Bean {} created for ObjectClass {}", beanName, objectClassName );
return bean;
}
catch ( ClassNotFoundException cnfe )
{
String message = "Cannot find a Bean class for the ObjectClass name " + objectClassName;
LOG.error( message );
throw new ConfigurationException( message );
}
catch ( SecurityException se )
{
String message = "Cannot access to the class " + beanName;
LOG.error( message );
throw new ConfigurationException( message );
}
catch ( NoSuchMethodException nsme )
{
String message = "Cannot find a constructor for the class " + beanName;
LOG.error( message );
throw new ConfigurationException( message );
}
catch ( InvocationTargetException ite )
{
String message = "Cannot invoke the class " + beanName + ", " + ite.getMessage();
LOG.error( message );
throw new ConfigurationException( message );
}
catch ( IllegalAccessException iae )
{
String message = "Cannot access to the constructor for class " + beanName;
LOG.error( message );
throw new ConfigurationException( message );
}
catch ( InstantiationException ie )
{
String message = "Cannot instanciate the class " + beanName + ", " + ie.getMessage();
LOG.error( message );
throw new ConfigurationException( message );
}
}
/**
* Retrieve the Field associated with an AttributeType name, if any.
*/
private static Field getField( Class<?> clazz, String attributeName, Class<?> originalClazz )
throws ConfigurationException
{
// We will check all the fields, as the AT name is case insentitive
// when the field is case sensitive
Field[] fields = clazz.getDeclaredFields();
for ( Field field : fields )
{
String fieldName = field.getName();
if ( fieldName.equalsIgnoreCase( attributeName ) )
{
return field;
}
}
// May be in the paren'ts class ?
if ( clazz.getSuperclass() != null )
{
return getField( clazz.getSuperclass(), attributeName, originalClazz );
}
String message = "Cannot find a field named " + attributeName + " in class " + originalClazz.getName();
LOG.error( message );
throw new ConfigurationException( message );
}
/**
* Read the single entry value for an AttributeType, and feed the Bean field with this value
*/
private void readSingleValueField( AdsBaseBean bean, Field beanField, EntryAttribute fieldAttr, boolean mandatory )
throws ConfigurationException
{
if ( fieldAttr == null )
{
return;
}
Value<?> value = fieldAttr.get();
String valueStr = value.getString();
Class<?> type = beanField.getType();
// Process the value accordingly to its type.
try
{
if ( type == String.class )
{
beanField.set( bean, value.getString() );
}
else if ( type == int.class )
{
beanField.setInt( bean, Integer.parseInt( valueStr ) );
}
else if ( type == long.class )
{
beanField.setLong( bean, Long.parseLong( valueStr ) );
}
else if ( type == boolean.class )
{
beanField.setBoolean( bean, Boolean.parseBoolean( valueStr ) );
}
else if ( type == Dn.class )
{
try
{
Dn dn = new Dn( valueStr );
beanField.set( bean, dn );
}
catch ( LdapInvalidDnException lide )
{
String message = "The Dn '" + valueStr + "' for attribute " + fieldAttr.getId()
+ " is not a valid Dn";
LOG.error( message );
throw new ConfigurationException( message );
}
}
}
catch ( IllegalArgumentException iae )
{
String message = "Cannot store '" + valueStr + "' into attribute " + fieldAttr.getId();
LOG.error( message );
throw new ConfigurationException( message );
}
catch ( IllegalAccessException e )
{
String message = "Cannot store '" + valueStr + "' into attribute " + fieldAttr.getId();
LOG.error( message );
throw new ConfigurationException( message );
}
}
/**
* Read the multiple entry value for an AttributeType, and feed the Bean field with this value
*/
private void readMultiValuedField( AdsBaseBean bean, Field beanField, EntryAttribute fieldAttr, boolean mandatory )
throws ConfigurationException
{
if ( fieldAttr == null )
{
return;
}
Class<?> type = beanField.getType();
String fieldName = beanField.getName();
String addMethodName = "add" + Character.toUpperCase( fieldName.charAt( 0 ) ) + fieldName.substring( 1 );
// loop on the values and inject them in the bean
for ( Value<?> value : fieldAttr )
{
String valueStr = value.getString();
try
{
if ( type == String.class )
{
beanField.set( bean, value.getString() );
}
else if ( type == int.class )
{
beanField.setInt( bean, Integer.parseInt( valueStr ) );
}
else if ( type == long.class )
{
beanField.setLong( bean, Long.parseLong( valueStr ) );
}
else if ( type == boolean.class )
{
beanField.setBoolean( bean, Boolean.parseBoolean( valueStr ) );
}
else if ( type == Dn.class )
{
try
{
Dn dn = new Dn( valueStr );
beanField.set( bean, dn );
}
catch ( LdapInvalidDnException lide )
{
String message = "The Dn '" + valueStr + "' for attribute " + fieldAttr.getId()
+ " is not a valid Dn";
LOG.error( message );
throw new ConfigurationException( message );
}
}
else if ( type == Set.class )
{
Type genericFieldType = beanField.getGenericType();
Class<?> fieldArgClass = null;
if ( genericFieldType instanceof ParameterizedType )
{
ParameterizedType parameterizedType = ( ParameterizedType ) genericFieldType;
Type[] fieldArgTypes = parameterizedType.getActualTypeArguments();
for ( Type fieldArgType : fieldArgTypes )
{
fieldArgClass = ( Class<?> ) fieldArgType;
}
}
Method method = bean.getClass().getMethod( addMethodName,
Array.newInstance( fieldArgClass, 0 ).getClass() );
method.invoke( bean, new Object[]
{ new String[]
{ valueStr } } );
}
else if ( type == List.class )
{
Type genericFieldType = beanField.getGenericType();
Class<?> fieldArgClass = null;
if ( genericFieldType instanceof ParameterizedType )
{
ParameterizedType parameterizedType = ( ParameterizedType ) genericFieldType;
Type[] fieldArgTypes = parameterizedType.getActualTypeArguments();
for ( Type fieldArgType : fieldArgTypes )
{
fieldArgClass = ( Class<?> ) fieldArgType;
}
}
Method method = bean.getClass().getMethod( addMethodName,
Array.newInstance( fieldArgClass, 0 ).getClass() );
method.invoke( bean, new Object[]
{ new String[]
{ valueStr } } );
}
}
catch ( IllegalArgumentException iae )
{
String message = "Cannot store '" + valueStr + "' into attribute " + fieldAttr.getId();
LOG.error( message );
throw new ConfigurationException( message );
}
catch ( IllegalAccessException e )
{
String message = "Cannot store '" + valueStr + "' into attribute " + fieldAttr.getId();
LOG.error( message );
throw new ConfigurationException( message );
}
catch ( SecurityException se )
{
String message = "Cannot access to the class " + bean.getClass().getName();
LOG.error( message );
throw new ConfigurationException( message );
}
catch ( NoSuchMethodException nsme )
{
String message = "Cannot find a method " + addMethodName + " in the class " + bean.getClass().getName();
LOG.error( message );
throw new ConfigurationException( message );
}
catch ( InvocationTargetException ite )
{
String message = "Cannot invoke the class " + bean.getClass().getName() + ", " + ite.getMessage();
LOG.error( message );
throw new ConfigurationException( message );
}
catch ( NegativeArraySizeException nase )
{
// No way that can happen...
}
}
}
/**
* Read all the required fields (AttributeTypes) for a given Entry.
*/
private void readFields( AdsBaseBean bean, Entry entry, Set<MutableAttributeTypeImpl> attributeTypes, boolean mandatory )
throws NoSuchFieldException, IllegalAccessException, Exception
{
for ( MutableAttributeTypeImpl attributeType : attributeTypes )
{
String fieldName = attributeType.getName();
String beanFieldName = fieldName;
// Remove the "ads-" from the beginning of the field name
if ( fieldName.startsWith( ADS_PREFIX ) )
{
beanFieldName = fieldName.substring( ADS_PREFIX.length() );
}
// Get the field
Field beanField = getField( bean.getClass(), beanFieldName, bean.getClass() );
// The field is private, we need to modify it to be able to access it.
beanField.setAccessible( true );
// Get the entry attribute for this field
EntryAttribute fieldAttr = entry.get( fieldName );
if ( ( fieldAttr == null ) && ( mandatory ) )
{
String message = "Attribute " + fieldName + " is mandatory and is not present for the Entry "
+ entry.getDn();
LOG.error( message );
throw new ConfigurationException( message );
}
// Get the associated AttributeType
MutableAttributeTypeImpl beanAT = schemaManager.getAttributeType( fieldName );
// Check if this AT has the ads-compositeElement as a superior
MutableAttributeTypeImpl superior = beanAT.getSuperior();
if ( ( superior != null )
&& superior.getOid().equals( ConfigSchemaConstants.ADS_COMPOSITE_ELEMENT_AT.getOid() ) )
{
// This is a composite element, we have to go one level down to read it.
// First, check if it's a SingleValued element
if ( beanAT.isSingleValued() )
{
// Yes : get the first element
List<AdsBaseBean> beans = read( entry.getDn(), fieldName, SearchScope.ONELEVEL, mandatory );
// We may not have found an element, but if the attribute is mandatory,
// this is an error
if ( ( beans == null ) || ( beans.size() == 0 ) )
{
if ( mandatory )
{
// This is an error !
String message = "The composite " + beanAT.getName()
+ " is mandatory, and was not found under the "
+ "configuration entry " + entry.getDn();
LOG.error( message );
throw new ConfigurationException( message );
}
}
else
{
// We must take the first element
AdsBaseBean readBean = beans.get( 0 );
if ( beans.size() > 1 )
{
// Not allowed as the AT is singled-valued
String message = "We have more than one entry for " + beanAT.getName() + " under "
+ entry.getDn();
LOG.error( message );
throw new ConfigurationException( message );
}
beanField.set( bean, readBean );
}
}
else
{
// No : we have to loop recursively on all the elements which are
// under the ou=<element-name> branch
Dn newBase = entry.getDn().add( "ou=" + beanFieldName );
// We have to remove the 's' at the end of the field name
String attributeName = fieldName.substring( 0, fieldName.length() - 1 );
// Sometime, the plural of a noun takes 'es'
if ( !schemaManager.getObjectClassRegistry().contains( attributeName ) )
{
// Try by removing 'es'
attributeName = fieldName.substring( 0, fieldName.length() - 2 );
if ( !schemaManager.getObjectClassRegistry().contains( attributeName ) )
{
String message = "Cannot find the ObjectClass named " + attributeName + " in the schema";
LOG.error( message );
throw new ConfigurationException( message );
}
}
// This is a multi-valued element, it can be a Set or a List
Collection<AdsBaseBean> beans = read( newBase, attributeName, SearchScope.ONELEVEL, mandatory );
if ( ( beans == null ) || ( beans.size() == 0 ) )
{
// If the element is mandatory, this is an error
if ( mandatory )
{
String message = "The composite " + beanAT.getName()
+ " is mandatory, and was not found under the "
+ "configuration entry " + entry.getDn();
LOG.error( message );
throw new ConfigurationException( message );
}
}
else
{
// Update the field
beanField.set( bean, beans );
}
}
}
else
// A standard AttributeType (ie, boolean, long, int or String)
{
// Process the field accordingly to its cardinality
if ( beanAT.isSingleValued() )
{
readSingleValueField( bean, beanField, fieldAttr, mandatory );
}
else
{
readMultiValuedField( bean, beanField, fieldAttr, mandatory );
}
}
}
}
/**
* Get the list of MUST AttributeTypes for an objectClass
*/
private Set<MutableAttributeTypeImpl> getAllMusts( ObjectClass objectClass )
{
Set<MutableAttributeTypeImpl> musts = new HashSet<MutableAttributeTypeImpl>();
// First, gets the direct MUST
musts.addAll( objectClass.getMustAttributeTypes() );
// then add all the superiors MUST (recursively)
List<ObjectClass> superiors = objectClass.getSuperiors();
if ( superiors != null )
{
for ( ObjectClass superior : superiors )
{
musts.addAll( getAllMusts( superior ) );
}
}
return musts;
}
/**
* Get the list of MAY AttributeTypes for an objectClass
*/
private Set<MutableAttributeTypeImpl> getAllMays( ObjectClass objectClass )
{
Set<MutableAttributeTypeImpl> mays = new HashSet<MutableAttributeTypeImpl>();
// First, gets the direct MAY
mays.addAll( objectClass.getMayAttributeTypes() );
// then add all the superiors MAY (recursively)
List<ObjectClass> superiors = objectClass.getSuperiors();
if ( superiors != null )
{
for ( ObjectClass superior : superiors )
{
mays.addAll( getAllMays( superior ) );
}
}
return mays;
}
/**
* Helper method to print a list of AT's names.
*/
private String dumpATs( Set<MutableAttributeTypeImpl> attributeTypes )
{
if ( ( attributeTypes == null ) || ( attributeTypes.size() == 0 ) )
{
return "";
}
StringBuilder sb = new StringBuilder();
boolean isFirst = true;
sb.append( '{' );
for ( MutableAttributeTypeImpl attributeType : attributeTypes )
{
if ( isFirst )
{
isFirst = false;
}
else
{
sb.append( ", " );
}
sb.append( attributeType.getName() );
}
sb.append( '}' );
return sb.toString();
}
/**
* Read some configuration element from the DIT using its name
*/
private List<AdsBaseBean> read( Dn baseDn, String name, SearchScope scope, boolean mandatory )
throws ConfigurationException
{
LOG.debug( "Reading from '{}', entry {}", baseDn, name );
// Search for the element starting at some point in the DIT
// Prepare the search request
MutableAttributeTypeImpl adsdAt = schemaManager.getAttributeType( SchemaConstants.OBJECT_CLASS_AT );
EqualityNode<?> filter = new EqualityNode( adsdAt, new StringValue( name ) );
SearchControls controls = new SearchControls();
controls.setSearchScope( scope.ordinal() );
IndexCursor<Long, Entry, Long> cursor = null;
// Create a container for all the read beans
List<AdsBaseBean> beans = new ArrayList<AdsBaseBean>();
try
{
// Do the search
cursor = se.cursor( baseDn, AliasDerefMode.NEVER_DEREF_ALIASES, filter, controls );
// First, check if we have some entries to process.
if ( !cursor.next() )
{
if ( mandatory )
{
cursor.close();
// the requested element is mandatory so let's throw an exception
String message = "No directoryService instance was configured under the Dn "
+ configPartition.getSuffix();
LOG.error( message );
throw new ConfigurationException( message );
}
else
{
return null;
}
}
// Loop on all the found elements
do
{
ForwardIndexEntry<Long, Entry, Long> forwardEntry = ( ForwardIndexEntry<Long, Entry, Long> ) cursor
.get();
// Now, get the entry
Entry entry = configPartition.lookup( forwardEntry.getId() );
LOG.debug( "Entry read : {}", entry );
// Let's instanciate the bean we need. The upper ObjectClass's name
// will be used to do that
EntryAttribute objectClassAttr = entry.get( SchemaConstants.OBJECT_CLASS_AT );
ObjectClass objectClass = findObjectClass( objectClassAttr );
AdsBaseBean bean = createBean( objectClass );
// Now, read the AttributeTypes and store the values into the bean fields
// The MAY
Set<MutableAttributeTypeImpl> mays = getAllMays( objectClass );
LOG.debug( "Fetching the following MAY attributes : {}", dumpATs( mays ) );
readFields( bean, entry, mays, OPTIONNAL );
// The MUST
Set<MutableAttributeTypeImpl> musts = getAllMusts( objectClass );
LOG.debug( "Fetching the following MAY attributes : {}", dumpATs( musts ) );
readFields( bean, entry, musts, MANDATORY );
bean.setDn( entry.getDn() );
// Done, we can add the bean into the list
beans.add( bean );
}
while ( cursor.next() );
}
catch ( ConfigurationException ce )
{
ce.printStackTrace();
throw ce;
}
catch ( Exception e )
{
String message = "Cannot open a cursor to read the configuration on " + baseDn;
LOG.error( message );
throw new ConfigurationException( message );
}
finally
{
if ( cursor != null )
{
try
{
cursor.close();
}
catch ( Exception e )
{
// So ??? If the cursor can't be close, there is nothing we can do
// but rethrow the exception
throw new ConfigurationException( e.getMessage(), e.getCause() );
}
}
}
return beans;
}
/**
* Read the configuration from the DIT, returning a bean containing all of it.
* <p>
* This method implicitly uses <em>"ou=config"</em> as base Dn
*
* @return The Config bean, containing the whole configuration
* @throws ConfigurationException If we had some issue reading the configuration
*/
public ConfigBean readConfig() throws LdapException
{
// The starting point is the DirectoryService element
return readConfig( new Dn( new Rdn( SchemaConstants.OU_AT, "config" ) ) );
}
/**
* Read the configuration from the DIT, returning a bean containing all of it.
*
* @param base The base Dn in the DIT where the configuration is stored
* @return The Config bean, containing the whole configuration
* @throws ConfigurationException If we had some issue reading the configuration
*/
public ConfigBean readConfig( String baseDn ) throws LdapException
{
// The starting point is the DirectoryService element
return readConfig( new Dn( baseDn ), ConfigSchemaConstants.ADS_DIRECTORY_SERVICE_OC.getValue() );
}
/**
* Read the configuration from the DIT, returning a bean containing all of it.
*
* @param base The base Dn in the DIT where the configuration is stored
* @return The Config bean, containing the whole configuration
* @throws ConfigurationException If we had some issue reading the configuration
*/
public ConfigBean readConfig( Dn baseDn ) throws ConfigurationException
{
// The starting point is the DirectoryService element
return readConfig( baseDn, ConfigSchemaConstants.ADS_DIRECTORY_SERVICE_OC.getValue() );
}
/**
* Read the configuration from the DIT, returning a bean containing all of it.
*
* @param baseDn The base Dn in the DIT where the configuration is stored
* @param objectClass The element to read from the DIT
* @return The bean containing the configuration for the required element
* @throws ConfigurationException
*/
public ConfigBean readConfig( String baseDn, String objectClass ) throws LdapException
{
return readConfig( new Dn( baseDn ), objectClass );
}
/**
* Read the configuration from the DIT, returning a bean containing all of it.
*
* @param baseDn The base Dn in the DIT where the configuration is stored
* @param objectClass The element to read from the DIT
* @return The bean containing the configuration for the required element
* @throws ConfigurationException
*/
public ConfigBean readConfig( Dn baseDn, String objectClass ) throws ConfigurationException
{
LOG.debug( "Reading configuration for the {} element, from {} ", objectClass, baseDn );
ConfigBean configBean = new ConfigBean();
if ( baseDn == null )
{
baseDn = configPartition.getSuffix();
}
List<AdsBaseBean> beans = read( baseDn, objectClass, SearchScope.ONELEVEL, MANDATORY );
if ( LOG.isDebugEnabled() )
{
if ( ( beans == null ) || ( beans.size() == 0 ) )
{
LOG.debug( "No {} element to read", objectClass );
}
else
{
LOG.debug( beans.get( 0 ).toString() );
}
}
configBean.setDirectoryServiceBeans( beans );
return configBean;
}
}