private void handleWithReferrals()

in protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/request/SearchRequestHandler.java [1201:1348]


    private void handleWithReferrals( LdapSession session, SearchRequest req ) throws LdapException
    {
        LdapResult result = req.getResultResponse().getLdapResult();
        Entry entry = null;
        boolean isReferral = false;
        boolean isparentReferral = false;
        DirectoryService directoryService = session.getCoreSession().getDirectoryService();
        ReferralManager referralManager = directoryService.getReferralManager();
        Dn reqTargetDn = req.getBase();

        if ( !reqTargetDn.isSchemaAware() )
        {
            reqTargetDn = new Dn( directoryService.getSchemaManager(), reqTargetDn );
            req.setBase( reqTargetDn );
        }

        // Check if the entry itself is a referral
        referralManager.lockRead();

        try
        {
            isReferral = referralManager.isReferral( reqTargetDn );

            if ( !isReferral )
            {
                // Check if the entry has a parent which is a referral
                isparentReferral = referralManager.hasParentReferral( reqTargetDn );
            }
        }
        finally
        {
            // Unlock the ReferralManager
            referralManager.unlock();
        }

        if ( !isReferral && !isparentReferral )
        {
            // This is not a referral and it does not have a parent which
            // is a referral : standard case, just deal with the request
            if ( IS_DEBUG )
            {
                LOG.debug( "Entry {} is NOT a referral.", reqTargetDn );
            }

            handleIgnoringReferrals( session, req );
        }
        else
        {
            // -------------------------------------------------------------------
            // Lookup Entry
            // -------------------------------------------------------------------

            // try to lookup the entry but ignore exceptions when it does not
            // exist since entry may not exist but may have an ancestor that is a
            // referral - would rather attempt a lookup that fails then do check
            // for existence than have to do another lookup to get entry info
            try
            {
                entry = session.getCoreSession().lookup( reqTargetDn );

                if ( IS_DEBUG )
                {
                    LOG.debug( "Entry for {} was found: ", reqTargetDn, entry );
                }
            }
            catch ( LdapException e )
            {
                /* ignore */
                LOG.debug( "Entry for {} not found.", reqTargetDn );
            }
            catch ( Exception e )
            {
                /* serious and needs handling */
                handleException( session, req, e );

                return;
            }

            // -------------------------------------------------------------------
            // Handle Existing Entry
            // -------------------------------------------------------------------

            if ( entry != null )
            {
                try
                {
                    if ( IS_DEBUG )
                    {
                        LOG.debug( "Entry is a referral: {}", entry );
                    }

                    handleReferralEntryForSearch( session, req, entry );
                }
                catch ( Exception e )
                {
                    handleException( session, req, e );
                }
            }

            // -------------------------------------------------------------------
            // Handle Non-existing Entry
            // -------------------------------------------------------------------

            // if the entry is null we still have to check for a referral ancestor
            // also the referrals need to be adjusted based on the ancestor's ref
            // values to yield the correct path to the entry in the target DSAs

            else
            {
                // The entry is null : it has a parent referral.
                Entry referralAncestor = null;

                try
                {
                    referralAncestor = getFarthestReferralAncestor( session, reqTargetDn );
                }
                catch ( Exception e )
                {
                    handleException( session, req, e );

                    return;
                }

                if ( referralAncestor == null )
                {
                    result.setDiagnosticMessage( "Entry not found." );
                    result.setResultCode( ResultCodeEnum.NO_SUCH_OBJECT );
                    session.getIoSession().write( req.getResultResponse() );

                    return;
                }

                // if we get here then we have a valid referral ancestor
                try
                {
                    Referral referral = getReferralOnAncestorForSearch( session, req, referralAncestor );

                    result.setResultCode( ResultCodeEnum.REFERRAL );
                    result.setReferral( referral );
                    session.getIoSession().write( req.getResultResponse() );
                }
                catch ( Exception e )
                {
                    handleException( session, req, e );
                }
            }
        }
    }