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 );