001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020 021package org.apache.directory.server.config; 022 023 024import java.lang.reflect.Array; 025import java.lang.reflect.Constructor; 026import java.lang.reflect.Field; 027import java.lang.reflect.InvocationTargetException; 028import java.lang.reflect.Method; 029import java.lang.reflect.ParameterizedType; 030import java.lang.reflect.Type; 031import java.util.ArrayList; 032import java.util.Collection; 033import java.util.HashSet; 034import java.util.List; 035import java.util.Set; 036 037import org.apache.directory.api.ldap.model.constants.SchemaConstants; 038import org.apache.directory.api.ldap.model.cursor.Cursor; 039import org.apache.directory.api.ldap.model.entry.Attribute; 040import org.apache.directory.api.ldap.model.entry.Entry; 041import org.apache.directory.api.ldap.model.entry.Value; 042import org.apache.directory.api.ldap.model.exception.LdapException; 043import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException; 044import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException; 045import org.apache.directory.api.ldap.model.filter.EqualityNode; 046import org.apache.directory.api.ldap.model.message.AliasDerefMode; 047import org.apache.directory.api.ldap.model.message.SearchScope; 048import org.apache.directory.api.ldap.model.name.Dn; 049import org.apache.directory.api.ldap.model.name.Rdn; 050import org.apache.directory.api.ldap.model.schema.AttributeType; 051import org.apache.directory.api.ldap.model.schema.ObjectClass; 052import org.apache.directory.api.ldap.model.schema.SchemaManager; 053import org.apache.directory.server.config.beans.AdsBaseBean; 054import org.apache.directory.server.config.beans.ConfigBean; 055import org.apache.directory.server.core.api.interceptor.context.SearchOperationContext; 056import org.apache.directory.server.core.api.partition.PartitionTxn; 057import org.apache.directory.server.core.partition.impl.btree.AbstractBTreePartition; 058import org.apache.directory.server.i18n.I18n; 059import org.apache.directory.server.xdbm.IndexEntry; 060import org.apache.directory.server.xdbm.search.PartitionSearchResult; 061import org.apache.directory.server.xdbm.search.SearchEngine; 062import org.slf4j.Logger; 063import org.slf4j.LoggerFactory; 064 065 066/** 067 * A class used for reading the configuration present in a Partition 068 * and instantiate the necessary objects like DirectoryService, Interceptors etc. 069 * 070 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 071 */ 072public class ConfigPartitionReader 073{ 074 /** The logger for this class */ 075 private static final Logger LOG = LoggerFactory.getLogger( ConfigPartitionReader.class ); 076 077 /** the partition which holds the configuration data */ 078 private AbstractBTreePartition configPartition; 079 080 /** the search engine of the partition */ 081 private SearchEngine se; 082 083 /** the schema manager set in the config partition */ 084 private SchemaManager schemaManager; 085 086 /** The prefix for all the configuration ObjectClass names */ 087 private static final String ADS_PREFIX = "ads-"; 088 089 /** The suffix for the bean */ 090 private static final String ADS_SUFFIX = "Bean"; 091 092 093 /** 094 * 095 * Creates a new instance of ConfigPartitionReader. 096 * 097 * @param configPartition the non null config partition 098 */ 099 public ConfigPartitionReader( AbstractBTreePartition configPartition ) 100 { 101 if ( configPartition == null ) 102 { 103 throw new IllegalArgumentException( I18n.err( I18n.ERR_503 ) ); 104 } 105 106 if ( !configPartition.isInitialized() ) 107 { 108 throw new IllegalStateException( I18n.err( I18n.ERR_504 ) ); 109 } 110 111 this.configPartition = configPartition; 112 se = configPartition.getSearchEngine(); 113 this.schemaManager = configPartition.getSchemaManager(); 114 } 115 116 117 /** 118 * Find the upper objectclass in a hierarchy. All the inherited ObjectClasses 119 * will be removed. 120 */ 121 private ObjectClass findObjectClass( Attribute objectClass ) throws Exception 122 { 123 Set<ObjectClass> candidates = new HashSet<ObjectClass>(); 124 125 try 126 { 127 // Create the set of candidates 128 for ( Value ocValue : objectClass ) 129 { 130 String ocName = ocValue.getValue(); 131 String ocOid = schemaManager.getObjectClassRegistry().getOidByName( ocName ); 132 ObjectClass oc = schemaManager.getObjectClassRegistry().get( ocOid ); 133 134 if ( oc.isStructural() ) 135 { 136 candidates.add( oc ); 137 } 138 } 139 } 140 catch ( Exception e ) 141 { 142 throw e; 143 } 144 145 // Now find the parent OC 146 for ( Value ocValue : objectClass ) 147 { 148 String ocName = ocValue.getValue(); 149 String ocOid = schemaManager.getObjectClassRegistry().getOidByName( ocName ); 150 ObjectClass oc = schemaManager.getObjectClassRegistry().get( ocOid ); 151 152 for ( ObjectClass superior : oc.getSuperiors() ) 153 { 154 if ( oc.isStructural() ) 155 { 156 if ( candidates.contains( superior ) ) 157 { 158 candidates.remove( superior ); 159 } 160 } 161 } 162 } 163 164 // The remaining OC in the candidates set is the one we are looking for 165 ObjectClass result = candidates.toArray( new ObjectClass[] 166 {} )[0]; 167 168 LOG.debug( "The top level object class is {}", result.getName() ); 169 return result; 170 } 171 172 173 /** 174 * Create the base Bean from the ObjectClass name. 175 * The bean name is constructed using the OjectClass name, by 176 * removing the ADS prefix, upper casing the first letter and adding "Bean" at the end. 177 * 178 * For instance, ads-directoryService wil become DirectoryServiceBean 179 */ 180 private AdsBaseBean createBean( ObjectClass objectClass ) throws ConfigurationException 181 { 182 // The remaining OC in the candidates set is the one we are looking for 183 String objectClassName = objectClass.getName(); 184 185 // Now, let's instantiate the associated bean. Get rid of the 'ads-' in front of the name, 186 // and uppercase the first letter. Finally add "Bean" at the end and add the package. 187 //String beanName = this.getClass().getPackage().getName() + "org.apache.directory.server.config.beans." + Character.toUpperCase( objectClassName.charAt( 4 ) ) + objectClassName.substring( 5 ) + "Bean"; 188 String beanName = this.getClass().getPackage().getName() + ".beans." 189 + Character.toUpperCase( objectClassName.charAt( ADS_PREFIX.length() ) ) 190 + objectClassName.substring( ADS_PREFIX.length() + 1 ) + ADS_SUFFIX; 191 192 try 193 { 194 Class<?> clazz = Class.forName( beanName ); 195 Constructor<?> constructor = clazz.getConstructor(); 196 AdsBaseBean bean = ( AdsBaseBean ) constructor.newInstance(); 197 198 LOG.debug( "Bean {} created for ObjectClass {}", beanName, objectClassName ); 199 200 return bean; 201 } 202 catch ( ClassNotFoundException cnfe ) 203 { 204 String message = "Cannot find a Bean class for the ObjectClass name " + objectClassName; 205 LOG.error( message ); 206 throw new ConfigurationException( message ); 207 } 208 catch ( SecurityException se ) 209 { 210 String message = "Cannot access to the class " + beanName; 211 LOG.error( message ); 212 throw new ConfigurationException( message ); 213 } 214 catch ( NoSuchMethodException nsme ) 215 { 216 String message = "Cannot find a constructor for the class " + beanName; 217 LOG.error( message ); 218 throw new ConfigurationException( message ); 219 } 220 catch ( InvocationTargetException ite ) 221 { 222 String message = "Cannot invoke the class " + beanName + ", " + ite.getMessage(); 223 LOG.error( message ); 224 throw new ConfigurationException( message ); 225 } 226 catch ( IllegalAccessException iae ) 227 { 228 String message = "Cannot access to the constructor for class " + beanName; 229 LOG.error( message ); 230 throw new ConfigurationException( message ); 231 } 232 catch ( InstantiationException ie ) 233 { 234 String message = "Cannot instantiate the class " + beanName + ", " + ie.getMessage(); 235 LOG.error( message ); 236 throw new ConfigurationException( message ); 237 } 238 } 239 240 241 /** 242 * Read the single entry value for an AttributeType, and feed the Bean field with this value 243 */ 244 private void readSingleValueField( AdsBaseBean bean, Field beanField, Attribute fieldAttr ) 245 throws ConfigurationException 246 { 247 if ( fieldAttr == null ) 248 { 249 return; 250 } 251 252 253 Value value = fieldAttr.get(); 254 String valueStr = ""; 255 256 if ( value != null ) 257 { 258 valueStr = value.getValue(); 259 } 260 261 Class<?> type = beanField.getType(); 262 263 // Process the value accordingly to its type. 264 try 265 { 266 if ( type == String.class ) 267 { 268 beanField.set( bean, valueStr ); 269 } 270 else if ( type == byte[].class ) 271 { 272 beanField.set( bean, value.getBytes() ); 273 } 274 else if ( type == int.class ) 275 { 276 beanField.setInt( bean, Integer.parseInt( valueStr ) ); 277 } 278 else if ( type == long.class ) 279 { 280 beanField.setLong( bean, Long.parseLong( valueStr ) ); 281 } 282 else if ( type == boolean.class ) 283 { 284 beanField.setBoolean( bean, Boolean.parseBoolean( valueStr ) ); 285 } 286 else if ( type == Dn.class ) 287 { 288 try 289 { 290 Dn dn = new Dn( valueStr ); 291 beanField.set( bean, dn ); 292 } 293 catch ( LdapInvalidDnException lide ) 294 { 295 String message = "The Dn '" + valueStr + "' for attribute " + fieldAttr.getId() 296 + " is not a valid Dn"; 297 LOG.error( message ); 298 throw new ConfigurationException( message ); 299 } 300 } 301 } 302 catch ( IllegalArgumentException iae ) 303 { 304 String message = "Cannot store '" + valueStr + "' into attribute " + fieldAttr.getId(); 305 LOG.error( message ); 306 throw new ConfigurationException( message ); 307 } 308 catch ( IllegalAccessException e ) 309 { 310 String message = "Cannot store '" + valueStr + "' into attribute " + fieldAttr.getId(); 311 LOG.error( message ); 312 throw new ConfigurationException( message ); 313 } 314 } 315 316 317 /** 318 * Read the multiple entry value for an AttributeType, and feed the Bean field with this value 319 */ 320 private void readMultiValuedField( AdsBaseBean bean, Field field, Attribute attribute ) 321 throws ConfigurationException 322 { 323 if ( attribute == null ) 324 { 325 return; 326 } 327 328 Class<?> type = field.getType(); 329 330 String fieldName = field.getName(); 331 String addMethodName = "add" + Character.toUpperCase( fieldName.charAt( 0 ) ) + fieldName.substring( 1 ); 332 333 // loop on the values and inject them in the bean 334 for ( Value value : attribute ) 335 { 336 String valueStr = value.getValue(); 337 338 try 339 { 340 if ( type == String.class ) 341 { 342 field.set( bean, valueStr ); 343 } 344 else if ( type == int.class ) 345 { 346 field.setInt( bean, Integer.parseInt( valueStr ) ); 347 } 348 else if ( type == long.class ) 349 { 350 field.setLong( bean, Long.parseLong( valueStr ) ); 351 } 352 else if ( type == boolean.class ) 353 { 354 field.setBoolean( bean, Boolean.parseBoolean( valueStr ) ); 355 } 356 else if ( type == Dn.class ) 357 { 358 try 359 { 360 Dn dn = new Dn( valueStr ); 361 field.set( bean, dn ); 362 } 363 catch ( LdapInvalidDnException lide ) 364 { 365 String message = "The Dn '" + valueStr + "' for attribute " + attribute.getId() 366 + " is not a valid Dn"; 367 LOG.error( message ); 368 throw new ConfigurationException( message ); 369 } 370 } 371 else if ( type == Set.class ) 372 { 373 Type genericFieldType = field.getGenericType(); 374 Class<?> fieldArgClass = null; 375 376 if ( genericFieldType instanceof ParameterizedType ) 377 { 378 ParameterizedType parameterizedType = ( ParameterizedType ) genericFieldType; 379 Type[] fieldArgTypes = parameterizedType.getActualTypeArguments(); 380 381 for ( Type fieldArgType : fieldArgTypes ) 382 { 383 fieldArgClass = ( Class<?> ) fieldArgType; 384 } 385 } 386 387 Method method = bean.getClass().getMethod( addMethodName, 388 Array.newInstance( fieldArgClass, 0 ).getClass() ); 389 390 method.invoke( bean, new Object[] 391 { new String[] 392 { valueStr } } ); 393 } 394 else if ( type == List.class ) 395 { 396 Type genericFieldType = field.getGenericType(); 397 Class<?> fieldArgClass = null; 398 399 if ( genericFieldType instanceof ParameterizedType ) 400 { 401 ParameterizedType parameterizedType = ( ParameterizedType ) genericFieldType; 402 Type[] fieldArgTypes = parameterizedType.getActualTypeArguments(); 403 404 for ( Type fieldArgType : fieldArgTypes ) 405 { 406 fieldArgClass = ( Class<?> ) fieldArgType; 407 } 408 } 409 410 Method method = bean.getClass().getMethod( addMethodName, 411 Array.newInstance( fieldArgClass, 0 ).getClass() ); 412 413 method.invoke( bean, new Object[] 414 { new String[] 415 { valueStr } } ); 416 } 417 } 418 catch ( IllegalArgumentException iae ) 419 { 420 String message = "Cannot store '" + valueStr + "' into attribute " + attribute.getId(); 421 LOG.error( message ); 422 throw new ConfigurationException( message ); 423 } 424 catch ( IllegalAccessException e ) 425 { 426 String message = "Cannot store '" + valueStr + "' into attribute " + attribute.getId(); 427 LOG.error( message ); 428 throw new ConfigurationException( message ); 429 } 430 catch ( SecurityException se ) 431 { 432 String message = "Cannot access to the class " + bean.getClass().getName(); 433 LOG.error( message ); 434 throw new ConfigurationException( message ); 435 } 436 catch ( NoSuchMethodException nsme ) 437 { 438 String message = "Cannot find a method " + addMethodName + " in the class " + bean.getClass().getName(); 439 LOG.error( message ); 440 throw new ConfigurationException( message ); 441 } 442 catch ( InvocationTargetException ite ) 443 { 444 String message = "Cannot invoke the class " + bean.getClass().getName() + ", " + ite.getMessage(); 445 LOG.error( message ); 446 throw new ConfigurationException( message ); 447 } 448 catch ( NegativeArraySizeException nase ) 449 { 450 // No way that can happen... 451 } 452 } 453 } 454 455 456 private void readFieldValue( AdsBaseBean bean, Field field, Entry entry, String attributeTypeName, boolean mandatory ) 457 throws ConfigurationException 458 { 459 // Get the entry attribute for this attribute type 460 Attribute attribute = entry.get( attributeTypeName ); 461 462 if ( attribute != null ) 463 { 464 if ( attribute.size() > 0 ) 465 { 466 if ( !isMultiple( field.getType() ) ) 467 { 468 readSingleValueField( bean, field, attribute ); 469 } 470 else 471 { 472 readMultiValuedField( bean, field, attribute ); 473 } 474 } 475 else if ( attribute.size() == 0 ) 476 { 477 // No value ? May be valid 478 readSingleValueField( bean, field, attribute ); 479 } 480 else if ( mandatory ) 481 { 482 // the requested element is mandatory so let's throw an exception 483 String message = "No value was configured for entry with DN '" 484 + entry.getDn() + "' and attribute type '" + attributeTypeName + "'."; 485 LOG.error( message ); 486 throw new ConfigurationException( message ); 487 } 488 } 489 else 490 { 491 if ( mandatory ) 492 { 493 // the requested element is mandatory so let's throw an exception 494 String message = "No value was configured for entry with DN '" 495 + entry.getDn() + "' and attribute type '" + attributeTypeName + "'."; 496 LOG.error( message ); 497 throw new ConfigurationException( message ); 498 } 499 } 500 } 501 502 503 /** 504 * Read some configuration element from the DIT using its name 505 * 506 * @param baseDn The base Dn in the DIT where the configuration is stored 507 * @param name The element to read 508 * @param scope The search scope 509 * @param mandatory If the element is mandatory or not 510 * @return The list of beans read 511 * @throws ConfigurationException If the configuration cannot be read 512 */ 513 public List<AdsBaseBean> read( Dn baseDn, String name, SearchScope scope, boolean mandatory ) 514 throws ConfigurationException 515 { 516 LOG.debug( "Reading from '{}', objectClass '{}'", baseDn, name ); 517 518 // Search for the element starting at some point in the DIT 519 // Prepare the search request 520 AttributeType ocAt = schemaManager.getAttributeType( SchemaConstants.OBJECT_CLASS_AT ); 521 EqualityNode<String> filter = null; 522 523 try 524 { 525 filter = new EqualityNode<>( ocAt, new Value( ocAt, name ) ); 526 } 527 catch ( LdapInvalidAttributeValueException liave ) 528 { 529 throw new ConfigurationException( liave.getMessage() ); 530 } 531 532 Cursor<IndexEntry<String, String>> cursor = null; 533 534 // Create a container for all the read beans 535 List<AdsBaseBean> beansList = new ArrayList<>(); 536 537 try 538 { 539 // Do the search 540 541 try ( PartitionTxn partitionTxn = configPartition.beginReadTransaction() ) 542 { 543 SearchOperationContext searchContext = new SearchOperationContext( null ); 544 searchContext.setAliasDerefMode( AliasDerefMode.NEVER_DEREF_ALIASES ); 545 searchContext.setDn( baseDn ); 546 searchContext.setFilter( filter ); 547 searchContext.setScope( scope ); 548 searchContext.setPartition( configPartition ); 549 searchContext.setTransaction( partitionTxn ); 550 PartitionSearchResult searchResult = se.computeResult( partitionTxn, schemaManager, searchContext ); 551 552 cursor = searchResult.getResultSet(); 553 554 // First, check if we have some entries to process. 555 if ( !cursor.next() ) 556 { 557 if ( mandatory ) 558 { 559 cursor.close(); 560 561 // the requested element is mandatory so let's throw an exception 562 String message = "No instance was configured under the DN '" 563 + baseDn + "' for the objectClass '" + name + "'."; 564 LOG.error( message ); 565 throw new ConfigurationException( message ); 566 } 567 else 568 { 569 return null; 570 } 571 } 572 573 // Loop on all the found elements 574 do 575 { 576 IndexEntry<String, String> forwardEntry = cursor.get(); 577 578 // Now, get the entry 579 Entry entry = configPartition.fetch( partitionTxn, forwardEntry.getId() ); 580 LOG.debug( "Entry read : {}", entry ); 581 582 AdsBaseBean bean = readConfig( entry ); 583 // Adding the bean to the list 584 beansList.add( bean ); 585 } 586 while ( cursor.next() ); 587 } 588 } 589 catch ( ConfigurationException ce ) 590 { 591 throw ce; 592 } 593 catch ( Exception e ) 594 { 595 String message = "An error occured while reading the configuration DN '" 596 + baseDn + "' for the objectClass '" + name + "':\n" + e.getMessage(); 597 LOG.error( message ); 598 throw new ConfigurationException( message, e ); 599 } 600 finally 601 { 602 if ( cursor != null ) 603 { 604 try 605 { 606 cursor.close(); 607 } 608 catch ( Exception e ) 609 { 610 // So ??? If the cursor can't be close, there is nothing we can do 611 // but rethrow the exception 612 throw new ConfigurationException( e.getMessage(), e.getCause() ); 613 } 614 } 615 } 616 617 return beansList; 618 } 619 620 621 /** 622 * Creates a configuration bean from the given entry. 623 * 624 * @param entry any configuration entry of the type "ads-base" 625 * @return The ApacheDS base configuration 626 * @throws Exception If the configuration cannot be read 627 */ 628 public AdsBaseBean readConfig( Entry entry ) throws Exception 629 { 630 // Let's instantiate the bean we need. The upper ObjectClass's name 631 // will be used to do that 632 ObjectClass objectClass = findObjectClass( entry.get( SchemaConstants.OBJECT_CLASS_AT ) ); 633 634 // Instantiating the bean 635 AdsBaseBean bean = createBean( objectClass ); 636 637 // Setting its DN 638 bean.setDn( entry.getDn() ); 639 640 // Getting the class of the bean 641 Class<?> beanClass = bean.getClass(); 642 643 // A flag to know when we reached the 'AdsBaseBean' class when 644 // looping on the class hierarchy of the bean 645 boolean adsBaseBeanClassFound = false; 646 647 // Looping until the 'AdsBaseBean' class has been found 648 while ( !adsBaseBeanClassFound ) 649 { 650 // Checking if we reached the 'AdsBaseBean' class 651 if ( beanClass == AdsBaseBean.class ) 652 { 653 adsBaseBeanClassFound = true; 654 } 655 656 // Looping on all fields of the bean 657 Field[] fields = beanClass.getDeclaredFields(); 658 for ( Field field : fields ) 659 { 660 // Making the field accessible (we get an exception if we don't do that) 661 field.setAccessible( true ); 662 663 // Getting the class of the field 664 Class<?> fieldClass = field.getType(); 665 666 // Looking for the @ConfigurationElement annotation 667 ConfigurationElement configurationElement = field.getAnnotation( ConfigurationElement.class ); 668 if ( configurationElement != null ) 669 { 670 // Getting the annotation's values 671 String fieldAttributeType = configurationElement.attributeType(); 672 String fieldObjectClass = configurationElement.objectClass(); 673 String container = configurationElement.container(); 674 boolean isOptional = configurationElement.isOptional(); 675 676 // Checking if we have a value for the attribute type 677 if ( ( fieldAttributeType != null ) && ( !"".equals( fieldAttributeType ) ) ) 678 { 679 readFieldValue( bean, field, entry, fieldAttributeType, !isOptional ); 680 } 681 // Checking if we have a value for the object class 682 else if ( ( fieldObjectClass != null ) && ( !"".equals( fieldObjectClass ) ) ) 683 { 684 // Checking if this is a multi-valued field (which values are stored in a container) 685 if ( isMultiple( fieldClass ) && ( container != null ) 686 && ( !"".equals( container ) ) ) 687 { 688 // Creating the DN of the container 689 Dn newBase = entry.getDn().add( "ou=" + container ); 690 691 // Looking for the field values 692 Collection<AdsBaseBean> fieldValues = read( newBase, fieldObjectClass, 693 SearchScope.ONELEVEL, !isOptional ); 694 695 // Setting the values to the field 696 if ( ( fieldValues != null ) && ( fieldValues.size() > 0 ) ) 697 { 698 field.set( bean, fieldValues ); 699 } 700 } 701 // This is a single-value field 702 else 703 { 704 // Looking for the field values 705 List<AdsBaseBean> fieldValues = read( entry.getDn(), fieldObjectClass, 706 SearchScope.ONELEVEL, !isOptional ); 707 708 // Setting the value to the field 709 if ( ( fieldValues != null ) && ( fieldValues.size() > 0 ) ) 710 { 711 field.set( bean, fieldValues.get( 0 ) ); 712 } 713 } 714 } 715 } 716 } 717 718 // Moving to the upper class in the class hierarchy 719 beanClass = beanClass.getSuperclass(); 720 } 721 722 return bean; 723 } 724 725 726 /** 727 * Indicates the given type is multiple. 728 * 729 * @param clazz 730 * the class 731 * @return 732 * <code>true</code> if the given is multiple, 733 * <code>false</code> if not. 734 */ 735 private boolean isMultiple( Class<?> clazz ) 736 { 737 return Collection.class.isAssignableFrom( clazz ); 738 } 739 740 741 /** 742 * Read the configuration from the DIT, returning a bean containing all of it. 743 * <p> 744 * This method implicitly uses <em>"ou=config"</em> as base Dn 745 * 746 * @return The Config bean, containing the whole configuration 747 * @throws ConfigurationException If we had some issue reading the configuration 748 */ 749 public ConfigBean readConfig() throws LdapException 750 { 751 // The starting point is the DirectoryService element 752 return readConfig( new Dn( new Rdn( SchemaConstants.OU_AT, "config" ) ) ); 753 } 754 755 756 /** 757 * Read the configuration from the DIT, returning a bean containing all of it. 758 * 759 * @param baseDn The base Dn in the DIT where the configuration is stored 760 * @return The Config bean, containing the whole configuration 761 * @throws ConfigurationException If we had some issue reading the configuration 762 */ 763 public ConfigBean readConfig( String baseDn ) throws LdapException 764 { 765 // The starting point is the DirectoryService element 766 return readConfig( new Dn( baseDn ) ); 767 } 768 769 770 /** 771 * Read the configuration from the DIT, returning a bean containing all of it. 772 * 773 * @param baseDn The base Dn in the DIT where the configuration is stored 774 * @return The Config bean, containing the whole configuration 775 * @throws ConfigurationException If we had some issue reading the configuration 776 */ 777 public ConfigBean readConfig( Dn baseDn ) throws ConfigurationException 778 { 779 // The starting point is the DirectoryService element 780 return readConfig( baseDn, ConfigSchemaConstants.ADS_DIRECTORY_SERVICE_OC.getValue() ); 781 } 782 783 784 /** 785 * Read the configuration from the DIT, returning a bean containing all of it. 786 * 787 * @param baseDn The base Dn in the DIT where the configuration is stored 788 * @param objectClass The element to read from the DIT 789 * @return The bean containing the configuration for the required element 790 * @throws ConfigurationException If the configuration cannot be read 791 */ 792 public ConfigBean readConfig( String baseDn, String objectClass ) throws LdapException 793 { 794 return readConfig( new Dn( baseDn ), objectClass ); 795 } 796 797 798 /** 799 * Read the configuration from the DIT, returning a bean containing all of it. 800 * 801 * @param baseDn The base Dn in the DIT where the configuration is stored 802 * @param objectClass The element to read from the DIT 803 * @return The bean containing the configuration for the required element 804 * @throws ConfigurationException If the configuration cannot be read 805 */ 806 public ConfigBean readConfig( Dn baseDn, String objectClass ) throws ConfigurationException 807 { 808 LOG.debug( "Reading configuration for the {} element, from {} ", objectClass, baseDn ); 809 ConfigBean configBean = new ConfigBean(); 810 811 if ( baseDn == null ) 812 { 813 baseDn = configPartition.getSuffixDn(); 814 } 815 816 List<AdsBaseBean> beans = read( baseDn, objectClass, SearchScope.ONELEVEL, true ); 817 818 if ( LOG.isDebugEnabled() ) 819 { 820 if ( ( beans == null ) || ( beans.size() == 0 ) ) 821 { 822 LOG.debug( "No {} element to read", objectClass ); 823 } 824 else 825 { 826 LOG.debug( beans.get( 0 ).toString() ); 827 } 828 } 829 830 configBean.setDirectoryServiceBeans( beans ); 831 832 return configBean; 833 } 834}