Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Public Attributes | Protected Types | Protected Member Functions | Protected Attributes
nsLDAPAutoCompleteSession Class Reference

#include <nsLDAPAutoCompleteSession.h>

Inheritance diagram for nsLDAPAutoCompleteSession:
Inheritance graph
[legend]
Collaboration diagram for nsLDAPAutoCompleteSession:
Collaboration graph
[legend]

List of all members.

Public Member Functions

NS_DECL_ISUPPORTS
NS_DECL_NSIAUTOCOMPLETESESSION
NS_DECL_NSILDAPMESSAGELISTENER
NS_DECL_NSILDAPAUTOCOMPLETESESSION 
nsLDAPAutoCompleteSession ()
virtual ~nsLDAPAutoCompleteSession ()
void onStartLookup (in wstring searchString, in nsIAutoCompleteResults previousSearchResult, in nsIAutoCompleteListener listener)
void onStopLookup ()
void onAutoComplete (in wstring searchString, in nsIAutoCompleteResults previousSearchResult, in nsIAutoCompleteListener listener)

Public Attributes

attribute AUTF8String filterTemplate
 A template used to construct the RFC 1960 LDAP search filter to use while autocompleting.
attribute long maxHits
 At most this many nsIAutoCompleteItems will be returned.
attribute unsigned long minStringLength
 Strings shorter than this will return |nsIAutoCompleteStatus::ignored| rather than triggering a search.
attribute unsigned long cjkMinStringLength
attribute nsILDAPURL serverURL
 LDAP server to complete against, in ldap: URL format.
attribute nsILDAPAutoCompFormatter formatter
 Callback used to format an individual LDAP message into an nsIAutoCompleteItem.
attribute AUTF8String login
 "Login as..." this ID.
attribute nsIAuthPrompt authPrompter
 If set, use this object to get a password for logging in to the server.
attribute unsigned long version
 What version of the LDAP protocol should be used? Allowed version number constants are defined in nsILDAPConnection.idl.
attribute nsIMutableArray searchServerControls
 If set, these arrays of nsILDAPControls are passed through to the nsILDAPOperation that searchExt is called on.
attribute nsIMutableArray searchClientControls

Protected Types

enum  SessionState {
  UNBOUND = nsILDAPAutoCompFormatter::STATE_UNBOUND, INITIALIZING = nsILDAPAutoCompFormatter::STATE_INITIALIZING, BINDING = nsILDAPAutoCompFormatter::STATE_BINDING, BOUND = nsILDAPAutoCompFormatter::STATE_BOUND,
  SEARCHING = nsILDAPAutoCompFormatter::STATE_SEARCHING
}

Protected Member Functions

nsresult InitConnection ()
nsresult OnLDAPBind (nsILDAPMessage *aMessage)
nsresult OnLDAPSearchEntry (nsILDAPMessage *aMessage)
nsresult OnLDAPSearchResult (nsILDAPMessage *aMessage)
nsresult StartLDAPSearch ()
nsresult IsMessageCurrent (nsILDAPMessage *aMessage, PRBool *aIsCurrent)
void FinishAutoCompleteLookup (AutoCompleteStatus aACStatus, const nsresult aResult, enum SessionState aEndState)
nsresult CreateResultsArray (void)

Protected Attributes

enum
nsLDAPAutoCompleteSession::SessionState 
mState
PRUint32 mEntriesReturned
nsCOMPtr< nsILDAPConnectionmConnection
nsCOMPtr< nsILDAPOperationmOperation
nsCOMPtr< nsIAutoCompleteListenermListener
nsCOMPtr< nsIAutoCompleteResultsmResults
nsCOMPtr< nsISupportsArraymResultsArray
nsString mSearchString
nsCString mFilterTemplate
nsCOMPtr< nsILDAPURLmServerURL
PRInt32 mMaxHits
PRUint32 mMinStringLength
PRUint32 mCjkMinStringLength
char ** mSearchAttrs
PRUint32 mSearchAttrsSize
nsCOMPtr< nsIAuthPromptmAuthPrompter
PRUint32 mVersion
nsUTF8String mLogin
nsCOMPtr
< nsILDAPAutoCompFormatter
mFormatter
nsCOMPtr< nsIMutableArraymSearchServerControls
nsCOMPtr< nsIMutableArraymSearchClientControls

Detailed Description

Definition at line 60 of file nsLDAPAutoCompleteSession.h.


Member Enumeration Documentation


Constructor & Destructor Documentation

NS_DECL_ISUPPORTS NS_DECL_NSIAUTOCOMPLETESESSION NS_DECL_NSILDAPMESSAGELISTENER NS_DECL_NSILDAPAUTOCOMPLETESESSION nsLDAPAutoCompleteSession::nsLDAPAutoCompleteSession ( )

Member Function Documentation

Definition at line 1231 of file nsLDAPAutoCompleteSession.cpp.

{
    nsresult rv;

    // create a result set
    //
    mResults = do_CreateInstance(NS_AUTOCOMPLETERESULTS_CONTRACTID, &rv);

    if (NS_FAILED(rv)) {
        NS_ERROR("nsLDAPAutoCompleteSession::StartLDAPSearch() couldn't"
                 " create " NS_AUTOCOMPLETERESULTS_CONTRACTID);
        return NS_ERROR_FAILURE;
    }

    // This seems to be necessary for things to work, though I'm not sure
    // why that's true.
    //
    rv = mResults->SetSearchString(mSearchString.get());
    if (NS_FAILED(rv)) {
        NS_ERROR("nsLDAPAutoCompleteSession::OnLDAPSearchResult(): couldn't "
                 "set search string in results object");
        return NS_ERROR_FAILURE;
    }

    // get a pointer to the array in question now, so that we don't have to
    // keep re-fetching it every time an entry callback happens
    //
    rv = mResults->GetItems(getter_AddRefs(mResultsArray));
    if (NS_FAILED(rv)) {
        NS_ERROR("nsLDAPAutoCompleteSession::StartLDAPSearch() couldn't "
                 "get results array.");
        return NS_ERROR_FAILURE;
    }

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsLDAPAutoCompleteSession::FinishAutoCompleteLookup ( AutoCompleteStatus  aACStatus,
const nsresult  aResult,
enum SessionState  aEndState 
) [protected]

Definition at line 1269 of file nsLDAPAutoCompleteSession.cpp.

{
    nsCOMPtr<nsIAutoCompleteItem> errorItem; // pointer to item we may create
    nsresult rv; // temp for return value 

    // if there's a listener, inform the listener that the search is over
    //
    rv = NS_OK;
    if (mListener) {
        
        switch (aACStatus) {

        case nsIAutoCompleteStatus::matchFound:
            rv = mListener->OnAutoComplete(mResults, aACStatus);
            break;

        case nsIAutoCompleteStatus::failureItems:
            // if the results array hasn't already been created, make one
            // to return the error message.  If there's an error, fallback
            // to ::failed
            //
            if (!mResults) {
                rv = CreateResultsArray();
                if (NS_FAILED(rv)) {
                    NS_ERROR("nsLDAPAutoCompleteSession::"
                             "FinishAutoCompleteLookup():"
                             " CreateResultsArray() failed");
                    rv = mListener->OnAutoComplete(0, 
                                                nsIAutoCompleteStatus::failed);
                    break;
                }
            }

            // create the error item
            //
            rv = mFormatter->FormatException(mState, aResult,
                                             getter_AddRefs(errorItem));
            if (NS_SUCCEEDED(rv)) {

                // try and append the error item; falling back to ::failed
                // if there's a problem 
                //
                rv = mResultsArray->AppendElement(errorItem);
                if (NS_FAILED(rv)) {
                    NS_ERROR("nsLDAPAutoCompleteSession::"
                             "FinishAutoCompleteLookup():"
                             " mItems->AppendElement() failed");
                    rv = mListener->OnAutoComplete(0, 
                                                nsIAutoCompleteStatus::failed);
                    break;
                } 

                // we don't want the autocomplete widget trying to 
                // automagically use the error item for anything.  If 
                // something goes wrong here, continue on anyway.
                //
                (void)mResults->SetDefaultItemIndex(-1);

                rv = mListener->OnAutoComplete(mResults, 
                                          nsIAutoCompleteStatus::failureItems);
                break;
            } 

            // fallback to ::failed
            NS_ERROR("nsLDAPAutoCompleteSession::FinishAutoCompleteLookup(): "
                     "error calling FormatException()");

            rv = mListener->OnAutoComplete(0, nsIAutoCompleteStatus::failed);
            break;
        
        case nsIAutoCompleteStatus::failed:
        default:
            rv = mListener->OnAutoComplete(0, aACStatus);
            break;
        }

    } else {
        // if there's no listener, something's wrong 
        // 
        NS_ERROR("nsLDAPAutoCompleteSession::FinishAutoCompleteLookup(): "
                 "called with mListener unset!");
    }

    if (NS_FAILED(rv)) {

        // there's nothing we can actually do here other than warn
        //
        NS_WARNING("nsLDAPAutoCompleteSession::FinishAutoCompleteLookup(): "
                   "error calling mListener->OnAutoComplete()");
    }

    // set the state appropriately
    //
    mState = aEndState;

    // we're done with various things; cause nsCOMPtr to release them
    //
    mResultsArray = 0;
    mResults = 0;
    mListener = 0;
    mOperation = 0;

    // If we are unbound, drop the connection (if any)
    //
    if (mState == UNBOUND) {
        mConnection = 0;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1123 of file nsLDAPAutoCompleteSession.cpp.

{
    nsresult rv;        // temp for xpcom return values
    nsCOMPtr<nsILDAPMessageListener> selfProxy;
    
    // create an LDAP connection
    //
    mConnection = do_CreateInstance(
        "@mozilla.org/network/ldap-connection;1", &rv);
    if (NS_FAILED(rv)) {
        NS_ERROR("nsLDAPAutoCompleteSession::InitConnection(): could "
                 "not create @mozilla.org/network/ldap-connection;1");
        FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv, 
                                 UNBOUND);
        return NS_ERROR_FAILURE;
    }

    // have we been properly initialized?
    //
    if (!mServerURL) {
        NS_ERROR("nsLDAPAutoCompleteSession::InitConnection(): mServerURL "
                 "is NULL");
        FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv, 
                                 UNBOUND);
        return NS_ERROR_NOT_INITIALIZED;
    }

    // host to connect to
    //
    nsCAutoString host;
    rv = mServerURL->GetAsciiHost(host);
    if (NS_FAILED(rv)) {
        FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv, 
                                 UNBOUND);
        return NS_ERROR_FAILURE;
    }

    // on which port
    //
    PRInt32 port;
    rv = mServerURL->GetPort(&port);
    if (NS_FAILED(rv)) {
        FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv,
                                 UNBOUND);
        return NS_ERROR_FAILURE;
    }
        
    // which options
    //
    PRUint32 options;
    rv = mServerURL->GetOptions(&options);
    if (NS_FAILED(rv)) {
        FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv,
                                 UNBOUND);
        return NS_ERROR_FAILURE;
    }
        
    // get a proxy object so the callback happens on the main thread
    //
    rv = NS_GetProxyForObject(NS_UI_THREAD_EVENTQ,
                              NS_GET_IID(nsILDAPMessageListener), 
                              NS_STATIC_CAST(nsILDAPMessageListener *, this), 
                              PROXY_ASYNC | PROXY_ALWAYS, 
                              getter_AddRefs(selfProxy));
    if (NS_FAILED(rv)) {
        NS_ERROR("nsLDAPAutoCompleteSession::InitConnection(): couldn't "
                 "create proxy to this object for callback");
        FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv, 
                                 UNBOUND);
        return NS_ERROR_FAILURE;
    }

    // Initialize the connection. This will cause an asynchronous DNS
    // lookup to occur, and we'll finish the binding of the connection
    // in the OnLDAPInit() listener function.
    //
    rv = mConnection->Init(host.get(), port,
                           (options & nsILDAPURL::OPT_SECURE) ? PR_TRUE 
                           : PR_FALSE, mLogin, selfProxy, nsnull, mVersion);
    if NS_FAILED(rv) {
        switch (rv) {

        case NS_ERROR_OUT_OF_MEMORY:
        case NS_ERROR_NOT_AVAILABLE:
        case NS_ERROR_FAILURE:
            PR_LOG(sLDAPAutoCompleteLogModule, PR_LOG_DEBUG, 
                   ("nsLDAPAutoCompleteSession::InitConnection(): mSimpleBind "
                    "failed, rv = 0x%lx", rv));
            FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv, 
                                     UNBOUND);
            return rv;

        case NS_ERROR_ILLEGAL_VALUE:
        default:
            FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv, 
                                     UNBOUND);
            return NS_ERROR_UNEXPECTED;
        }
    }

    // set our state
    //
    mState = INITIALIZING;

    return NS_OK;
}

Here is the call graph for this function:

nsresult nsLDAPAutoCompleteSession::IsMessageCurrent ( nsILDAPMessage aMessage,
PRBool aIsCurrent 
) [protected]

Definition at line 1496 of file nsLDAPAutoCompleteSession.cpp.

{
    // if there's no operation, this message must be stale (ie non-current)
    //
    if ( !mOperation ) {
        *aIsCurrent = PR_FALSE;
        return NS_OK;
    }

    // get the message id from the current operation
    //
    PRInt32 currentId;
    nsresult rv = mOperation->GetMessageID(&currentId);
    if (NS_FAILED(rv)) {
        PR_LOG(sLDAPAutoCompleteLogModule, PR_LOG_DEBUG, 
               ("nsLDAPAutoCompleteSession::IsMessageCurrent(): unexpected "
                "error 0x%lx calling mOperation->GetMessageId()", rv));
        return NS_ERROR_UNEXPECTED;
    }

    // get the message operation from the message
    //
    nsCOMPtr<nsILDAPOperation> msgOp;
    rv = aMessage->GetOperation(getter_AddRefs(msgOp));
    if (NS_FAILED(rv)) {
        PR_LOG(sLDAPAutoCompleteLogModule, PR_LOG_DEBUG, 
               ("nsLDAPAutoCompleteSession::IsMessageCurrent(): unexpected "
                "error 0x%lx calling aMessage->GetOperation()", rv));
        return NS_ERROR_UNEXPECTED;
    }

    // get the message operation id from the message operation
    //
    PRInt32 msgOpId;
    rv = msgOp->GetMessageID(&msgOpId);
    if (NS_FAILED(rv)) {
        PR_LOG(sLDAPAutoCompleteLogModule, PR_LOG_DEBUG, 
               ("nsLDAPAutoCompleteSession::IsMessageCurrent(): unexpected "
                "error 0x%lx calling msgOp->GetMessageId()", rv));
        return NS_ERROR_UNEXPECTED;
    }
    
    *aIsCurrent = (msgOpId == currentId);

    return NS_OK;
}

Here is the call graph for this function:

void nsIAutoCompleteSession::onAutoComplete ( in wstring  searchString,
in nsIAutoCompleteResults  previousSearchResult,
in nsIAutoCompleteListener  listener 
) [inherited]

Definition at line 655 of file nsLDAPAutoCompleteSession.cpp.

{
    PRInt32 errCode;

    mOperation = 0;  // done with bind op; make nsCOMPtr release it

    // get the status of the bind
    //
    nsresult rv = aMessage->GetErrorCode(&errCode);
    if (NS_FAILED(rv)) {
        
        NS_ERROR("nsLDAPAutoCompleteSession::OnLDAPBind(): couldn't get "
                 "error code from aMessage");

        // reset to the default state, and pass along the LDAP error code
        // to the formatter
        //
        FinishAutoCompleteLookup(
            nsIAutoCompleteStatus::failureItems,
            NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_LDAP, errCode), 
            UNBOUND);
        return NS_ERROR_FAILURE;
    }

    // check to be sure the bind succeeded
    //
    if (errCode != nsILDAPErrors::SUCCESS) {

        PR_LOG(sLDAPAutoCompleteLogModule, PR_LOG_WARNING, 
                ("nsLDAPAutoCompleteSession::OnLDAPBind(): error binding to "
                "LDAP server, errCode = 0x%x", errCode));

        // if the login failed, tell the wallet to forget this password
        //
        if ( errCode == nsILDAPErrors::INAPPROPRIATE_AUTH ||
             errCode == nsILDAPErrors::INVALID_CREDENTIALS ) {

            // make sure the wallet service has been created, and in doing so,
            // pass in a login-failed message to tell it to forget this passwd.
            //
            // apparently getting passwords stored in the wallet
            // doesn't require the service to be running, which is why
            // this might not exist yet.
            //
            rv = NS_CreateServicesFromCategory("passwordmanager", mServerURL,
                                               "login-failed");
            if (NS_FAILED(rv)) {
                NS_ERROR("nsLDAPAutoCompleteSession::ForgetPassword(): error"
                         " creating password manager service");
                // not much to do at this point, though conceivably we could 
                // pop up a dialog telling the user to go manually delete
                // this password in the password manager.
            }

            // XXXdmose We should probably pop up an error dialog telling
            // the user that the login failed here, rather than just bringing 
            // up the password dialog again, which is what calling OnLDAPInit()
            // does.  See bug 152997.

            PR_LOG(sLDAPAutoCompleteLogModule, PR_LOG_DEBUG, 
                   ("nsLDAPAutoCompleteSession::OnLDAPBind(): auth error;"
                    " calling OnLDAPInit() again"));
        
            return OnLDAPInit(nsnull, NS_OK);
        }

        // reset to the default state
        //
        mState = UNBOUND;
        FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, 
                     NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_LDAP, errCode),
                                 UNBOUND);
        return NS_ERROR_FAILURE;
    }

    // ok, we're starting a search
    //
    mState = SEARCHING;

    PR_LOG(sLDAPAutoCompleteLogModule, PR_LOG_DEBUG, 
           ("nsLDAPAutoCompleteSession::OnLDAPBind(): initial search "
            "starting\n"));

    return StartLDAPSearch();
}

Here is the call graph for this function:

Definition at line 742 of file nsLDAPAutoCompleteSession.cpp.

{
    PR_LOG(sLDAPAutoCompleteLogModule, PR_LOG_DEBUG, 
           ("nsLDAPAutoCompleteSession::OnLDAPSearchEntry entered\n"));

    // make sure this is only getting called after StartLDAPSearch has 
    // initialized the result set
    //
    NS_ASSERTION(mResultsArray,
                 "nsLDAPAutoCompleteSession::OnLDAPSearchEntry(): "
                 "mResultsArrayItems is uninitialized");

    // Errors in this method return an error (which ultimately gets
    // ignored, since this is being called through an async proxy).
    // But the important thing is that we're bailing out here rather
    // than trying to generate a bogus nsIAutoCompleteItem.  Also note
    // that FinishAutoCompleteLookup is _NOT_ being called here, because
    // this error may just have to do with this particular item.

    // generate an autocomplete item from this message by calling the
    // formatter
    //
    nsCOMPtr<nsIAutoCompleteItem> item;
    nsresult rv = mFormatter->Format(aMessage, getter_AddRefs(item));
    if (NS_FAILED(rv)) {
        PR_LOG(sLDAPAutoCompleteLogModule, PR_LOG_DEBUG,
               ("nsLDAPAutoCompleteSession::OnLDAPSearchEntry(): "
                "mFormatter->Format() failed"));
        return NS_ERROR_FAILURE;
    }

    rv = mResultsArray->AppendElement(item);
    if (NS_FAILED(rv)) {
        NS_ERROR("nsLDAPAutoCompleteSession::OnLDAPSearchEntry(): "
                 "mItems->AppendElement() failed");
        return NS_ERROR_FAILURE;
    }

    // remember that something has been returned
    //
    mEntriesReturned++;

    return NS_OK;
}

Here is the call graph for this function:

Definition at line 788 of file nsLDAPAutoCompleteSession.cpp.

{
    nsresult rv;        // temp for return vals

    PR_LOG(sLDAPAutoCompleteLogModule, PR_LOG_DEBUG, 
           ("nsLDAPAutoCompleteSession::OnLDAPSearchResult entered\n"));

    // figure out if we succeeded or failed, and set the status 
    // and default index appropriately
    //
    AutoCompleteStatus status;
    PRInt32 lderrno;

    if (mEntriesReturned) {

        status = nsIAutoCompleteStatus::matchFound;

        // there's at least one match, so the default index should
        // point to the first thing here.  This ensures that if the local
        // addressbook autocomplete session only found foo@local.domain, 
        // this will be given preference
        //
        rv = mResults->SetDefaultItemIndex(0);
        if (NS_FAILED(rv)) {
            NS_ERROR("nsLDAPAutoCompleteSession::OnLDAPSearchResult(): "
                     "mResults->SetDefaultItemIndex(0) failed");
            FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv, 
                                     BOUND);
        }
    } else {
        // note that we only look at the error code if there are no results for
        // this session; if we got results and then an error happened, this
        // is ignored, in part because it seems likely to be confusing to the
        // user, and in part because it is likely to be scrolled out of view 
        // anyway
        //
        aMessage->GetErrorCode(&lderrno);
        if (lderrno != nsILDAPErrors::SUCCESS) {

            PR_LOG(sLDAPAutoCompleteLogModule, PR_LOG_DEBUG, 
                   ("nsLDAPAutoCompleteSession::OnLDAPSearchResult(): "
                    "lderrno=%d\n", lderrno));
            FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, 
                                     NS_ERROR_GENERATE_FAILURE(
                                         NS_ERROR_MODULE_LDAP, lderrno), 
                                     BOUND);
            return NS_OK;
        }

        // we could potentially keep track of non-fatal errors to the 
        // search, and if there has been more than 1, and there are no entries,
        // we could return |failed| instead of |noMatch|.  It's unclear to me
        // that this actually buys us anything though.
        //
        status = nsIAutoCompleteStatus::noMatch;
    }

    // call the mListener's OnAutoComplete and clean up
    //
    // XXXdmose should we really leave the connection BOUND here?
    FinishAutoCompleteLookup(status, NS_OK, BOUND);

    return NS_OK;
}

Here is the call graph for this function:

void nsIAutoCompleteSession::onStartLookup ( in wstring  searchString,
in nsIAutoCompleteResults  previousSearchResult,
in nsIAutoCompleteListener  listener 
) [inherited]

Definition at line 854 of file nsLDAPAutoCompleteSession.cpp.

{
    nsresult rv; // temp for xpcom return values
    nsCOMPtr<nsILDAPMessageListener> selfProxy; // for callback

    PR_LOG(sLDAPAutoCompleteLogModule, PR_LOG_DEBUG, 
           ("nsLDAPAutoCompleteSession::StartLDAPSearch entered\n"));

    // create and initialize an LDAP operation (to be used for the search
    //  
    mOperation = 
        do_CreateInstance("@mozilla.org/network/ldap-operation;1", &rv);

    if (NS_FAILED(rv)) {
        NS_ERROR("nsLDAPAutoCompleteSession::StartLDAPSearch(): couldn't "
                 "create @mozilla.org/network/ldap-operation;1");

        FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv, 
                                 BOUND);
        return NS_ERROR_FAILURE;
    }

    // get a proxy object so the callback happens on the main thread
    //
    rv = NS_GetProxyForObject(NS_UI_THREAD_EVENTQ, 
                              NS_GET_IID(nsILDAPMessageListener), 
                              NS_STATIC_CAST(nsILDAPMessageListener *, this), 
                              PROXY_ASYNC | PROXY_ALWAYS, 
                              getter_AddRefs(selfProxy));
    if (NS_FAILED(rv)) {
        NS_ERROR("nsLDAPAutoCompleteSession::StartLDAPSearch(): couldn't "
                 "create proxy to this object for callback");
        FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv, 
                                 BOUND);
        return NS_ERROR_FAILURE;
    }

    // initialize the LDAP operation object
    //
    rv = mOperation->Init(mConnection, selfProxy, nsnull);
    if (NS_FAILED(rv)) {
        NS_ERROR("nsLDAPAutoCompleteSession::StartLDAPSearch(): couldn't "
                 "initialize LDAP operation");
        FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv, 
                                 BOUND);
        return NS_ERROR_UNEXPECTED;
    }

    // set the server and client controls on the operation
    if (mSearchServerControls) {
        rv = mOperation->SetServerControls(mSearchServerControls);
        if (NS_FAILED(rv)) {
            NS_ERROR("nsLDAPAutoCompleteSession::StartLDAPSearch(): couldn't "
                     "initialize LDAP search operation server controls");
            FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv, 
                                     BOUND);
            return NS_ERROR_UNEXPECTED;
        }
    }
    if (mSearchClientControls) {
        rv = mOperation->SetClientControls(mSearchClientControls);
        if (NS_FAILED(rv)) {
            NS_ERROR("nsLDAPAutoCompleteSession::StartLDAPSearch(): couldn't "
                     "initialize LDAP search operation client controls");
            FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv, 
                                     BOUND);
            return NS_ERROR_UNEXPECTED;
        }
    }

    // get the search filter associated with the directory server url; 
    // it will be ANDed with the rest of the search filter that we're using.
    //
    nsCAutoString urlFilter;
    rv = mServerURL->GetFilter(urlFilter);
    if ( NS_FAILED(rv) ){
        FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv,
                                 BOUND);
        return NS_ERROR_UNEXPECTED;
    }

    // get the LDAP service, since createFilter is called through it.
    //
    nsCOMPtr<nsILDAPService> ldapSvc = do_GetService(
        "@mozilla.org/network/ldap-service;1", &rv);
    if (NS_FAILED(rv)) {
        NS_ERROR("nsLDAPAutoCompleteSession::StartLDAPSearch(): couldn't "
                 "get @mozilla.org/network/ldap-service;1");
        FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv,
                                 BOUND);
        return NS_ERROR_FAILURE;
    }

    // if urlFilter is unset (or set to the default "objectclass=*"), there's
    // no need to AND in an empty search term, so leave prefix and suffix empty
    //
    nsCAutoString prefix, suffix;
    if (urlFilter.Length() && !urlFilter.Equals(NS_LITERAL_CSTRING("(objectclass=*)"))) {

        // if urlFilter isn't parenthesized, we need to add in parens so that
        // the filter works as a term to &
        //
        if (urlFilter[0] != '(') {
            prefix = NS_LITERAL_CSTRING("(&(") + urlFilter +
                NS_LITERAL_CSTRING(")");
        } else {
            prefix = NS_LITERAL_CSTRING("(&") + urlFilter;
        }
        
        suffix = ')';
    }

    // generate an LDAP search filter from mFilterTemplate.  If it's unset,
    // use the default.
    //
#define MAX_AUTOCOMPLETE_FILTER_SIZE 1024
    nsCAutoString searchFilter;
    rv = ldapSvc->CreateFilter(MAX_AUTOCOMPLETE_FILTER_SIZE,
                               mFilterTemplate,
                               prefix, suffix, EmptyCString(), 
                               NS_ConvertUCS2toUTF8(mSearchString),
                               searchFilter);
    if (NS_FAILED(rv)) {
        switch(rv) {

        case NS_ERROR_OUT_OF_MEMORY:
            FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv,
                                     BOUND);
            return rv;

        case NS_ERROR_NOT_AVAILABLE:
            PR_LOG(sLDAPAutoCompleteLogModule, PR_LOG_DEBUG, 
                   ("nsLDAPAutoCompleteSession::StartLDAPSearch(): "
                    "createFilter generated filter longer than max filter "
                    "size of %d", MAX_AUTOCOMPLETE_FILTER_SIZE));
            FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv,
                                     BOUND);
            return rv;

        case NS_ERROR_INVALID_ARG:
        case NS_ERROR_UNEXPECTED:
        default:

            // all this stuff indicates code bugs
            //
            NS_ERROR("nsLDAPAutoCompleteSession::StartLDAPSearch(): "
                     "createFilter returned unexpected value");
            FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv, 
                                     BOUND);
            return NS_ERROR_UNEXPECTED;
        }

    }

    // If the results array for this search hasn't already been created, do
    // so now.  Note that we don't return ::failureItems here, because if
    // there's no array, there's nowhere to put the items.
    //
    rv = CreateResultsArray();
    if (NS_FAILED(rv)) {
        FinishAutoCompleteLookup(nsIAutoCompleteStatus::failed, rv, BOUND);
    }

    // nothing returned yet!
    //
    mEntriesReturned = 0;
    
    // get the base dn to search
    //
    nsCAutoString dn;
    rv = mServerURL->GetDn(dn);
    if ( NS_FAILED(rv) ){
        FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv,
                                 BOUND);
        return NS_ERROR_UNEXPECTED;
    }

    // and the scope
    //
    PRInt32 scope;
    rv = mServerURL->GetScope(&scope);
    if ( NS_FAILED(rv) ){
        mState = BOUND;
        FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv, 
                                 BOUND);
        return NS_ERROR_UNEXPECTED;
    }

    // take the relevant controls on this object and set them
    // on the operation
    rv = mOperation->SetServerControls(mSearchServerControls.get());
    if ( NS_FAILED(rv) ){
        mState = BOUND;
        FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv, 
                                 BOUND);
        return NS_ERROR_UNEXPECTED;
    }

    rv = mOperation->SetClientControls(mSearchClientControls.get());
    if ( NS_FAILED(rv) ){
        mState = BOUND;
        FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv, 
                                 BOUND);
        return NS_ERROR_UNEXPECTED;
    }

    // time to kick off the search.
    //
    // XXXdmose what about timeouts? 
    //
    rv = mOperation->SearchExt(dn, scope, searchFilter, mSearchAttrsSize,
                               NS_CONST_CAST(const char **, mSearchAttrs),
                               0, mMaxHits);
    if (NS_FAILED(rv)) {
        switch(rv) {

        case NS_ERROR_LDAP_ENCODING_ERROR:
            PR_LOG(sLDAPAutoCompleteLogModule, PR_LOG_DEBUG, 
                   ("nsLDAPAutoCompleteSession::StartLDAPSearch(): SearchExt "
                    "returned NS_ERROR_LDAP_ENCODING_ERROR"));
            FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv, 
                                     BOUND);
            return NS_OK;

        case NS_ERROR_LDAP_FILTER_ERROR:
            PR_LOG(sLDAPAutoCompleteLogModule, PR_LOG_DEBUG, 
                   ("nsLDAPAutoCompleteSession::StartLDAPSearch(): SearchExt "
                    "returned NS_ERROR_LDAP_FILTER_ERROR"));
            FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv, 
                                     BOUND);
            return NS_OK;

        case NS_ERROR_LDAP_SERVER_DOWN:
            // XXXdmose discuss with leif how to handle this in general in the 
            // LDAP XPCOM SDK.  

            PR_LOG(sLDAPAutoCompleteLogModule, PR_LOG_DEBUG, 
                   ("nsLDAPAutoCompleteSession::StartLDAPSearch(): SearchExt "
                    "returned NS_ERROR_LDAP_SERVER_DOWN"));
            FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv,
                                     UNBOUND);
            return NS_OK;

        case NS_ERROR_OUT_OF_MEMORY:
            FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv, 
                                     BOUND);
            return NS_ERROR_OUT_OF_MEMORY;

        case NS_ERROR_LDAP_NOT_SUPPORTED:
        case NS_ERROR_NOT_INITIALIZED:        
        case NS_ERROR_INVALID_ARG:
        default:

            // all this stuff indicates code bugs
            //
            NS_ERROR("nsLDAPAutoCompleteSession::StartLDAPSearch(): SearchExt "
                     "returned unexpected value");
            FinishAutoCompleteLookup(nsIAutoCompleteStatus::failureItems, rv, 
                                     BOUND);
            return NS_ERROR_UNEXPECTED;
        }
    }

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

If set, use this object to get a password for logging in to the server.

Definition at line 132 of file nsILDAPAutoCompleteSession.idl.

Definition at line 106 of file nsILDAPAutoCompleteSession.idl.

A template used to construct the RFC 1960 LDAP search filter to use while autocompleting.

The authoritative documentation for the format in use can be found at at http://docs.iplanet.com/docs/manuals/dirsdk/csdk41/html/filter.htm. The Linux/OpenLDAP man page for ldapfilter.conf(5) does a pretty decent job as well, however.

As of this writing, the "@mozilla.org/autocompleteSession;1?type=ldap" contractid happens to use a default value of (|(cn=v1*v2-*)(mail=v1*v2-*)(sn=v1*v2-*))

Exceptions:
NS_ERROR_NULL_POINTERNULL pointer passed to getter
NS_ERROR_OUT_OF_MEMORYGetter couldn't allocate string

Definition at line 72 of file nsILDAPAutoCompleteSession.idl.

Callback used to format an individual LDAP message into an nsIAutoCompleteItem.

Definition at line 120 of file nsILDAPAutoCompleteSession.idl.

"Login as..." this ID.

Currently, this must be specified as a DN. In the future, we may support userid and/or email address as well. If unset, bind anonymously.

Definition at line 127 of file nsILDAPAutoCompleteSession.idl.

Definition at line 94 of file nsLDAPAutoCompleteSession.h.

At most this many nsIAutoCompleteItems will be returned.

This is useful for keeping bandwidth usage over slow-speed connections as well as ensuring that the number of choices offered in the UI is manageble.

1-65535 are interpreted literally 0 means "unlimited" -1 uses the default limit for the LDAP connection in use

Exceptions:
NS_ERROR_NULL_POINTERNULL pointer passed to getter
NS_ERROR_ILLEGAL_VALUEOut-of-range value passed to setter

Definition at line 87 of file nsILDAPAutoCompleteSession.idl.

Definition at line 91 of file nsLDAPAutoCompleteSession.h.

Definition at line 81 of file nsLDAPAutoCompleteSession.h.

Definition at line 80 of file nsLDAPAutoCompleteSession.h.

Definition at line 87 of file nsLDAPAutoCompleteSession.h.

Definition at line 103 of file nsLDAPAutoCompleteSession.h.

Strings shorter than this will return |nsIAutoCompleteStatus::ignored| rather than triggering a search.

This allows browsers to be configured to not search on substrings so short that they aren't indexed by the LDAP server (such searches can use significantly more server resources and return a very large number of entries). cjkMinStringLength is used for CJK languages, and minStringLength for everything else. As of this writing, the "@mozilla.org/autocompleteSession;1?type=ldap" contractid uses defaults of two and zero, respectively. This avoids most unindexed searches with at least one widely-deployed webserver, but allows CJK languages, where a single glyph can be an an entire name to still get results.

Exceptions:
NS_ERROR_NULL_POINTERNULL pointer passed to getter

Definition at line 105 of file nsILDAPAutoCompleteSession.idl.

Definition at line 83 of file nsLDAPAutoCompleteSession.h.

Definition at line 99 of file nsLDAPAutoCompleteSession.h.

Definition at line 89 of file nsLDAPAutoCompleteSession.h.

Definition at line 90 of file nsLDAPAutoCompleteSession.h.

Definition at line 82 of file nsLDAPAutoCompleteSession.h.

Definition at line 84 of file nsLDAPAutoCompleteSession.h.

Definition at line 85 of file nsLDAPAutoCompleteSession.h.

Definition at line 92 of file nsLDAPAutoCompleteSession.h.

Definition at line 93 of file nsLDAPAutoCompleteSession.h.

Definition at line 136 of file nsLDAPAutoCompleteSession.h.

Definition at line 135 of file nsLDAPAutoCompleteSession.h.

Definition at line 86 of file nsLDAPAutoCompleteSession.h.

Definition at line 88 of file nsLDAPAutoCompleteSession.h.

Definition at line 95 of file nsLDAPAutoCompleteSession.h.

Definition at line 148 of file nsILDAPAutoCompleteSession.idl.

If set, these arrays of nsILDAPControls are passed through to the nsILDAPOperation that searchExt is called on.

Definition at line 147 of file nsILDAPAutoCompleteSession.idl.

LDAP server to complete against, in ldap: URL format.

May change to an nsILDAPServer once that infrastructure lands.

Exceptions:
NS_ERROR_NULL_POINTERNULL pointer passed to getter

Definition at line 114 of file nsILDAPAutoCompleteSession.idl.

What version of the LDAP protocol should be used? Allowed version number constants are defined in nsILDAPConnection.idl.

Exceptions:
NS_ERROR_ILLEGAL_VALUEillegal version num passed to setter
NS_ERROR_NULL_POINTERnull pointer passed to getter

Definition at line 141 of file nsILDAPAutoCompleteSession.idl.


The documentation for this class was generated from the following files: