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 2015/03/25 14:26:31 UTC

svn commit: r1669123 [6/6] - in /directory/studio/trunk/plugins: ./ openldap.config.editor/ openldap.config.editor/resources/ openldap.config.editor/resources/icons/ openldap.config.editor/src/ openldap.config.editor/src/main/ openldap.config.editor/sr...

Added: directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/model/OlcSyncProvConfig.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/model/OlcSyncProvConfig.java?rev=1669123&view=auto
==============================================================================
--- directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/model/OlcSyncProvConfig.java (added)
+++ directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/model/OlcSyncProvConfig.java Wed Mar 25 13:26:29 2015
@@ -0,0 +1,104 @@
+package org.apache.directory.studio.openldap.config.model;
+
+
+/**
+ * Java bean for the 'olcSyncProvConfig' object class.
+ */
+public class OlcSyncProvConfig extends OlcOverlayConfig
+{
+    /**
+     * Field for the 'olcSpCheckpoint' attribute.
+     */
+    @ConfigurationElement(attributeType = "olcSpCheckpoint")
+    private String olcSpCheckpoint;
+
+    /**
+     * Field for the 'olcSpNoPresent' attribute.
+     */
+    @ConfigurationElement(attributeType = "olcSpNoPresent")
+    private Boolean olcSpNoPresent;
+
+    /**
+     * Field for the 'olcSpReloadHint' attribute.
+     */
+    @ConfigurationElement(attributeType = "olcSpReloadHint")
+    private Boolean olcSpReloadHint;
+
+    /**
+     * Field for the 'olcSpSessionlog' attribute.
+     */
+    @ConfigurationElement(attributeType = "olcSpSessionlog")
+    private Integer olcSpSessionlog;
+
+
+    /**
+     * @return the olcSpCheckpoint
+     */
+    public String getOlcSpCheckpoint()
+    {
+        return olcSpCheckpoint;
+    }
+
+
+    /**
+     * @return the olcSpNoPresent
+     */
+    public Boolean getOlcSpNoPresent()
+    {
+        return olcSpNoPresent;
+    }
+
+
+    /**
+     * @return the olcSpReloadHint
+     */
+    public Boolean getOlcSpReloadHint()
+    {
+        return olcSpReloadHint;
+    }
+
+
+    /**
+     * @return the olcSpSessionlog
+     */
+    public Integer getOlcSpSessionlog()
+    {
+        return olcSpSessionlog;
+    }
+
+
+    /**
+     * @param olcSpCheckpoint the olcSpCheckpoint to set
+     */
+    public void setOlcSpCheckpoint( String olcSpCheckpoint )
+    {
+        this.olcSpCheckpoint = olcSpCheckpoint;
+    }
+
+
+    /**
+     * @param olcSpNoPresent the olcSpNoPresent to set
+     */
+    public void setOlcSpNoPresent( Boolean olcSpNoPresent )
+    {
+        this.olcSpNoPresent = olcSpNoPresent;
+    }
+
+
+    /**
+     * @param olcSpReloadHint the olcSpReloadHint to set
+     */
+    public void setOlcSpReloadHint( Boolean olcSpReloadHint )
+    {
+        this.olcSpReloadHint = olcSpReloadHint;
+    }
+
+
+    /**
+     * @param olcSpSessionlog the olcSpSessionlog to set
+     */
+    public void setOlcSpSessionlog( Integer olcSpSessionlog )
+    {
+        this.olcSpSessionlog = olcSpSessionlog;
+    }
+}

Added: directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/model/OpenLdapConfiguration.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/model/OpenLdapConfiguration.java?rev=1669123&view=auto
==============================================================================
--- directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/model/OpenLdapConfiguration.java (added)
+++ directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/model/OpenLdapConfiguration.java Wed Mar 25 13:26:29 2015
@@ -0,0 +1,68 @@
+package org.apache.directory.studio.openldap.config.model;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * This class implements the basic class for an OpenLDAP configuration.
+ * <p>
+ * It contains all the configuration objects found under the "cn=config" branch. 
+ */
+public class OpenLdapConfiguration
+{
+    private List<OlcConfig> configurationElements = new ArrayList<OlcConfig>();
+
+
+    /**
+     * @return the configurationElements
+     */
+    public List<OlcConfig> getConfigurationElements()
+    {
+        return configurationElements;
+    }
+
+
+    /**
+     * @param e
+     * @return
+     * @see java.util.List#add(java.lang.Object)
+     */
+    public boolean add( OlcConfig o )
+    {
+        return configurationElements.add( o );
+    }
+
+
+    /**
+     * @param o
+     * @return
+     * @see java.util.List#contains(java.lang.Object)
+     */
+    public boolean contains( OlcConfig o )
+    {
+        return configurationElements.contains( o );
+    }
+
+
+    /**
+     * @param o
+     * @return
+     * @see java.util.List#remove(java.lang.Object)
+     */
+    public boolean remove( OlcConfig o )
+    {
+        return configurationElements.remove( o );
+    }
+
+
+    /**
+     * @return
+     * @see java.util.List#size()
+     */
+    public int size()
+    {
+        return configurationElements.size();
+    }
+}

Added: directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/model/io/ConfigurationException.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/model/io/ConfigurationException.java?rev=1669123&view=auto
==============================================================================
--- directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/model/io/ConfigurationException.java (added)
+++ directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/model/io/ConfigurationException.java Wed Mar 25 13:26:29 2015
@@ -0,0 +1,49 @@
+package org.apache.directory.studio.openldap.config.model.io;
+
+
+import org.apache.directory.api.ldap.model.exception.LdapException;
+
+
+/**
+ * An exception used when we cannot read the configuration, or when an error
+ * occured while reading it from the DIT.
+ */
+public class ConfigurationException extends LdapException
+{
+    /** The serial version UUID */
+    private static final long serialVersionUID = 1L;
+
+
+    /**
+     * Creates a new instance of ConfigurationException.
+     *
+     * @param message The exception message
+     */
+    public ConfigurationException( String message )
+    {
+        super( message );
+    }
+
+
+    /**
+     * Creates a new instance of ConfigurationException.
+     *
+     * @param cause the original cause
+     */
+    public ConfigurationException( Throwable cause )
+    {
+        super( cause );
+    }
+
+
+    /**
+     * Creates a new instance of ConfigurationException.
+     *
+     * @param message The exception message
+     * @param cause the original cause
+     */
+    public ConfigurationException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+}

Added: directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/model/io/ConfigurationReader.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/model/io/ConfigurationReader.java?rev=1669123&view=auto
==============================================================================
--- directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/model/io/ConfigurationReader.java (added)
+++ directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/model/io/ConfigurationReader.java Wed Mar 25 13:26:29 2015
@@ -0,0 +1,638 @@
+package org.apache.directory.studio.openldap.config.model.io;
+
+
+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.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.naming.directory.SearchResult;
+
+import org.apache.directory.api.ldap.model.constants.SchemaConstants;
+import org.apache.directory.api.ldap.model.entry.Attribute;
+import org.apache.directory.api.ldap.model.entry.AttributeUtils;
+import org.apache.directory.api.ldap.model.entry.DefaultEntry;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.entry.Value;
+import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
+import org.apache.directory.api.ldap.model.exception.LdapNoSuchObjectException;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.api.ldap.model.schema.ObjectClass;
+import org.apache.directory.api.ldap.model.schema.SchemaManager;
+import org.apache.directory.studio.common.core.jobs.StudioProgressMonitor;
+import org.apache.directory.studio.connection.core.io.StudioNamingEnumeration;
+import org.apache.directory.studio.ldapbrowser.core.BrowserCorePlugin;
+import org.apache.directory.studio.ldapbrowser.core.jobs.SearchRunnable;
+import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection;
+import org.apache.directory.studio.ldapbrowser.core.model.SearchParameter;
+import org.apache.directory.studio.ldapbrowser.core.model.schema.Schema;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+
+import org.apache.directory.studio.openldap.config.editor.ConnectionServerConfigurationInput;
+import org.apache.directory.studio.openldap.config.editor.ServerConfigurationEditorUtils;
+import org.apache.directory.studio.openldap.config.jobs.EntryBasedConfigurationPartition;
+import org.apache.directory.studio.openldap.config.model.AuxiliaryObjectClass;
+import org.apache.directory.studio.openldap.config.model.ConfigurationElement;
+import org.apache.directory.studio.openldap.config.model.OlcConfig;
+import org.apache.directory.studio.openldap.config.model.OpenLdapConfiguration;
+
+
+/**
+ * This class implements a configuration reader for OpenLDAP.
+ */
+public class ConfigurationReader
+{
+    private static final String MODEL_PACKAGE_NAME = "org.apache.directory.studio.openldap.config.model";
+
+
+    public static OpenLdapConfiguration readConfiguration( ConnectionServerConfigurationInput input ) throws Exception
+    {
+        // Creating a new OpenLDAP configuration
+        OpenLdapConfiguration configuration = new OpenLdapConfiguration();
+
+        // Getting the browser connection associated with the connection in the input
+        IBrowserConnection browserConnection = BrowserCorePlugin.getDefault().getConnectionManager()
+            .getBrowserConnection( input.getConnection() );
+
+        // Reading the configuration entries on the server
+        List<Entry> configurationEntries = readEntries( input, browserConnection );
+
+        // For each configuration entries we create an associated configuration
+        // object and store it in the OpenLDAP configuration
+        for ( Entry entry : configurationEntries )
+        {
+            OlcConfig configurationObject = createConfigurationObject( entry, browserConnection.getSchema() );
+            if ( configurationObject != null )
+            {
+                configuration.add( configurationObject );
+            }
+        }
+
+        return configuration;
+    }
+
+
+    /**
+     * Gets the highest structural object class found in the attribute.
+     *
+     * @param objectClassAttribute the 'objectClass' attribute
+     * @param schema the schema associated with the connection
+     * @return the highest structural object class found in the attribute.
+     */
+    public static ObjectClass getHighestStructuralObjectClass( Attribute objectClassAttribute, Schema schema )
+    {
+        Set<ObjectClass> candidates = new HashSet<ObjectClass>();
+
+        if ( ( objectClassAttribute != null ) && ( schema != null ) )
+        {
+            // Create the set of candidates
+            for ( Value<?> objectClassValue : objectClassAttribute )
+            {
+                ObjectClass oc = schema.getObjectClassDescription( objectClassValue.getString() );
+                if ( oc.isStructural() )
+                {
+                    candidates.add( oc );
+                }
+            }
+
+            // Now find the parent OC
+            for ( Value<?> objectClassValue : objectClassAttribute )
+            {
+                String ocName = objectClassValue.getString();
+                ObjectClass oc = schema.getObjectClassDescription( ocName );
+
+                for ( String superiorName : oc.getSuperiorOids() )
+                {
+                    ObjectClass superior = schema.getObjectClassDescription( superiorName );
+                    if ( superior != null )
+                    {
+                        if ( oc.isStructural() )
+                        {
+                            if ( candidates.contains( superior ) )
+                            {
+                                candidates.remove( superior );
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        // The remaining OC in the candidates set is the one we are looking for
+        return candidates.toArray( new ObjectClass[]
+            {} )[0];
+    }
+
+
+    /**
+     * Gets the highest object class found in the attribute.
+     *
+     * @param objectClassAttribute the 'objectClass' attribute
+     * @param schema the schema associated with the connection
+     * @return the highest object class found in the attribute.
+     */
+    public static ObjectClass[] getAuxiliaryObjectClasses( Attribute objectClassAttribute, Schema schema )
+    {
+        List<ObjectClass> auxiliaryObjectClasses = new ArrayList<ObjectClass>();
+
+        if ( ( objectClassAttribute != null ) && ( schema != null ) )
+        {
+            for ( Value<?> objectClassValue : objectClassAttribute )
+            {
+                ObjectClass oc = schema.getObjectClassDescription( objectClassValue.getString() );
+                if ( oc.isAuxiliary() )
+                {
+                    auxiliaryObjectClasses.add( oc );
+                }
+            }
+        }
+
+        return auxiliaryObjectClasses.toArray( new ObjectClass[0] );
+    }
+
+
+    public static List<Entry> readEntries( ConnectionServerConfigurationInput input,
+        IBrowserConnection browserConnection ) throws Exception
+    {
+        List<Entry> foundEntries = new ArrayList<Entry>();
+
+        IProgressMonitor progressMonitor = new NullProgressMonitor();
+        StudioProgressMonitor monitor = new StudioProgressMonitor( progressMonitor );
+
+        // Creating the schema manager
+        SchemaManager schemaManager = ServerConfigurationEditorUtils.createSchemaManager( input.getConnection() );
+
+        // The DN corresponding to the configuration base
+        Dn configBaseDn = new Dn( "cn=config" ); // TODO Change this
+
+        // Creating the configuration partition
+        EntryBasedConfigurationPartition configurationPartition = ServerConfigurationEditorUtils
+            .createConfigurationPartition( schemaManager, configBaseDn );
+
+        // Creating the search parameter
+        SearchParameter configSearchParameter = new SearchParameter();
+        configSearchParameter.setSearchBase( configBaseDn );
+        configSearchParameter.setFilter( "(objectClass=*)" );
+        configSearchParameter.setScope( SearchScope.OBJECT );
+        configSearchParameter.setReturningAttributes( SchemaConstants.ALL_USER_ATTRIBUTES_ARRAY );
+
+        // Looking for the 'ou=config' base entry
+        Entry configEntry = null;
+        StudioNamingEnumeration enumeration = SearchRunnable.search( browserConnection, configSearchParameter,
+            monitor );
+
+        // Checking if an error occurred
+        if ( monitor.errorsReported() )
+        {
+            throw monitor.getException();
+        }
+
+        // Getting the entry
+        if ( enumeration.hasMore() )
+        {
+            // Creating the 'ou=config' base entry
+            SearchResult searchResult = ( SearchResult ) enumeration.next();
+            configEntry = new DefaultEntry( schemaManager, AttributeUtils.toEntry( searchResult.getAttributes(),
+                new Dn( searchResult.getNameInNamespace() ) ) );
+        }
+        enumeration.close();
+
+        // Verifying we found the 'ou=config' base entry
+        if ( configEntry == null )
+        {
+            throw new LdapNoSuchObjectException( "Unable to find the 'ou=config' base entry." );
+        }
+
+        // Creating a list to hold the entries that needs to be checked
+        // for children and added to the partition
+        List<Entry> entries = new ArrayList<Entry>();
+        entries.add( configEntry );
+
+        // Looping on the entries list until it's empty
+        while ( !entries.isEmpty() )
+        {
+            // Removing the first entry from the list
+            Entry entry = entries.remove( 0 );
+
+            // Adding the entry to the partition and the entries list
+            configurationPartition.addEntry( entry );
+            foundEntries.add( entry );
+
+            SearchParameter searchParameter = new SearchParameter();
+            searchParameter.setSearchBase( entry.getDn() );
+            searchParameter.setFilter( "(objectClass=*)" );
+            searchParameter.setScope( SearchScope.ONELEVEL );
+            searchParameter.setReturningAttributes( SchemaConstants.ALL_USER_ATTRIBUTES_ARRAY );
+
+            // Looking for the children of the entry
+            StudioNamingEnumeration childrenEnumeration = SearchRunnable.search( browserConnection,
+                searchParameter, monitor );
+
+            // Checking if an error occurred
+            if ( monitor.errorsReported() )
+            {
+                throw monitor.getException();
+            }
+
+            while ( childrenEnumeration.hasMore() )
+            {
+                // Creating the child entry
+                SearchResult searchResult = ( SearchResult ) childrenEnumeration.next();
+                Entry childEntry = new DefaultEntry( schemaManager, AttributeUtils.toEntry(
+                    searchResult.getAttributes(),
+                    new Dn( searchResult.getNameInNamespace() ) ) );
+
+                // Adding the children to the list of entries
+                entries.add( childEntry );
+            }
+            childrenEnumeration.close();
+        }
+
+        // Setting the created partition to the input
+        input.setOriginalPartition( configurationPartition );
+
+        return foundEntries;
+    }
+
+
+    private static OlcConfig createConfigurationObject( Entry entry, Schema schema )
+        throws ConfigurationException
+    {
+        // Getting the 'objectClass' attribute
+        Attribute objectClassAttribute = entry.get( SchemaConstants.OBJECT_CLASS_AT );
+        if ( objectClassAttribute != null )
+        {
+            // Getting the highest structural object class based on schema
+            ObjectClass highestStructuralObjectClass = getHighestStructuralObjectClass( objectClassAttribute, schema );
+
+            // Computing the class name for the bean corresponding to the structural object class
+            String highestObjectClassName = highestStructuralObjectClass.getName();
+            String className = MODEL_PACKAGE_NAME + "."
+                + Character.toUpperCase( highestObjectClassName.charAt( 0 ) ) +
+                highestObjectClassName.substring( 1 );
+
+            // Instantiating the object
+            OlcConfig bean = null;
+            try
+            {
+                Class<?> clazz = Class.forName( className );
+                Constructor<?> constructor = clazz.getConstructor();
+                bean = ( OlcConfig ) constructor.newInstance();
+            }
+            catch ( Exception e )
+            {
+                throw new ConfigurationException( e );
+            }
+
+            // Checking if the bean as been created
+            if ( bean == null )
+            {
+                throw new ConfigurationException( "The instantiated bean for '" + highestObjectClassName + "' is null" );
+            }
+
+            // Checking auxiliary object classes
+            ObjectClass[] auxiliaryObjectClasses = getAuxiliaryObjectClasses( objectClassAttribute, schema );
+            if ( ( auxiliaryObjectClasses != null ) && ( auxiliaryObjectClasses.length > 0 ) )
+            {
+                for ( ObjectClass auxiliaryObjectClass : auxiliaryObjectClasses )
+                {
+                    // Computing the class name for the bean corresponding to the auxiliary object class
+                    String auxiliaryObjectClassName = auxiliaryObjectClass.getName();
+                    className = MODEL_PACKAGE_NAME + "."
+                        + Character.toUpperCase( auxiliaryObjectClassName.charAt( 0 ) ) +
+                        auxiliaryObjectClassName.substring( 1 );
+
+                    // Instantiating the object
+                    AuxiliaryObjectClass auxiliaryObjectClassBean = null;
+                    try
+                    {
+                        Class<?> clazz = Class.forName( className );
+                        Constructor<?> constructor = clazz.getConstructor();
+                        auxiliaryObjectClassBean = ( AuxiliaryObjectClass ) constructor.newInstance();
+                    }
+                    catch ( Exception e )
+                    {
+                        throw new ConfigurationException( e );
+                    }
+
+                    // Checking if the bean as been created
+                    if ( auxiliaryObjectClassBean == null )
+                    {
+                        throw new ConfigurationException( "The instantiated auxiliary object class bean for '"
+                            + auxiliaryObjectClassName + "' is null" );
+                    }
+
+                    // Reading all values
+                    readValues( entry, auxiliaryObjectClassBean );
+
+                    // Adding the auxiliary object class bean to the bean
+                    bean.addAuxiliaryObjectClasses( auxiliaryObjectClassBean );
+                }
+            }
+
+            // Reading all values
+            readValues( entry, bean );
+
+            // Storing the parent DN
+            bean.setParentDn( entry.getDn().getParent() );
+
+            return bean;
+        }
+        return null;
+    }
+
+
+    /**
+     * Reads the values of the entry and saves them to the bean.
+     *
+     * @param entry the entry
+     * @param bean then bean
+     * @throws ConfigurationException
+     */
+    private static void readValues( Entry entry, Object bean ) throws ConfigurationException
+    {
+        // Checking all fields of the bean (including super class fields)
+        Class<?> clazz = bean.getClass();
+        while ( clazz != null )
+        {
+            // Looping on all fields of the class
+            Field[] fields = clazz.getDeclaredFields();
+            for ( Field field : fields )
+            {
+                // Looking for the @ConfigurationElement annotation
+                ConfigurationElement configurationElement = field.getAnnotation( ConfigurationElement.class );
+                if ( configurationElement != null )
+                {
+                    // Checking if we're have a value  for the attribute type
+                    String attributeType = configurationElement.attributeType();
+                    if ( ( attributeType != null ) && ( !"".equals( attributeType ) ) )
+                    {
+                        Attribute attribute = entry.get( attributeType );
+                        if ( ( attribute != null ) && ( attribute.size() > 0 ) )
+                        {
+                            // Making the field accessible (we get an exception if we don't do that)
+                            field.setAccessible( true );
+
+                            // loop on the values and inject them in the bean
+                            for ( Value<?> value : attribute )
+                            {
+                                readAttributeValue( bean, field, attribute, value );
+                            }
+                        }
+                    }
+                }
+            }
+
+            // Switching to the super class
+            clazz = clazz.getSuperclass();
+        }
+    }
+
+
+    /**
+     * Reads the attribute value.
+     *
+     * @param bean the bean
+     * @param field the field
+     * @param attribute the attribute
+     * @param value the value
+     * @throws ConfigurationException
+     */
+    private static void readAttributeValue( Object bean, Field field, Attribute attribute, Value<?> value )
+        throws ConfigurationException
+    {
+        Class<?> type = field.getType();
+        String addMethodName = "add" + Character.toUpperCase( field.getName().charAt( 0 ) )
+            + field.getName().substring( 1 );
+        String valueStr = value.getString();
+
+        try
+        {
+            // String class
+            if ( type == String.class )
+            {
+                Object stringValue = readSingleValue( type, attribute, valueStr );
+                if ( stringValue != null )
+                {
+                    field.set( bean, stringValue );
+                }
+            }
+            // Int primitive type
+            else if ( type == int.class )
+            {
+                Object integerValue = readSingleValue( type, attribute, valueStr );
+                if ( integerValue != null )
+                {
+                    field.setInt( bean, ( ( Integer ) integerValue ).intValue() );
+                }
+            }
+            // Integer class
+            else if ( type == Integer.class )
+            {
+                Object integerValue = readSingleValue( type, attribute, valueStr );
+                if ( integerValue != null )
+                {
+                    field.set( bean, ( Integer ) integerValue );
+                }
+            }
+            // Long primitive type
+            else if ( type == long.class )
+            {
+                Object longValue = readSingleValue( type, attribute, valueStr );
+                if ( longValue != null )
+                {
+                    field.setLong( bean, ( ( Long ) longValue ).longValue() );
+                }
+            }
+            // Long class
+            else if ( type == Long.class )
+            {
+                Object longValue = readSingleValue( type, attribute, valueStr );
+                if ( longValue != null )
+                {
+                    field.setLong( bean, ( Long ) longValue );
+                }
+            }
+            // Boolean primitive type
+            else if ( type == boolean.class )
+            {
+                Object booleanValue = readSingleValue( type, attribute, valueStr );
+                if ( booleanValue != null )
+                {
+                    field.setBoolean( bean, ( ( Boolean ) booleanValue ).booleanValue() );
+                }
+            }
+            // Boolean class
+            else if ( type == Boolean.class )
+            {
+                Object booleanValue = readSingleValue( type, attribute, valueStr );
+                if ( booleanValue != null )
+                {
+                    field.set( bean, ( Boolean ) booleanValue );
+                }
+            }
+            // Dn class
+            else if ( type == Dn.class )
+            {
+                Object dnValue = readSingleValue( type, attribute, valueStr );
+                if ( dnValue != null )
+                {
+                    field.set( bean, dnValue );
+                }
+            }
+            // Set class
+            else if ( type == Set.class )
+            {
+                Type genericFieldType = field.getGenericType();
+
+                if ( genericFieldType instanceof ParameterizedType )
+                {
+                    ParameterizedType parameterizedType = ( ParameterizedType ) genericFieldType;
+                    Type[] fieldArgTypes = parameterizedType.getActualTypeArguments();
+                    if ( ( fieldArgTypes != null ) && ( fieldArgTypes.length > 0 ) )
+                    {
+                        Class<?> fieldArgClass = ( Class<?> ) fieldArgTypes[0];
+
+                        Object methodParameter = Array.newInstance( fieldArgClass, 1 );
+                        Array.set( methodParameter, 0, readSingleValue( fieldArgClass, attribute, valueStr ) );
+
+                        Method method = bean.getClass().getMethod( addMethodName, methodParameter.getClass() );
+
+                        method.invoke( bean, new Object[]
+                            { methodParameter } );
+                    }
+                }
+            }
+            // List class
+            else if ( type == List.class )
+            {
+                Type genericFieldType = field.getGenericType();
+
+                if ( genericFieldType instanceof ParameterizedType )
+                {
+                    ParameterizedType parameterizedType = ( ParameterizedType ) genericFieldType;
+                    Type[] fieldArgTypes = parameterizedType.getActualTypeArguments();
+                    if ( ( fieldArgTypes != null ) && ( fieldArgTypes.length > 0 ) )
+                    {
+                        Class<?> fieldArgClass = ( Class<?> ) fieldArgTypes[0];
+
+                        Object methodParameter = Array.newInstance( fieldArgClass, 1 );
+                        Array.set( methodParameter, 0, readSingleValue( fieldArgClass, attribute, valueStr ) );
+
+                        Method method = bean.getClass().getMethod( addMethodName, methodParameter.getClass() );
+
+                        method.invoke( bean, new Object[]
+                            { methodParameter } );
+                    }
+                }
+            }
+        }
+        catch ( IllegalArgumentException iae )
+        {
+            throw new ConfigurationException( "Cannot store '" + valueStr + "' into attribute "
+                + attribute.getId() );
+        }
+        catch ( IllegalAccessException e )
+        {
+            throw new ConfigurationException( "Cannot store '" + valueStr + "' into attribute "
+                + attribute.getId() );
+        }
+        catch ( SecurityException se )
+        {
+            throw new ConfigurationException( "Cannot access to the class "
+                + bean.getClass().getName() );
+        }
+        catch ( NoSuchMethodException nsme )
+        {
+            throw new ConfigurationException( "Cannot find a method " + addMethodName
+                + " in the class "
+                + bean.getClass().getName() );
+        }
+        catch ( InvocationTargetException ite )
+        {
+            throw new ConfigurationException( "Cannot invoke the class "
+                + bean.getClass().getName() + ", "
+                + ite.getMessage() );
+        }
+        catch ( NegativeArraySizeException nase )
+        {
+            // No way that can happen...
+        }
+    }
+
+
+    /**
+     * Reads a single value attribute.
+     *
+     * @param field the field
+     * @param attribute the attribute
+     * @param value the value as a String
+     * @throws ConfigurationException
+     */
+    private static Object readSingleValue( Class<?> type, Attribute attribute, String value )
+        throws ConfigurationException
+    {
+        try
+        {
+            // String class
+            if ( type == String.class )
+            {
+                return value;
+            }
+            // Int primitive type
+            else if ( type == int.class )
+            {
+                return new Integer( value );
+            }
+            // Integer class
+            else if ( type == Integer.class )
+            {
+                return new Integer( value );
+            }
+            // Long class
+            else if ( type == long.class )
+            {
+                return new Long( value );
+            }
+            // Boolean primitive type
+            else if ( type == boolean.class )
+            {
+                return new Boolean( value );
+            }
+            // Boolean class
+            else if ( type == Boolean.class )
+            {
+                return new Boolean( value );
+            }
+            // Dn class
+            else if ( type == Dn.class )
+            {
+                try
+                {
+                    return new Dn( value );
+                }
+                catch ( LdapInvalidDnException lide )
+                {
+                    throw new ConfigurationException( "The Dn '" + value + "' for attribute " + attribute.getId()
+                        + " is not a valid Dn" );
+                }
+            }
+
+            return null;
+        }
+        catch ( IllegalArgumentException iae )
+        {
+            throw new ConfigurationException( "Cannot store '" + value + "' into attribute "
+                + attribute.getId() );
+        }
+    }
+}

Added: directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/model/io/ConfigurationWriter.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/model/io/ConfigurationWriter.java?rev=1669123&view=auto
==============================================================================
--- directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/model/io/ConfigurationWriter.java (added)
+++ directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/model/io/ConfigurationWriter.java Wed Mar 25 13:26:29 2015
@@ -0,0 +1,514 @@
+package org.apache.directory.studio.openldap.config.model.io;
+
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.directory.api.ldap.model.constants.SchemaConstants;
+import org.apache.directory.api.ldap.model.entry.Attribute;
+import org.apache.directory.api.ldap.model.entry.DefaultAttribute;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
+import org.apache.directory.api.ldap.model.ldif.LdifEntry;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.api.ldap.model.name.Rdn;
+import org.apache.directory.api.ldap.model.schema.ObjectClass;
+import org.apache.directory.studio.ldapbrowser.core.model.schema.Schema;
+
+import org.apache.directory.studio.openldap.config.model.ConfigurationElement;
+import org.apache.directory.studio.openldap.config.model.OlcConfig;
+import org.apache.directory.studio.openldap.config.model.OpenLdapConfiguration;
+
+
+/**
+ * This class implements a configuration reader for OpenLDAP.
+ */
+public class ConfigurationWriter
+{
+    /** The schema */
+    private Schema schema;
+
+    /** The configuration */
+    private OpenLdapConfiguration configuration;
+
+    /** The list of entries */
+    private List<LdifEntry> entries;
+
+
+    /**
+     * Creates a new instance of ConfigWriter.
+     *
+     * @param schema
+     *      the schema
+     * @param configuration
+     *      the configuration
+     */
+    public ConfigurationWriter( Schema schema, OpenLdapConfiguration configuration )
+    {
+        this.schema = schema;
+        this.configuration = configuration;
+    }
+
+
+    /**
+     * Converts the configuration bean to a list of LDIF entries.
+     */
+    private void convertConfigurationBeanToLdifEntries() throws ConfigurationException
+    {
+        try
+        {
+            if ( entries == null )
+            {
+                entries = new ArrayList<LdifEntry>();
+
+                for ( OlcConfig configurationBean : configuration.getConfigurationElements() )
+                {
+                    addConfigurationBean( configurationBean );
+                }
+            }
+        }
+        catch ( Exception e )
+        {
+            throw new ConfigurationException( "Unable to convert the configuration bean to LDIF entries", e );
+        }
+    }
+
+
+    private void addConfigurationBean( OlcConfig configurationBean ) throws Exception
+    {
+        if ( configurationBean != null )
+        {
+            // Getting the class of the bean
+            Class<?> beanClass = configurationBean.getClass();
+
+            // Creating the entry to hold the bean and adding it to the list
+            LdifEntry entry = new LdifEntry();
+            entry.setDn( getDn( configurationBean ) );
+            addObjectClassAttribute( entry, getObjectClassNameForBean( beanClass ) );
+            entries.add( entry );
+
+            // A flag to know when we reached the 'OlcConfig' class when 
+            // looping on the class hierarchy of the bean
+            boolean olcConfigBeanClassFound = false;
+
+            // Looping until the 'OlcConfig' class has been found
+            while ( !olcConfigBeanClassFound )
+            {
+                // Checking if we reached the 'OlcConfig' class
+                if ( beanClass == OlcConfig.class )
+                {
+                    olcConfigBeanClassFound = true;
+                }
+
+                // Looping on all fields of the bean
+                Field[] fields = beanClass.getDeclaredFields();
+                for ( Field field : fields )
+                {
+                    // Making the field accessible (we get an exception if we don't do that)
+                    field.setAccessible( true );
+
+                    // Getting the class of the field
+                    Class<?> fieldClass = field.getType();
+                    Object fieldValue = field.get( configurationBean );
+
+                    if ( fieldValue != null )
+                    {
+                        // Looking for the @ConfigurationElement annotation
+                        ConfigurationElement configurationElement = field.getAnnotation( ConfigurationElement.class );
+                        if ( configurationElement != null )
+                        {
+                            // Checking if we have a value for the attribute type
+                            String attributeType = configurationElement.attributeType();
+                            if ( ( attributeType != null ) && ( !"".equals( attributeType ) ) )
+                            {
+                                // Checking if the field is optional and if the default value matches
+                                if ( configurationElement.isOptional() )
+                                {
+                                    if ( configurationElement.defaultValue().equalsIgnoreCase( fieldValue.toString() ) )
+                                    {
+                                        // Skipping the addition of the value
+                                        continue;
+                                    }
+                                }
+
+                                // Adding values to the entry
+                                addAttributeTypeValues( configurationElement.attributeType(), fieldValue, entry );
+
+                                continue;
+                            }
+
+                            // Checking if we're dealing with a AdsBaseBean subclass type
+                            if ( OlcConfig.class.isAssignableFrom( fieldClass ) )
+                            {
+                                addConfigurationBean( ( OlcConfig ) fieldValue );
+                                continue;
+                            }
+                        }
+                    }
+                }
+
+                // Moving to the upper class in the class hierarchy
+                beanClass = beanClass.getSuperclass();
+            }
+        }
+    }
+
+
+    /**
+     * Gets the Dn associated with the configuration bean.
+     *
+     * @param bean
+     *      the configuration bean
+     * @return
+     *      the Dn associated with the configuration bean based on the given base Dn.
+     * @throws LdapInvalidDnException
+     * @throws IllegalArgumentException
+     * @throws IllegalAccessException
+     */
+    private Dn getDn( OlcConfig bean ) throws LdapInvalidDnException, IllegalArgumentException,
+        IllegalAccessException
+    {
+        // Getting the class of the bean
+        Class<?> beanClass = bean.getClass();
+
+        // A flag to know when we reached the 'AdsBaseBean' class when 
+        // looping on the class hierarchy of the bean
+        boolean olcConfigBeanClassFound = false;
+
+        // Looping until the 'OlcConfig' class has been found
+        while ( !olcConfigBeanClassFound )
+        {
+            // Checking if we reached the 'OlcConfig' class
+            if ( beanClass == OlcConfig.class )
+            {
+                olcConfigBeanClassFound = true;
+            }
+
+            // Looping on all fields of the bean
+            Field[] fields = beanClass.getDeclaredFields();
+            for ( Field field : fields )
+            {
+                // Making the field accessible (we get an exception if we don't do that)
+                field.setAccessible( true );
+
+                // Looking for the @ConfigurationElement annotation and
+                // if the field is the Rdn
+                ConfigurationElement configurationElement = field.getAnnotation( ConfigurationElement.class );
+                if ( ( configurationElement != null ) && ( configurationElement.isRdn() ) )
+                {
+                    Object value = field.get( bean );
+                    if ( value == null )
+                    {
+                        continue;
+                    }
+
+                    // Is the value multiple?
+                    if ( isMultiple( value.getClass() ) )
+                    {
+                        Collection<?> values = ( Collection<?> ) value;
+                        if ( values.size() == 0 )
+                        {
+                            continue;
+                        }
+                        value = values.toArray()[0];
+                    }
+
+                    return bean.getParentDn().add( new Rdn( configurationElement.attributeType(), value.toString() ) );
+                }
+            }
+
+            // Moving to the upper class in the class hierarchy
+            beanClass = beanClass.getSuperclass();
+        }
+
+        return Dn.EMPTY_DN; // TODO Throw an error when we reach that point
+    }
+
+
+    /**
+     * Gets the name of the object class to use for the given bean class.
+     *
+     * @param c
+     *      the bean class
+     * @return
+     *      the name of the object class to use for the given bean class
+     */
+    private String getObjectClassNameForBean( Class<?> c )
+    {
+        String classNameWithPackage = getClassNameWithoutPackageName( c );
+        return Character.toLowerCase( classNameWithPackage.charAt( 0 ) ) + classNameWithPackage.substring( 1 );
+    }
+
+
+    /**
+     * Gets the class name of the given class stripped from its package name.
+     *
+     * @param c
+     *      the class
+     * @return
+     *      the class name of the given class stripped from its package name
+     */
+    private String getClassNameWithoutPackageName( Class<?> c )
+    {
+        String className = c.getName();
+
+        int firstChar = className.lastIndexOf( '.' ) + 1;
+        if ( firstChar > 0 )
+        {
+            return className.substring( firstChar );
+        }
+
+        return className;
+    }
+
+
+    /**
+     * Writes the configuration bean as LDIF to the given file.
+     *
+     * @param path
+     *      the output file path
+     * @throws ConfigurationException
+     *      if an error occurs during the conversion to LDIF
+     * @throws IOException
+     *      if an error occurs when writing the file
+     */
+    public void writeToPath( String path ) throws ConfigurationException, IOException
+    {
+        writeToFile( new File( path ) );
+    }
+
+
+    /**
+     * Writes the configuration bean as LDIF to the given file.
+     *
+     * @param file
+     *      the output file
+     * @throws ConfigurationException
+     *      if an error occurs during the conversion to LDIF
+     * @throws IOException
+     *      if an error occurs when writing the file
+     */
+    public void writeToFile( File file ) throws ConfigurationException, IOException
+    {
+        // Writing the file to disk
+        FileWriter writer = new FileWriter( file );
+        writer.append( writeToString() );
+        writer.close();
+    }
+
+
+    /**
+     * Writes the configuration to a String object.
+     *
+     * @return
+     *      a String containing the LDIF 
+     *      representation of the configuration
+     * @throws ConfigurationException
+     *      if an error occurs during the conversion to LDIF
+     */
+    public String writeToString() throws ConfigurationException
+    {
+        return null;
+    }
+
+
+    /**
+     * Gets the converted LDIF entries from the configuration bean.
+     *
+     * @return
+     *      the list of converted LDIF entries
+     * @throws ConfigurationException
+     *      if an error occurs during the conversion to LDIF
+     */
+    public List<LdifEntry> getConvertedLdifEntries() throws ConfigurationException
+    {
+        // Converting the configuration bean to a list of LDIF entries
+        convertConfigurationBeanToLdifEntries();
+
+        // Returning the list of entries
+        return entries;
+    }
+
+
+    /**
+     * Adds the computed 'objectClass' attribute for the given entry and object class name.
+     *
+     * @param entry
+     *      the entry
+     * @param objectClass
+     *      the object class name
+     * @throws LdapException
+     */
+    private void addObjectClassAttribute( LdifEntry entry, String objectClass )
+        throws LdapException
+    {
+        ObjectClass objectClassObject = schema.getObjectClassDescription( objectClass );
+        if ( objectClassObject != null )
+        {
+            // Building the list of 'objectClass' attribute values
+            Set<String> objectClassAttributeValues = new HashSet<String>();
+            computeObjectClassAttributeValues( objectClassAttributeValues, objectClassObject );
+
+            // Adding values to the entry
+            addAttributeTypeValues( SchemaConstants.OBJECT_CLASS_AT, objectClassAttributeValues, entry );
+        }
+        else
+        {
+            // TODO: throw an exception 
+        }
+    }
+
+
+    /**
+     * Recursively computes the 'objectClass' attribute values set.
+     *
+     * @param schemaManager
+     *      the schema manager
+     * @param objectClassAttributeValues
+     *      the set containing the values
+     * @param objectClass
+     *      the current object class
+     * @throws LdapException
+     */
+    private void computeObjectClassAttributeValues( Set<String> objectClassAttributeValues, ObjectClass objectClass )
+        throws LdapException
+    {
+        ObjectClass topObjectClass = schema.getObjectClassDescription( SchemaConstants.TOP_OC );
+        if ( topObjectClass != null )
+        {
+            // TODO throw new exception (there should be a top object class 
+        }
+
+        if ( topObjectClass.equals( objectClass ) )
+        {
+            objectClassAttributeValues.add( objectClass.getName() );
+        }
+        else
+        {
+            objectClassAttributeValues.add( objectClass.getName() );
+
+            List<String> superiors = objectClass.getSuperiorOids();
+            if ( ( superiors != null ) && ( superiors.size() > 0 ) )
+            {
+                for ( String superior : superiors )
+                {
+                    ObjectClass superiorObjectClass = schema.getObjectClassDescription( superior );
+                    computeObjectClassAttributeValues( objectClassAttributeValues, superiorObjectClass );
+                }
+            }
+            else
+            {
+                objectClassAttributeValues.add( topObjectClass.getName() );
+            }
+        }
+    }
+
+
+    /**
+     * Adds values for an attribute type to the given entry.
+     *
+     * @param attributeType
+     *      the attribute type
+     * @param value
+     *      the value
+     * @param entry
+     *      the entry
+     * @throws org.apache.directory.api.ldap.model.exception.LdapException
+     */
+    private void addAttributeTypeValues( String attributeType, Object o, LdifEntry entry )
+        throws LdapException
+    {
+        // We don't store a 'null' value
+        if ( o != null )
+        {
+            // Is the value multiple?
+            if ( isMultiple( o.getClass() ) )
+            {
+                // Adding each single value separately
+                Collection<?> values = ( Collection<?> ) o;
+                if ( values != null )
+                {
+                    for ( Object value : values )
+                    {
+                        addAttributeTypeValue( attributeType, value, entry );
+                    }
+                }
+            }
+            else
+            {
+                // Adding the single value
+                addAttributeTypeValue( attributeType, o, entry );
+            }
+        }
+    }
+
+
+    /**
+     * Adds a value, either byte[] or another type (converted into a String 
+     * via the Object.toString() method), to the attribute.
+     *
+     * @param attributeType
+     *      the attribute type
+     * @param value
+     *      the value
+     * @param entry
+     *      the entry
+     */
+    private void addAttributeTypeValue( String attributeType, Object value, LdifEntry entry ) throws LdapException
+    {
+        // We don't store a 'null' value
+        if ( value != null )
+        {
+            // Getting the attribute from the entry
+            Attribute attribute = entry.get( attributeType );
+
+            // If no attribute has been found, we need to create it and add it to the entry
+            if ( attribute == null )
+            {
+                attribute = new DefaultAttribute( attributeType );
+                entry.addAttribute( attribute );
+            }
+
+            // Storing the value to the attribute
+            if ( value instanceof byte[] )
+            {
+                // Value is a byte[]
+                attribute.add( ( byte[] ) value );
+            }
+            // Storing the boolean value in UPPERCASE (TRUE or FALSE) to the attribute
+            else if ( value instanceof Boolean )
+            {
+                // Value is a byte[]
+                attribute.add( value.toString().toUpperCase() );
+            }
+            else
+            {
+                // Value is another type of object that we store as a String
+                // (There will be an automatic translation for primary types like int, long, etc.)
+                attribute.add( value.toString() );
+            }
+        }
+    }
+
+
+    /**
+     * Indicates the given type is multiple.
+     *
+     * @param clazz
+     *      the class
+     * @return
+     *      <code>true</code> if the given is multiple,
+     *      <code>false</code> if not.
+     */
+    private boolean isMultiple( Class<?> clazz )
+    {
+        return Collection.class.isAssignableFrom( clazz );
+    }
+}

Added: directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/model/io/SaveConfigurationRunnable.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/model/io/SaveConfigurationRunnable.java?rev=1669123&view=auto
==============================================================================
--- directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/model/io/SaveConfigurationRunnable.java (added)
+++ directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/model/io/SaveConfigurationRunnable.java Wed Mar 25 13:26:29 2015
@@ -0,0 +1,131 @@
+/*
+ *  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.studio.openldap.config.model.io;
+
+
+import org.apache.directory.studio.common.core.jobs.StudioProgressMonitor;
+import org.apache.directory.studio.common.core.jobs.StudioRunnableWithProgress;
+import org.apache.directory.studio.ldapbrowser.core.BrowserCorePlugin;
+import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.ui.IEditorInput;
+
+import org.apache.directory.studio.openldap.config.OpenLdapConfigurationPlugin;
+import org.apache.directory.studio.openldap.config.editor.ConnectionServerConfigurationInput;
+import org.apache.directory.studio.openldap.config.editor.ServerConfigurationEditor;
+import org.apache.directory.studio.openldap.config.editor.ServerConfigurationEditorUtils;
+
+
+/**
+ * This class implements a {@link Job} that is used to save a server configuration.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class SaveConfigurationRunnable implements StudioRunnableWithProgress
+{
+    /** The associated editor */
+    private ServerConfigurationEditor editor;
+
+
+    /**
+     * Creates a new instance of SaveConfigurationRunnable.
+     * 
+     * @param editor
+     *            the editor
+     */
+    public SaveConfigurationRunnable( ServerConfigurationEditor editor )
+    {
+        super();
+        this.editor = editor;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getErrorMessage()
+    {
+        return "Unable to save the configuration.";
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object[] getLockedObjects()
+    {
+        return new Object[0];
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getName()
+    {
+        return "Save Configuration";
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void run( StudioProgressMonitor monitor )
+    {
+        try
+        {
+            if ( editor.isDirty() )
+            {
+                monitor.beginTask( "Saving the server configuration", IProgressMonitor.UNKNOWN );
+
+                IEditorInput input = editor.getEditorInput();
+                boolean success = false;
+
+                // If the input is a ConnectionServerConfigurationInput, then we 
+                // read the server configuration from the selected connection
+                if ( input instanceof ConnectionServerConfigurationInput )
+                {
+                    ConnectionServerConfigurationInput connectionServerConfigurationInput = ( ConnectionServerConfigurationInput ) input;
+
+                    // Getting the browser connection associated with the connection in the input
+                    IBrowserConnection browserConnection = BrowserCorePlugin.getDefault().getConnectionManager()
+                        .getBrowserConnection( connectionServerConfigurationInput.getConnection() );
+
+                    ConfigurationWriter configurationWriter = new ConfigurationWriter( browserConnection.getSchema(),
+                        editor.getConfiguration() );
+
+                    // Saving the ServerConfiguration to the connection
+                    ServerConfigurationEditorUtils.saveConfiguration( ( ConnectionServerConfigurationInput ) input,
+                        configurationWriter, monitor );
+                    success = true;
+                }
+
+                editor.setDirty( !success );
+            }
+        }
+        catch ( Exception e )
+        {
+            // Reporting the error to the monitor
+            monitor.reportError( e );
+        }
+    }
+}

Modified: directory/studio/trunk/plugins/pom-first.xml
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/pom-first.xml?rev=1669123&r1=1669122&r2=1669123&view=diff
==============================================================================
--- directory/studio/trunk/plugins/pom-first.xml (original)
+++ directory/studio/trunk/plugins/pom-first.xml Wed Mar 25 13:26:29 2015
@@ -49,6 +49,7 @@
     <module>aciitemeditor/pom-first.xml</module>
     <module>ldapservers.apacheds.v200/pom-first.xml</module>
     <module>openldap.common.ui/pom-first.xml</module>
+    <module>openldap.config.editor/pom-first.xml</module>
     <module>rcp/pom-first.xml</module>
   </modules>
 

Modified: directory/studio/trunk/plugins/pom.xml
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/pom.xml?rev=1669123&r1=1669122&r2=1669123&view=diff
==============================================================================
--- directory/studio/trunk/plugins/pom.xml (original)
+++ directory/studio/trunk/plugins/pom.xml Wed Mar 25 13:26:29 2015
@@ -49,5 +49,6 @@
     <module>schemaeditor</module>
     <module>valueeditors</module>
     <module>openldap.common.ui</module>
+    <module>openldap.config.editor</module>
   </modules>
 </project>