Package org.apache.directory.studio.ldapbrowser.core.jobs

Source Code of org.apache.directory.studio.ldapbrowser.core.jobs.ImportDsmlJob

/*
*  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.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;

import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.ModificationItem;
import javax.naming.directory.SearchControls;
import javax.naming.ldap.Control;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.directory.shared.dsmlv2.Dsmlv2Parser;
import org.apache.directory.shared.dsmlv2.reponse.AddResponseDsml;
import org.apache.directory.shared.dsmlv2.reponse.AuthResponseDsml;
import org.apache.directory.shared.dsmlv2.reponse.BatchResponseDsml;
import org.apache.directory.shared.dsmlv2.reponse.CompareResponseDsml;
import org.apache.directory.shared.dsmlv2.reponse.DelResponseDsml;
import org.apache.directory.shared.dsmlv2.reponse.ExtendedResponseDsml;
import org.apache.directory.shared.dsmlv2.reponse.ModDNResponseDsml;
import org.apache.directory.shared.dsmlv2.reponse.ModifyResponseDsml;
import org.apache.directory.shared.dsmlv2.request.BatchRequest;
import org.apache.directory.shared.ldap.codec.ControlCodec;
import org.apache.directory.shared.ldap.codec.LdapConstants;
import org.apache.directory.shared.ldap.codec.LdapMessageCodec;
import org.apache.directory.shared.ldap.codec.LdapResultCodec;
import org.apache.directory.shared.ldap.codec.add.AddRequestCodec;
import org.apache.directory.shared.ldap.codec.bind.BindRequestCodec;
import org.apache.directory.shared.ldap.codec.compare.CompareRequestCodec;
import org.apache.directory.shared.ldap.codec.del.DelRequestCodec;
import org.apache.directory.shared.ldap.codec.extended.ExtendedRequestCodec;
import org.apache.directory.shared.ldap.codec.modify.ModifyRequestCodec;
import org.apache.directory.shared.ldap.codec.modifyDn.ModifyDNRequestCodec;
import org.apache.directory.shared.ldap.codec.search.SearchRequestCodec;
import org.apache.directory.shared.ldap.codec.util.LdapURLEncodingException;
import org.apache.directory.shared.ldap.entry.Entry;
import org.apache.directory.shared.ldap.entry.EntryAttribute;
import org.apache.directory.shared.ldap.entry.Modification;
import org.apache.directory.shared.ldap.entry.ModificationOperation;
import org.apache.directory.shared.ldap.message.MessageTypeEnum;
import org.apache.directory.shared.ldap.message.ResultCodeEnum;
import org.apache.directory.shared.ldap.name.LdapDN;
import org.apache.directory.shared.ldap.util.AttributeUtils;
import org.apache.directory.studio.connection.core.Connection;
import org.apache.directory.studio.connection.core.DnUtils;
import org.apache.directory.studio.connection.core.Connection.AliasDereferencingMethod;
import org.apache.directory.studio.connection.core.Connection.ReferralHandlingMethod;
import org.apache.directory.studio.connection.core.io.jndi.StudioNamingEnumeration;
import org.apache.directory.studio.connection.core.jobs.StudioProgressMonitor;
import org.apache.directory.studio.ldapbrowser.core.BrowserCoreMessages;
import org.apache.directory.studio.ldapbrowser.core.events.BulkModificationEvent;
import org.apache.directory.studio.ldapbrowser.core.events.EventRegistry;
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.SearchParameter;

import com.sun.jndi.ldap.BasicControl;


/**
* This class implements a Job for Importing a DSML File into a LDAP server
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
* @version $Rev$, $Date$
*/
public class ImportDsmlJob extends AbstractNotificationJob
{
    /** The connection to use */
    private IBrowserConnection browserConnection;

    /** The DSML file to use */
    private File dsmlFile;

    /** The Save file to use */
    private File responseFile;


    /**
     * Creates a new instance of ImportDsmlJob.
     *
     * @param connection
     *          The connection to use
     * @param dsmlFile
     *          The DSML file to read from
     * @param saveFile
     *          The Save file to use
     * @param continueOnError
     *          The ContinueOnError flag
     */
    public ImportDsmlJob( IBrowserConnection connection, File dsmlFile, File saveFile )
    {
        this.browserConnection = connection;
        this.dsmlFile = dsmlFile;
        this.responseFile = saveFile;

        setName( BrowserCoreMessages.jobs__import_dsml_name );
    }


    /**
     * Creates a new instance of ImportDsmlJob.
     *
     * @param connection
     *          The Connection to use
     * @param dsmlFile
     *          The DSML file to read from
     * @param continueOnError
     *          The ContinueOnError flag
     */
    public ImportDsmlJob( IBrowserConnection connection, File dsmlFile )
    {
        this( connection, dsmlFile, null );
    }


    /**
     * {@inheritDoc}
     */
    protected Connection[] getConnections()
    {
        return new Connection[]
            { browserConnection.getConnection() };
    }


    /**
     * {@inheritDoc}
     */
    protected Object[] getLockedObjects()
    {
        List<Object> l = new ArrayList<Object>();
        l.add( browserConnection.getUrl() + "_" + DigestUtils.shaHex( dsmlFile.toString() ) );
        return l.toArray();
    }


    /**
     * {@inheritDoc}
     */
    protected void executeNotificationJob( StudioProgressMonitor monitor )
    {
        monitor.beginTask( BrowserCoreMessages.jobs__import_dsml_task, 2 );
        monitor.reportProgress( " " ); //$NON-NLS-1$
        monitor.worked( 1 );

        try
        {
            // Parsing the file
            Dsmlv2Parser parser = new Dsmlv2Parser();
            parser.setInput( new FileInputStream( dsmlFile ), "UTF-8" );
            parser.parseAllRequests();

            // Getting the batch request
            BatchRequest batchRequest = parser.getBatchRequest();

            // Creating a DSML batch response (only if needed)
            BatchResponseDsml batchResponseDsml = null;
            if ( responseFile != null )
            {
                batchResponseDsml = new BatchResponseDsml();
            }

            // Setting the errors counter
            int errorsCount = 0;

            // Creating a dummy monitor that will be used to check if something
            // went wrong when executing the request
            StudioProgressMonitor dummyMonitor = new StudioProgressMonitor( monitor );

            // Processing each request
            List<?> requests = batchRequest.getRequests();
            for ( Object request : requests )
            {
                // Processing the request
                processRequest( request, batchResponseDsml, dummyMonitor );

                // Verifying if any error has been reported
                if ( dummyMonitor.errorsReported() )
                {
                    errorsCount++;
                }

                dummyMonitor.reset();
            }

            // Writing the DSML response file to its final destination file.
            if ( responseFile != null )
            {
                FileOutputStream fos = new FileOutputStream( responseFile );
                OutputStreamWriter osw = new OutputStreamWriter( fos, "UTF-8" );
                BufferedWriter bufferedWriter = new BufferedWriter( osw );
                bufferedWriter.write( batchResponseDsml.toDsml() );
                bufferedWriter.close();
                osw.close();
                fos.close();
            }

            // Displaying an error message if we've had some errors
            if ( errorsCount > 0 )
            {
                monitor.reportError( BrowserCoreMessages.bind(
                    "{0} errors occurred, see the response file for details", new String[]
                        { "" + errorsCount } ) );
            }
        }
        catch ( Exception e )
        {
            monitor.reportError( e );
        }
    }


    /**
     * Processes the request.
     *
     * @param request
     *      the request
     * @param batchResponseDsml
     *      the DSML batch response (can be <code>null</code>)
     * @throws NamingException
     * @throws LdapURLEncodingException
     */
    private void processRequest( Object request, BatchResponseDsml batchResponseDsml, StudioProgressMonitor monitor )
        throws NamingException, LdapURLEncodingException
    {
        if ( request instanceof BindRequestCodec )
        {
            processBindRequest( ( BindRequestCodec ) request, batchResponseDsml, monitor );
        }
        else if ( request instanceof AddRequestCodec )
        {
            processAddRequest( ( AddRequestCodec ) request, batchResponseDsml, monitor );
        }
        else if ( request instanceof CompareRequestCodec )
        {
            processCompareRequest( ( CompareRequestCodec ) request, batchResponseDsml, monitor );
        }
        else if ( request instanceof DelRequestCodec )
        {
            processDelRequest( ( DelRequestCodec ) request, batchResponseDsml, monitor );
        }
        else if ( request instanceof ExtendedRequestCodec )
        {
            processExtendedRequest( ( ExtendedRequestCodec ) request, batchResponseDsml, monitor );
        }
        else if ( request instanceof ModifyRequestCodec )
        {
            processModifyRequest( ( ModifyRequestCodec ) request, batchResponseDsml, monitor );
        }
        else if ( request instanceof ModifyDNRequestCodec )
        {
            processModifyDNRequest( ( ModifyDNRequestCodec ) request, batchResponseDsml, monitor );
        }
        else if ( request instanceof SearchRequestCodec )
        {
            processSearchRequest( ( SearchRequestCodec ) request, batchResponseDsml, monitor );
        }
    }


    /**
     * Processes an bind request.
     *
     * @param request
     *      the request
     * @param batchResponseDsml
     *      the DSML batch response (can be <code>null</code>)
     */
    private void processBindRequest( BindRequestCodec request, BatchResponseDsml batchResponseDsml,
        StudioProgressMonitor monitor )
    {
        // We can not support extended requests at the moment,
        // we need a more advanced connection wrapper.

        // Creating the response
        if ( batchResponseDsml != null )
        {
            AuthResponseDsml authResponseDsml = new AuthResponseDsml();
            LdapResultCodec ldapResult = new LdapResultCodec();
            ldapResult.setResultCode( ResultCodeEnum.UNWILLING_TO_PERFORM );
            ldapResult.setErrorMessage( "This kind of request is not yet supported." );
            authResponseDsml.setLdapResult( ldapResult );
            batchResponseDsml.addResponse( authResponseDsml );
        }
    }


    /**
     * Processes an add request.
     *
     * @param request
     *      the request
     * @param batchResponseDsml
     *      the DSML batch response (can be <code>null</code>)
     */
    private void processAddRequest( AddRequestCodec request, BatchResponseDsml batchResponseDsml,
        StudioProgressMonitor monitor )
    {
        // Executing the add request
        Entry entry = request.getEntry();
        browserConnection.getConnection().getJNDIConnectionWrapper().createEntry( entry.getDn().getUpName(),
            AttributeUtils.toAttributes( entry ), getControls( request ), monitor, null );

        // Creating the response
        if ( batchResponseDsml != null )
        {
            AddResponseDsml addResponseDsml = new AddResponseDsml();
            addResponseDsml.setLdapResult( getLdapResult( monitor, MessageTypeEnum.ADD_REQUEST ) );
            addResponseDsml.getLdapResult().setMatchedDN( entry.getDn() );
            batchResponseDsml.addResponse( addResponseDsml );
        }

        // Update cached entries
        LdapDN dn = entry.getDn();
        IEntry e = browserConnection.getEntryFromCache( dn );
        LdapDN parentDn = DnUtils.getParent( dn );
        IEntry parentEntry = parentDn != null ? browserConnection.getEntryFromCache( parentDn ) : null;
        if ( e != null )
        {
            e.setAttributesInitialized( false );
        }
        if ( parentEntry != null )
        {
            parentEntry.setChildrenInitialized( false );
        }
    }


    /**
     * Processes a compare request.
     *
     * @param request
     *      the request
     * @param batchResponseDsml
     *      the DSML batch response (can be <code>null</code>)
     */
    private void processCompareRequest( CompareRequestCodec request, BatchResponseDsml batchResponseDsml,
        StudioProgressMonitor monitor )
    {
        // We can not support extended requests at the moment,
        // we need a more advanced connection wrapper.

        // Creating the response
        if ( batchResponseDsml != null )
        {
            CompareResponseDsml compareResponseDsml = new CompareResponseDsml();
            LdapResultCodec ldapResult = new LdapResultCodec();
            ldapResult.setResultCode( ResultCodeEnum.UNWILLING_TO_PERFORM );
            ldapResult.setErrorMessage( "This kind of request is not yet supported." );
            compareResponseDsml.setLdapResult( ldapResult );
            batchResponseDsml.addResponse( compareResponseDsml );
        }
    }


    /**
     * Processes a del request.
     *
     * @param request
     *      the request
     * @param batchResponseDsml
     *      the DSML batch response (can be <code>null</code>)
     */
    private void processDelRequest( DelRequestCodec request, BatchResponseDsml batchResponseDsml,
        StudioProgressMonitor monitor )
    {
        // Executing the del request
        browserConnection.getConnection().getJNDIConnectionWrapper().deleteEntry( request.getEntry().getUpName(),
            getControls( request ), monitor, null );

        // Creating the response
        if ( batchResponseDsml != null )
        {
            DelResponseDsml delResponseDsml = new DelResponseDsml();
            delResponseDsml.setLdapResult( getLdapResult( monitor, MessageTypeEnum.DEL_REQUEST ) );
            delResponseDsml.getLdapResult().setMatchedDN( request.getEntry() );
            batchResponseDsml.addResponse( delResponseDsml );
        }

        // Update cached entries
        LdapDN dn = request.getEntry();
        IEntry e = browserConnection.getEntryFromCache( dn );
        LdapDN parentDn = DnUtils.getParent( dn );
        IEntry parentEntry = parentDn != null ? browserConnection.getEntryFromCache( parentDn ) : null;
        if ( e != null )
        {
            e.setAttributesInitialized( false );
            browserConnection.uncacheEntryRecursive( e );
        }
        if ( parentEntry != null )
        {
            parentEntry.setChildrenInitialized( false );
        }
    }


    /**
     * Processes an extended request.
     *
     * @param request
     *      the request
     * @param batchResponseDsml
     *      the DSML batch response (can be <code>null</code>)
     */
    private void processExtendedRequest( ExtendedRequestCodec request, BatchResponseDsml batchResponseDsml,
        StudioProgressMonitor monitor )
    {
        // We can not support extended requests at the moment,
        // we need a more advanced connection wrapper.

        // Creating the response
        if ( batchResponseDsml != null )
        {
            ExtendedResponseDsml extendedResponseDsml = new ExtendedResponseDsml();
            LdapResultCodec ldapResult = new LdapResultCodec();
            ldapResult.setResultCode( ResultCodeEnum.UNWILLING_TO_PERFORM );
            ldapResult.setErrorMessage( "This kind of request is not yet supported." );
            extendedResponseDsml.setLdapResult( ldapResult );
            batchResponseDsml.addResponse( extendedResponseDsml );
        }
    }


    /**
     * Processes a modify request.
     *
     * @param request
     *      the request
     * @param batchResponseDsml
     *      the DSML batch response (can be <code>null</code>)
     */
    private void processModifyRequest( ModifyRequestCodec request, BatchResponseDsml batchResponseDsml,
        StudioProgressMonitor monitor )
    {
        // Creating the modification items
        List<ModificationItem> modificationItems = new ArrayList<ModificationItem>();
        for ( Modification modification : request.getModifications() )
        {
            modificationItems.add( new ModificationItem( convertModificationOperation( modification.getOperation() ),
                AttributeUtils.toAttribute( modification.getAttribute() ) ) );
        }

        // Executing the modify request
        browserConnection.getConnection().getJNDIConnectionWrapper().modifyEntry( request.getObject().getUpName(),
            modificationItems.toArray( new ModificationItem[0] ), getControls( request ), monitor, null );

        // Creating the response
        if ( batchResponseDsml != null )
        {
            ModifyResponseDsml modifyResponseDsml = new ModifyResponseDsml();
            modifyResponseDsml.setLdapResult( getLdapResult( monitor, MessageTypeEnum.MODIFY_REQUEST ) );
            modifyResponseDsml.getLdapResult().setMatchedDN( request.getObject() );
            batchResponseDsml.addResponse( modifyResponseDsml );
        }

        LdapDN dn = request.getObject();
        IEntry e = browserConnection.getEntryFromCache( dn );
        if ( e != null )
        {
            e.setAttributesInitialized( false );
        }
    }


    /**
     * Converts the modification operation from Shared LDAP to JNDI
     *
     * @param operation
     *      the Shared LDAP modification operation
     * @return
     *      the equivalent modification operation in JNDI
     */
    private int convertModificationOperation( ModificationOperation operation )
    {
        switch ( operation )
        {
            case ADD_ATTRIBUTE:
                return DirContext.ADD_ATTRIBUTE;
            case REMOVE_ATTRIBUTE:
                return DirContext.REMOVE_ATTRIBUTE;
            case REPLACE_ATTRIBUTE:
                return DirContext.REPLACE_ATTRIBUTE;
            default:
                return 0;
        }
    }


    /**
     * Processes a modify DN request.
     *
     * @param request
     *      the request
     * @param batchResponseDsml
     *      the DSML batch response (can be <code>null</code>)
     */
    private void processModifyDNRequest( ModifyDNRequestCodec request, BatchResponseDsml batchResponseDsml,
        StudioProgressMonitor monitor )
    {
        // Executing the modify DN request
        browserConnection.getConnection().getJNDIConnectionWrapper().renameEntry( request.getEntry().getUpName(),
            request.getNewRDN().getUpName(), request.isDeleteOldRDN(), getControls( request ), monitor, null );

        // Creating the response
        if ( batchResponseDsml != null )
        {
            ModDNResponseDsml modDNResponseDsml = new ModDNResponseDsml();
            modDNResponseDsml.setLdapResult( getLdapResult( monitor, MessageTypeEnum.MOD_DN_REQUEST ) );
            modDNResponseDsml.getLdapResult().setMatchedDN( request.getEntry() );
            batchResponseDsml.addResponse( modDNResponseDsml );
        }

        // Update cached entries
        LdapDN dn = request.getEntry();
        IEntry e = browserConnection.getEntryFromCache( dn );
        LdapDN parentDn = DnUtils.getParent( dn );
        IEntry parentEntry = parentDn != null ? browserConnection.getEntryFromCache( parentDn ) : null;
        if ( e != null )
        {
            e.setAttributesInitialized( false );
            browserConnection.uncacheEntryRecursive( e );
        }
        if ( parentEntry != null )
        {
            parentEntry.setChildrenInitialized( false );
        }
        if ( request.getNewSuperior() != null )
        {
            LdapDN newSuperiorDn = request.getNewSuperior();
            IEntry newSuperiorEntry = browserConnection.getEntryFromCache( newSuperiorDn );
            if ( newSuperiorEntry != null )
            {
                newSuperiorEntry.setChildrenInitialized( false );
            }
        }
    }


    /**
     * Processes a search request.
     *
     * @param request
     *      the request
     * @param batchResponseDsml
     *      the DSML batch response (can be <code>null</code>)
     * @throws NamingException
     * @throws LdapURLEncodingException
     */
    private void processSearchRequest( SearchRequestCodec request, BatchResponseDsml batchResponseDsml,
        StudioProgressMonitor monitor ) throws NamingException, LdapURLEncodingException
    {
        // Creating the response
        if ( batchResponseDsml != null )
        {
            // [Optimization] We're only searching if we need to produce a response
            StudioNamingEnumeration ne = browserConnection.getConnection().getJNDIConnectionWrapper().search(
                request.getBaseObject().getUpName(), request.getFilter().toString(), getSearchControls( request ),
                getAliasDereferencingMethod( request ), ReferralHandlingMethod.IGNORE, getControls( request ), monitor,
                null );

            SearchParameter sp = new SearchParameter();
            sp.setReferralsHandlingMethod( browserConnection.getReferralsHandlingMethod() );
            ExportDsmlJob.processAsDsmlResponse( ne, batchResponseDsml, monitor, sp );
        }
    }


    /**
     * Returns the {@link SearchControls} object associated with the request.
     *
     * @param request
     *      the search request
     * @return
     *      the associated {@link SearchControls} object
     */
    private SearchControls getSearchControls( SearchRequestCodec request )
    {
        SearchControls controls = new SearchControls();

        // Scope
        switch ( request.getScope() )
        {
            case OBJECT:
                controls.setSearchScope( SearchControls.OBJECT_SCOPE );
                break;
            case ONELEVEL:
                controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
                break;
            case SUBTREE:
                controls.setSearchScope( SearchControls.SUBTREE_SCOPE );
                break;
            default:
                controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
        }

        // Returning attributes
        List<String> returningAttributes = new ArrayList<String>();
        for ( EntryAttribute entryAttribute : request.getAttributes() )
        {
            returningAttributes.add( entryAttribute.getId() );
        }
        // If the returning attributes are empty, we need to return the user attributes
        // [Cf. RFC 2251 - "There are two special values which may be used: an empty
        //  list with no attributes, and the attribute description string '*'.  Both of
        //  these signify that all user attributes are to be returned."]
        if ( returningAttributes.size() == 0 )
        {
            returningAttributes.add( "*" );
        }

        controls.setReturningAttributes( returningAttributes.toArray( new String[0] ) );

        // Size Limit
        controls.setCountLimit( request.getSizeLimit() );

        // Time Limit
        controls.setTimeLimit( request.getTimeLimit() );

        return controls;
    }


    /**
     * Returns the {@link AliasDereferencingMethod} object associated with the request.
     *
     * @param request
     *      the search request
     * @return
     *      the associated {@link AliasDereferencingMethod} object
     */
    private AliasDereferencingMethod getAliasDereferencingMethod( SearchRequestCodec request )
    {
        switch ( request.getDerefAliases() )
        {
            case LdapConstants.NEVER_DEREF_ALIASES:
                return AliasDereferencingMethod.NEVER;
            case LdapConstants.DEREF_ALWAYS:
                return AliasDereferencingMethod.ALWAYS;
            case LdapConstants.DEREF_FINDING_BASE_OBJ:
                return AliasDereferencingMethod.FINDING;
            case LdapConstants.DEREF_IN_SEARCHING:
                return AliasDereferencingMethod.SEARCH;
            default:
                return AliasDereferencingMethod.NEVER;
        }
    }


    private Control[] getControls( LdapMessageCodec request )
    {
        List<ControlCodec> controls = request.getControls();
        if ( controls != null )
        {
            List<Control> jndiControls = new ArrayList<Control>();
            for ( ControlCodec control : controls )
            {
                Control jndiControl = new BasicControl( control.getControlType(), control.getCriticality(), control
                    .getEncodedValue() );
                jndiControls.add( jndiControl );
            }
            return jndiControls.toArray( new Control[jndiControls.size()] );
        }
        return null;
    }


    /**
     * Get the LDAP Result corresponding to the given monitor
     *
     * @param monitor
     *      the progress monitor
     * @return
     *      the corresponding LDAP Result
     */
    private LdapResultCodec getLdapResult( StudioProgressMonitor monitor, MessageTypeEnum messageType )
    {
        LdapResultCodec ldapResult = new LdapResultCodec();

        if ( !monitor.errorsReported() )
        {
            ldapResult.setResultCode( ResultCodeEnum.SUCCESS );
        }
        else
        {
            // Getting the exception
            Throwable t = monitor.getException();

            // Setting the result code
            ldapResult.setResultCode( ResultCodeEnum.getBestEstimate( t, messageType ) );

            // Setting the error message if there's one
            if ( t.getMessage() != null )
            {
                ldapResult.setErrorMessage( t.getMessage() );
            }
        }

        return ldapResult;
    }


    /**
     * {@inheritDoc}
     */
    protected String getErrorMessage()
    {
        return BrowserCoreMessages.jobs__import_dsml_error;
    }


    /**
     * {@inheritDoc}
     */
    protected void runNotification()
    {
        EventRegistry.fireEntryUpdated( new BulkModificationEvent( browserConnection ), this );
    }

}
TOP

Related Classes of org.apache.directory.studio.ldapbrowser.core.jobs.ImportDsmlJob

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.