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 17:52:07 UTC

svn commit: r592082 [4/20] - in /directory/sandbox/felixk/studio-ldapbrowser-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/ sr...

Added: directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/AbstractEclipseJob.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/AbstractEclipseJob.java?rev=592082&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/AbstractEclipseJob.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/AbstractEclipseJob.java Mon Nov  5 08:51:43 2007
@@ -0,0 +1,302 @@
+/*
+ *  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.ldapbrowser.core.jobs;
+
+
+import org.apache.directory.studio.connection.core.Connection;
+import org.apache.directory.studio.connection.core.Messages;
+import org.apache.directory.studio.connection.core.StudioProgressMonitor;
+import org.apache.directory.studio.connection.core.event.ConnectionEventRegistry;
+import org.apache.directory.studio.ldapbrowser.core.BrowserCoreMessages;
+import org.apache.directory.studio.ldapbrowser.core.model.IAttribute;
+import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection;
+import org.apache.directory.studio.ldapbrowser.core.model.IEntry;
+import org.apache.directory.studio.ldapbrowser.core.model.ISearch;
+import org.apache.directory.studio.ldapbrowser.core.model.IValue;
+import org.apache.directory.studio.ldapbrowser.core.model.impl.BrowserConnection;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+
+
+public abstract class AbstractEclipseJob extends Job
+{
+
+    private IProgressMonitor externalProgressMonitor;
+
+    private IStatus externalResult;
+
+
+    protected AbstractEclipseJob()
+    {
+        super( "" ); //$NON-NLS-1$
+    }
+
+
+    protected abstract Connection[] getConnections();
+
+
+    protected abstract void executeAsyncJob( StudioProgressMonitor monitor ) throws Exception;
+
+
+    protected String getErrorMessage()
+    {
+        return BrowserCoreMessages.jobs__error_occurred;
+    }
+
+
+    protected final IStatus run( IProgressMonitor ipm )
+    {
+
+        StudioProgressMonitor monitor = new StudioProgressMonitor( externalProgressMonitor == null ? ipm
+            : externalProgressMonitor );
+
+        // ensure that connections are opened
+        Connection[] connections = getConnections();
+        for ( int i = 0; i < connections.length; i++ )
+        {
+            if ( connections[i] != null && !connections[i].getJNDIConnectionWrapper().isConnected() )
+            {
+                monitor.setTaskName( Messages.bind( Messages.jobs__open_connections_task, new String[]
+                    { connections[i].getName() } ) );
+                monitor.worked( 1 );
+
+                connections[i].getJNDIConnectionWrapper().connect( monitor );
+                connections[i].getJNDIConnectionWrapper().bind( monitor );
+                ConnectionEventRegistry.fireConnectionOpened( connections[i], this );
+            }
+        }
+
+        // execute job
+        if ( !monitor.errorsReported() )
+        {
+            try
+            {
+                executeAsyncJob( monitor );
+            }
+            catch ( Exception e )
+            {
+                monitor.reportError( e );
+            }
+            finally
+            {
+                monitor.done();
+                ipm.done();
+            }
+        }
+
+        // error handling
+        if ( monitor.isCanceled() )
+        {
+            // System.out.println("Job: CANCEL+CANCEL");
+            externalResult = Status.CANCEL_STATUS;
+            return Status.CANCEL_STATUS;
+        }
+        else if ( monitor.errorsReported() )
+        {
+            externalResult = monitor.getErrorStatus( getErrorMessage() );
+            if ( externalProgressMonitor == null )
+            {
+                // System.out.println("Job: ERROR+ERROR");
+                return externalResult;
+            }
+            else
+            {
+                // System.out.println("Job: ERROR+OK");
+                return Status.OK_STATUS;
+            }
+        }
+        else
+        {
+            // System.out.println("Job: OK+OK");
+            externalResult = Status.OK_STATUS;
+            return Status.OK_STATUS;
+        }
+    }
+
+
+    public void setExternalProgressMonitor( IProgressMonitor externalProgressMonitor )
+    {
+        this.externalProgressMonitor = externalProgressMonitor;
+    }
+
+
+    public IStatus getExternalResult()
+    {
+        return this.externalResult;
+    }
+
+
+    public final void execute()
+    {
+        setUser( true );
+        schedule();
+    }
+
+
+    protected abstract Object[] getLockedObjects();
+
+
+    public boolean shouldSchedule()
+    {
+
+        Object[] myLockedObjects = getLockedObjects();
+        String[] myLockedObjectsIdentifiers = getLockIdentifiers( myLockedObjects );
+
+        // TODO: read, write
+
+        Job[] jobs = Platform.getJobManager().find( null );
+        for ( int i = 0; i < jobs.length; i++ )
+        {
+            Job job = jobs[i];
+
+            // if(job instanceof AbstractEclipseJob) {
+            if ( job.getClass() == this.getClass() && job != this )
+            {
+
+                AbstractEclipseJob otherJob = ( AbstractEclipseJob ) job;
+                Object[] otherLockedObjects = otherJob.getLockedObjects();
+                String[] otherLockedObjectIdentifiers = getLockIdentifiers( otherLockedObjects );
+
+                for ( int j = 0; j < otherLockedObjectIdentifiers.length; j++ )
+                {
+                    String other = otherLockedObjectIdentifiers[j];
+                    for ( int k = 0; k < myLockedObjectsIdentifiers.length; k++ )
+                    {
+                        String my = myLockedObjectsIdentifiers[k];
+
+                        System.out.print( "other:" + other + ", my: " + my );
+
+                        if ( other.startsWith( my ) || my.startsWith( other ) )
+                        {
+                            System.out.println( ", shouldSchedule() = " + false );
+                            return false;
+                        }
+                        else
+                        {
+                            System.out.println();
+                        }
+
+                    }
+                }
+
+            }
+        }
+        return super.shouldSchedule();
+
+        // // Doesn't work
+        // Job[] jobs = getJobManager().find(null);
+        // for (int i = 0; i < jobs.length; i++) {
+        // Job job = jobs[i];
+        // if(job instanceof AbstractEclipseJob) {
+        // System.out.println("shouldSchedule() = " + false);
+        // return false;
+        // }
+        // }
+        // System.out.println("shouldSchedule() = " + true);
+        // return true;
+
+        // return super.shouldSchedule();
+    }
+
+
+    protected static String[] getLockIdentifiers( Object[] objects )
+    {
+        String[] identifiers = new String[objects.length];
+        for ( int i = 0; i < identifiers.length; i++ )
+        {
+            Object o = objects[i];
+            if ( o instanceof IBrowserConnection )
+            {
+                identifiers[i] = getLockIdentifier( ( IBrowserConnection ) o );
+            }
+            else if ( o instanceof IEntry )
+            {
+                identifiers[i] = getLockIdentifier( ( IEntry ) o );
+            }
+            else if ( o instanceof IAttribute )
+            {
+                identifiers[i] = getLockIdentifier( ( IAttribute ) o );
+            }
+            else if ( o instanceof IValue )
+            {
+                identifiers[i] = getLockIdentifier( ( IValue ) o );
+            }
+            else if ( o instanceof ISearch )
+            {
+                identifiers[i] = getLockIdentifier( ( ISearch ) o );
+            }
+            else
+            {
+                identifiers[i] = getLockIdentifier( objects[i] );
+            }
+        }
+        return identifiers;
+    }
+
+
+    protected static String getLockIdentifier( IBrowserConnection browserConnection )
+    {
+        if ( browserConnection instanceof BrowserConnection )
+        {
+            return browserConnection.getConnection().getHost() + ":" + browserConnection.getConnection().getPort();
+        }
+        else
+        {
+            return "";
+        }
+    }
+
+
+    protected static String getLockIdentifier( IEntry entry )
+    {
+        return getLockIdentifier( entry.getBrowserConnection() ) + "_"
+            + new StringBuffer( entry.getDn().getNormName() ).reverse().toString();
+    }
+
+
+    protected static String getLockIdentifier( IAttribute attribute )
+    {
+        return getLockIdentifier( attribute.getEntry() ) + "_" + attribute.getDescription();
+    }
+
+
+    protected static String getLockIdentifier( IValue value )
+    {
+        return getLockIdentifier( value.getAttribute() ) + "_" + value.getStringValue();
+    }
+
+
+    protected static String getLockIdentifier( ISearch search )
+    {
+        return getLockIdentifier( search.getBrowserConnection() ) + "_"
+            + new StringBuffer( search.getSearchBase().getNormName() ).reverse().toString();
+    }
+
+
+    protected static String getLockIdentifier( Object object )
+    {
+        return object.toString();
+    }
+
+}

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

Added: directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/AbstractNotificationJob.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/AbstractNotificationJob.java?rev=592082&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/AbstractNotificationJob.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/AbstractNotificationJob.java Mon Nov  5 08:51:43 2007
@@ -0,0 +1,67 @@
+/*
+ *  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.ldapbrowser.core.jobs;
+
+
+import org.apache.directory.studio.connection.core.StudioProgressMonitor;
+import org.apache.directory.studio.ldapbrowser.core.events.EventRegistry;
+
+
+/**
+ * Abstract Job used to fire a notification after the job was executed.   
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public abstract class AbstractNotificationJob extends AbstractEclipseJob
+{
+
+    protected final void executeAsyncJob( StudioProgressMonitor pm )
+    {
+        EventRegistry.suspendEventFireingInCurrentThread();
+
+        try
+        {
+            executeNotificationJob( pm );
+        }
+        finally
+        {
+            EventRegistry.resumeEventFireingInCurrentThread();
+        }
+
+        runNotification();
+    }
+
+
+    /**
+     * Executes the job.
+     * 
+     * @param pm monitor progress monitor
+     */
+    protected abstract void executeNotificationJob( StudioProgressMonitor monitor );
+
+
+    /**
+     * Runs the notification.
+     */
+    protected abstract void runNotification();
+
+}

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

Added: directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/CopyEntriesJob.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/CopyEntriesJob.java?rev=592082&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/CopyEntriesJob.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/CopyEntriesJob.java Mon Nov  5 08:51:43 2007
@@ -0,0 +1,378 @@
+/*
+ *  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.ldapbrowser.core.jobs;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.naming.InvalidNameException;
+
+import org.apache.directory.shared.ldap.name.AttributeTypeAndValue;
+import org.apache.directory.shared.ldap.name.Rdn;
+import org.apache.directory.studio.connection.core.Connection;
+import org.apache.directory.studio.connection.core.StudioProgressMonitor;
+import org.apache.directory.studio.ldapbrowser.core.BrowserCoreMessages;
+import org.apache.directory.studio.ldapbrowser.core.events.ChildrenInitializedEvent;
+import org.apache.directory.studio.ldapbrowser.core.events.EventRegistry;
+import org.apache.directory.studio.ldapbrowser.core.model.IAttribute;
+import org.apache.directory.studio.ldapbrowser.core.model.IEntry;
+import org.apache.directory.studio.ldapbrowser.core.model.ISearch;
+import org.apache.directory.studio.ldapbrowser.core.model.ISearchResult;
+import org.apache.directory.studio.ldapbrowser.core.model.IValue;
+import org.apache.directory.studio.ldapbrowser.core.model.SearchParameter;
+import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection.AliasDereferencingMethod;
+import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection.ReferralHandlingMethod;
+import org.apache.directory.studio.ldapbrowser.core.model.ISearch.SearchScope;
+import org.apache.directory.studio.ldapbrowser.core.model.impl.Attribute;
+import org.apache.directory.studio.ldapbrowser.core.model.impl.Entry;
+import org.apache.directory.studio.ldapbrowser.core.model.impl.Search;
+import org.apache.directory.studio.ldapbrowser.core.model.impl.Value;
+import org.apache.directory.studio.ldapbrowser.core.model.schema.SchemaUtils;
+import org.apache.directory.studio.ldapbrowser.core.utils.DnUtils;
+
+
+/**
+ * Job to copy entries asynchronously.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class CopyEntriesJob extends AbstractNotificationJob
+{
+
+    /** The parent entry. */
+    private IEntry parent;
+
+    /** The entries to copy. */
+    private IEntry[] entriesToCopy;
+
+    /** The copy scope */
+    private SearchScope scope;
+
+
+    /**
+     * Creates a new instance of CopyEntriesJob.
+     * 
+     * @param parent the parent entry
+     * @param entriesToCopy the entries to copy
+     * @param scope the copy scope
+     */
+    public CopyEntriesJob( final IEntry parent, final IEntry[] entriesToCopy, SearchScope scope )
+    {
+        this.parent = parent;
+        this.entriesToCopy = entriesToCopy;
+        this.scope = scope;
+        setName( entriesToCopy.length == 1 ? BrowserCoreMessages.jobs__copy_entries_name_1
+            : BrowserCoreMessages.jobs__copy_entries_name_n );
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.jobs.AbstractEclipseJob#getConnections()
+     */
+    protected Connection[] getConnections()
+    {
+        return new Connection[]
+            { parent.getBrowserConnection().getConnection() };
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.jobs.AbstractEclipseJob#getLockedObjects()
+     */
+    protected Object[] getLockedObjects()
+    {
+        List<IEntry> l = new ArrayList<IEntry>();
+        l.add( parent );
+        l.addAll( Arrays.asList( entriesToCopy ) );
+        return l.toArray();
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.jobs.AbstractNotificationJob#executeNotificationJob(org.apache.directory.studio.connection.core.StudioProgressMonitor)
+     */
+    protected void executeNotificationJob( StudioProgressMonitor monitor )
+    {
+        monitor.beginTask( entriesToCopy.length == 1 ? BrowserCoreMessages.bind(
+            BrowserCoreMessages.jobs__copy_entries_task_1, new String[]
+                { entriesToCopy[0].getDn().getUpName(), parent.getDn().getUpName() } ) : BrowserCoreMessages.bind(
+            BrowserCoreMessages.jobs__copy_entries_task_n, new String[]
+                { Integer.toString( entriesToCopy.length ), parent.getDn().getUpName() } ), 2 + entriesToCopy.length );
+
+        monitor.reportProgress( " " ); //$NON-NLS-1$
+        monitor.worked( 1 );
+
+        if ( scope == SearchScope.OBJECT || scope == SearchScope.ONELEVEL || scope == SearchScope.SUBTREE )
+        {
+            int num = 0;
+            for ( int i = 0; !monitor.isCanceled() && i < entriesToCopy.length; i++ )
+            {
+                IEntry entryToCopy = entriesToCopy[i];
+
+                if ( scope == SearchScope.OBJECT
+                    || !parent.getDn().getNormName().endsWith( entryToCopy.getDn().getNormName() ) )
+                {
+                    num = copyEntryRecursive( entryToCopy, parent, scope, num, monitor );
+                }
+                else
+                {
+                    monitor.reportError( BrowserCoreMessages.jobs__copy_entries_source_and_target_are_equal );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.jobs.AbstractNotificationJob#runNotification()
+     */
+    protected void runNotification()
+    {
+        parent.setChildrenInitialized( false );
+        parent.setHasChildrenHint( true );
+        EventRegistry.fireEntryUpdated( new ChildrenInitializedEvent( parent ), this );
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.jobs.AbstractEclipseJob#getErrorMessage()
+     */
+    protected String getErrorMessage()
+    {
+        return entriesToCopy.length == 1 ? BrowserCoreMessages.jobs__copy_entries_error_1
+            : BrowserCoreMessages.jobs__copy_entries_error_n;
+    }
+
+
+    /**
+     * Copies the entry recursive.
+     * 
+     * @param entryToCopy the entry to copy
+     * @param parent the parent entry
+     * @param scope the copy scope
+     * @param num the number of copied entries
+     * @param monitor the progress monitor
+     * 
+     * @return the number of copied entries
+     */
+    private int copyEntryRecursive( IEntry entryToCopy, IEntry parent, SearchScope scope, int num, StudioProgressMonitor monitor )
+    {
+        try
+        {
+            // TODO: use JNDI here!!!
+            SearchParameter param = new SearchParameter();
+            param.setSearchBase( entryToCopy.getDn() );
+            param.setFilter( ISearch.FILTER_TRUE );
+            param.setScope( SearchScope.OBJECT );
+            param.setAliasesDereferencingMethod( AliasDereferencingMethod.NEVER );
+            param.setReferralsHandlingMethod( ReferralHandlingMethod.IGNORE );
+            param.setReturningAttributes( new String[]
+                { ISearch.ALL_USER_ATTRIBUTES, IAttribute.REFERRAL_ATTRIBUTE } );
+            ISearch search = new Search( entryToCopy.getBrowserConnection(), param );
+            
+            SearchJob.searchAndUpdateModel( entryToCopy.getBrowserConnection(), search, monitor );
+
+            ISearchResult[] srs = search.getSearchResults();
+            if ( !monitor.isCanceled() && srs != null && srs.length == 1 )
+            {
+                entryToCopy = srs[0].getEntry();
+                IAttribute[] attributesToCopy = entryToCopy.getAttributes();
+
+                // create new entry
+                Rdn rdn = entryToCopy.getRdn();
+                IEntry newEntry = new Entry( parent, rdn );
+
+                // change RDN if entry already exists
+                StudioProgressMonitor testMonitor = new StudioProgressMonitor( monitor );
+                IEntry testEntry = ReadEntryJob.getEntry( parent.getBrowserConnection(), newEntry.getDn(), testMonitor );
+                if ( testEntry != null )
+                {
+                    Object rdnValue = rdn.getUpValue();
+                    String newRdnValue = BrowserCoreMessages.bind( BrowserCoreMessages.copy_n_of_s, "", rdnValue ); //$NON-NLS-1$
+                    Rdn newRdn = getNewRdn( rdn, newRdnValue );
+                    newEntry = new Entry( parent, newRdn );
+                    testEntry = ReadEntryJob.getEntry( parent.getBrowserConnection(), newEntry.getDn(), testMonitor );
+                    for ( int i = 2; testEntry != null; i++ )
+                    {
+                        newRdnValue = BrowserCoreMessages.bind( BrowserCoreMessages.copy_n_of_s, i + " ", rdnValue ); //$NON-NLS-1$
+                        newRdn = getNewRdn( rdn, newRdnValue );
+                        newEntry = new Entry( parent, newRdn );
+                        testEntry = ReadEntryJob.getEntry( parent.getBrowserConnection(), newEntry.getDn(), testMonitor );
+                    }
+                }
+
+                // copy attributes
+                for ( int i = 0; i < attributesToCopy.length; i++ )
+                {
+                    IAttribute attributeToCopy = attributesToCopy[i];
+
+                    if ( SchemaUtils.isModifyable( attributeToCopy.getAttributeTypeDescription() )
+                        || IAttribute.REFERRAL_ATTRIBUTE.equalsIgnoreCase( attributeToCopy.getDescription() ) )
+                    {
+                        IAttribute newAttribute = new Attribute( newEntry, attributeToCopy.getDescription() );
+                        newEntry.addAttribute( newAttribute );
+                        IValue[] valuesToCopy = attributeToCopy.getValues();
+                        for ( int j = 0; j < valuesToCopy.length; j++ )
+                        {
+                            IValue valueToCopy = valuesToCopy[j];
+                            IValue newValue = new Value( newAttribute, valueToCopy.getRawValue() );
+                            newAttribute.addValue( newValue );
+                        }
+                    }
+                }
+
+                // check if RDN attributes ar present
+                Rdn newRdn = newEntry.getRdn();
+                Iterator<AttributeTypeAndValue> atavIterator = newRdn.iterator();
+                while(atavIterator.hasNext())
+                {
+                    AttributeTypeAndValue atav = atavIterator.next();
+                    IAttribute rdnAttribute = newEntry.getAttribute( atav.getUpType() );
+                    if ( rdnAttribute != null )
+                    {
+                        IValue[] values = rdnAttribute.getValues();
+                        for ( int ii = 0; ii < values.length; ii++ )
+                        {
+                            if ( atav.getUpValue().equals( values[ii].getRawValue() ) )
+                            {
+                                rdnAttribute.deleteValue( values[ii] );
+                            }
+                            if ( rdnAttribute.getValueSize() == 0 )
+                            {
+                                newEntry.deleteAttribute( rdnAttribute );
+                            }
+                        }
+                    }
+                }
+                atavIterator = newRdn.iterator();
+                while(atavIterator.hasNext())
+                {
+                    AttributeTypeAndValue atav = atavIterator.next();
+                    IAttribute rdnAttribute = newEntry.getAttribute( atav.getUpType() );
+                    if ( rdnAttribute == null )
+                    {
+                        rdnAttribute = new Attribute( newEntry, atav.getUpType() );
+                        newEntry.addAttribute( rdnAttribute );
+                        rdnAttribute.addValue( new Value( rdnAttribute, atav.getUpValue() ) );
+                    }
+                    else
+                    {
+                        boolean mustAdd = true;
+                        IValue[] values = rdnAttribute.getValues();
+                        for ( int ii = 0; ii < values.length; ii++ )
+                        {
+                            if ( atav.getUpValue().equals( values[ii].getStringValue() ) )
+                            {
+                                mustAdd = false;
+                                break;
+                            }
+                        }
+                        if ( mustAdd )
+                        {
+                            rdnAttribute.addValue( new Value( rdnAttribute, atav.getUpValue() ) );
+                        }
+                    }
+                }
+
+                CreateEntryJob.createEntry( newEntry.getBrowserConnection(), newEntry, monitor );
+                newEntry.setHasChildrenHint( false );
+
+                num++;
+                monitor.reportProgress( BrowserCoreMessages.bind( BrowserCoreMessages.model__copied_n_entries,
+                    new String[]
+                        { Integer.toString( num ) } ) );
+
+                // check for children
+                if ( !monitor.isCanceled() && ( scope == SearchScope.ONELEVEL || scope == SearchScope.SUBTREE ) )
+                {
+                    // TODO: use JNDI here!!!
+                    SearchParameter subParam = new SearchParameter();
+                    subParam.setSearchBase( entryToCopy.getDn() );
+                    subParam.setFilter( ISearch.FILTER_TRUE );
+                    subParam.setScope( SearchScope.ONELEVEL );
+                    subParam.setReturningAttributes( ISearch.NO_ATTRIBUTES );
+                    ISearch subSearch = new Search( entryToCopy.getBrowserConnection(), subParam );
+                    SearchJob.searchAndUpdateModel( entryToCopy.getBrowserConnection(), subSearch, monitor );
+
+                    ISearchResult[] subSrs = subSearch.getSearchResults();
+                    if ( !monitor.isCanceled() && subSrs != null && subSrs.length > 0 )
+                    {
+                        for ( int i = 0; i < subSrs.length; i++ )
+                        {
+                            ISearchResult subSearchResult = subSrs[i];
+                            IEntry childEntry = subSearchResult.getEntry();
+
+                            if ( scope == SearchScope.ONELEVEL )
+                            {
+                                num = this
+                                    .copyEntryRecursive( childEntry, newEntry,SearchScope.OBJECT, num, monitor );
+                            }
+                            else if ( scope == SearchScope.SUBTREE )
+                            {
+                                num = this.copyEntryRecursive( childEntry, newEntry, SearchScope.SUBTREE, num,
+                                    monitor );
+                            }
+                        }
+
+                    }
+                }
+            }
+        }
+        catch ( Exception e )
+        {
+            monitor.reportError( e );
+        }
+        return num;
+    }
+
+
+    /**
+     * Gets the new rdn.
+     * 
+     * @param rdn the rdn
+     * @param newRdnValue the new rdn value
+     * 
+     * @return the new rdn
+     * @throws InvalidNameException 
+     */
+    private Rdn getNewRdn( Rdn rdn, String newRdnValue ) throws InvalidNameException
+    {
+        String[] rdnTypes = new String[rdn.size()];
+        String[] rdnValues = new String[rdn.size()];
+        int i = 0;
+        Iterator<AttributeTypeAndValue> atavIterator = rdn.iterator();
+        while(atavIterator.hasNext())
+        {
+            AttributeTypeAndValue atav = atavIterator.next();
+            rdnTypes[i] = atav.getUpType();
+            rdnValues[i] = ( String ) atav.getUpValue();
+            i++;
+        }
+        rdnValues[0] = newRdnValue;
+        Rdn newRdn = DnUtils.composeRdn( rdnTypes, rdnValues );
+        return newRdn;
+    }
+
+}

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

Added: directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/CreateEntryJob.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/CreateEntryJob.java?rev=592082&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/CreateEntryJob.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/CreateEntryJob.java Mon Nov  5 08:51:43 2007
@@ -0,0 +1,186 @@
+/*
+ *  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.ldapbrowser.core.jobs;
+
+
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.ldap.Control;
+import javax.naming.ldap.ManageReferralControl;
+
+import org.apache.directory.studio.connection.core.Connection;
+import org.apache.directory.studio.connection.core.StudioProgressMonitor;
+import org.apache.directory.studio.ldapbrowser.core.BrowserCoreMessages;
+import org.apache.directory.studio.ldapbrowser.core.events.EntryAddedEvent;
+import org.apache.directory.studio.ldapbrowser.core.events.EventRegistry;
+import org.apache.directory.studio.ldapbrowser.core.model.IAttribute;
+import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection;
+import org.apache.directory.studio.ldapbrowser.core.model.IEntry;
+import org.apache.directory.studio.ldapbrowser.core.model.IValue;
+
+
+/**
+ * Job to create an entry asynchronously.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class CreateEntryJob extends AbstractNotificationJob
+{
+
+    /** The entry to create. */
+    private IEntry entryToCreate;
+
+    /** The browser connection. */
+    private IBrowserConnection browserConnection;
+
+    /** The created entry. */
+    private IEntry createdEntry;
+
+
+    /**
+     * Creates a new instance of CreateEntryJob.
+     * 
+     * @param entryToCreate the entry to create
+     * @param browserConnection the browser connection
+     */
+    public CreateEntryJob( IEntry entryToCreate, IBrowserConnection browserConnection )
+    {
+        this.entryToCreate = entryToCreate;
+        this.browserConnection = browserConnection;
+        this.createdEntry = null;
+
+        setName( BrowserCoreMessages.jobs__create_entry_name_1 );
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.jobs.AbstractEclipseJob#getConnections()
+     */
+    protected Connection[] getConnections()
+    {
+        return new Connection[]
+            { browserConnection.getConnection() };
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.jobs.AbstractEclipseJob#getLockedObjects()
+     */
+    protected Object[] getLockedObjects()
+    {
+        return new Object[]
+            { browserConnection };
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.jobs.AbstractNotificationJob#executeNotificationJob(org.apache.directory.studio.connection.core.StudioProgressMonitor)
+     */
+    protected void executeNotificationJob( StudioProgressMonitor monitor )
+    {
+        monitor.beginTask( BrowserCoreMessages.bind( BrowserCoreMessages.jobs__create_entry_task_1, new String[]
+            { entryToCreate.getDn().getUpName() } ), 2 + 1 );
+        monitor.reportProgress( " " ); //$NON-NLS-1$
+        monitor.worked( 1 );
+
+        createEntry( browserConnection, entryToCreate, monitor );
+
+        if ( !monitor.errorsReported() )
+        {
+            createdEntry = ReadEntryJob.getEntry( browserConnection, entryToCreate.getDn(), monitor );
+            // createdEntries[i].getParententry().addChild(entry, this);
+            createdEntry.setHasChildrenHint( false );
+        }
+
+        monitor.reportProgress( " " ); //$NON-NLS-1$
+        monitor.worked( 1 );
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.jobs.AbstractNotificationJob#runNotification()
+     */
+    protected void runNotification()
+    {
+        if ( createdEntry != null )
+        {
+            EventRegistry.fireEntryUpdated( new EntryAddedEvent( browserConnection, createdEntry ), this );
+        }
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.jobs.AbstractEclipseJob#getErrorMessage()
+     */
+    protected String getErrorMessage()
+    {
+        return BrowserCoreMessages.jobs__create_entry_error_1;
+    }
+
+
+    /**
+     * Creates the entry using the underlying JNDI connection wrapper.
+     * 
+     * @param browserConnection the browser connection
+     * @param entryToCreate the entry to create
+     * @param monitor the monitor
+     */
+    static void createEntry( IBrowserConnection browserConnection, IEntry entryToCreate, StudioProgressMonitor monitor )
+    {
+        // dn
+        String dn = entryToCreate.getDn().getUpName();
+
+        // attributes
+        Attributes jndiAttributes = new BasicAttributes();
+        IAttribute[] attributes = entryToCreate.getAttributes();
+        for ( int i = 0; i < attributes.length; i++ )
+        {
+            String description = attributes[i].getDescription();
+            IValue[] values = attributes[i].getValues();
+            for ( int ii = 0; ii < values.length; ii++ )
+            {
+                IValue value = values[ii];
+                Object rawValue = value.getRawValue();
+                if ( jndiAttributes.get( description ) != null )
+                {
+                    jndiAttributes.get( description ).add( rawValue );
+                }
+                else
+                {
+                    jndiAttributes.put( description, rawValue );
+                }
+            }
+        }
+
+        // controls
+        Control[] controls = null;
+        if ( entryToCreate.isReferral() )
+        {
+            controls = new Control[]
+                { new ManageReferralControl() };
+        }
+
+        browserConnection.getConnection().getJNDIConnectionWrapper()
+            .createEntry( dn, jndiAttributes, controls, monitor );
+    }
+
+}

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

Added: directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/CreateValuesJob.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/CreateValuesJob.java?rev=592082&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/CreateValuesJob.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/CreateValuesJob.java Mon Nov  5 08:51:43 2007
@@ -0,0 +1,230 @@
+/*
+ *  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.ldapbrowser.core.jobs;
+
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+import javax.naming.ldap.Control;
+import javax.naming.ldap.ManageReferralControl;
+
+import org.apache.directory.studio.connection.core.StudioProgressMonitor;
+import org.apache.directory.studio.ldapbrowser.core.BrowserCoreMessages;
+import org.apache.directory.studio.ldapbrowser.core.events.AttributesInitializedEvent;
+import org.apache.directory.studio.ldapbrowser.core.events.EntryModificationEvent;
+import org.apache.directory.studio.ldapbrowser.core.events.EventRegistry;
+import org.apache.directory.studio.ldapbrowser.core.events.ValueAddedEvent;
+import org.apache.directory.studio.ldapbrowser.core.model.IAttribute;
+import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection;
+import org.apache.directory.studio.ldapbrowser.core.model.IEntry;
+import org.apache.directory.studio.ldapbrowser.core.model.IValue;
+import org.apache.directory.studio.ldapbrowser.core.model.impl.Attribute;
+import org.apache.directory.studio.ldapbrowser.core.model.impl.Value;
+
+
+/**
+ * Job to create values asynchronously.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class CreateValuesJob extends AbstractAttributeModificationJob
+{
+
+    /** The entry to modify. */
+    private IEntry entry;
+
+    /** The values to create. */
+    private IValue[] valuesToCreate;
+
+    /** The created values. */
+    private IValue[] createdValues;
+
+
+    /**
+     * Creates a new instance of CreateValuesJob.
+     * 
+     * @param entry the entry to modify
+     * @param valuesToCreate the values to create
+     */
+    public CreateValuesJob( IEntry entry, IValue[] valuesToCreate )
+    {
+        this.entry = entry;
+        this.valuesToCreate = valuesToCreate;
+
+        setName( valuesToCreate.length == 1 ? BrowserCoreMessages.jobs__create_values_name_1
+            : BrowserCoreMessages.jobs__create_values_name_n );
+    }
+
+
+    /**
+     * Creates a new instance of CreateValuesJob.
+     *
+     * @param attribute the attribute to modify
+     * @param newValue the new value
+     */
+    public CreateValuesJob( IAttribute attribute, Object newValue )
+    {
+        this( attribute.getEntry(), new IValue[]
+            { new Value( attribute, newValue ) } );
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.jobs.AbstractAttributeModificationJob#executeAttributeModificationJob(org.apache.directory.studio.connection.core.StudioProgressMonitor)
+     */
+    protected void executeAttributeModificationJob( StudioProgressMonitor monitor )
+    {
+        monitor.beginTask( valuesToCreate.length == 1 ? BrowserCoreMessages.jobs__create_values_task_1
+            : BrowserCoreMessages.jobs__create_values_task_n, 2 );
+        monitor.reportProgress( " " ); //$NON-NLS-1$
+        monitor.worked( 1 );
+
+        IValue[] newValues = new IValue[valuesToCreate.length];
+        for ( int i = 0; i < newValues.length; i++ )
+        {
+            IAttribute attribute = entry.getAttribute( valuesToCreate[i].getAttribute().getDescription() );
+            if ( attribute == null )
+            {
+                attribute = new Attribute( entry, valuesToCreate[i].getAttribute().getDescription() );
+            }
+
+            newValues[i] = new Value( attribute, valuesToCreate[i].getRawValue() );
+        }
+
+        createValues( entry.getBrowserConnection(), entry, newValues, monitor );
+        if ( !monitor.errorsReported() )
+        {
+            createdValues = newValues;
+        }
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.jobs.AbstractAttributeModificationJob#getModifiedEntry()
+     */
+    protected IEntry getModifiedEntry()
+    {
+        return entry;
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.jobs.AbstractAttributeModificationJob#getAffectedAttributeDescriptions()
+     */
+    protected String[] getAffectedAttributeDescriptions()
+    {
+        Set<String> attributeDescriptionSet = new HashSet<String>();
+        for ( IValue value : valuesToCreate )
+        {
+            attributeDescriptionSet.add( value.getAttribute().getDescription() );
+        }
+        return attributeDescriptionSet.toArray( new String[attributeDescriptionSet.size()] );
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.jobs.AbstractNotificationJob#runNotification()
+     */
+    protected void runNotification()
+    {
+        EntryModificationEvent event;
+
+        if ( createdValues != null && createdValues.length > 0 )
+        {
+            event = new ValueAddedEvent( entry.getBrowserConnection(), entry, createdValues[0].getAttribute(),
+                createdValues[0] );
+        }
+        else
+        {
+            event = new AttributesInitializedEvent( entry );
+        }
+
+        EventRegistry.fireEntryUpdated( event, this );
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.jobs.AbstractEclipseJob#getErrorMessage()
+     */
+    protected String getErrorMessage()
+    {
+        return valuesToCreate.length == 1 ? BrowserCoreMessages.jobs__create_values_error_1
+            : BrowserCoreMessages.jobs__create_values_error_n;
+    }
+
+
+    /**
+     * Creates the values using the underlying JNDI connection wrapper.
+     * 
+     * @param browserConnection the browser connection
+     * @param entryToModify the entry to modify
+     * @param valuesToCreate the values to create
+     * @param monitor the progress monitor
+     */
+    static void createValues( IBrowserConnection browserConnection, IEntry entryToModify, IValue[] valuesToCreate,
+        StudioProgressMonitor monitor )
+    {
+        if ( browserConnection.getConnection() != null )
+        {
+            // dn
+            String dn = entryToModify.getDn().getUpName();
+
+            // modification items
+            ModificationItem[] modificationItems = new ModificationItem[valuesToCreate.length];
+            for ( int i = 0; i < modificationItems.length; i++ )
+            {
+                BasicAttribute attribute = new BasicAttribute( valuesToCreate[i].getAttribute().getDescription(),
+                    valuesToCreate[i].getRawValue() );
+                modificationItems[i] = new ModificationItem( DirContext.ADD_ATTRIBUTE, attribute );
+            }
+
+            // controls
+            Control[] controls = null;
+            if ( entryToModify.isReferral() )
+            {
+                controls = new Control[]
+                    { new ManageReferralControl() };
+            }
+
+            browserConnection.getConnection().getJNDIConnectionWrapper().modifyAttributes( dn, modificationItems,
+                controls, monitor );
+        }
+        else
+        {
+            for ( IValue value : valuesToCreate )
+            {
+                IAttribute attribute = entryToModify.getAttribute( value.getAttribute().getDescription() );
+                if ( attribute == null )
+                {
+                    attribute = new Attribute( entryToModify, value.getAttribute().getDescription() );
+                    entryToModify.addAttribute( attribute );
+                }
+                attribute.addValue( value );
+            }
+        }
+    }
+
+}

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

Added: directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/DeleteAttributesValueJob.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/DeleteAttributesValueJob.java?rev=592082&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/DeleteAttributesValueJob.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/DeleteAttributesValueJob.java Mon Nov  5 08:51:43 2007
@@ -0,0 +1,278 @@
+/*
+ *  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.ldapbrowser.core.jobs;
+
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+import javax.naming.ldap.Control;
+import javax.naming.ldap.ManageReferralControl;
+
+import org.apache.directory.studio.connection.core.StudioProgressMonitor;
+import org.apache.directory.studio.ldapbrowser.core.BrowserCoreMessages;
+import org.apache.directory.studio.ldapbrowser.core.events.AttributeDeletedEvent;
+import org.apache.directory.studio.ldapbrowser.core.events.AttributesInitializedEvent;
+import org.apache.directory.studio.ldapbrowser.core.events.EntryModificationEvent;
+import org.apache.directory.studio.ldapbrowser.core.events.EventRegistry;
+import org.apache.directory.studio.ldapbrowser.core.events.ValueDeletedEvent;
+import org.apache.directory.studio.ldapbrowser.core.model.AttributeHierarchy;
+import org.apache.directory.studio.ldapbrowser.core.model.IAttribute;
+import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection;
+import org.apache.directory.studio.ldapbrowser.core.model.IEntry;
+import org.apache.directory.studio.ldapbrowser.core.model.IValue;
+
+
+/**
+ * Job to delete attributes and values from an entry.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class DeleteAttributesValueJob extends AbstractAttributeModificationJob
+{
+
+    /** The entry. */
+    private IEntry entry;
+
+    /** The attributes to delete. */
+    private IAttribute[] attributesToDelete;
+
+    /** The values to delete. */
+    private IValue[] valuesToDelete;
+
+    /** The deleted attributes. */
+    private IAttribute[] deletedAttributes;
+
+    /** The deleted values. */
+    private IValue[] deletedValues;
+
+
+    /**
+     * Creates a new instance of DeleteAttributesValueJob.
+     * 
+     * @param attributesToDelete the attributes to delete
+     * @param valuesToDelete the values to delete
+     */
+    public DeleteAttributesValueJob( IAttribute attributesToDelete[], IValue[] valuesToDelete )
+    {
+        this.attributesToDelete = attributesToDelete;
+        this.valuesToDelete = valuesToDelete;
+        for ( int i = 0; attributesToDelete != null && i < attributesToDelete.length; i++ )
+        {
+            if ( this.entry == null )
+            {
+                this.entry = attributesToDelete[i].getEntry();
+            }
+        }
+        for ( int i = 0; valuesToDelete != null && i < valuesToDelete.length; i++ )
+        {
+            if ( this.entry == null )
+            {
+                this.entry = valuesToDelete[i].getAttribute().getEntry();
+            }
+        }
+
+        setName( attributesToDelete.length + valuesToDelete.length == 1 ? BrowserCoreMessages.jobs__delete_attributes_name_1
+            : BrowserCoreMessages.jobs__delete_attributes_name_n );
+    }
+
+
+    /**
+     * Creates a new instance of DeleteAttributesValueJob.
+     * 
+     * @param attributeHierarchyToDelete the attribute hierarchy to delete
+     */
+    public DeleteAttributesValueJob( AttributeHierarchy attributeHierarchyToDelete )
+    {
+        this( attributeHierarchyToDelete.getAttributes(), new IValue[0] );
+    }
+
+
+    /**
+     * Creates a new instance of DeleteAttributesValueJob.
+     * 
+     * @param valueToDelete the value to delete
+     */
+    public DeleteAttributesValueJob( IValue valueToDelete )
+    {
+        this( new IAttribute[0], new IValue[]
+            { valueToDelete } );
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.jobs.AbstractAttributeModificationJob#executeAttributeModificationJob(org.apache.directory.studio.connection.core.StudioProgressMonitor)
+     */
+    protected void executeAttributeModificationJob( StudioProgressMonitor monitor )
+    {
+        monitor.beginTask(
+            attributesToDelete.length + valuesToDelete.length == 1 ? BrowserCoreMessages.jobs__delete_attributes_task_1
+                : BrowserCoreMessages.jobs__delete_attributes_task_n, 2 );
+        monitor.reportProgress( " " ); //$NON-NLS-1$
+        monitor.worked( 1 );
+
+        deleteAttributesAndValues( entry.getBrowserConnection(), entry, attributesToDelete, valuesToDelete, monitor );
+
+        if ( !monitor.errorsReported() )
+        {
+            deletedValues = valuesToDelete;
+            deletedAttributes = attributesToDelete;
+        }
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.jobs.AbstractAttributeModificationJob#getModifiedEntry()
+     */
+    protected IEntry getModifiedEntry()
+    {
+        return entry;
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.jobs.AbstractAttributeModificationJob#getAffectedAttributeDescriptions()
+     */
+    protected String[] getAffectedAttributeDescriptions()
+    {
+        Set<String> affectedAttributeNameSet = new HashSet<String>();
+        for ( int i = 0; i < attributesToDelete.length; i++ )
+        {
+            affectedAttributeNameSet.add( attributesToDelete[i].getDescription() );
+        }
+        for ( int i = 0; i < valuesToDelete.length; i++ )
+        {
+            affectedAttributeNameSet.add( valuesToDelete[i].getAttribute().getDescription() );
+        }
+        return affectedAttributeNameSet.toArray( new String[affectedAttributeNameSet.size()] );
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.jobs.AbstractNotificationJob#runNotification()
+     */
+    protected void runNotification()
+    {
+        EntryModificationEvent event;
+
+        if ( deletedValues != null && deletedValues.length > 0 )
+        {
+            event = new ValueDeletedEvent( entry.getBrowserConnection(), entry, deletedValues[0].getAttribute(),
+                deletedValues[0] );
+        }
+        else if ( deletedAttributes != null && deletedAttributes.length > 0 )
+        {
+            event = new AttributeDeletedEvent( entry.getBrowserConnection(), entry, deletedAttributes[0] );
+        }
+        else
+        {
+            event = new AttributesInitializedEvent( entry );
+        }
+
+        EventRegistry.fireEntryUpdated( event, this );
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.jobs.AbstractEclipseJob#getErrorMessage()
+     */
+    protected String getErrorMessage()
+    {
+        return attributesToDelete.length + valuesToDelete.length == 1 ? BrowserCoreMessages.jobs__delete_attributes_error_1
+            : BrowserCoreMessages.jobs__delete_attributes_error_n;
+    }
+
+
+    /**
+     * Delete attributes and values.
+     * 
+     * @param browserConnection the browser connection
+     * @param entry the entry
+     * @param attributesToDelete the attributes to delete
+     * @param valuesToDelete the values to delete
+     * @param monitor the progress monitor
+     */
+    static void deleteAttributesAndValues( IBrowserConnection browserConnection, IEntry entry,
+        IAttribute[] attributesToDelete, IValue[] valuesToDelete, StudioProgressMonitor monitor )
+    {
+        if ( browserConnection.getConnection() != null )
+        {
+            // dn
+            String dn = entry.getDn().getUpName();
+
+            // modification items
+            List<ModificationItem> modificationItems = new ArrayList<ModificationItem>();
+            if ( attributesToDelete != null )
+            {
+                for ( IAttribute attribute : attributesToDelete )
+                {
+                    BasicAttribute ba = new BasicAttribute( attribute.getDescription() );
+                    ModificationItem modificationItem = new ModificationItem( DirContext.REMOVE_ATTRIBUTE, ba );
+                    modificationItems.add( modificationItem );
+                }
+            }
+            if ( valuesToDelete != null )
+            {
+                for ( IValue value : valuesToDelete )
+                {
+                    BasicAttribute ba = new BasicAttribute( value.getAttribute().getDescription(), value.getRawValue() );
+                    ModificationItem modificationItem = new ModificationItem( DirContext.REMOVE_ATTRIBUTE, ba );
+                    modificationItems.add( modificationItem );
+                }
+            }
+
+            // controls
+            Control[] controls = null;
+            if ( entry.isReferral() )
+            {
+                controls = new Control[]
+                    { new ManageReferralControl() };
+            }
+
+            browserConnection.getConnection().getJNDIConnectionWrapper().modifyAttributes( dn,
+                modificationItems.toArray( new ModificationItem[modificationItems.size()] ), controls, monitor );
+        }
+        else
+        {
+            if ( attributesToDelete != null )
+            {
+                for ( IAttribute attribute : attributesToDelete )
+                {
+                    attribute.getEntry().deleteAttribute( attribute );
+                }
+            }
+            if ( valuesToDelete != null )
+            {
+                for ( IValue value : valuesToDelete )
+                {
+                    value.getAttribute().deleteValue( value );
+                }
+            }
+        }
+    }
+
+}

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

Added: directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/DeleteEntriesJob.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/DeleteEntriesJob.java?rev=592082&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/DeleteEntriesJob.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/DeleteEntriesJob.java Mon Nov  5 08:51:43 2007
@@ -0,0 +1,307 @@
+/*
+ *  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.ldapbrowser.core.jobs;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.naming.ldap.Control;
+import javax.naming.ldap.ManageReferralControl;
+
+import org.apache.directory.studio.connection.core.Connection;
+import org.apache.directory.studio.connection.core.StudioProgressMonitor;
+import org.apache.directory.studio.ldapbrowser.core.BrowserCoreMessages;
+import org.apache.directory.studio.ldapbrowser.core.events.ChildrenInitializedEvent;
+import org.apache.directory.studio.ldapbrowser.core.events.EntryDeletedEvent;
+import org.apache.directory.studio.ldapbrowser.core.events.EventRegistry;
+import org.apache.directory.studio.ldapbrowser.core.events.SearchUpdateEvent;
+import org.apache.directory.studio.ldapbrowser.core.model.IAttribute;
+import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection;
+import org.apache.directory.studio.ldapbrowser.core.model.IEntry;
+import org.apache.directory.studio.ldapbrowser.core.model.ISearch;
+import org.apache.directory.studio.ldapbrowser.core.model.ISearchResult;
+import org.apache.directory.studio.ldapbrowser.core.model.SearchParameter;
+import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection.AliasDereferencingMethod;
+import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection.ReferralHandlingMethod;
+import org.apache.directory.studio.ldapbrowser.core.model.ISearch.SearchScope;
+import org.apache.directory.studio.ldapbrowser.core.model.impl.Search;
+
+
+/*
+ * Search+Delete vs. Delete+SearchOnError
+ * 
+ * Test for:
+ * - delete leaf entry 100.000 times
+ * - tree with 100.000 childs
+ * - tree with 1000 childs each with 1000 childs 
+ * 
+ */
+
+public class DeleteEntriesJob extends AbstractNotificationJob
+{
+
+    private IEntry[] entriesToDelete;
+
+    private Set deletedEntriesSet = new HashSet();
+
+    private Set entriesToUpdateSet = new HashSet();
+
+    private Set searchesToUpdateSet = new HashSet();
+
+
+    public DeleteEntriesJob( final IEntry[] entriesToDelete )
+    {
+        this.entriesToDelete = entriesToDelete;
+        setName( entriesToDelete.length == 1 ? BrowserCoreMessages.jobs__delete_entries_name_1
+            : BrowserCoreMessages.jobs__delete_entries_name_n );
+    }
+
+
+    protected Connection[] getConnections()
+    {
+        Connection[] connections = new Connection[entriesToDelete.length];
+        for ( int i = 0; i < connections.length; i++ )
+        {
+            connections[i] = entriesToDelete[i].getBrowserConnection().getConnection();
+        }
+        return connections;
+    }
+
+
+    protected Object[] getLockedObjects()
+    {
+        List l = new ArrayList();
+        l.addAll( Arrays.asList( entriesToDelete ) );
+        return l.toArray();
+    }
+
+
+    protected void executeNotificationJob( StudioProgressMonitor monitor )
+    {
+
+        monitor.beginTask( entriesToDelete.length == 1 ? BrowserCoreMessages.bind(
+            BrowserCoreMessages.jobs__delete_entries_task_1, new String[]
+                { entriesToDelete[0].getDn().getUpName() } ) : BrowserCoreMessages.bind(
+            BrowserCoreMessages.jobs__delete_entries_task_n, new String[]
+                { Integer.toString( entriesToDelete.length ) } ), 2 + entriesToDelete.length );
+        monitor.reportProgress( " " ); //$NON-NLS-1$
+        monitor.worked( 1 );
+
+        int num = 0;
+        for ( int i = 0; !monitor.isCanceled() && !monitor.errorsReported() && i < entriesToDelete.length; i++ )
+        {
+
+            IEntry entryToDelete = entriesToDelete[i];
+            IBrowserConnection connection = entryToDelete.getBrowserConnection();
+
+            // delete from directory
+            // TODO: use TreeDelete Control, if available
+            int errorStatusSize1 = monitor.getErrorStatus( "" ).getChildren().length; //$NON-NLS-1$
+            num = deleteEntryRecursive( entryToDelete, false, num, monitor );
+            int errorStatusSize2 = monitor.getErrorStatus( "" ).getChildren().length; //$NON-NLS-1$
+            deletedEntriesSet.add( entryToDelete );
+
+            if ( errorStatusSize1 == errorStatusSize2 )
+            {
+                // delete from parent
+                entryToDelete.getParententry().deleteChild( entryToDelete );
+                entriesToUpdateSet.add( entryToDelete.getParententry() );
+
+                // delete from searches
+                ISearch[] searches = connection.getSearchManager().getSearches();
+                for ( int j = 0; j < searches.length; j++ )
+                {
+                    ISearch search = searches[j];
+                    if ( search.getSearchResults() != null )
+                    {
+                        ISearchResult[] searchResults = search.getSearchResults();
+                        for ( int k = 0; k < searchResults.length; k++ )
+                        {
+                            ISearchResult result = searchResults[k];
+                            if ( entryToDelete.equals( result.getEntry() ) )
+                            {
+                                ISearchResult[] newsrs = new ISearchResult[searchResults.length - 1];
+                                System.arraycopy( searchResults, 0, newsrs, 0, k );
+                                System.arraycopy( searchResults, k + 1, newsrs, k, searchResults.length - k - 1 );
+                                search.setSearchResults( newsrs );
+                                searchResults = newsrs;
+                                k--;
+                                searchesToUpdateSet.add( search );
+                            }
+                        }
+                    }
+                }
+            }
+
+            monitor.worked( 1 );
+        }
+    }
+
+
+    
+    private int deleteEntryRecursive( IBrowserConnection browserConnection, String dn, int numberOfDeletedEntries, StudioProgressMonitor monitor )
+    {
+//        int numberInBatch;
+//        
+//        JNDIConnectionWrapper connectionWrapper = browserConnection.getConnection().getJNDIConnectionWrapper();
+//        
+//        SearchControls searchControls = new SearchControls();
+//        searchControls.setCountLimit( 1000 );
+//        searchControls.setReturningAttributes( new String[]
+//                                                          { IAttribute.OBJECTCLASS_ATTRIBUTE, IAttribute.REFERRAL_ATTRIBUTE } );
+//        searchControls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+//        
+//        connectionWrapper.search( dn, ISearch.FILTER_TRUE, searchControls, derefAliasMethod, handleReferralsMethod, controls, monitor )
+        
+        return 0;
+    }
+    
+    
+    private int deleteEntryRecursive( IEntry entry, boolean refInitialized, int numberOfDeletedEntries,
+        StudioProgressMonitor monitor )
+    {
+        try
+        {
+            int numberInBatch;
+            do
+            {
+                numberInBatch = 0;
+                
+                // TODO: use JNDI here!!!
+                
+                SearchParameter subParam = new SearchParameter();
+                subParam.setSearchBase( entry.getDn() );
+                subParam.setFilter( ISearch.FILTER_TRUE );
+                subParam.setScope( SearchScope.ONELEVEL );
+                subParam.setAliasesDereferencingMethod( AliasDereferencingMethod.NEVER );
+                subParam.setReferralsHandlingMethod( ReferralHandlingMethod.IGNORE );
+                subParam.setReturningAttributes( new String[]
+                    { IAttribute.OBJECTCLASS_ATTRIBUTE, IAttribute.REFERRAL_ATTRIBUTE } );
+                subParam.setCountLimit( 1000 );
+                ISearch search = new Search( entry.getBrowserConnection(), subParam );
+                SearchJob.searchAndUpdateModel( entry.getBrowserConnection(), search, monitor );
+
+                ISearchResult[] srs = search.getSearchResults();
+                for ( int i = 0; !monitor.isCanceled() && srs != null && i < srs.length; i++ )
+                {
+                    IEntry childEntry = srs[i].getEntry();
+                    numberOfDeletedEntries = this.deleteEntryRecursive( childEntry, true, numberOfDeletedEntries,
+                        monitor );
+                    numberInBatch++;
+                }
+            }
+            while ( numberInBatch > 0 && !monitor.isCanceled() && !monitor.errorsReported() );
+
+            if ( !monitor.isCanceled() && !monitor.errorsReported() )
+            {
+                // check for referrals
+                if ( !refInitialized )
+                {
+                    // TODO: use JNDI here!!!
+                    SearchParameter param = new SearchParameter();
+                    param.setSearchBase( entry.getDn() );
+                    param.setFilter( ISearch.FILTER_TRUE );
+                    param.setScope( SearchScope.OBJECT );
+                    param.setAliasesDereferencingMethod( AliasDereferencingMethod.NEVER );
+                    param.setReferralsHandlingMethod( ReferralHandlingMethod.IGNORE );
+                    param.setReturningAttributes( new String[]
+                        { IAttribute.OBJECTCLASS_ATTRIBUTE, IAttribute.REFERRAL_ATTRIBUTE } );
+                    ISearch search = new Search( entry.getBrowserConnection(), param );
+                    SearchJob.searchAndUpdateModel( entry.getBrowserConnection(), search, monitor );
+
+                    ISearchResult[] srs = search.getSearchResults();
+                    if ( !monitor.isCanceled() && srs != null && srs.length == 1 )
+                    {
+                        entry = srs[0].getEntry();
+                    }
+                }
+
+                int errorStatusSize1 = monitor.getErrorStatus( "" ).getChildren().length; //$NON-NLS-1$
+                deleteEntry( entry.getBrowserConnection(), entry, monitor );
+                int errorStatusSize2 = monitor.getErrorStatus( "" ).getChildren().length; //$NON-NLS-1$
+
+                if ( errorStatusSize1 == errorStatusSize2 )
+                {
+                    numberOfDeletedEntries++;
+                    monitor.reportProgress( BrowserCoreMessages.bind( BrowserCoreMessages.model__deleted_n_entries,
+                        new String[]
+                            { "" + numberOfDeletedEntries } ) ); //$NON-NLS-1$
+                }
+            }
+
+        }
+        catch ( Exception e )
+        {
+            monitor.reportError( e );
+        }
+
+        return numberOfDeletedEntries;
+    }
+
+
+    protected void runNotification()
+    {
+        for ( Iterator it = deletedEntriesSet.iterator(); it.hasNext(); )
+        {
+            IEntry entry = ( IEntry ) it.next();
+            EventRegistry.fireEntryUpdated( new EntryDeletedEvent( entry.getBrowserConnection(), entry ), this );
+        }
+        for ( Iterator it = entriesToUpdateSet.iterator(); it.hasNext(); )
+        {
+            IEntry parent = ( IEntry ) it.next();
+            EventRegistry.fireEntryUpdated( new ChildrenInitializedEvent( parent ), this );
+        }
+        for ( Iterator it = searchesToUpdateSet.iterator(); it.hasNext(); )
+        {
+            ISearch search = ( ISearch ) it.next();
+            EventRegistry.fireSearchUpdated( new SearchUpdateEvent( search, SearchUpdateEvent.EventDetail.SEARCH_PERFORMED ), this );
+        }
+    }
+
+
+    protected String getErrorMessage()
+    {
+        return entriesToDelete.length == 1 ? BrowserCoreMessages.jobs__delete_entries_error_1
+            : BrowserCoreMessages.jobs__delete_entries_error_n;
+    }
+
+    static void deleteEntry( IBrowserConnection browserConnection, IEntry entry, StudioProgressMonitor monitor )
+    {
+        // dn
+        String dn = entry.getDn().getUpName();
+
+        // controls
+        Control[] controls = null;
+        if ( entry.isReferral() )
+        {
+            controls = new Control[]
+                { new ManageReferralControl() };
+        }
+
+        browserConnection.getConnection().getJNDIConnectionWrapper()
+            .deleteEntry( dn, controls, monitor );
+    }
+}

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

Added: directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExecuteLdifJob.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExecuteLdifJob.java?rev=592082&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExecuteLdifJob.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExecuteLdifJob.java Mon Nov  5 08:51:43 2007
@@ -0,0 +1,148 @@
+/*
+ *  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.ldapbrowser.core.jobs;
+
+
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.directory.studio.connection.core.Connection;
+import org.apache.directory.studio.connection.core.StudioProgressMonitor;
+import org.apache.directory.studio.ldapbrowser.core.BrowserCoreMessages;
+import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection;
+import org.apache.directory.studio.ldapbrowser.core.model.ldif.LdifEnumeration;
+import org.apache.directory.studio.ldapbrowser.core.model.ldif.parser.LdifParser;
+
+
+/**
+ * Job to execute an LDIF.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ExecuteLdifJob extends AbstractEclipseJob
+{
+
+    /** The browser connection. */
+    private IBrowserConnection browserConnection;
+
+    /** The LDIF to execute. */
+    private String ldif;
+
+    /** The continue on error flag. */
+    private boolean continueOnError;
+
+
+    /**
+     * Creates a new instance of ExecuteLdifJob.
+     * 
+     * @param browserConnection the browser connection
+     * @param ldif the LDIF to execute
+     * @param continueOnError the continue on error flag
+     */
+    public ExecuteLdifJob( IBrowserConnection browserConnection, String ldif, boolean continueOnError )
+    {
+        this.browserConnection = browserConnection;
+        this.ldif = ldif;
+        this.continueOnError = continueOnError;
+
+        setName( BrowserCoreMessages.jobs__execute_ldif_name );
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.jobs.AbstractEclipseJob#getConnections()
+     */
+    protected Connection[] getConnections()
+    {
+        return new Connection[]
+            { browserConnection.getConnection() };
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.jobs.AbstractEclipseJob#getLockedObjects()
+     */
+    protected Object[] getLockedObjects()
+    {
+        List<Object> l = new ArrayList<Object>();
+        l.add( browserConnection.getUrl() + "_" + DigestUtils.shaHex( ldif ) );
+        return l.toArray();
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.jobs.AbstractEclipseJob#executeAsyncJob(org.apache.directory.studio.connection.core.StudioProgressMonitor)
+     */
+    protected void executeAsyncJob( StudioProgressMonitor monitor )
+    {
+        monitor.beginTask( BrowserCoreMessages.jobs__execute_ldif_task, 2 );
+        monitor.reportProgress( " " ); //$NON-NLS-1$
+        monitor.worked( 1 );
+
+        try
+        {
+            Reader ldifReader = new StringReader( this.ldif );
+            LdifParser parser = new LdifParser();
+            LdifEnumeration enumeration = parser.parse( ldifReader );
+
+            Writer logWriter = new Writer()
+            {
+                public void close()
+                {
+                }
+
+
+                public void flush()
+                {
+                }
+
+
+                public void write( char[] cbuf, int off, int len )
+                {
+                }
+            };
+
+            ImportLdifJob.importLdif( browserConnection, enumeration, logWriter, continueOnError, monitor );
+
+            logWriter.close();
+            ldifReader.close();
+        }
+        catch ( Exception e )
+        {
+            monitor.reportError( e );
+        }
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.ldapbrowser.core.jobs.AbstractEclipseJob#getErrorMessage()
+     */
+    protected String getErrorMessage()
+    {
+        return BrowserCoreMessages.jobs__execute_ldif_error;
+    }
+
+}

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