You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by fe...@apache.org on 2007/11/05 15:45:45 UTC

svn commit: r592021 [2/3] - in /directory/sandbox/felixk/studio-connection-core: ./ META-INF/ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/directory/ src/main/java/org/apache/directory/studio/ src/...

Added: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/IModificationLogger.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/IModificationLogger.java?rev=592021&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/IModificationLogger.java (added)
+++ directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/IModificationLogger.java Mon Nov  5 06:45:40 2007
@@ -0,0 +1,62 @@
+package org.apache.directory.studio.connection.core;
+
+
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.ModificationItem;
+import javax.naming.ldap.Control;
+
+
+/**
+ * Callback interface to log modifications
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public interface IModificationLogger
+{
+
+    /**
+     * Logs a changetype:add.
+     * 
+     * @param dn the dn
+     * @param attributes the attributes
+     * @param controls the controls
+     * @param ex the naming exception if an error occurred, null otherwise
+     */
+    public void logChangetypeAdd( final String dn, final Attributes attributes, final Control[] controls, NamingException ex );
+
+
+    /**
+     * Logs a changetype:delete.
+     * 
+     * @param dn the dn
+     * @param controls the controls
+     * @param ex the naming exception if an error occurred, null otherwise
+     */
+    public void logChangetypeDelete( final String dn, final Control[] controls, NamingException ex );
+
+
+    /**
+     * Logs a changetype:modify.
+     * 
+     * @param dn the dn
+     * @param modificationItems the modification items
+     * @param controls the controls
+     * @param ex the naming exception if an error occurred, null otherwise
+     */
+    public void logChangetypeModify( final String dn, final ModificationItem[] modificationItems, final Control[] controls, NamingException ex );
+
+
+    /**
+     * Logs a changetype:moddn.
+     * 
+     * @param oldDn the old dn
+     * @param newDn the new dn
+     * @param deleteOldRdn the delete old rdn
+     * @param controls the controls
+     * @param ex the naming exception if an error occurred, null otherwise
+     */
+    public void logChangetypeModDn( final String oldDn, final String newDn, final boolean deleteOldRdn, final Control[] controls, NamingException ex );
+
+}

Propchange: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/IModificationLogger.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/Messages.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/Messages.java?rev=592021&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/Messages.java (added)
+++ directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/Messages.java Mon Nov  5 06:45:40 2007
@@ -0,0 +1,79 @@
+/*
+ *  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.connection.core;
+
+
+import org.eclipse.osgi.util.NLS;
+
+
+/**
+ * This class contains most of the Strings used by the Plugin
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class Messages extends NLS
+{
+    private static final String BUNDLE_NAME = "org.apache.directory.studio.connection.core.messages"; //$NON-NLS-1$
+
+
+    /**
+     * Creates a new instance of Messages.
+     */
+    private Messages()
+    {
+    }
+
+    static
+    {
+        // initialize resource bundle
+        NLS.initializeMessages( BUNDLE_NAME, Messages.class );
+    }
+
+    public static String copy_n_of_s;
+
+    public static String model__no_auth_handler;
+    public static String model__no_credentials;
+
+    public static String jobs__error_occurred;
+    public static String jobs__progressmonitor_check_cancellation;
+    public static String jobs__progressmonitor_report_progress;
+
+    public static String jobs__check_bind_name;
+    public static String jobs__check_bind_task;
+    public static String jobs__check_bind_error;
+    public static String jobs__check_network_name;
+    public static String jobs__check_network_task;
+    public static String jobs__check_network_error;
+
+    public static String jobs__open_connections_name_1;
+    public static String jobs__open_connections_name_n;
+    public static String jobs__open_connections_task;
+    public static String jobs__open_connections_error_1;
+    public static String jobs__open_connections_error_n;
+
+    public static String jobs__close_connections_name_1;
+    public static String jobs__close_connections_name_n;
+    public static String jobs__close_connections_task;
+    public static String jobs__close_connections_error_1;
+    public static String jobs__close_connections_error_n;
+
+}

Propchange: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/Messages.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/StudioProgressMonitor.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/StudioProgressMonitor.java?rev=592021&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/StudioProgressMonitor.java (added)
+++ directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/StudioProgressMonitor.java Mon Nov  5 06:45:40 2007
@@ -0,0 +1,385 @@
+/*
+ *  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.connection.core;
+
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.ProgressMonitorWrapper;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+
+
+/**
+ * The StudioProgressMonitor extends the the Eclipse
+ * Progress Monitor with active cancellation capabilities.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class StudioProgressMonitor extends ProgressMonitorWrapper
+{
+
+    private boolean done;
+
+    private List<Status> errorStatusList;
+
+    private List<CancelListener> cancelListenerList;
+
+    private Job checkCanceledJob;
+
+    private Job reportProgressJob = null;
+
+    private String reportProgressMessage = null;
+
+
+    /**
+     * Creates a new instance of ExtendedProgressMonitor.
+     * 
+     * @param monitor the progress monitor to forward to
+     */
+    public StudioProgressMonitor( IProgressMonitor monitor )
+    {
+        super( monitor );
+        this.done = false;
+
+        this.checkCanceledJob = new Job( Messages.jobs__progressmonitor_check_cancellation )
+        {
+            protected IStatus run( IProgressMonitor monitor )
+            {
+                while ( !done )
+                {
+                    if ( isCanceled() )
+                    {
+                        fireCancelRequested();
+                        break;
+                    }
+                    else
+                    {
+                        try
+                        {
+                            Thread.sleep( 1000 );
+                        }
+                        catch ( InterruptedException e )
+                        {
+                        }
+                    }
+                }
+                return Status.OK_STATUS;
+            }
+        };
+        this.checkCanceledJob.setSystem( true );
+        this.checkCanceledJob.schedule();
+    }
+
+
+    /**
+     * @see org.eclipse.core.runtime.ProgressMonitorWrapper#setCanceled(boolean)
+     */
+    public void setCanceled( boolean b )
+    {
+        super.setCanceled( b );
+        if ( b )
+        {
+            fireCancelRequested();
+        }
+    }
+
+
+    /**
+     * @see org.eclipse.core.runtime.ProgressMonitorWrapper#done()
+     */
+    public void done()
+    {
+        synchronized ( this )
+        {
+            done = true;
+            super.done();
+        }
+    }
+
+
+    /**
+     * Adds the cancel listener.
+     * 
+     * @param listener the listener
+     */
+    public void addCancelListener( CancelListener listener )
+    {
+        if ( cancelListenerList == null )
+        {
+            cancelListenerList = new ArrayList<CancelListener>();
+        }
+        if ( !cancelListenerList.contains( listener ) )
+        {
+            cancelListenerList.add( listener );
+        }
+    }
+
+
+    /**
+     * Removes the cancel listener.
+     * 
+     * @param listener the listener
+     */
+    public void removeCancelListener( CancelListener listener )
+    {
+        if ( cancelListenerList != null && cancelListenerList.contains( listener ) )
+        {
+            cancelListenerList.remove( listener );
+        }
+    }
+
+
+    private void fireCancelRequested()
+    {
+        CancelEvent event = new CancelEvent( this );
+        if ( cancelListenerList != null )
+        {
+            for ( int i = 0; i < cancelListenerList.size(); i++ )
+            {
+                CancelListener listener = cancelListenerList.get( i );
+                listener.cancelRequested( event );
+            }
+        }
+    }
+
+
+    /**
+     * Report progress.
+     * 
+     * @param message the message
+     */
+    public void reportProgress( String message )
+    {
+        synchronized ( this )
+        {
+            if ( !done )
+            {
+                if ( reportProgressJob == null )
+                {
+                    reportProgressJob = new Job( Messages.jobs__progressmonitor_report_progress )
+                    {
+                        protected IStatus run( IProgressMonitor monitor )
+                        {
+                            synchronized ( StudioProgressMonitor.this )
+                            {
+                                if ( !done )
+                                {
+                                    subTask( reportProgressMessage );
+                                }
+                                return Status.OK_STATUS;
+                            }
+                        }
+                    };
+                    reportProgressJob.setSystem( true );
+                }
+
+                reportProgressMessage = message;
+                reportProgressJob.schedule( 1000 );
+            }
+        }
+    }
+
+
+    /**
+     * Report error.
+     * 
+     * @param message the message
+     */
+    public void reportError( String message )
+    {
+        this.reportError( message, null );
+    }
+
+
+    /**
+     * Report error.
+     * 
+     * @param throwable the throwable
+     */
+    public void reportError( Throwable throwable )
+    {
+        reportError( throwable.getMessage() != null ? throwable.getMessage() : throwable.toString(), throwable );
+    }
+
+
+    /**
+     * Report error.
+     * 
+     * @param exception the exception
+     * @param message the message
+     */
+    public void reportError( String message, Throwable exception )
+    {
+        if ( errorStatusList == null )
+        {
+            errorStatusList = new ArrayList<Status>( 3 );
+        }
+
+        do
+        {
+            if ( message == null )
+            {
+                message = ""; //$NON-NLS-1$
+            }
+
+            Status errorStatus = new Status( IStatus.ERROR, ConnectionCorePlugin.PLUGIN_ID, IStatus.ERROR, message,
+                exception );
+            errorStatusList.add( errorStatus );
+
+            if ( exception != null )
+            {
+                exception = exception.getCause();
+            }
+            if ( exception != null )
+            {
+                message = exception.getMessage();
+            }
+        }
+        while ( exception != null );
+    }
+
+
+    /**
+     * Errors reported.
+     * 
+     * @return true, if errors reported
+     */
+    public boolean errorsReported()
+    {
+        return errorStatusList != null;
+    }
+
+
+    /**
+     * Gets the error status.
+     * 
+     * @param message the message
+     * 
+     * @return the error status
+     */
+    public IStatus getErrorStatus( String message )
+    {
+        if ( errorStatusList != null && !errorStatusList.isEmpty() )
+        {
+            Throwable exception = null;
+            for ( Iterator<Status> it = errorStatusList.iterator(); it.hasNext(); )
+            {
+                Status status = it.next();
+                if ( status.getException() != null )
+                {
+                    exception = status.getException();
+                    break;
+                }
+            }
+
+            MultiStatus multiStatus = new MultiStatus( ConnectionCorePlugin.PLUGIN_ID, IStatus.ERROR, message,
+                exception );
+
+            for ( Iterator<Status> it = errorStatusList.iterator(); it.hasNext(); )
+            {
+                Status status = it.next();
+                multiStatus.add( new Status( status.getSeverity(), status.getPlugin(), status.getCode(), status
+                    .getMessage(), null ) );
+            }
+
+            return multiStatus;
+
+        }
+        else
+        {
+            return Status.OK_STATUS;
+        }
+    }
+
+
+    /**
+     * Gets the exception.
+     * 
+     * @return the exception
+     */
+    public Throwable getException()
+    {
+
+        if ( errorStatusList != null )
+        {
+            return errorStatusList.get( 0 ).getException();
+        }
+        return null;
+    }
+
+    /**
+     * CancelEvent.
+     *
+     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+     * @version $Rev$, $Date$
+     */
+    public static class CancelEvent
+    {
+        private IProgressMonitor monitor;
+
+
+        /**
+         * Creates a new instance of CancelEvent.
+         * 
+         * @param monitor the progress monitor
+         */
+        public CancelEvent( IProgressMonitor monitor )
+        {
+            this.monitor = monitor;
+        }
+
+
+        /**
+         * Gets the monitor.
+         * 
+         * @return the progress monitor
+         */
+        public IProgressMonitor getMonitor()
+        {
+            return monitor;
+        }
+    }
+
+    /**
+     * CancelListener.
+     *
+     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+     * @version $Rev$, $Date$
+     */
+    public interface CancelListener
+    {
+
+        /**
+         * Cancel requested.
+         * 
+         * @param event the event
+         */
+        public void cancelRequested( CancelEvent event );
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/StudioProgressMonitor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/Utils.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/Utils.java?rev=592021&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/Utils.java (added)
+++ directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/Utils.java Mon Nov  5 06:45:40 2007
@@ -0,0 +1,69 @@
+/*
+ *  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.connection.core;
+
+
+/**
+ * Some utils.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class Utils
+{
+
+    /**
+     * Shortens the given label to the given maximum length.
+     * 
+     * @param label the label
+     * @param maxLength the max length
+     * 
+     * @return the shortened label
+     */
+    public static String shorten( String label, int maxLength )
+    {
+        if ( label == null )
+        {
+            return null;
+        }
+        if ( maxLength < 3 )
+        {
+            return "...";
+        }
+        if ( label.length() > maxLength )
+        {
+            label = label.substring( 0, maxLength / 2 ) + "..."
+                + label.substring( label.length() - maxLength / 2, label.length() );
+
+        }
+        StringBuffer sb = new StringBuffer( maxLength + 3 );
+        for ( int i = 0; i < label.length(); i++ )
+        {
+            char c = label.charAt( i );
+            if ( c > 31 && c < 127 )
+                sb.append( c );
+            else
+                sb.append( '.' );
+        }
+        return sb.toString();
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/Utils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/ConnectionEventRegistry.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/ConnectionEventRegistry.java?rev=592021&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/ConnectionEventRegistry.java (added)
+++ directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/ConnectionEventRegistry.java Mon Nov  5 06:45:40 2007
@@ -0,0 +1,336 @@
+/*
+ *  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.connection.core.event;
+
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.directory.studio.connection.core.Connection;
+import org.apache.directory.studio.connection.core.ConnectionFolder;
+
+
+/**
+ * The ConnectionEventRegistry is a central point to register for connection specific
+ * events and to fire events to registered listeners.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ConnectionEventRegistry
+{
+
+    /** The list of threads with suspended event fireing. */
+    private static Set<Thread> suspendedEventFireringThreads = new HashSet<Thread>();;
+
+    /** The lock used to synchronize event fireings */
+    private static Object lock = new Object();
+
+
+    /**
+     * Checks if event fireing is suspended in the current thread.
+     *
+     * @return true, if event fireing is suspended in the current thread
+     */
+    public static boolean isEventFireingSuspendedInCurrentThread()
+    {
+        return suspendedEventFireringThreads.contains( Thread.currentThread() );
+    }
+
+
+    /**
+     * Resumes event fireing in the current thread.
+     */
+    public static void resumeEventFireingInCurrentThread()
+    {
+        suspendedEventFireringThreads.remove( Thread.currentThread() );
+    }
+
+
+    /**
+     * Suspends event fireing in the current thread.
+     */
+    public static void suspendEventFireingInCurrentThread()
+    {
+        suspendedEventFireringThreads.add( Thread.currentThread() );
+    }
+
+    /** The map with connection update listeners and their runners */
+    private static Map<ConnectionUpdateListener, EventRunner> connectionUpdateListeners = new HashMap<ConnectionUpdateListener, EventRunner>();
+
+
+    /**
+     * Adds the connection update listener.
+     *
+     * @param listener the listener
+     * @param runner the runner
+     */
+    public static void addConnectionUpdateListener( ConnectionUpdateListener listener, EventRunner runner )
+    {
+        assert listener != null;
+        assert runner != null;
+
+        if ( !connectionUpdateListeners.containsKey( listener ) )
+        {
+            connectionUpdateListeners.put( listener, runner );
+        }
+    }
+
+
+    /**
+     * Removes the connection update listener.
+     *
+     * @param listener the listener
+     */
+    public static void removeConnectionUpdateListener( ConnectionUpdateListener listener )
+    {
+        if ( connectionUpdateListeners.containsKey( listener ) )
+        {
+            connectionUpdateListeners.remove( listener );
+        }
+    }
+
+
+    /**
+     * Notifies each {@link ConnectionUpdateListener} about the opened connection.
+     * Uses the {@link EventRunner}s.
+     *
+     * @param connection the opened connection
+     * @param source the source
+     */
+    public static void fireConnectionOpened( final Connection connection, final Object source )
+    {
+        if ( isEventFireingSuspendedInCurrentThread() )
+        {
+            return;
+        }
+
+        Map<ConnectionUpdateListener, EventRunner> listeners = new HashMap<ConnectionUpdateListener, EventRunner>(
+            connectionUpdateListeners );
+        Iterator<ConnectionUpdateListener> it = listeners.keySet().iterator();
+        while ( it.hasNext() )
+        {
+            final ConnectionUpdateListener listener = it.next();
+            EventRunnable runnable = new EventRunnable()
+            {
+                public void run()
+                {
+                    listener.connectionOpened( connection );
+                }
+            };
+
+            EventRunner runner = listeners.get( listener );
+            synchronized ( lock )
+            {
+                runner.execute( runnable );
+            }
+        }
+    }
+
+
+    /**
+     * Notifies each {@link ConnectionUpdateListener} about the closed connection.
+     * Uses the {@link EventRunner}s.
+     *
+     * @param connection the closed connection
+     * @param source the source
+     */
+    public static void fireConnectionClosed( final Connection connection, final Object source )
+    {
+        if ( isEventFireingSuspendedInCurrentThread() )
+        {
+            return;
+        }
+
+        Map<ConnectionUpdateListener, EventRunner> listeners = new HashMap<ConnectionUpdateListener, EventRunner>(
+            connectionUpdateListeners );
+        Iterator<ConnectionUpdateListener> it = listeners.keySet().iterator();
+        while ( it.hasNext() )
+        {
+            final ConnectionUpdateListener listener = it.next();
+            EventRunnable runnable = new EventRunnable()
+            {
+                public void run()
+                {
+                    listener.connectionClosed( connection );
+                }
+            };
+
+            EventRunner runner = listeners.get( listener );
+            synchronized ( lock )
+            {
+                runner.execute( runnable );
+            }
+        }
+    }
+
+
+    /**
+     * Notifies each {@link ConnectionUpdateListener} about the updated connection.
+     * Uses the {@link EventRunner}s.
+     *
+     * @param connection the updated connection
+     * @param source the source
+     */
+    public static void fireConnectionUpdated( final Connection connection, final Object source )
+    {
+        if ( isEventFireingSuspendedInCurrentThread() )
+        {
+            return;
+        }
+
+        Map<ConnectionUpdateListener, EventRunner> listeners = new HashMap<ConnectionUpdateListener, EventRunner>(
+            connectionUpdateListeners );
+        Iterator<ConnectionUpdateListener> it = listeners.keySet().iterator();
+        while ( it.hasNext() )
+        {
+            final ConnectionUpdateListener listener = it.next();
+            EventRunnable runnable = new EventRunnable()
+            {
+                public void run()
+                {
+                    listener.connectionUpdated( connection );
+                }
+            };
+
+            EventRunner runner = listeners.get( listener );
+            synchronized ( lock )
+            {
+                runner.execute( runnable );
+            }
+        }
+    }
+
+
+    /**
+     * Notifies each {@link ConnectionUpdateListener} about the added connection.
+     * Uses the {@link EventRunner}s.
+     *
+     * @param connection the added connection
+     * @param source the source
+     */
+    public static void fireConnectionAdded( final Connection connection, final Object source )
+    {
+        if ( isEventFireingSuspendedInCurrentThread() )
+        {
+            return;
+        }
+
+        Map<ConnectionUpdateListener, EventRunner> listeners = new HashMap<ConnectionUpdateListener, EventRunner>(
+            connectionUpdateListeners );
+        Iterator<ConnectionUpdateListener> it = listeners.keySet().iterator();
+        while ( it.hasNext() )
+        {
+            final ConnectionUpdateListener listener = it.next();
+            EventRunnable runnable = new EventRunnable()
+            {
+                public void run()
+                {
+                    listener.connectionAdded( connection );
+                }
+            };
+
+            EventRunner runner = listeners.get( listener );
+            synchronized ( lock )
+            {
+                runner.execute( runnable );
+            }
+        }
+    }
+
+
+    /**
+     * Notifies each {@link ConnectionUpdateListener} about the removed connection.
+     * Uses the {@link EventRunner}s.
+     *
+     * @param connection the removed connection
+     * @param source the source
+     */
+    public static void fireConnectionRemoved( final Connection connection, final Object source )
+    {
+        if ( isEventFireingSuspendedInCurrentThread() )
+        {
+            return;
+        }
+
+        Map<ConnectionUpdateListener, EventRunner> listeners = new HashMap<ConnectionUpdateListener, EventRunner>(
+            connectionUpdateListeners );
+        Iterator<ConnectionUpdateListener> it = listeners.keySet().iterator();
+        while ( it.hasNext() )
+        {
+            final ConnectionUpdateListener listener = it.next();
+            EventRunnable runnable = new EventRunnable()
+            {
+                public void run()
+                {
+                    listener.connectionRemoved( connection );
+                }
+            };
+
+            EventRunner runner = listeners.get( listener );
+            synchronized ( lock )
+            {
+                runner.execute( runnable );
+            }
+        }
+    }
+    
+    
+    /**
+     * Notifies each {@link ConnectionUpdateListener} about the modified connection folder.
+     * Uses the {@link EventRunner}s.
+     *
+     * @param connectionFolder the modified connection folder
+     * @param source the source
+     */
+    public static void fireConnectonFolderModified( final ConnectionFolder connectionFolder, final Object source )
+    {
+        if ( isEventFireingSuspendedInCurrentThread() )
+        {
+            return;
+        }
+        
+        Map<ConnectionUpdateListener, EventRunner> listeners = new HashMap<ConnectionUpdateListener, EventRunner>(
+            connectionUpdateListeners );
+        Iterator<ConnectionUpdateListener> it = listeners.keySet().iterator();
+        while ( it.hasNext() )
+        {
+            final ConnectionUpdateListener listener = it.next();
+            EventRunnable runnable = new EventRunnable()
+            {
+                public void run()
+                {
+                    listener.connectionFolderModified( connectionFolder );
+                }
+            };
+            
+            EventRunner runner = listeners.get( listener );
+            synchronized ( lock )
+            {
+                runner.execute( runnable );
+            }
+        }
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/ConnectionEventRegistry.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/ConnectionUpdateListener.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/ConnectionUpdateListener.java?rev=592021&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/ConnectionUpdateListener.java (added)
+++ directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/ConnectionUpdateListener.java Mon Nov  5 06:45:40 2007
@@ -0,0 +1,86 @@
+/*
+ *  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.connection.core.event;
+
+
+import java.util.EventListener;
+
+import org.apache.directory.studio.connection.core.Connection;
+import org.apache.directory.studio.connection.core.ConnectionFolder;
+
+
+/**
+ * A listener for connection updates
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public interface ConnectionUpdateListener extends EventListener
+{
+
+    /**
+     * Called when an {@link Connection} was opened.
+     *
+     * @param connection the opened connection 
+     */
+    public void connectionOpened( Connection connection );
+
+
+    /**
+     * Called when an {@link Connection} was closed.
+     *
+     * @param connection the closed connection 
+     */
+    public void connectionClosed( Connection connection );
+
+
+    /**
+     * Called when an {@link Connection} was added.
+     *
+     * @param connection the added connection 
+     */
+    public void connectionAdded( Connection connection );
+
+
+    /**
+     * Called when an {@link Connection} was removed.
+     *
+     * @param connection the removed connection 
+     */
+    public void connectionRemoved( Connection connection );
+
+
+    /**
+     * Called when {@link Connection} parameters were updated.
+     *
+     * @param connection the updated connection 
+     */
+    public void connectionUpdated( Connection connection );
+
+
+    /**
+     * Called when {@link ConnectionFolder}s were modified.
+     *
+     * @param connectionFolder the modified connection folder 
+     */
+    public void connectionFolderModified( ConnectionFolder connectionFolder );
+
+}

Propchange: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/ConnectionUpdateListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/CoreEventRunner.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/CoreEventRunner.java?rev=592021&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/CoreEventRunner.java (added)
+++ directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/CoreEventRunner.java Mon Nov  5 06:45:40 2007
@@ -0,0 +1,44 @@
+/*
+ *  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.connection.core.event;
+
+
+/**
+ * Default implementation of {@link EventRunner} that executes an {@link EventRunnable}
+ * withing the current thread.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class CoreEventRunner implements EventRunner
+{
+
+    /**
+     * {@inheritDoc}
+     *
+     * This implementation executes the given {@link EventRunnable} within
+     * the current thread.
+     */
+    public void execute( EventRunnable runnable )
+    {
+        runnable.run();
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/CoreEventRunner.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/EventRunnable.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/EventRunnable.java?rev=592021&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/EventRunnable.java (added)
+++ directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/EventRunnable.java Mon Nov  5 06:45:40 2007
@@ -0,0 +1,35 @@
+/*
+ *  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.connection.core.event;
+
+
+/**
+ * The <code>EventRunnable</code> interface should be implemented by any
+ * class whose instances are intended to be executed by an {@link EventRunner}.
+ * The class must define a method of no arguments called <code>run</code>.
+ * <p>
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public interface EventRunnable extends Runnable
+{
+}

Propchange: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/EventRunnable.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/EventRunner.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/EventRunner.java?rev=592021&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/EventRunner.java (added)
+++ directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/EventRunner.java Mon Nov  5 06:45:40 2007
@@ -0,0 +1,39 @@
+/*
+ *  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.connection.core.event;
+
+
+/**
+ * An EventRunner is used to execute an {@link EventRunnable}.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public interface EventRunner
+{
+
+    /**
+     * Executes the given {@link EventRunnable}.
+     *
+     * @param runnable the event runnable to run
+     */
+    public void execute( EventRunnable runnable );
+
+}

Propchange: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/event/EventRunner.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/ConnectionIO.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/ConnectionIO.java?rev=592021&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/ConnectionIO.java (added)
+++ directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/ConnectionIO.java Mon Nov  5 06:45:40 2007
@@ -0,0 +1,501 @@
+/*
+ *  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.connection.core.io;
+
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+
+import org.apache.directory.studio.connection.core.ConnectionFolder;
+import org.apache.directory.studio.connection.core.ConnectionParameter;
+import org.apache.directory.studio.connection.core.ConnectionParameter.AuthenticationMethod;
+import org.apache.directory.studio.connection.core.ConnectionParameter.EncryptionMethod;
+import org.dom4j.Attribute;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+import org.dom4j.io.OutputFormat;
+import org.dom4j.io.SAXReader;
+import org.dom4j.io.XMLWriter;
+
+
+/**
+ * This class is used to read/write the 'connections.xml' file.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ConnectionIO
+{
+    // XML tags
+    private static final String CONNECTIONS_TAG = "connections";
+    private static final String CONNECTION_TAG = "connection";
+    private static final String ID_TAG = "id";
+    private static final String NAME_TAG = "name";
+    private static final String HOST_TAG = "host";
+    private static final String PORT_TAG = "port";
+    private static final String ENCRYPTION_METHOD_TAG = "encryptionMethod";
+    private static final String AUTH_METHOD_TAG = "authMethod";
+    private static final String BIND_PRINCIPAL_TAG = "bindPrincipal";
+    private static final String BIND_PASSWORD_TAG = "bindPassword";
+    private static final String EXTENDED_PROPERTIES_TAG = "extendedProperties";
+    private static final String EXTENDED_PROPERTY_TAG = "extendedProperty";
+    private static final String KEY_TAG = "key";
+    private static final String VALUE_TAG = "value";
+
+    private static final String CONNECTION_FOLDERS_TAG = "connectionFolders";
+    private static final String CONNECTION_FOLDER_TAG = "connectionFolder";
+    private static final String SUB_FOLDERS_TAG = "subFolders";
+    private static final String SUB_FOLDER_TAG = "subFolder";
+
+    /**
+     * Loads the connections using the reader
+     *
+     * @param stream
+     *      the FileInputStream
+     * @return
+     *      the connections
+     * @throws ConnectionIOException 
+     *      if an error occurs when converting the document
+     */
+    public static Set<ConnectionParameter> load( FileInputStream stream ) throws ConnectionIOException
+    {
+        Set<ConnectionParameter> connections = new HashSet<ConnectionParameter>();
+
+        SAXReader saxReader = new SAXReader();
+        Document document = null;
+
+        try
+        {
+            document = saxReader.read( stream );
+        }
+        catch ( DocumentException e )
+        {
+            throw new ConnectionIOException( e.getMessage() );
+        }
+
+        Element rootElement = document.getRootElement();
+        if ( !rootElement.getName().equals( CONNECTIONS_TAG ) )
+        {
+            throw new ConnectionIOException( "The file does not seem to be a valid Connections file." );
+        }
+
+        for ( Iterator<?> i = rootElement.elementIterator( CONNECTION_TAG ); i.hasNext(); )
+        {
+            Element connectionElement = ( Element ) i.next();
+            connections.add( readConnection( connectionElement ) );
+        }
+
+        return connections;
+    }
+
+
+    /**
+     * Reads a connection from the given Element.
+     *
+     * @param element
+     *      the element
+     * @return
+     *      the corresponding connection
+     * @throws ConnectionIOException
+     *      if an error occurs when converting values
+     */
+    private static ConnectionParameter readConnection( Element element ) throws ConnectionIOException
+    {
+        ConnectionParameter connection = new ConnectionParameter();
+
+        // ID
+        Attribute idAttribute = element.attribute( ID_TAG );
+        if ( idAttribute != null )
+        {
+            connection.setId( idAttribute.getValue() );
+        }
+
+        // Name
+        Attribute nameAttribute = element.attribute( NAME_TAG );
+        if ( nameAttribute != null )
+        {
+            connection.setName( nameAttribute.getValue() );
+        }
+
+        // Host        
+        Attribute hostAttribute = element.attribute( HOST_TAG );
+        if ( hostAttribute != null )
+        {
+            connection.setHost( hostAttribute.getValue() );
+        }
+
+        // Port
+        Attribute portAttribute = element.attribute( PORT_TAG );
+        if ( portAttribute != null )
+        {
+            try
+            {
+                connection.setPort( Integer.parseInt( portAttribute.getValue() ) );
+            }
+            catch ( NumberFormatException e )
+            {
+                throw new ConnectionIOException( "Unable to parse 'Port' of connection '" + connection.getName()
+                    + "' as int value. Port value :" + portAttribute.getValue() );
+            }
+        }
+
+        // Encryption Method
+        Attribute encryptionMethodAttribute = element.attribute( ENCRYPTION_METHOD_TAG );
+        if ( encryptionMethodAttribute != null )
+        {
+            try
+            {
+                connection.setEncryptionMethod( EncryptionMethod.valueOf( encryptionMethodAttribute.getValue() ) );
+            }
+            catch ( IllegalArgumentException e )
+            {
+                throw new ConnectionIOException( "Unable to parse 'Encryption Method' of connection '"
+                    + connection.getName() + "' as int value. Encryption Method value :"
+                    + encryptionMethodAttribute.getValue() );
+            }
+        }
+
+        // Auth Method
+        Attribute authMethodAttribute = element.attribute( AUTH_METHOD_TAG );
+        if ( authMethodAttribute != null )
+        {
+            try
+            {
+                connection.setAuthMethod( AuthenticationMethod.valueOf( authMethodAttribute.getValue() ) );
+            }
+            catch ( IllegalArgumentException e )
+            {
+                throw new ConnectionIOException( "Unable to parse 'Authentication Method' of connection '"
+                    + connection.getName() + "' as int value. Authentication Method value :"
+                    + authMethodAttribute.getValue() );
+            }
+        }
+
+        // Bind Principal        
+        Attribute bindPrincipalAttribute = element.attribute( BIND_PRINCIPAL_TAG );
+        if ( bindPrincipalAttribute != null )
+        {
+            connection.setBindPrincipal( bindPrincipalAttribute.getValue() );
+        }
+
+        // Bind Password
+        Attribute bindPasswordAttribute = element.attribute( BIND_PASSWORD_TAG );
+        if ( bindPasswordAttribute != null )
+        {
+            connection.setBindPassword( bindPasswordAttribute.getValue() );
+        }
+
+        // Extended Properties
+        Element extendedPropertiesElement = element.element( EXTENDED_PROPERTIES_TAG );
+        if ( extendedPropertiesElement != null )
+        {
+            for ( Iterator<?> i = extendedPropertiesElement.elementIterator( EXTENDED_PROPERTY_TAG ); i.hasNext(); )
+            {
+                Element extendedPropertyElement = ( Element ) i.next();
+
+                Attribute keyAttribute = extendedPropertyElement.attribute( KEY_TAG );
+                Attribute valueAttribute = extendedPropertyElement.attribute( VALUE_TAG );
+
+                if ( keyAttribute != null && valueAttribute != null )
+                {
+                    connection.setExtendedProperty( keyAttribute.getValue(), valueAttribute.getValue() );
+                }
+            }
+        }
+
+        return connection;
+    }
+
+
+    /**
+     * Saves the connections using the writer.
+     *
+     * @param connections
+     *      the connections
+     * @param stream
+     *      the OutputStream
+     * @throws IOException
+     *      if an I/O error occurs
+     */
+    public static void save( Set<ConnectionParameter> connections, FileOutputStream stream ) throws IOException
+    {
+        // Creating the Document
+        Document document = DocumentHelper.createDocument();
+
+        // Creating the root element
+        Element root = document.addElement( CONNECTIONS_TAG );
+
+        if ( connections != null )
+        {
+            for ( ConnectionParameter connection : connections )
+            {
+                addConnection( root, connection );
+            }
+        }
+
+        // Writing the file to disk
+        OutputFormat outformat = OutputFormat.createPrettyPrint();
+        outformat.setEncoding( "UTF-8" );
+        XMLWriter writer = new XMLWriter( stream, outformat );
+        writer.write( document );
+        writer.flush();
+    }
+
+
+    /**
+     * Adds the given connection to the given parent Element.
+     *
+     * @param parent
+     *      the parent Element
+     * @param connection
+     *      the connection
+     */
+    private static void addConnection( Element parent, ConnectionParameter connection )
+    {
+        Element connectionElement = parent.addElement( CONNECTION_TAG );
+
+        // ID
+        connectionElement.addAttribute( ID_TAG, connection.getId() );
+
+        // Name
+        connectionElement.addAttribute( NAME_TAG, connection.getName() );
+
+        // Host
+        connectionElement.addAttribute( HOST_TAG, connection.getHost() );
+
+        // Port
+        connectionElement.addAttribute( PORT_TAG, "" + connection.getPort() );
+
+        // Encryption Method
+        connectionElement.addAttribute( ENCRYPTION_METHOD_TAG, connection.getEncryptionMethod().toString() );
+
+        // Auth Method
+        connectionElement.addAttribute( AUTH_METHOD_TAG, connection.getAuthMethod().toString() );
+
+        // Bind Principal
+        connectionElement.addAttribute( BIND_PRINCIPAL_TAG, connection.getBindPrincipal() );
+
+        // Bind Password
+        connectionElement.addAttribute( BIND_PASSWORD_TAG, connection.getBindPassword() );
+
+        // Extended Properties
+        Element extendedPropertiesElement = connectionElement.addElement( EXTENDED_PROPERTIES_TAG );
+        Map<String, String> extendedProperties = connection.getExtendedProperties();
+        if ( extendedProperties != null )
+        {
+            for ( Iterator<Entry<String, String>> iter = extendedProperties.entrySet().iterator(); iter.hasNext(); )
+            {
+                Map.Entry<String, String> element = ( Map.Entry<String, String> ) iter.next();
+
+                Element extendedPropertyElement = extendedPropertiesElement.addElement( EXTENDED_PROPERTY_TAG );
+                extendedPropertyElement.addAttribute( KEY_TAG, element.getKey() );
+                extendedPropertyElement.addAttribute( VALUE_TAG, element.getValue() );
+            }
+        }
+    }
+
+
+    /**
+     * Loads the connection folders using the reader
+     *
+     * @param stream
+     *      the FileInputStream
+     * @return
+     *      the connection folders
+     * @throws ConnectionIOException 
+     *      if an error occurs when converting the document
+     */
+    public static Set<ConnectionFolder> loadConnectionFolders( FileInputStream stream ) throws ConnectionIOException
+    {
+        Set<ConnectionFolder> connectionFolders = new HashSet<ConnectionFolder>();
+
+        SAXReader saxReader = new SAXReader();
+        Document document = null;
+
+        try
+        {
+            document = saxReader.read( stream );
+        }
+        catch ( DocumentException e )
+        {
+            throw new ConnectionIOException( e.getMessage() );
+        }
+
+        Element rootElement = document.getRootElement();
+        if ( !rootElement.getName().equals( CONNECTION_FOLDERS_TAG ) )
+        {
+            throw new ConnectionIOException( "The file does not seem to be a valid ConnectionFolders file." );
+        }
+
+        for ( Iterator<?> i = rootElement.elementIterator( CONNECTION_FOLDER_TAG ); i.hasNext(); )
+        {
+            Element connectionFolderElement = ( Element ) i.next();
+            connectionFolders.add( readConnectionFolder( connectionFolderElement ) );
+        }
+
+        return connectionFolders;
+    }
+
+
+    /**
+     * Reads a connection folder from the given Element.
+     *
+     * @param element
+     *      the element
+     * @return
+     *      the corresponding connection folder
+     * @throws ConnectionIOException
+     *      if an error occurs when converting values
+     */
+    private static ConnectionFolder readConnectionFolder( Element element ) throws ConnectionIOException
+    {
+        ConnectionFolder connectionFolder = new ConnectionFolder();
+
+        // ID
+        Attribute idAttribute = element.attribute( ID_TAG );
+        if ( idAttribute != null )
+        {
+            connectionFolder.setId( idAttribute.getValue() );
+        }
+
+        // Name
+        Attribute nameAttribute = element.attribute( NAME_TAG );
+        if ( nameAttribute != null )
+        {
+            connectionFolder.setName( nameAttribute.getValue() );
+        }
+
+        // Connections
+        Element connectionsElement = element.element( CONNECTIONS_TAG );
+        if ( connectionsElement != null )
+        {
+            for ( Iterator<?> i = connectionsElement.elementIterator( CONNECTION_TAG ); i.hasNext(); )
+            {
+                Element connectionElement = ( Element ) i.next();
+
+                Attribute connectionIdAttribute = connectionElement.attribute( ID_TAG );
+
+                if ( connectionIdAttribute != null )
+                {
+                    connectionFolder.addConnectionId( connectionIdAttribute.getValue() );
+                }
+            }
+        }
+
+        // Sub-folders
+        Element foldersElement = element.element( SUB_FOLDERS_TAG );
+        if ( foldersElement != null )
+        {
+            for ( Iterator<?> i = foldersElement.elementIterator( SUB_FOLDER_TAG ); i.hasNext(); )
+            {
+                Element folderElement = ( Element ) i.next();
+                
+                Attribute folderIdAttribute = folderElement.attribute( ID_TAG );
+                
+                if ( folderIdAttribute != null )
+                {
+                    connectionFolder.addSubFolderId( folderIdAttribute.getValue() );
+                }
+            }
+        }
+
+        return connectionFolder;
+    }
+
+
+    /**
+     * Saves the connection folders using the writer.
+     *
+     * @param connectionFolders
+     *      the connection folders
+     * @param stream
+     *      the OutputStream
+     * @throws IOException
+     *      if an I/O error occurs
+     */
+    public static void saveConnectionFolders( Set<ConnectionFolder> connectionFolders, FileOutputStream stream ) throws IOException
+    {
+        // Creating the Document
+        Document document = DocumentHelper.createDocument();
+
+        // Creating the root element
+        Element root = document.addElement( CONNECTION_FOLDERS_TAG );
+
+        if ( connectionFolders != null )
+        {
+            for ( ConnectionFolder connectionFolder : connectionFolders )
+            {
+                addFolderConnection( root, connectionFolder );
+            }
+        }
+
+        // Writing the file to disk
+        OutputFormat outformat = OutputFormat.createPrettyPrint();
+        outformat.setEncoding( "UTF-8" );
+        XMLWriter writer = new XMLWriter( stream, outformat );
+        writer.write( document );
+        writer.flush();
+    }
+
+
+    /**
+     * Adds the given connection folder to the given parent Element.
+     *
+     * @param parent
+     *      the parent Element
+     * @param connectionFolder
+     *      the connection folder
+     */
+    private static void addFolderConnection( Element parent, ConnectionFolder connectionFolder )
+    {
+        Element connectionFolderElement = parent.addElement( CONNECTION_FOLDER_TAG );
+
+        // ID
+        connectionFolderElement.addAttribute( ID_TAG, connectionFolder.getId() );
+
+        // Name
+        connectionFolderElement.addAttribute( NAME_TAG, connectionFolder.getName() );
+
+        // Connections
+        Element connectionsElement = connectionFolderElement.addElement( CONNECTIONS_TAG );
+        for ( String connectionId : connectionFolder.getConnectionIds() )
+        {
+            Element connectionElement = connectionsElement.addElement( CONNECTION_TAG );
+            connectionElement.addAttribute( ID_TAG, connectionId );
+        }
+        
+        // Sub-folders
+        Element foldersElement = connectionFolderElement.addElement( SUB_FOLDERS_TAG );
+        for ( String folderId : connectionFolder.getSubFolderIds() )
+        {
+            Element folderElement = foldersElement.addElement( SUB_FOLDER_TAG );
+            folderElement.addAttribute( ID_TAG, folderId );
+        }
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/ConnectionIO.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/ConnectionIOException.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/ConnectionIOException.java?rev=592021&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/ConnectionIOException.java (added)
+++ directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/ConnectionIOException.java Mon Nov  5 06:45:40 2007
@@ -0,0 +1,44 @@
+/*
+ *  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.connection.core.io;
+
+
+/**
+ * This exception can be raised when loading the Connections file.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ConnectionIOException extends Exception
+{
+    private static final long serialVersionUID = 1L;
+
+
+    /**
+     * Creates a new instance of ConnectionIOException.
+     *
+     * @param message
+     *      the message
+     */
+    public ConnectionIOException( String message )
+    {
+        super( message );
+    }
+}
\ No newline at end of file

Propchange: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/ConnectionIOException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/ConnectionWrapper.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/ConnectionWrapper.java?rev=592021&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/ConnectionWrapper.java (added)
+++ directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/ConnectionWrapper.java Mon Nov  5 06:45:40 2007
@@ -0,0 +1,70 @@
+/*
+ *  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.connection.core.io;
+
+
+import org.apache.directory.studio.connection.core.StudioProgressMonitor;
+
+
+/**
+ * A ConnectionWrapper is a wrapper for a real directory connection implementation.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public interface ConnectionWrapper
+{
+
+    /**
+     * Connects to the directory server.
+     * 
+     * @param monitor the progres monitor
+     */
+    public void connect( StudioProgressMonitor monitor );
+
+
+    /**
+     * Disconnects from the directory server.
+     */
+    public void disconnect();
+
+
+    /**
+     * Binds to the directory server.
+     * 
+     * @param monitor the progress monitor
+     */
+    public void bind( StudioProgressMonitor monitor );
+
+
+    /**
+     * Unbinds from the directory server.
+     */
+    public void unbind();
+
+
+    /**
+     * Checks if is connected.
+     * 
+     * @return true, if is connected
+     */
+    public boolean isConnected();
+
+}

Propchange: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/ConnectionWrapper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/jndi/CancelException.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/jndi/CancelException.java?rev=592021&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/jndi/CancelException.java (added)
+++ directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/jndi/CancelException.java Mon Nov  5 06:45:40 2007
@@ -0,0 +1,58 @@
+/*
+ *  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.connection.core.io.jndi;
+
+
+import javax.naming.NamingException;
+
+
+/**
+ * A specific {@link NamingException} that represents the cancellation of an request.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class CancelException extends NamingException
+{
+
+    private static final long serialVersionUID = 1L;
+
+
+    /**
+     * Creates a new instance of CancelException.
+     */
+    public CancelException()
+    {
+        super();
+    }
+
+
+    /**
+     * Creates a new instance of CancelException.
+     *
+     * @param message the message
+     */
+    public CancelException( String message )
+    {
+        super( message );
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/jndi/CancelException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/jndi/DummySSLSocketFactory.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/jndi/DummySSLSocketFactory.java?rev=592021&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/jndi/DummySSLSocketFactory.java (added)
+++ directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/jndi/DummySSLSocketFactory.java Mon Nov  5 06:45:40 2007
@@ -0,0 +1,213 @@
+/*
+ *  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.connection.core.io.jndi;
+
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.security.SecureRandom;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+
+/**
+ * A SSLSocketFactory that accepts every certificat without validation.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class DummySSLSocketFactory extends SSLSocketFactory
+{
+
+    /** The default instance. */
+    private static SocketFactory instance;
+
+
+    /**
+     * Gets the default instance.
+     * 
+     * Note: This method is invoked from the JNDI framework when 
+     * creating a ldaps:// connection.
+     * 
+     * @return the default instance
+     */
+    public static SocketFactory getDefault()
+    {
+        if ( instance == null )
+        {
+            instance = new DummySSLSocketFactory();
+        }
+        return instance;
+    }
+
+    /** The delegate. */
+    private SSLSocketFactory delegate;
+
+
+    /**
+     * Creates a new instance of DummySSLSocketFactory.
+     */
+    public DummySSLSocketFactory()
+    {
+        try
+        {
+            TrustManager tm = new X509TrustManager()
+            {
+                public X509Certificate[] getAcceptedIssuers()
+                {
+                    return new X509Certificate[0];
+                }
+
+
+                public void checkClientTrusted( X509Certificate[] arg0, String arg1 ) throws CertificateException
+                {
+                }
+
+
+                public void checkServerTrusted( X509Certificate[] arg0, String arg1 ) throws CertificateException
+                {
+                }
+            };
+            TrustManager[] tma =
+                { tm };
+            SSLContext sc = SSLContext.getInstance( "TLS" ); //$NON-NLS-1$
+            sc.init( null, tma, new SecureRandom() );
+            delegate = sc.getSocketFactory();
+        }
+        catch ( Exception e )
+        {
+            e.printStackTrace();
+        }
+    }
+
+
+    /**
+     * @see javax.net.ssl.SSLSocketFactory#getDefaultCipherSuites()
+     */
+    public String[] getDefaultCipherSuites()
+    {
+        return delegate.getDefaultCipherSuites();
+    }
+
+
+    /**
+     * @see javax.net.ssl.SSLSocketFactory#getSupportedCipherSuites()
+     */
+    public String[] getSupportedCipherSuites()
+    {
+        return delegate.getSupportedCipherSuites();
+    }
+
+
+    /**
+     * @see javax.net.ssl.SSLSocketFactory#createSocket(java.net.Socket, java.lang.String, int, boolean)
+     */
+    public Socket createSocket( Socket arg0, String arg1, int arg2, boolean arg3 ) throws IOException
+    {
+        try
+        {
+            return delegate.createSocket( arg0, arg1, arg2, arg3 );
+        }
+        catch ( IOException e )
+        {
+            e.printStackTrace();
+            throw e;
+        }
+    }
+
+
+    /**
+     * @see javax.net.SocketFactory#createSocket(java.lang.String, int)
+     */
+    public Socket createSocket( String arg0, int arg1 ) throws IOException, UnknownHostException
+    {
+        try
+        {
+            return delegate.createSocket( arg0, arg1 );
+        }
+        catch ( IOException e )
+        {
+            e.printStackTrace();
+            throw e;
+        }
+    }
+
+
+    /**
+     * @see javax.net.SocketFactory#createSocket(java.net.InetAddress, int)
+     */
+    public Socket createSocket( InetAddress arg0, int arg1 ) throws IOException
+    {
+        try
+        {
+            return delegate.createSocket( arg0, arg1 );
+        }
+        catch ( IOException e )
+        {
+            e.printStackTrace();
+            throw e;
+        }
+    }
+
+
+    /**
+     * @see javax.net.SocketFactory#createSocket(java.lang.String, int, java.net.InetAddress, int)
+     */
+    public Socket createSocket( String arg0, int arg1, InetAddress arg2, int arg3 ) throws IOException,
+        UnknownHostException
+    {
+        try
+        {
+            return delegate.createSocket( arg0, arg1, arg2, arg3 );
+        }
+        catch ( IOException e )
+        {
+            e.printStackTrace();
+            throw e;
+        }
+    }
+
+
+    /**
+     * @see javax.net.SocketFactory#createSocket(java.net.InetAddress, int, java.net.InetAddress, int)
+     */
+    public Socket createSocket( InetAddress arg0, int arg1, InetAddress arg2, int arg3 ) throws IOException
+    {
+        try
+        {
+            return delegate.createSocket( arg0, arg1, arg2, arg3 );
+        }
+        catch ( IOException e )
+        {
+            e.printStackTrace();
+            throw e;
+        }
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-connection-core/src/main/java/org/apache/directory/studio/connection/core/io/jndi/DummySSLSocketFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native