Package org.apache.directory.ldapstudio.browser.core.internal.model

Source Code of org.apache.directory.ldapstudio.browser.core.internal.model.ConnectionSearchHandler

/*
*  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.ldapstudio.browser.core.internal.model;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.apache.directory.ldapstudio.browser.core.BrowserCoreMessages;
import org.apache.directory.ldapstudio.browser.core.jobs.ExtendedProgressMonitor;
import org.apache.directory.ldapstudio.browser.core.model.AttributeHierarchy;
import org.apache.directory.ldapstudio.browser.core.model.Control;
import org.apache.directory.ldapstudio.browser.core.model.DN;
import org.apache.directory.ldapstudio.browser.core.model.IAttribute;
import org.apache.directory.ldapstudio.browser.core.model.IConnection;
import org.apache.directory.ldapstudio.browser.core.model.IEntry;
import org.apache.directory.ldapstudio.browser.core.model.IRootDSE;
import org.apache.directory.ldapstudio.browser.core.model.ISearch;
import org.apache.directory.ldapstudio.browser.core.model.ISearchResult;
import org.apache.directory.ldapstudio.browser.core.model.ModelModificationException;
import org.apache.directory.ldapstudio.browser.core.model.SearchParameter;
import org.apache.directory.ldapstudio.browser.core.model.ldif.LdifEnumeration;
import org.apache.directory.ldapstudio.browser.core.model.ldif.container.LdifContainer;
import org.apache.directory.ldapstudio.browser.core.model.ldif.container.LdifContentRecord;
import org.apache.directory.ldapstudio.browser.core.model.ldif.lines.LdifAttrValLine;
import org.apache.directory.ldapstudio.browser.core.model.schema.ObjectClassDescription;
import org.apache.directory.ldapstudio.browser.core.utils.Utils;


public class ConnectionSearchHandler
{

    private Connection connection;


    ConnectionSearchHandler( Connection connection )
    {
        this.connection = connection;
    }


    void connectionClosed()
    {
    }


    void connectionOpened()
    {
    }


    boolean existsEntry( DN dn, ExtendedProgressMonitor monitor )
    {
        SearchParameter sp = new SearchParameter();
        sp.setSearchBase( dn );
        sp.setFilter( ISearch.FILTER_TRUE );
        sp.setScope( ISearch.SCOPE_OBJECT );
        sp.setReturningAttributes( ISearch.NO_ATTRIBUTES );

        try
        {
            LdifEnumeration le = connection.connectionProvider.search( sp, monitor );
            return le.hasNext( monitor );
        }
        catch ( ConnectionException e )
        {
            monitor.reportError( e );
            return false;
        }
    }


    IEntry getEntry( DN dn, ExtendedProgressMonitor monitor )
    {
        try
        {
            // first check cache
            IEntry entry = connection.getEntryFromCache( dn );
            if ( entry != null )
            {
                return entry;
            }

            // search in directory
            ISearch search = new Search( null, connection, dn, null, ISearch.NO_ATTRIBUTES, ISearch.SCOPE_OBJECT, 1, 0,
                IConnection.DEREFERENCE_ALIASES_NEVER, IConnection.HANDLE_REFERRALS_IGNORE, true, true, null );
            this.search( search, monitor );
            ISearchResult[] srs = search.getSearchResults();
            if ( srs.length > 0 )
            {
                return srs[0].getEntry();
            }
            else
            {
                monitor.reportError( BrowserCoreMessages.model__no_such_entry );
                return null;
            }
        }
        catch ( Exception e )
        {
            monitor.reportError( e.getMessage(), e );
            return null;
        }
    }


    void search( ISearch search, ExtendedProgressMonitor monitor )
    {

        try
        {

            if ( !monitor.isCanceled() )
            {

                // add returning attributes for children and alias detection
                SearchParameter searchParameter = getSearchParameter( search );
                ArrayList searchResultList = new ArrayList();

                try
                {

                    // search
                    LdifEnumeration enumeration = connection.connectionProvider.search( searchParameter, monitor );

                    // iterate through the search result
                    while ( !monitor.isCanceled() && enumeration.hasNext( monitor ) )
                    {
                        LdifContainer container = enumeration.next( monitor );
                        if ( container instanceof LdifContentRecord )
                        {

                            LdifContentRecord record = ( LdifContentRecord ) container;
                            DN dn = new DN( record.getDnLine().getValueAsString() );

                            // get entry from cache or create it
                            IEntry entry = connection.getEntryFromCache( dn );
                            if ( entry == null )
                            {
                                entry = createAndCacheEntry( dn );
                            }

                            // initialize special flags
                            initFlags( entry, record, searchParameter );

                            // fill the attributes
                            fillAttributes( entry, record, searchParameter );

                            searchResultList
                                .add( new org.apache.directory.ldapstudio.browser.core.internal.model.SearchResult(
                                    entry, search ) );

                            monitor
                                .reportProgress( searchResultList.size() == 1 ? BrowserCoreMessages.model__retrieved_1_entry
                                    : BrowserCoreMessages.bind( BrowserCoreMessages.model__retrieved_n_entries,
                                        new String[]
                                            { Integer.toString( searchResultList.size() ) } ) );
                        }
                    }
                }
                catch ( ConnectionException ce )
                {

                    if ( ce.getLdapStatusCode() == 3 || ce.getLdapStatusCode() == 4 || ce.getLdapStatusCode() == 11 )
                    {
                        search.setCountLimitExceeded( true );
                    }
                    else if ( ce instanceof ReferralException )
                    {

                        if ( search.getReferralsHandlingMethod() == IConnection.HANDLE_REFERRALS_FOLLOW )
                        {

                            ReferralException re = ( ReferralException ) ce;
                            ISearch[] referralSearches = re.getReferralSearches();
                            for ( int i = 0; i < referralSearches.length; i++ )
                            {
                                ISearch referralSearch = referralSearches[i];

                                // open connection
                                if ( !referralSearch.getConnection().isOpened() )
                                {
                                    referralSearch.getConnection().open( monitor );
                                }

                                referralSearch.getConnection().search( referralSearch, monitor );

                                ISearchResult[] referralSearchResults = referralSearch.getSearchResults();
                                for ( int j = 0; referralSearchResults != null && j < referralSearchResults.length; j++ )
                                {
                                    ISearchResult referralSearchResult = referralSearchResults[j];
                                    referralSearchResult.setSearch( search );
                                    searchResultList.add( referralSearchResult );
                                }
                            }
                        }
                    }
                    else
                    {
                        monitor.reportError( ce );
                    }
                }

                monitor.reportProgress( searchResultList.size() == 1 ? BrowserCoreMessages.model__retrieved_1_entry
                    : BrowserCoreMessages.bind( BrowserCoreMessages.model__retrieved_n_entries, new String[]
                        { Integer.toString( searchResultList.size() ) } ) );
                monitor.worked( 1 );

                search.setSearchResults( ( ISearchResult[] ) searchResultList
                    .toArray( new ISearchResult[searchResultList.size()] ) );
            }
        }
        catch ( Exception e )
        {
            if ( search != null )
            {
                search.setSearchResults( new ISearchResult[0] );
            }
            monitor.reportError( e );
        }
    }


    private IEntry createAndCacheEntry( DN dn ) throws ModelModificationException
    {
        IEntry entry = null;

        // build tree to parent
        LinkedList parentDnList = new LinkedList();
        DN parentDN = dn;
        while ( parentDN != null && connection.getEntryFromCache( parentDN ) == null )
        {
            parentDnList.addFirst( parentDN );
            parentDN = parentDN.getParentDn();
        }
        for ( Iterator it = parentDnList.iterator(); it.hasNext(); )
        {
            DN aDN = ( DN ) it.next();
            if ( aDN.getParentDn() == null )
            {
                entry = new BaseDNEntry( aDN, connection );
                connection.cacheEntry( entry );
            }
            else if ( connection.getEntryFromCache( aDN.getParentDn() ) != null )
            {
                IEntry parentEntry = connection.getEntryFromCache( aDN.getParentDn() );
                entry = new Entry( parentEntry, aDN.getRdn() );
                entry.setDirectoryEntry( true );

                parentEntry.addChild( entry );
                // parentEntry.setAttributesInitialized(false, this);

                parentEntry.setChildrenInitialized( true );
                parentEntry.setHasMoreChildren( true );
                parentEntry.setHasChildrenHint( true );

                connection.cacheEntry( entry );
            }
            else
            {
                // ??
            }
        }

        return entry;
    }


    private void initFlags( IEntry entry, LdifContentRecord record, SearchParameter search )
    {

        LdifAttrValLine[] lines = record.getAttrVals();
        for ( int i = 0; i < lines.length; i++ )
        {

            String attributeName = lines[i].getUnfoldedAttributeDescription();

            if ( search.isInitHasChildrenFlag() )
            {
                // hasChildren flag
                if ( IAttribute.OPERATIONAL_ATTRIBUTE_HAS_SUBORDINATES.equalsIgnoreCase( attributeName ) )
                {
                    if ( "FALSE".equalsIgnoreCase( lines[i].getValueAsString() ) ) { //$NON-NLS-1$
                        entry.setHasChildrenHint( false );
                    }
                }
                if ( IAttribute.OPERATIONAL_ATTRIBUTE_NUM_SUBORDINATES.equalsIgnoreCase( attributeName ) )
                {
                    if ( "0".equalsIgnoreCase( lines[i].getValueAsString() ) ) { //$NON-NLS-1$
                        entry.setHasChildrenHint( false );
                    }
                }
                if ( IAttribute.OPERATIONAL_ATTRIBUTE_SUBORDINATE_COUNT.equalsIgnoreCase( attributeName ) )
                {
                    if ( "0".equalsIgnoreCase( lines[i].getValueAsString() ) ) { //$NON-NLS-1$
                        entry.setHasChildrenHint( false );
                    }
                }
            }

            if ( search.isInitAliasAndReferralFlag() )
            {
                if ( IAttribute.OBJECTCLASS_ATTRIBUTE.equalsIgnoreCase( attributeName ) )
                {
                    if ( ObjectClassDescription.OC_ALIAS.equalsIgnoreCase( lines[i].getValueAsString() ) )
                    {
                        entry.setAlias( true );
                    }
                    if ( ObjectClassDescription.OC_REFERRAL.equalsIgnoreCase( lines[i].getValueAsString() ) )
                    {
                        entry.setReferral( true );
                    }
                }
            }

        }

        if ( search.getControls() != null
            && Arrays.asList( search.getControls() ).contains( Control.SUBENTRIES_CONTROL ) )
        {
            entry.setSubentry( true );
            entry.setHasChildrenHint( false );
        }

    }


    private SearchParameter getSearchParameter( ISearch search )
    {
        SearchParameter searchParameter = ( SearchParameter ) search.getSearchParameter().clone();

        // add children detetion attributes
        if ( search.isInitHasChildrenFlag() )
        {
            if ( search.getConnection().getSchema().hasAttributeTypeDescription(
                IAttribute.OPERATIONAL_ATTRIBUTE_HAS_SUBORDINATES )
                && !Utils.containsIgnoreCase( Arrays.asList( searchParameter.getReturningAttributes() ),
                    IAttribute.OPERATIONAL_ATTRIBUTE_HAS_SUBORDINATES ) )
            {
                String[] returningAttributes = new String[searchParameter.getReturningAttributes().length + 1];
                System.arraycopy( searchParameter.getReturningAttributes(), 0, returningAttributes, 0, searchParameter
                    .getReturningAttributes().length );
                returningAttributes[returningAttributes.length - 1] = IAttribute.OPERATIONAL_ATTRIBUTE_HAS_SUBORDINATES;
                searchParameter.setReturningAttributes( returningAttributes );
            }
            else if ( search.getConnection().getSchema().hasAttributeTypeDescription(
                IAttribute.OPERATIONAL_ATTRIBUTE_NUM_SUBORDINATES )
                && !Utils.containsIgnoreCase( Arrays.asList( searchParameter.getReturningAttributes() ),
                    IAttribute.OPERATIONAL_ATTRIBUTE_NUM_SUBORDINATES ) )
            {
                String[] returningAttributes = new String[searchParameter.getReturningAttributes().length + 1];
                System.arraycopy( searchParameter.getReturningAttributes(), 0, returningAttributes, 0, searchParameter
                    .getReturningAttributes().length );
                returningAttributes[returningAttributes.length - 1] = IAttribute.OPERATIONAL_ATTRIBUTE_NUM_SUBORDINATES;
                searchParameter.setReturningAttributes( returningAttributes );
            }
            else if ( search.getConnection().getSchema().hasAttributeTypeDescription(
                IAttribute.OPERATIONAL_ATTRIBUTE_SUBORDINATE_COUNT )
                && !Utils.containsIgnoreCase( Arrays.asList( searchParameter.getReturningAttributes() ),
                    IAttribute.OPERATIONAL_ATTRIBUTE_SUBORDINATE_COUNT ) )
            {
                String[] returningAttributes = new String[searchParameter.getReturningAttributes().length + 1];
                System.arraycopy( searchParameter.getReturningAttributes(), 0, returningAttributes, 0, searchParameter
                    .getReturningAttributes().length );
                returningAttributes[returningAttributes.length - 1] = IAttribute.OPERATIONAL_ATTRIBUTE_SUBORDINATE_COUNT;
                searchParameter.setReturningAttributes( returningAttributes );
            }
        }

        // to init the alias/referral flag we need the objectClass
        if ( search.isInitAliasAndReferralFlag() )
        {
            if ( !Utils.containsIgnoreCase( Arrays.asList( searchParameter.getReturningAttributes() ),
                IAttribute.OBJECTCLASS_ATTRIBUTE ) )
            {
                String[] returningAttributes = new String[searchParameter.getReturningAttributes().length + 1];
                System.arraycopy( searchParameter.getReturningAttributes(), 0, returningAttributes, 0, searchParameter
                    .getReturningAttributes().length );
                returningAttributes[returningAttributes.length - 1] = IAttribute.OBJECTCLASS_ATTRIBUTE;
                searchParameter.setReturningAttributes( returningAttributes );
            }
        }

        // if returning attributes are requested but objectClass isn't included
        // then add it
        if ( search.getReturningAttributes() == null || search.getReturningAttributes().length > 0 )
        {
            if ( !Utils.containsIgnoreCase( Arrays.asList( searchParameter.getReturningAttributes() ),
                IAttribute.OBJECTCLASS_ATTRIBUTE ) )
            {
                String[] returningAttributes = new String[searchParameter.getReturningAttributes().length + 1];
                System.arraycopy( searchParameter.getReturningAttributes(), 0, returningAttributes, 0, searchParameter
                    .getReturningAttributes().length );
                returningAttributes[returningAttributes.length - 1] = IAttribute.OBJECTCLASS_ATTRIBUTE;
                searchParameter.setReturningAttributes( returningAttributes );
            }
        }

        // filter controls if not supported by server
        if ( searchParameter.getControls() != null )
        {

            Set suppportedConrolSet = new HashSet();
            if ( connection.getRootDSE() != null
                && connection.getRootDSE().getAttribute( IRootDSE.ROOTDSE_ATTRIBUTE_SUPPORTEDCONTROL ) != null )
            {
                IAttribute scAttribute = connection.getRootDSE().getAttribute(
                    IRootDSE.ROOTDSE_ATTRIBUTE_SUPPORTEDCONTROL );
                String[] supportedControls = scAttribute.getStringValues();
                for ( int i = 0; i < supportedControls.length; i++ )
                {
                    suppportedConrolSet.add( supportedControls[i].toLowerCase() );
                }
            }

            Control[] controls = searchParameter.getControls();
            List controlList = new ArrayList();
            for ( int i = 0; i < controls.length; i++ )
            {
                if ( suppportedConrolSet.contains( controls[i].getOid().toLowerCase() ) )
                {
                    controlList.add( controls[i] );
                }
            }
            searchParameter.setControls( ( Control[] ) controlList.toArray( new Control[controlList.size()] ) );
        }

        return searchParameter;
    }


    private void fillAttributes( IEntry entry, LdifContentRecord record, SearchParameter search )
        throws ModelModificationException
    {

        if ( search.getReturningAttributes() == null || search.getReturningAttributes().length > 0 )
        {
            LdifAttrValLine[] lines = record.getAttrVals();

            // clear old attributes defined as returing attributes or all
            if ( search.getReturningAttributes() != null )
            {
                String[] ras = search.getReturningAttributes();
               
                // special case *
                if( Arrays.asList( ras ).contains( ISearch.ALL_USER_ATTRIBUTES ) )
                {
                    // clear all user attributes
                    IAttribute[] oldAttributes = entry.getAttributes();
                    for ( int i = 0; oldAttributes != null && i < oldAttributes.length; i++ )
                    {
                        if( !oldAttributes[i].isOperationalAttribute() )
                        {
                            try
                            {
                                entry.deleteAttribute( oldAttributes[i] );
                            }
                            catch ( ModelModificationException e )
                            {
                            }
                        }
                    }
                }
               
                // special case +
                if( Arrays.asList( ras ).contains( ISearch.ALL_OPERATIONAL_ATTRIBUTES ) )
                {
                    // clear all operational attributes
                    IAttribute[] oldAttributes = entry.getAttributes();
                    for ( int i = 0; oldAttributes != null && i < oldAttributes.length; i++ )
                    {
                        if( oldAttributes[i].isOperationalAttribute() )
                        {
                            try
                            {
                                entry.deleteAttribute( oldAttributes[i] );
                            }
                            catch ( ModelModificationException e )
                            {
                            }
                        }
                    }
                }
               
               
                for ( int r = 0; r < ras.length; r++ )
                {
                    // clear attributes requested from server, also include subtypes
                    AttributeHierarchy ah = entry.getAttributeWithSubtypes( ras[r] );
                    if ( ah != null )
                    {
                        for ( Iterator it = ah.iterator(); it.hasNext(); )
                        {
                            IAttribute attribute = ( IAttribute ) it.next();
                            try
                            {
                                entry.deleteAttribute( attribute );
                            }
                            catch ( ModelModificationException e )
                            {
                            }
                        }
                    }
                }
            }
            else
            {
                // clear all
                IAttribute[] oldAttributes = entry.getAttributes();
                for ( int i = 0; oldAttributes != null && i < oldAttributes.length; i++ )
                {
                    try
                    {
                        entry.deleteAttribute( oldAttributes[i] );
                    }
                    catch ( ModelModificationException e )
                    {
                    }
                }
            }


            // additional clear old attributes if the record contains the
            // attribute
            for ( int i = 0; i < lines.length; i++ )
            {
                String attributeDesc = lines[i].getUnfoldedAttributeDescription();
                IAttribute oldAttribute = entry.getAttribute( attributeDesc );
                if ( oldAttribute != null )
                {
                    try
                    {
                        entry.deleteAttribute( oldAttribute );
                    }
                    catch ( ModelModificationException mme )
                    {
                    }
                }
            }

            // set new attributes and values
            for ( int i = 0; i < lines.length; i++ )
            {

                IAttribute attribute = null;
                String attributeName = lines[i].getUnfoldedAttributeDescription();
                // attributeName = attributeName.replaceAll(";binary", "");
                if ( entry.getAttribute( attributeName ) == null )
                {
                    attribute = new Attribute( entry, attributeName );
                    entry.addAttribute( attribute );
                }
                else
                {
                    attribute = entry.getAttribute( attributeName );
                }

                attribute.addValue( new Value( attribute, lines[i].getValueAsObject() ) );
            }
        }
    }

}
TOP

Related Classes of org.apache.directory.ldapstudio.browser.core.internal.model.ConnectionSearchHandler

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.