| Adding Directory Support

## Searches

> The `DirContext` interface contains the following methods (plus their `java.lang.String` overloads) for searching a directory:
> - `search(Name name, Attributes matches)`
> - `search(Name name, Attributes matches, String[] retIDs)`
> - `search(Name name, String filter, SearchControls cons)`
> - `search(Name name, String filterExpr, Object[] filterArgs, SearchControls cons)`
> As a developer of a context implementation, you need to be concerned only about two of them. This is because two of them usually can be written in terms of the other two.

> The form that accepts a name and a set of matching attributes can be implemented by using the form that accepts the additional `retIDs` parameter, as follows.

> >     public NamingEnumeration search(Name name, Attributes matchingAttrs)
> >         throws NamingException {
> >             return search(name, matchingAttrs, null);
> >     }

> A `null` value for the `retIDs` parameter means to return all attributes.

> The form that accepts a filter expression and `Object[]` can be implemented by converting the `filterExpr` and `filterArgs` parameters into a string filter, as follows.

> >     public NamingEnumeration search(Name name,
> >         String filterExpr, Object[] filterArgs, SearchControls cons)
> >         throws NamingException {
> >         // Fill in the expression
> >         String filter = format(filterExpr, filterArgs);

> >         return search(name, filter, cons);
> >     }

> `format()` is a utility method that takes a filter expression and arguments and returns a filter string that conforms to RFC 2254. See the hierarchical directory example for a sample implementation of this method.

> You are then left with two methods to implement:

> - The basic search that accepts a set of matching attributes and a list of attribute IDs to return
> - The advanced search that accepts a string filter and a `SearchControls` parameter

> Your implementation can support both, none, or only one of these methods. Typically, an implementation that supports the advanced search also supports the basic search. The basic search can be implemented in terms of the advanced search by converting the matching attributes into a string filter.

> Theoretically, any context implementation can support both search methods, regardless of the capabilities of the underlying directory service. A context implementation for a directory service that does not support any searches can implement these methods by reading the directory data and then performing the searches in the context implementation itself. Similarly, a context implementation for a directory service that has only limited search capabilities can implement more-complicated searches by using the directory's limited capabilities. A context implementation for an LDAP directory service does not need to do much work, since the LDAP has full search capabilities. For directories with limited search capabilities, you need to evaluate whether it is cost-effective to provide full search capabilities despite possibly poor performance and heavy network load.

> If your implementation does not support one of these methods, then the unsupported method should throw an `OperationNotSupportedException`.

> #### The Basic Search

> The basic search involves searching the named context for entries that contain the matching attributes. The method returns a `NamingEnumeration`; each item in the enumeration is a `SearchResult`. Each `SearchResult` consists of the entry's name relative to the named context and the entry's attributes selected by using the `retIDs` parameter. Because the search involves only the named context, the name is usually atomic, unless an alias or referral has been followed.

> If the API user invokes `NamingEnumeration.close()`, the context implementation should release resources associated with the search.

> #### The Advanced Search

> The complexity of implementing the advanced search has two dimensions. One dimension is the ability to process search filters that are arbitrarily complex. The other is the ability to satisfy the constraints specified in the `SearchControls` parameter. For example, an API user can specify a subtree search via this parameter. The advanced search maps easily onto directories that implement the LDAP or X.500 protocols. Context implementations for other protocols might need substantial work in order to support this method.

> Like the basic search, the advanced search returns a `NamingEnumeration` of `SearchResult`s. A `SearchResult` can contain, in addition to the name and requested attributes of the entry, the object bound to the name, provided that the API user requested it via the `SearchControls` parameter. See later in this lesson for a description of how to make the context implementation extensible in the types of objects that it can return in a `SearchResult`.

| Adding Directory Support