You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2010/10/25 23:37:48 UTC

svn commit: r1027277 - in /directory/apacheds/branches/apacheds-config/server-config/src: main/java/org/apache/directory/server/config/ main/java/org/apache/directory/server/config/beans/ test/java/org/apache/directory/server/config/

Author: elecharny
Date: Mon Oct 25 21:37:47 2010
New Revision: 1027277

URL: http://svn.apache.org/viewvc?rev=1027277&view=rev
Log:
o Added logs
o Added Exceptions
o Added corener cases handling
o Dealt with case sensitive fields

Modified:
    directory/apacheds/branches/apacheds-config/server-config/src/main/java/org/apache/directory/server/config/ConfigPartitionReader.java
    directory/apacheds/branches/apacheds-config/server-config/src/main/java/org/apache/directory/server/config/beans/ConfigBean.java
    directory/apacheds/branches/apacheds-config/server-config/src/test/java/org/apache/directory/server/config/ConfigPartitionReaderTest.java

Modified: directory/apacheds/branches/apacheds-config/server-config/src/main/java/org/apache/directory/server/config/ConfigPartitionReader.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-config/server-config/src/main/java/org/apache/directory/server/config/ConfigPartitionReader.java?rev=1027277&r1=1027276&r2=1027277&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-config/server-config/src/main/java/org/apache/directory/server/config/ConfigPartitionReader.java (original)
+++ directory/apacheds/branches/apacheds-config/server-config/src/main/java/org/apache/directory/server/config/ConfigPartitionReader.java Mon Oct 25 21:37:47 2010
@@ -90,6 +90,7 @@ import org.apache.directory.shared.ldap.
 import org.apache.directory.shared.ldap.entry.StringValue;
 import org.apache.directory.shared.ldap.entry.Value;
 import org.apache.directory.shared.ldap.exception.LdapException;
+import org.apache.directory.shared.ldap.exception.LdapInvalidDnException;
 import org.apache.directory.shared.ldap.filter.EqualityNode;
 import org.apache.directory.shared.ldap.filter.PresenceNode;
 import org.apache.directory.shared.ldap.filter.SearchScope;
@@ -130,6 +131,12 @@ public class ConfigPartitionReader
 
     /** the parent directory of the config partition's working directory */
     private File workDir;
+    
+    /** 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";
 
     /** LDIF file filter */
     private FilenameFilter ldifFilter = new FilenameFilter()
@@ -649,14 +656,24 @@ public class ConfigPartitionReader
     }
     
     
-    private AdsBaseBean readBean( ObjectClass objectClass ) throws Exception
+    /** 
+     * 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 = "org.apache.directory.server.config.beans." + Character.toUpperCase( objectClassName.charAt( 4 ) ) + objectClassName.substring( 5 ) + "Bean";
+        //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
         {
@@ -664,55 +681,77 @@ public class ConfigPartitionReader
             Constructor<?> constructor = clazz.getConstructor();
             AdsBaseBean bean = (AdsBaseBean)constructor.newInstance();
             
+            LOG.debug( "Bean {} created for ObjectClass {}", beanName, objectClassName );
+            
             return bean;
         } 
         catch ( ClassNotFoundException cnfe )
         {
-            cnfe.printStackTrace();
+            String message = "Cannot find a Bean class for the ObjectClass name " + objectClassName;
+            LOG.error( message );
+            throw new ConfigurationException( message );
         }
-        catch (SecurityException se)
+        catch ( SecurityException se )
         {
-            se.printStackTrace();
+            String message = "Cannot access to the class " + beanName;
+            LOG.error( message );
+            throw new ConfigurationException( message );
         } 
-        catch (NoSuchMethodException nsme)
+        catch ( NoSuchMethodException nsme )
         {
-            nsme.printStackTrace();
+            String message = "Cannot find a constructor for the class " + beanName;
+            LOG.error( message );
+            throw new ConfigurationException( message );
         }
         catch ( InvocationTargetException ite )
         {
-            ite.printStackTrace();
+            String message = "Cannot invoke the class " + beanName + ", " + ite.getMessage();
+            LOG.error( message );
+            throw new ConfigurationException( message );
         }
         catch ( IllegalAccessException iae )
         {
-            iae.printStackTrace();
+            String message = "Cannot access to the constructor for class " + beanName;
+            LOG.error( message );
+            throw new ConfigurationException( message );
         }
         catch ( InstantiationException ie )
         {
-            ie.printStackTrace();
+            String message = "Cannot instanciate the class " + beanName + ", " + ie.getMessage();
+            LOG.error( message );
+            throw new ConfigurationException( message );
         }
-        
-        return null;
     }
+    
 
-    private static Field getField ( Class<?> clazz, String fieldName ) throws NoSuchFieldException 
+    /**
+     * Retrieve the Field associated with an AttributeType name, if any.
+     */
+    private static Field getField( Class<?> clazz, String attributeName ) throws ConfigurationException 
     {
-        try 
-        {
-            return clazz.getDeclaredField( fieldName );
-        } 
-        catch ( NoSuchFieldException e ) 
+        // 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 )
         {
-            Class<?> superClass = clazz.getSuperclass();
+            String fieldName = field.getName();
             
-            if ( superClass == null ) 
-            {
-                throw e;
-            } 
-            else 
+            if ( fieldName.equalsIgnoreCase( attributeName ) )
             {
-                return getField( superClass, fieldName );
+                return field;
             }
         }
+        
+        // May be in the paren'ts class ?
+        if ( clazz.getSuperclass() != null )
+        {
+            return getField( clazz.getSuperclass(), attributeName );
+        }
+        
+        String message = "Cannot find a field named " + attributeName + " in class " + clazz.getName();
+        LOG.error( message );
+        throw new ConfigurationException( message );
     }
     
     
@@ -734,7 +773,10 @@ public class ConfigPartitionReader
     }
     
     
-    private void readSingleValueField( AdsBaseBean bean, Field beanField, EntryAttribute fieldAttr, boolean mandatory ) throws Exception
+    /**
+     * 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 )
         {
@@ -745,26 +787,59 @@ public class ConfigPartitionReader
         String valueStr = value.getString();
         Class<?> type = beanField.getType();
         
-        if ( type == String.class )
-        {
-            beanField.set( bean, value.getString() );
-        }
-        else if ( type == int.class )
+        // Process the value accordingly to its type.
+        try
         {
-            beanField.setInt( bean, Integer.parseInt( valueStr )  );
+            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 == long.class )
+        catch ( IllegalArgumentException iae )
         {
-            beanField.setLong( bean, Long.parseLong( valueStr )  );
+            String message = "Cannot store '" + valueStr + "' into attribute " + fieldAttr.getId(); ;
+            LOG.error( message );
+            throw new ConfigurationException( message );
         }
-        else if ( type == boolean.class )
+        catch ( IllegalAccessException e )
         {
-            beanField.setBoolean( bean, Boolean.parseBoolean( valueStr ) );
+            String message = "Cannot store '" + valueStr + "' into attribute " + fieldAttr.getId(); ;
+            LOG.error( message );
+            throw new ConfigurationException( message );
         }
     }
     
     
-    private void readMultiValuedField( AdsBaseBean bean, Field beanField, EntryAttribute fieldAttr, boolean mandatory ) throws Exception
+    /**
+     * 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 )
         {
@@ -778,67 +853,120 @@ public class ConfigPartitionReader
         {
             String valueStr = value.getString();
             
-            if ( type == String.class )
+            try
             {
-                beanField.set( bean, value.getString() );
+                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( "add" + beanField.getName(), 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( "add" + beanField.getName(), Array.newInstance( fieldArgClass, 0 ).getClass() );
+    
+                    method.invoke( bean, new Object[]{ new String[]{valueStr} } );
+                }
             }
-            else if ( type == int.class )
+            catch ( IllegalArgumentException iae )
             {
-                beanField.setInt( bean, Integer.parseInt( valueStr )  );
+                String message = "Cannot store '" + valueStr + "' into attribute " + fieldAttr.getId(); ;
+                LOG.error( message );
+                throw new ConfigurationException( message );
             }
-            else if ( type == long.class )
+            catch ( IllegalAccessException e )
             {
-                beanField.setLong( bean, Long.parseLong( valueStr )  );
+                String message = "Cannot store '" + valueStr + "' into attribute " + fieldAttr.getId(); ;
+                LOG.error( message );
+                throw new ConfigurationException( message );
             }
-            else if ( type == boolean.class )
+            catch ( SecurityException se )
             {
-                beanField.setBoolean( bean, Boolean.parseBoolean( valueStr ) );
+                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 constructor for the class " + bean.getClass().getName();
+                LOG.error( message );
+                throw new ConfigurationException( message );
             }
-            else if ( type == Set.class )
+            catch ( InvocationTargetException ite )
             {
-                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( "add" + beanField.getName(), Array.newInstance( fieldArgClass, 0 ).getClass() );
-
-                method.invoke( bean, new Object[]{ new String[]{valueStr} } );
+                String message = "Cannot invoke the class " + bean.getClass().getName() + ", " + ite.getMessage();
+                LOG.error( message );
+                throw new ConfigurationException( message );
             }
-            else if ( type == List.class )
+            catch ( NegativeArraySizeException nase )
             {
-                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( "add" + beanField.getName(), Array.newInstance( fieldArgClass, 0 ).getClass() );
-
-                method.invoke( bean, new Object[]{ new String[]{valueStr} } );
+                // No way that can happen...
             }
         }
-
     }
 
     
+    /**
+     * Read all the required fields (AttributeTypes) for a given Entry.
+     */
     private void readFields( AdsBaseBean bean, Entry entry, Set<AttributeType> attributeTypes, boolean mandatory ) throws NoSuchFieldException, IllegalAccessException, Exception
     {
         for ( AttributeType attributeType : attributeTypes )
@@ -847,13 +975,15 @@ public class ConfigPartitionReader
             String beanFieldName = fieldName;
             
             // Remove the "ads-" from the beginning of the field name
-            if ( fieldName.startsWith( "ads-" ) )
+            if ( fieldName.startsWith( ADS_PREFIX ) )
             {
-                beanFieldName = fieldName.substring( 4 );
+                beanFieldName = fieldName.substring( ADS_PREFIX.length() );
             }
             
             // Get the field
             Field beanField = getField( bean.getClass(), StringTools.toLowerCase( beanFieldName ) );
+            
+            // 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
@@ -861,10 +991,12 @@ public class ConfigPartitionReader
             
             if ( ( fieldAttr == null ) && ( mandatory ) )
             {
-                System.out.println( "!!! Attribute " + fieldName + " is mandatory and is not present for the Entry " + entry.getDn() );
-                continue;
+                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
             AttributeType beanAT = schemaManager.getAttributeType( fieldName );
             
             // Check if this AT has the ads-compositeElement as a superior
@@ -876,23 +1008,35 @@ public class ConfigPartitionReader
                 // First, check if it's a SingleValued element
                 if ( beanAT.isSingleValued() )
                 {
-                    // Yes : get the first element if it's mandatory
-                    //DN newBase = entry.getDn().add( "ou=" + beanFieldName );
+                    // 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 !
-                            System.out.println( "ERROR !!!" );
-                            throw new Exception();
+                            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 );
                     }
                 }
@@ -905,17 +1049,42 @@ public class ConfigPartitionReader
                     // 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 );
-                    beanField.set( bean, beans );
+                    
+                    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
+            else // A standard AttributeType (ie, boolean, long, int or String)
             {
                 // Process the field accordingly to its cardinality
                 if ( beanAT.isSingleValued() )
@@ -1066,7 +1235,7 @@ public class ConfigPartitionReader
                 EntryAttribute objectClassAttr = entry.get( SchemaConstants.OBJECT_CLASS_AT );
                 
                 ObjectClass objectClass = findObjectClass( objectClassAttr );
-                AdsBaseBean bean = readBean( objectClass );
+                AdsBaseBean bean = createBean( objectClass );
                 
                 // Now, read the AttributeTypes and store the values into the bean fields
                 // The MAY
@@ -1084,6 +1253,11 @@ public class ConfigPartitionReader
             }
             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;
@@ -1300,6 +1474,8 @@ public class ConfigPartitionReader
         
         configBean.setDirectoryServiceBeans( beans );
         
+        System.out.println( configBean );
+        
         return configBean;
     }
     

Modified: directory/apacheds/branches/apacheds-config/server-config/src/main/java/org/apache/directory/server/config/beans/ConfigBean.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-config/server-config/src/main/java/org/apache/directory/server/config/beans/ConfigBean.java?rev=1027277&r1=1027276&r2=1027277&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-config/server-config/src/main/java/org/apache/directory/server/config/beans/ConfigBean.java (original)
+++ directory/apacheds/branches/apacheds-config/server-config/src/main/java/org/apache/directory/server/config/beans/ConfigBean.java Mon Oct 25 21:37:47 2010
@@ -69,4 +69,20 @@ public class ConfigBean 
     {
         this.directoryServiceBeans = directoryServiceBeans;
     }
+    
+    
+    /**
+     * {@inheritDoc}
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+     
+        for ( AdsBaseBean directoryService : directoryServiceBeans )
+        {
+            sb.append( directoryService ).append( "\n\n" );
+        }
+        
+        return sb.toString();
+    }
 }

Modified: directory/apacheds/branches/apacheds-config/server-config/src/test/java/org/apache/directory/server/config/ConfigPartitionReaderTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-config/server-config/src/test/java/org/apache/directory/server/config/ConfigPartitionReaderTest.java?rev=1027277&r1=1027276&r2=1027277&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-config/server-config/src/test/java/org/apache/directory/server/config/ConfigPartitionReaderTest.java (original)
+++ directory/apacheds/branches/apacheds-config/server-config/src/test/java/org/apache/directory/server/config/ConfigPartitionReaderTest.java Mon Oct 25 21:37:47 2010
@@ -131,7 +131,7 @@ public class ConfigPartitionReaderTest
         ConfigPartitionReader cpReader = new ConfigPartitionReader( configPartition, workDir );
         
         ConfigBean configBean = cpReader.readConfig( "ou=config" );
-
+        
         assertNotNull( configBean );
         DirectoryServiceBean directoryServiceBean = (DirectoryServiceBean)configBean.getDirectoryServiceBeans().get( 0 );
         assertNotNull( directoryServiceBean );