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

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

/*
*  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.List;

import org.apache.directory.studio.connection.core.Connection;
import org.apache.directory.studio.connection.core.StudioControl;
import org.apache.directory.studio.connection.core.StudioPagedResultsControl;
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.jobs.StudioBulkRunnableWithProgress;
import org.apache.directory.studio.connection.core.jobs.StudioProgressMonitor;
import org.apache.directory.studio.ldapbrowser.core.BrowserCoreConstants;
import org.apache.directory.studio.ldapbrowser.core.BrowserCoreMessages;
import org.apache.directory.studio.ldapbrowser.core.BrowserCorePlugin;
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.IBrowserConnection;
import org.apache.directory.studio.ldapbrowser.core.model.IEntry;
import org.apache.directory.studio.ldapbrowser.core.model.IRootDSE;
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.ISearch.SearchScope;
import org.apache.directory.studio.ldapbrowser.core.model.impl.ContinuedSearchResultEntry;
import org.apache.directory.studio.ldapbrowser.core.model.impl.Search;
import org.apache.directory.studio.ldapbrowser.core.model.impl.SearchContinuation;


/**
* Runnable to initialize the child entries of an entry
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
* @version $Rev$, $Date$
*/
public class InitializeChildrenRunnable implements StudioBulkRunnableWithProgress
{

    /** The entries. */
    private IEntry[] entries;

    /** The purge all caches flag. */
    private boolean purgeAllCaches;

    /** The paged search control, only used internally. */
    private StudioControl pagedSearchControl;


    /**
     * Creates a new instance of InitializeChildrenRunnable.
     *
     * @param entries the entries
     * @param purgeAllCaches true to purge all caches
     */
    public InitializeChildrenRunnable( boolean purgeAllCaches, IEntry... entries )
    {
        this.entries = entries;
        this.purgeAllCaches = purgeAllCaches;
    }


    /**
     * Creates a new instance of InitializeChildrenRunnable.
     *
     * @param entry the entry
     * @param pagedSearchControl the paged search control
     */
    private InitializeChildrenRunnable( IEntry entry, StudioControl pagedSearchControl )
    {
        this.entries = new IEntry[]
            { entry };
        this.pagedSearchControl = pagedSearchControl;
    }


    /**
     * {@inheritDoc}
     */
    public Connection[] getConnections()
    {
        Connection[] connections = new Connection[entries.length];
        for ( int i = 0; i < connections.length; i++ )
        {
            connections[i] = entries[i].getBrowserConnection().getConnection();
        }
        return connections;
    }


    /**
     * {@inheritDoc}
     */
    public String getName()
    {
        return BrowserCoreMessages.jobs__init_entries_title_subonly;
    }


    /**
     * {@inheritDoc}
     */
    public Object[] getLockedObjects()
    {
        List<Object> l = new ArrayList<Object>();
        l.addAll( Arrays.asList( entries ) );
        return l.toArray();
    }


    /**
     * {@inheritDoc}
     */
    public String getErrorMessage()
    {
        return entries.length == 1 ? BrowserCoreMessages.jobs__init_entries_error_1
            : BrowserCoreMessages.jobs__init_entries_error_n;
    }


    /**
     * {@inheritDoc}
     */
    public void run( StudioProgressMonitor monitor )
    {
        monitor.beginTask( " ", entries.length + 2 ); //$NON-NLS-1$
        monitor.reportProgress( " " ); //$NON-NLS-1$

        for ( IEntry entry : entries )
        {
            monitor.setTaskName( BrowserCoreMessages.bind( BrowserCoreMessages.jobs__init_entries_task, new String[]
                { entry.getDn().getUpName() } ) );
            monitor.worked( 1 );

            IBrowserConnection browserConnection = entry.getBrowserConnection();
            if ( browserConnection != null )
            {
                if ( entry instanceof IRootDSE )
                {
                    // special handling for Root DSE
                    InitializeRootDSERunnable.loadRootDSE( browserConnection, monitor );
                    continue;
                }

                if ( pagedSearchControl == null && browserConnection.isPagedSearch() )
                {
                    pagedSearchControl = new StudioPagedResultsControl( browserConnection.getPagedSearchSize(), null,
                        false, browserConnection.isPagedSearchScrollMode() );
                }

                initializeChildren( entry, monitor, pagedSearchControl );
            }
        }
    }


    /**
     * {@inheritDoc}
     */
    public void runNotification( StudioProgressMonitor monitor )
    {
        for ( IEntry entry : entries )
        {
            if ( entry.getBrowserConnection() != null && entry.isChildrenInitialized() )
            {
                EventRegistry.fireEntryUpdated( new ChildrenInitializedEvent( entry ), this );
            }
        }
    }


    /**
     * Initializes the child entries.
     *
     * @param parent the parent
     * @param monitor the progress monitor
     * @param pagedSearchControl the paged search control
     */
    private void initializeChildren( IEntry parent, StudioProgressMonitor monitor, StudioControl pagedSearchControl )
    {
        monitor.reportProgress( BrowserCoreMessages.bind( BrowserCoreMessages.jobs__init_entries_progress_sub,
            new String[]
                { parent.getDn().getUpName() } ) );

        // clear old children
        clearCaches( parent, purgeAllCaches );

        // create search
        ISearch search = createSearch( parent, pagedSearchControl, false, false, false );

        // search
        executeSearch( parent, search, monitor );
        ISearchResult[] srs = search.getSearchResults();
        SearchContinuation[] scs = search.getSearchContinuations();

        // fill children in search result
        if ( ( srs != null && srs.length > 0 ) || ( scs != null && scs.length > 0 ) )
        {
            // clearing old children before filling new children is
            // necessary to handle aliases and referrals.
            clearCaches( parent, false );

            do
            {
                if ( srs != null )
                {
                    for ( ISearchResult searchResult : srs )
                    {
                        parent.addChild( searchResult.getEntry() );
                    }
                    srs = null;
                }

                if ( scs != null )
                {
                    for ( SearchContinuation searchContinuation : scs )
                    {
                        ContinuedSearchResultEntry entry = new ContinuedSearchResultEntry( parent
                            .getBrowserConnection(), searchContinuation.getUrl().getDn() );
                        entry.setUnresolved( searchContinuation.getUrl() );
                        parent.addChild( entry );
                    }
                    scs = null;
                }

                StudioPagedResultsControl sprRequestControl = null;
                StudioPagedResultsControl sprResponseControl = null;
                for ( StudioControl responseControl : search.getResponseControls() )
                {
                    if ( responseControl instanceof StudioPagedResultsControl )
                    {
                        sprResponseControl = ( StudioPagedResultsControl ) responseControl;
                    }
                }
                for ( StudioControl requestControl : search.getControls() )
                {
                    if ( requestControl instanceof StudioPagedResultsControl )
                    {
                        sprRequestControl = ( StudioPagedResultsControl ) requestControl;
                    }
                }

                if ( sprRequestControl != null && sprResponseControl != null )
                {
                    if ( sprRequestControl.isScrollMode() )
                    {
                        if ( sprRequestControl.getCookie() != null )
                        {
                            // create top page search runnable, same as original search
                            InitializeChildrenRunnable topPageChildrenRunnable = new InitializeChildrenRunnable(
                                parent, null );
                            parent.setTopPageChildrenRunnable( topPageChildrenRunnable );
                        }

                        if ( sprResponseControl.getCookie() != null )
                        {
                            StudioPagedResultsControl newSprc = new StudioPagedResultsControl( sprRequestControl
                                .getSize(), sprResponseControl.getCookie(), sprRequestControl.isCritical(),
                                sprRequestControl.isScrollMode() );
                            InitializeChildrenRunnable nextPageChildrenRunnable = new InitializeChildrenRunnable(
                                parent, newSprc );
                            parent.setNextPageChildrenRunnable( nextPageChildrenRunnable );
                        }
                    }
                    else
                    {
                        // transparently continue search, till count limit is reached
                        if ( sprResponseControl.getCookie() != null
                            && ( search.getCountLimit() == 0 || search.getSearchResults().length < search
                                .getCountLimit() ) )
                        {

                            search.setSearchResults( new ISearchResult[0] );
                            search.getResponseControls().clear();
                            sprRequestControl.setCookie( sprResponseControl.getCookie() );

                            executeSearch( parent, search, monitor );
                            srs = search.getSearchResults();
                            scs = search.getSearchContinuations();
                        }
                    }
                }
            }
            while ( srs != null && srs.length > 0 );
        }
        else
        {
            parent.setHasChildrenHint( false );
        }

        // get sub-entries
        ISearch subSearch = createSearch( parent, null, true, false, false );
        if ( parent.getBrowserConnection().isFetchSubentries() || parent.isFetchSubentries() )
        {
            executeSubSearch( parent, subSearch, monitor );
        }

        // get aliases and referrals
        ISearch aliasOrReferralSearch = createSearch( parent, null, false, parent.isFetchAliases(), parent
            .isFetchReferrals() );
        if ( parent.isFetchAliases() || parent.isFetchReferrals() )
        {
            executeSubSearch( parent, aliasOrReferralSearch, monitor );
        }

        // check exceeded limits / canceled
        parent.setHasMoreChildren( search.isCountLimitExceeded() || subSearch.isCountLimitExceeded()
            || aliasOrReferralSearch.isCountLimitExceeded() || monitor.isCanceled() );

        // set initialized state
        parent.setChildrenInitialized( true );
    }


    private void executeSubSearch( IEntry parent, ISearch subSearch, StudioProgressMonitor monitor )
    {
        executeSearch( parent, subSearch, monitor );
        ISearchResult[] subSrs = subSearch.getSearchResults();
        SearchContinuation[] subScs = subSearch.getSearchContinuations();

        // fill children in search result
        if ( subSrs != null && subSrs.length > 0 )
        {
            for ( ISearchResult searchResult : subSrs )
            {
                parent.addChild( searchResult.getEntry() );
            }
            for ( SearchContinuation searchContinuation : subScs )
            {
                ContinuedSearchResultEntry entry = new ContinuedSearchResultEntry( parent.getBrowserConnection(),
                    searchContinuation.getUrl().getDn() );
                entry.setUnresolved( searchContinuation.getUrl() );
                parent.addChild( entry );
            }
        }
    }


    private static void executeSearch( IEntry parent, ISearch search, StudioProgressMonitor monitor )
    {
        SearchRunnable.searchAndUpdateModel( parent.getBrowserConnection(), search, monitor );
        ISearchResult[] srs = search.getSearchResults();
        monitor.reportProgress( BrowserCoreMessages.bind( BrowserCoreMessages.jobs__init_entries_progress_subcount,
            new String[]
                { srs == null ? Integer.toString( 0 ) : Integer.toString( srs.length ), parent.getDn().getUpName() } ) );
    }


    private static ISearch createSearch( IEntry parent, StudioControl pagedSearchControl, boolean isSubentriesSearch,
        boolean isAliasSearch, boolean isReferralsSearch )
    {
        // scope
        SearchScope scope = SearchScope.ONELEVEL;

        // filter
        String filter = parent.getChildrenFilter();
        if ( isSubentriesSearch )
        {
            filter = ISearch.FILTER_SUBENTRY;
        }
        else if ( isAliasSearch && isReferralsSearch )
        {
            filter = ISearch.FILTER_ALIAS_OR_REFERRAL;
        }
        else if ( isAliasSearch )
        {
            filter = ISearch.FILTER_ALIAS;
        }
        else if ( isReferralsSearch )
        {
            filter = ISearch.FILTER_REFERRAL;
        }

        // alias handling
        AliasDereferencingMethod aliasesDereferencingMethod = parent.getBrowserConnection()
            .getAliasesDereferencingMethod();
        if ( parent.isAlias() || isAliasSearch )
        {
            aliasesDereferencingMethod = AliasDereferencingMethod.NEVER;
        }

        // referral handling
        ReferralHandlingMethod referralsHandlingMethod = parent.getBrowserConnection().getReferralsHandlingMethod();

        // create search
        ISearch search = new Search( null, parent.getBrowserConnection(), parent.getDn(), filter,
            ISearch.NO_ATTRIBUTES, scope, parent.getBrowserConnection().getCountLimit(), parent.getBrowserConnection()
                .getTimeLimit(), aliasesDereferencingMethod, referralsHandlingMethod, BrowserCorePlugin.getDefault()
                .getPluginPreferences().getBoolean( BrowserCoreConstants.PREFERENCE_CHECK_FOR_CHILDREN ), null );

        // controls
        if ( parent.isReferral() || isReferralsSearch || parent.getBrowserConnection().isManageDsaIT() )
        {
            search.getSearchParameter().getControls().add( StudioControl.MANAGEDSAIT_CONTROL );
        }
        if ( isSubentriesSearch )
        {
            search.getSearchParameter().getControls().add( StudioControl.SUBENTRIES_CONTROL );
        }
        if ( pagedSearchControl != null )
        {
            search.getSearchParameter().getControls().add( pagedSearchControl );
        }

        return search;
    }


    static void clearCaches( IEntry entry, boolean purgeAllCaches )
    {
        // clear the parent-child relationship, recursively
        IEntry[] children = entry.getChildren();
        if ( children != null )
        {
            for ( IEntry child : children )
            {
                if ( child != null )
                {
                    entry.deleteChild( child );
                    clearCaches( child, purgeAllCaches );
                }
            }
        }
        entry.setChildrenInitialized( false );

        // reset paging runnables
        entry.setTopPageChildrenRunnable( null );
        entry.setNextPageChildrenRunnable( null );

        // reset attributes and additional flags
        if ( purgeAllCaches )
        {
            entry.setAttributesInitialized( false );
            entry.setHasChildrenHint( true );
            entry.setHasMoreChildren( false );
        }
    }

}
TOP

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

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.