Hi Emmanuel,

On Wed, Apr 1, 2009 at 2:38 PM, Emmanuel Lecharny <elecharny@apache.org> wrote:
let's move to the Search operation now. It's the most complex operation, and we have to be carefull not to have a hundreds of overloaded methods. We will try to keep the 90/10 approach.

Yep it is insane.

Basically, the search operation has many parameters :
- baseDN
- scope
- derefAliases
- sizeLimit
- timeLimit
- typesOnly
- filter
- attributes

Out of them, the most used parameters are :
- baseDN
- filter
- scope
- attributes
- sizeLimit

As a rule things start getting ugly with API methods when you have more than 4 arguments and more than 4 overloads.

The most important thing to realize is what changes most with each search request.  The base does change most.  The filter does but sometimes does not need to be provided since people just want everything.  I can see something like:

conn.search() => searches the rootDSE ? Or should this be conn.getRootDse() ?
conn.search( baseDN ) => searches the base with one level scope and (objectClass=*)
conn.search( baseDN, filter )
conn.search( baseDN, filter, scope )

Attributes and size/time limits might be best left to be overridden in the SearchRequest? However these parameters should be set to some smart default when using the signatures above.  For example the sizeLimit may default to 1000 entries.

NOTE: timeLimit != timeout where the timeLimit is the limit for a search operation on the server, and the timeout is the time the client will wait at most for any operation to complete before disconnecting/abandoning the client request. 

The two firsts are absolutely mandatory. The three later are frequent. Then you have the others.

What I would suggest is that the four first parameters are always present in a search request :
search( String dn, String filter, ScopeEnum scope, String... attributes )

Note that the attributes is a varargs parameter.
Now, it makes it impossible to add a fifth parameter, as the varargs must be the last one.

All other parameters can be set using the SearchRequest object, with setters, and the following method :

search( SearchRequest request )
search( SearchRequest request, SearchListener listener ) for the non-blocking form.

Do you have better ideas ?

Don't know there's much to think about  but I'm sure things will pop into our heads as we think about this.  I suggest taking as much time as we need to on this since it is by far the most important operation.

Also I was wondering how the Cursor interface fits into this.  Right now we used the DirectoryListener.