971 lines
46 KiB
Plaintext
971 lines
46 KiB
Plaintext
<!--
|
|
|
|
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
|
Portions copyright 1999 Netscape Communications Corporation. All
|
|
Rights Reserved.
|
|
|
|
The contents of this document are subject to the terms of the
|
|
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
|
version (the "License"). You may not use this document except in
|
|
compliance with the License.
|
|
|
|
See the License for the specific language governing
|
|
permissions and limitations under the License. You can obtain
|
|
a copy of the License at
|
|
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
|
|
|
-->
|
|
<chapter id="searching"><title>Searching the Directory With &DirectorySDKForJava;</title>
|
|
<highlights>
|
|
<para>This chapter explains how to use the LDAP Java classes to search the
|
|
directory to retrieve entries. The chapter also describes how to get attributes
|
|
and attribute values from an entry.</para>
|
|
<itemizedlist>
|
|
<para>This chapter covers the following topics:</para>
|
|
<listitem><para><olink targetptr="searching-overview">Searching With the LDAP
|
|
Java Classes</olink></para></listitem>
|
|
<listitem><para><olink targetptr="searching-request">Sending a Search Request
|
|
With Directory SDK for Java</olink></para></listitem>
|
|
<listitem><para><olink targetptr="searching-results">Getting the Search Results
|
|
With Directory SDK for Java</olink></para></listitem>
|
|
<listitem><para><olink targetptr="searching-sorting">Sorting the Search Results
|
|
With Directory SDK for Java</olink></para></listitem>
|
|
<listitem><para><olink targetptr="searching-abandoning">Abandoning a Search
|
|
With Directory SDK for Java</olink></para></listitem>
|
|
<listitem><para><olink targetptr="searching-example">Searching the Directory
|
|
With Directory SDK for Java</olink></para></listitem>
|
|
<listitem><para><olink targetptr="searching-read">Reading an Entry With Directory
|
|
SDK for Java</olink></para></listitem>
|
|
<listitem><para><olink targetptr="searching-child-entries">Listing Child Entries
|
|
With Directory SDK for Java</olink></para></listitem>
|
|
</itemizedlist>
|
|
</highlights>
|
|
<sect1 id="searching-overview"><title>Searching With the LDAP Java Classes</title>
|
|
<itemizedlist>
|
|
<para>In &DirectorySDKForJava;, searches are represented by objects of
|
|
the following classes:</para>
|
|
<listitem><para>You can send a search request by invoking the <literal>search</literal> method
|
|
of the <classname>LDAPConnection</classname> object.</para></listitem>
|
|
<listitem><para>You can specify a set of search constraints by using an <classname>
|
|
LDAPSearchConstraints</classname> object. The constraints can specify the
|
|
maximum number of results to return. The constraints can also specify the
|
|
maximum amount of time that is allowed for a search.</para></listitem>
|
|
<listitem><para>You can specify different parts of the search criteria in
|
|
separate arguments. Alternatively, you can construct an <classname>LDAPUrl</classname> object
|
|
to specify the search criteria.</para></listitem>
|
|
<listitem><para>You can search for a single entry by invoking the <literal>read</literal> method
|
|
of the <classname>LDAPConnection</classname> object.</para></listitem>
|
|
<listitem><para>The server returns the search results to the LDAP Java classes,
|
|
which represents the results as an <classname>LDAPSearchResults</classname> object.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</sect1>
|
|
<sect1 id="searching-request"><title>Sending a Search Request With &DirectorySDKForJava;</title>
|
|
<para>To search the directory, use the <literal>search</literal> method of
|
|
the <classname>LDAPConnection</classname> object. The search results are returned
|
|
in the form of an <classname>LDAPSearchResults</classname> object.</para>
|
|
<programlisting>public LDAPSearchResults search(String base, int scope,
|
|
String filter, String attrs[], boolean attrsOnly,
|
|
LDAPSearchConstraints cons) throws LDAPException</programlisting>
|
|
<para>You need to specify the following parameters as arguments to the <literal>search
|
|
</literal> method.</para>
|
|
<variablelist>
|
|
<varlistentry><term><parameter>base</parameter></term>
|
|
<listitem><para>Specifies the base DN, which is the entry on and under which
|
|
the search is carried out.</para>
|
|
<para>For example, when searching entries with DNs such as <literal>uid=bjensen,ou=People,dc=example,dc=com
|
|
</literal>, the <parameter>base</parameter> could be <literal>ou=People,dc=example,dc=com
|
|
</literal> or <literal>dc=example,dc=com</literal>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><parameter>scope</parameter></term>
|
|
<listitem><para>Specifies the scope of the search.</para>
|
|
<para>You can adjust the scope of the search to examine only the entry identified
|
|
by the <parameter>base</parameter>, only those entries one level down the
|
|
tree from the <parameter>base</parameter>, or the entire subtree underneath
|
|
the <parameter>base</parameter>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><parameter>filter</parameter></term>
|
|
<listitem><para>Specifies what to search for.</para>
|
|
<para>A search filter specifies what search results to return. The filter
|
|
meaning can be simple, such as “find entries where the last name is
|
|
Jensen”. The filter meaning can also be complex, such as “find
|
|
entries that belong to Dept. #17 and with first names that start with the
|
|
letter F.”</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><parameter>attrs</parameter></term><term><parameter>attrsOnly
|
|
</parameter></term>
|
|
<listitem><para>Specify the entry attributes to retrieve.</para>
|
|
<para>For example, you can use <parameter>attrs</parameter> to retrieve only
|
|
email addresses and phone numbers. Alternatively, you can set up a search
|
|
to return all attributes in an entry. You can also specify to return only
|
|
the names of attributes, not the values, by setting <parameter>attrsOnly</parameter> to <constant>
|
|
true</constant>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><parameter>cons</parameter></term>
|
|
<listitem><para>Specifies constraints to apply to the search when you do not
|
|
want to use the default constraints.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>The following figure illustrates how search criteria work.</para>
|
|
<figure id="searching-criteria"><title>Criteria for an LDAP Search</title>
|
|
<mediaobject>
|
|
<imageobject><imagedata entityref="hierovrw"></imageobject>
|
|
<textobject><simpara>How search criteria work</simpara></textobject>
|
|
</mediaobject>
|
|
</figure>
|
|
<para>You can also specify the criteria in the form of an LDAP URL. An LDAP
|
|
URL allows you to specify the host name and port number of the LDAP server
|
|
that you want to search. To search a different LDAP server than the server
|
|
you are connected to, you can invoke the search method. You then specify an
|
|
LDAP URL in the form of an <classname>LDAPUrl</classname> object. See <olink
|
|
targetptr="ldap-urls">Chapter 7, LDAP URLs With Directory SDK for Java</olink> for
|
|
details.</para>
|
|
<sect2 id="searching-specify-base"><title>Specifying the Base DN and Scope</title>
|
|
<indexterm>
|
|
<primary>base DN</primary>
|
|
<secondary>explained</secondary>
|
|
</indexterm><indexterm>
|
|
<primary>scope</primary>
|
|
<secondary>explained</secondary>
|
|
</indexterm>
|
|
<para>When sending a search request, you need to specify the base DN and scope
|
|
of the search to identify the entries that you want searched.</para>
|
|
<para>The base DN is the DN of the entry that serves as the starting point
|
|
of the search.</para>
|
|
<itemizedlist>
|
|
<para>To specify the scope of the search, you pass one of the following values
|
|
as the scope parameter:</para>
|
|
<listitem><para><constant>LDAPv3.SCOPE_SUB</constant> — Search the base
|
|
entry and all entries at all levels under the base entry.</para>
|
|
<mediaobject>
|
|
<imageobject><imagedata entityref="hiersrch"></imageobject>
|
|
<textobject><simpara>Subtree scope applies to everything below the base DN.</simpara>
|
|
</textobject>
|
|
</mediaobject>
|
|
</listitem>
|
|
<listitem><para><constant>LDAPv3.SCOPE_ONE</constant> — Search all entries
|
|
at one level under the base entry.</para>
|
|
<mediaobject>
|
|
<imageobject><imagedata entityref="hier1lvl"></imageobject>
|
|
<textobject><simpara>One level scope applies to all entries just below the
|
|
base DN.</simpara></textobject>
|
|
</mediaobject>
|
|
<para>The base entry is not included in the search. Use this setting if you
|
|
just want a list of the entries under a given entry.</para></listitem>
|
|
<listitem><para><constant>LDAPv3.SCOPE_BASE</constant> — Search only
|
|
the base entry.</para>
|
|
<mediaobject>
|
|
<imageobject><imagedata entityref="hierbase"></imageobject>
|
|
<textobject><simpara>Base scope applies only to the base DN entry.</simpara>
|
|
</textobject>
|
|
</mediaobject>
|
|
<para>Use this setting if you want to read the attributes of only the base
|
|
entry.</para></listitem>
|
|
</itemizedlist>
|
|
</sect2>
|
|
<sect2 id="searching-filter"><title>Specifying a Search Filter</title>
|
|
<indexterm>
|
|
<primary>filters</primary>
|
|
</indexterm><indexterm>
|
|
<primary>search filters</primary>
|
|
<secondary>specifying</secondary>
|
|
</indexterm>
|
|
<para>When you search the directory, you use a search filter to define the
|
|
search. Here is the basic syntax for a search filter:</para>
|
|
<programlisting>(<replaceable>attribute</replaceable> <replaceable>operator</replaceable> <replaceable>
|
|
value</replaceable>)</programlisting>
|
|
<para>Here is a simple example of a search filter:</para>
|
|
<programlisting>(cn=Barbara Jensen)</programlisting>
|
|
<para>In this example, <literal>cn</literal> is the attribute. <literal>=</literal> is
|
|
the operator. <literal>Barbara Jensen</literal> is the value. The filter finds
|
|
entries with the common name <literal>Barbara Jensen</literal>.</para>
|
|
<para>Valid attributes that you can use in your search filter are provided
|
|
in the documentation for the LDAP server.</para>
|
|
<para>Following are descriptions of valid operators for search filters, and
|
|
example filters that use the operators.</para>
|
|
<variablelist>
|
|
<varlistentry><term><literal>=</literal></term>
|
|
<listitem><para>Return entries whose attributes are equal to the value provided.</para>
|
|
<para>For example, the following filter matches Barbara Jensen's entry:</para>
|
|
<programlisting>(cn=Barbara Jensen)</programlisting>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><literal>>=</literal></term>
|
|
<listitem><para>Return entries whose attributes are greater than or equal
|
|
to the value provided.</para>
|
|
<para>For example, the following filter matches Barbara Jensen's entry and
|
|
entries for people with surnames following Jensen in alphabetic order, such
|
|
as entries with <literal>sn=Seuss</literal> and <literal>sn=Zhivago</literal>:</para>
|
|
<programlisting>(sn>=jensen)</programlisting>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><literal><=</literal></term>
|
|
<listitem><para>Return entries whose attributes are less than or equal to
|
|
the value provided.</para>
|
|
<para>For example, the following filter matches Barbara Jensen's entry and
|
|
entries for people with surnames that precede Jensen in alphabetic order,
|
|
such as entries with <literal>sn=Anderson</literal> and <literal>sn=Cubbins</literal>:
|
|
</para>
|
|
<programlisting>(sn<=jensen)</programlisting>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><literal>=*</literal></term>
|
|
<listitem><para>Return entries that have a value set for the attribute (presence).
|
|
</para>
|
|
<para>For example, the following filter matches all entries that have a value
|
|
for the surname:</para>
|
|
<programlisting>(sn=*)</programlisting>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><literal>~=</literal></term>
|
|
<listitem><para>Return entries whose attribute value approximately matches
|
|
the specified value, such as the value sounds like the specified value.</para>
|
|
<para>For example, the following filter matches all entries with values for
|
|
surname that sound like Jensen, such as Barbara Jensen's entry, but also Emanuel
|
|
Johnson's entry:</para>
|
|
<programlisting>(sn~=jensen)</programlisting>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>With Boolean operators and with parentheses, you can combine different
|
|
sets of conditions. Here is the syntax for combining search filters:</para>
|
|
<programlisting>(<replaceable>boolean</replaceable>(<replaceable>filter1</replaceable>)(<replaceable>
|
|
filter2</replaceable>)(…))</programlisting>
|
|
<para>Following are descriptions of the valid boolean operators.</para>
|
|
<variablelist>
|
|
<varlistentry><term><literal>&</literal></term>
|
|
<listitem><para>Return entries that match all specified filters.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><literal>|</literal></term>
|
|
<listitem><para>Return entries that match one or more of the specified filters.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><literal>!</literal></term>
|
|
<listitem><para>Return entries that do not match the specified filter.</para>
|
|
<para>This operator is unary because you can apply the operator only to a
|
|
single set of results. In other words, to specify “entries that match
|
|
neither <replaceable>filter1</replaceable> nor <replaceable>filter2</replaceable>,”
|
|
use the syntax:</para>
|
|
<programlisting>(!(|(<replaceable>filter1</replaceable>)(<replaceable>filter2</replaceable>)))
|
|
</programlisting>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>You can also include wildcard characters to search for entries that
|
|
start with, contain, or end with a given value. For example, you can use the
|
|
following filter to search for all entries with first names that begin with
|
|
the letter <literal>F</literal>:</para>
|
|
<programlisting>(givenName=F*)</programlisting>
|
|
</sect2>
|
|
<sect2 id="searching-specify-attrs"><title>Specifying the Attributes to Retrieve</title>
|
|
<indexterm>
|
|
<primary>attributes</primary>
|
|
<secondary>operational</secondary>
|
|
</indexterm><indexterm>
|
|
<primary>attributes</primary>
|
|
<secondary>retrieving in a search</secondary>
|
|
</indexterm><indexterm>
|
|
<primary>operational attributes</primary>
|
|
</indexterm>
|
|
<itemizedlist>
|
|
<para>With the <parameter>attrs</parameter> parameter, you can retrieve all
|
|
attributes in entries returned by the search. Alternatively, you can specify
|
|
the attributes that you want returned in the search results. For example,
|
|
you can specify to return the attributes in one of the following ways:</para>
|
|
<listitem><para>To return selected attributes, pass an array of the attribute
|
|
names as the <parameter>attrs</parameter> parameter. For example, to return
|
|
only email addresses and phone numbers, pass the array <literal>{"mail", "telephoneNumber"}
|
|
</literal> as the <parameter>attrs</parameter> parameter.</para></listitem>
|
|
<listitem><para>To return all attributes in an entry, pass <constant>null</constant> as
|
|
the <parameter>attrs</parameter> parameter.</para></listitem>
|
|
<listitem><para>To return no attributes from an entry, pass <constant>LDAPv3.NO_ATTRS
|
|
</constant> as the <parameter>attrs</parameter> parameter.</para></listitem>
|
|
</itemizedlist>
|
|
<para>You might plan to sort the results on your client as described in <olink
|
|
targetptr="searching-sorting">Sorting the Search Results With Directory SDK
|
|
for Java</olink>. Return the attributes that you plan to use for sorting.
|
|
For example, if you plan to sort by email address, make sure that the mail
|
|
attribute is returned in the search results.</para>
|
|
<para>Some attributes are used by servers for administering the directory.
|
|
For example, the <literal>creatorsName</literal> attribute specifies the DN
|
|
of the user who added the entry. These attributes are called <firstterm>operational
|
|
attributes</firstterm>.</para>
|
|
<para>Servers do not normally return operational attributes in search results
|
|
unless you specify the attributes by name. For example, if you pass <constant>null
|
|
</constant> as the <parameter>attrs</parameter> parameter to retrieve all
|
|
of the attributes in entries found by the search, the operational attribute <literal>
|
|
creatorsName</literal> is not returned to your client. You need to explicitly
|
|
specify the <literal>creatorsName</literal> attribute in the <parameter>attrs</parameter> parameter.
|
|
</para>
|
|
<para>To return all attributes in an entry with selected operational attributes,
|
|
pass a string array containing <constant>LDAPv3.ALL_USER_ATTRS</constant>,
|
|
and also the names of the operational attributes as the <parameter>attrs</parameter> parameter.
|
|
Following are a few operational attributes and a description of what each
|
|
attribute contains.</para>
|
|
<variablelist>
|
|
<varlistentry><term><literal>createTimestamp</literal></term>
|
|
<listitem><para>The time when the entry was added to the directory.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><literal>modifyTimestamp</literal></term>
|
|
<listitem><para>The time when the entry was last modified.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><literal>creatorsName</literal></term>
|
|
<listitem><para>Distinguished name (DN) of the user who added the entry to
|
|
the directory.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><literal>modifiersName</literal></term>
|
|
<listitem><para>DN of the user who last modified the entry.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><literal>subschemaSubentry</literal></term>
|
|
<listitem><para>DN of the subschema entry, that controls the schema for this
|
|
entry.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</sect2>
|
|
<sect2 id="searching-set-prefs"><title>Setting Search Preferences</title>
|
|
<para>For a given search, you can apply a set of preferences that determine
|
|
how the search is performed. For example, you can specify the maximum number
|
|
of results to be returned or the maximum amount of time to wait for a search.</para>
|
|
<para>The <classname>LDAPSearchConstraints</classname> class represents a
|
|
set of search constraints. The methods of this class allow you to get and
|
|
set the constraints.</para>
|
|
<sect3 id="searching-set-prefs-all"><title>Setting Preferences for All Searches</title>
|
|
<indexterm>
|
|
<primary>search results</primary>
|
|
<secondary>setting preferences</secondary>
|
|
</indexterm>
|
|
<para>The <classname>LDAPConnection</classname> object, which represents a
|
|
connection to the LDAP server, is associated with a default set of search
|
|
constraints. These constraints apply to all searches that you perform over
|
|
the connection.</para>
|
|
<itemizedlist>
|
|
<listitem><para>To get the default set of search constraints for the connection,
|
|
you can use the <literal>getSearchConstraints</literal> method.</para>
|
|
</listitem>
|
|
<listitem><para>To get or set any of the search constraints individually,
|
|
you can use the <literal>getOption</literal> method and the <literal>setOption</literal> method.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
<para>For example, if you want to specify the maximum number of results returned,
|
|
you can set this constraint for the connection:</para>
|
|
<programlisting>LDAPConnection ld = new LDAPConnection();
|
|
ld.connect("ldap.example.com", LDAPv3.DEFAULT_PORT);
|
|
ld.setOption(LDAPv3.SIZELIMIT, new Integer(100));</programlisting>
|
|
</sect3>
|
|
<sect3 id="searching-set-prefs-override"><title>Overriding Preferences for
|
|
Individual Searches</title>
|
|
<para>To override the default set of search constraints for a given search
|
|
request, construct your own <classname>LDAPSearchConstraints</classname> object.
|
|
Pass the object to the <literal>search</literal> method of the <classname>LDAPConnection
|
|
</classname> object.</para>
|
|
<para>You can also modify a copy of the existing search constraints. Pass
|
|
the modified set of constraints to the <literal>search</literal> method. Invoke
|
|
the <literal>getSearchConstraints</literal> method of the <classname>LDAPConnection
|
|
</classname> object to get the default set of constraints for that connection.
|
|
Then invoke the clone method of the <classname>LDAPSearchConstraints</classname> object
|
|
to make a copy of the set that you can then modify.</para></sect3>
|
|
<sect3 id="searching-set-prefs-wait"><title>Configuring the Search to Wait
|
|
for All Results</title>
|
|
<indexterm>
|
|
<primary>search results</primary>
|
|
<secondary>waiting for all</secondary>
|
|
</indexterm>
|
|
<para>By default, the <literal>search</literal> method of the <classname>LDAPConnection
|
|
</classname> object does not block until all results are received. Instead,
|
|
the <literal>search</literal> method returns as soon as one of the results
|
|
has been received.</para>
|
|
<itemizedlist>
|
|
<para>If you want the <literal>search</literal> method to block until all
|
|
results are received, you can do one of the following:</para>
|
|
<listitem><para>Use the <literal>setOption</literal> method of the <classname>LDAPConnection
|
|
</classname> object to set the <constant>LDAPv3.BATCHSIZE</constant> preference
|
|
to <literal>0</literal>.</para></listitem>
|
|
<listitem><para>Pass a <literal>0</literal> to the <literal>setBatchSize</literal> method
|
|
of the <classname>LDAPSearchConstraints</classname> object to change the behavior
|
|
for a particular set of search constraints.</para></listitem>
|
|
</itemizedlist>
|
|
<para>Whether waiting for one or all results of the <literal>search</literal> method,
|
|
you still need to invoke the <literal>next</literal> method of the returned <classname>
|
|
LDAPSearchResults</classname> object to retrieve each individual result.</para>
|
|
</sect3>
|
|
<sect3 id="searching-set-prefs-size"><title>Setting Size and Time Limits</title>
|
|
<indexterm>
|
|
<primary>search results</primary>
|
|
<secondary>setting size limits</secondary>
|
|
</indexterm><indexterm>
|
|
<primary>search results</primary>
|
|
<secondary>setting time limits</secondary>
|
|
</indexterm>
|
|
<para>By default, when you search the directory from a client that you built
|
|
with &DirectorySDKForJava;, the maximum number of entries to return is
|
|
set to <literal>1000</literal>. No maximum time limit is set for waiting on
|
|
an operation to complete.</para>
|
|
<itemizedlist>
|
|
<para>To change these default values, you can do one of the following:</para>
|
|
<listitem><para>Use the <literal>setOption</literal> method of the <classname>LDAPConnection
|
|
</classname> object to set the <constant>LDAPv3.SIZELIMIT</constant> and <constant>
|
|
LDAPv3.TIMELIMIT</constant> preferences.</para></listitem>
|
|
<listitem><para>Use the <literal>setMaxResults</literal> method and the <literal>
|
|
setTimeLimit</literal> method of the <classname>LDAPSearchConstraints</classname> object
|
|
to change the behavior for a particular set of search constraints.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
<itemizedlist>
|
|
<para>When you set the size limit or time limit, you might cause an <classname>LDAPException
|
|
</classname> to be returned. The exception is returned when the limit is exceeded.
|
|
</para>
|
|
<listitem><para>If the size limit is exceeded, the server returns an <constant>LDAPException.SIZE_LIMIT_EXCEEDED
|
|
</constant> result code.</para></listitem>
|
|
<listitem><para>If the time limit is exceeded, the server returns an <constant>LDAPException.TIME_LIMIT_EXCEEDED
|
|
</constant> result code.</para></listitem>
|
|
</itemizedlist>
|
|
</sect3>
|
|
</sect2>
|
|
<sect2 id="searching-example-request"><title>Search Request Example</title>
|
|
<para>The following section of code searches for all entries with surname <literal>
|
|
Jensen</literal>. The search retrieves the names and values of the <literal>cn</literal>, <literal>
|
|
mail</literal>, and <literal>telephoneNumber</literal> attributes.</para>
|
|
<programlisting>LDAPConnection ld = null;
|
|
try {
|
|
/* Create a new LDAPConnection object. */
|
|
ld = new LDAPConnection();
|
|
|
|
/* Connect and bind to the server. */
|
|
String HOSTNAME = "localhost";
|
|
ld.connect(HOSTNAME, LDAPv3.DEFAULT_PORT, null, null);
|
|
|
|
/* Specify the search criteria. */
|
|
String baseDN = "dc=example,dc=com";
|
|
int searchScope = LDAPv3.SCOPE_SUB;
|
|
String searchFilter = "(sn=Jensen)";
|
|
String getAttrs[] = {"cn", "mail", "telephoneNumber"};
|
|
|
|
/* Send the search request. */
|
|
LDAPSearchResults res = ld.search(baseDN, searchScope,
|
|
searchFilter, getAttrs, false);
|
|
} catch(LDAPException e) {
|
|
System.out.println("Error: " + e.toString);
|
|
}</programlisting>
|
|
</sect2>
|
|
</sect1>
|
|
<sect1 id="searching-results"><title>Getting the Search Results With &DirectorySDKForJava;</title>
|
|
<indexterm>
|
|
<primary>search results</primary>
|
|
<secondary>getting</secondary>
|
|
</indexterm>
|
|
<para>When you invoke the <literal>search</literal> method of an <classname>LDAPConnection
|
|
</classname> object to search the directory, the method returns the search
|
|
results in the form of an <classname>LDAPSearchResults</classname> object.</para>
|
|
<para>The search results consist of an enumeration of entries, which are represented
|
|
by <classname>LDAPEntry</classname> objects. The search results can also include
|
|
smart referrals, also known as <firstterm>search references</firstterm>, and
|
|
exceptions.</para>
|
|
<para>Each entry contains a set of attributes, which are represented by <classname>
|
|
LDAPAttributeSet</classname> objects. Individual attributes are represented
|
|
by <classname>LDAPAttribute</classname> objects. Each attribute has a set
|
|
of values that you can get.</para>
|
|
<para>The following figure illustrates the relationship between entries, attributes,
|
|
values, and search results.</para>
|
|
<figure id="searching-result-set"><title>Entries, Attributes, and Values in
|
|
Search Results</title>
|
|
<mediaobject>
|
|
<imageobject><imagedata entityref="entries"></imageobject>
|
|
<textobject><simpara>Relationship between entries, attributes, values, and
|
|
search results</simpara></textobject>
|
|
</mediaobject>
|
|
</figure>
|
|
<sect2 id="searching-results-entries"><title>Getting Entries</title>
|
|
<indexterm>
|
|
<primary>entries</primary>
|
|
<secondary>getting from search results</secondary>
|
|
</indexterm><indexterm>
|
|
<primary>search results</primary>
|
|
<secondary>getting entries</secondary>
|
|
</indexterm>
|
|
<para>The <classname>LDAPSearchResults</classname> object represents the results
|
|
of the search. These results can include entries found by the search, search
|
|
references, and result codes. Your LDAP client can receive an <returnvalue>ADMIN_LIMIT_EXCEEDED
|
|
</returnvalue>, <returnvalue>TIME_LIMIT_EXCEEDED</returnvalue>, or <returnvalue>SIZE_LIMIT_EXCEEDED
|
|
</returnvalue> result code from the server. When the result code is received, &DirectorySDKForJava; adds
|
|
an exception for this result code to the search results.</para>
|
|
<para>To get entries from the <classname>LDAPSearchResults</classname> object,
|
|
you can either invoke the <literal>next</literal> method or the <literal>nextElement
|
|
</literal> method.</para>
|
|
<itemizedlist>
|
|
<listitem><para>When you invoke the <literal>next</literal> method, if the
|
|
next item in the search results is an entry, the method returns an <classname>LDAPEntry
|
|
</classname> object.</para>
|
|
<itemizedlist>
|
|
<para><indexterm>
|
|
<primary>referrals</primary>
|
|
<secondary><classname>LDAPReferralException</classname> and</secondary>
|
|
</indexterm><indexterm>
|
|
<primary>referrals</primary>
|
|
<secondary>getting from search results</secondary>
|
|
</indexterm>If the next item is a search reference, one of the following can
|
|
occur:</para>
|
|
<listitem><para>If referrals are not followed automatically, an <classname>LDAPReferralException
|
|
</classname> is returned. The exception is also returned if the referral hop
|
|
limit is exceeded.</para></listitem>
|
|
<listitem><para>The LDAP Java classes follow the referral when two conditions
|
|
are fulfilled. Referrals must be followed automatically, the referral hop
|
|
limit must not be exceeded. </para></listitem>
|
|
</itemizedlist>
|
|
<para>The classes also retrieve the entry for you. The method creates a new
|
|
connection to the server that is specified in the referral and attempts to
|
|
retrieve the entry from that server.</para><para>See <olink
|
|
targetptr="handling-referrals">Handling Referrals With Directory SDK for Java</olink> for
|
|
more information about referrals and search references.</para><para>If the
|
|
next item is an LDAP result code such as <returnvalue>ADMIN_LIMIT_EXCEEDED</returnvalue>, <returnvalue>
|
|
TIME_LIMIT_EXCEEDED</returnvalue>, or <returnvalue>SIZE_LIMIT_EXCEEDED</returnvalue>,
|
|
the LDAP Java classes return an <classname>LDAPException</classname>.</para>
|
|
</listitem>
|
|
<listitem><para>When you invoke the <literal>nextElement</literal> method,
|
|
the method returns an object that you must cast. The object is an <classname>LDAPEntry
|
|
</classname> object, an <classname>LDAPReferralException</classname>, or an <classname>
|
|
LDAPException</classname>.</para></listitem>
|
|
</itemizedlist>
|
|
<para>As you iterate through the search results, you can invoke the <literal>hasMoreElements
|
|
</literal> method to determine if you have reached the end of the search results.
|
|
</para>
|
|
<programlisting>LDAPConnection ld = null;
|
|
try {
|
|
/* Create a new LDAPConnection object. */
|
|
ld = new LDAPConnection();
|
|
|
|
/* Set up parameters for the search request... */
|
|
|
|
/* Send the search request. */
|
|
LDAPSearchResults res = ld.search(baseDN, searchScope,
|
|
searchFilter, getAttrs, false);
|
|
|
|
/* Iterate through the results until finished. */
|
|
while (res.hasMoreElements()) {
|
|
|
|
/* Get the next entry in the results. */
|
|
LDAPEntry findEntry = null;
|
|
try {
|
|
findEntry = res.next();
|
|
|
|
/* If it is a referral, print the LDAP URLs. */
|
|
} catch (LDAPReferralException e) {
|
|
System.out.println("Search references: ");
|
|
LDAPUrl refUrls[] = e.getURLs();
|
|
for (int i=0; i < refUrls.length; i++) {
|
|
System.out.println("\t" + refUrls[i].getUrl());
|
|
}
|
|
continue;
|
|
} catch (LDAPException e) {
|
|
System.out.println("Error: " + e.toString());
|
|
continue;
|
|
}
|
|
/* Do something with the entry... */
|
|
}
|
|
} catch (LDAPException e) {
|
|
/* Handle exceptions arising outside the search... */
|
|
}</programlisting>
|
|
</sect2>
|
|
<sect2 id="searching-results-dns"><title>Getting Distinguished Names</title>
|
|
<indexterm>
|
|
<primary>distinguished names</primary>
|
|
<secondary>getting from search results</secondary>
|
|
</indexterm><indexterm>
|
|
<primary>search results</primary>
|
|
<secondary>getting distinguished names</secondary>
|
|
</indexterm>
|
|
<para>To get the distinguished name of an <classname>LDAPEntry</classname> object,
|
|
invoke the <literal>getDN</literal> method. This method returns a <classname>String
|
|
</classname>.</para>
|
|
<programlisting>LDAPEntry nextEntry = res.next();
|
|
String nextDN = nextEntry.getDN();</programlisting>
|
|
<para>Although the <literal>netscape.ldap</literal> package includes an <classname>
|
|
LDAPDN</classname> class, you typically do not construct objects of this class
|
|
to represent DNs. The <classname>LDAPDN</classname> class is mainly a utility
|
|
class that provides methods for manipulating string DNs.</para></sect2>
|
|
<sect2 id="searching-results-attrs"><title>Getting Attributes</title>
|
|
<indexterm>
|
|
<primary>attributes</primary>
|
|
<secondary>getting from search results</secondary>
|
|
</indexterm><indexterm>
|
|
<primary>search results</primary>
|
|
<secondary>getting attributes</secondary>
|
|
</indexterm>
|
|
<para>To get the set of attributes in an <classname>LDAPEntry</classname> object,
|
|
invoke the <literal>getAttributeSet</literal> method. This method returns
|
|
an <classname>LDAPAttributeSet</classname> object.</para>
|
|
<programlisting>LDAPEntry nextEntry = res.next();
|
|
LDAPAttributeSet entryAttrs = nextEntry.getAttributeSet();</programlisting>
|
|
<para>To get individual attributes from an <classname>LDAPAttributeSet</classname> object,
|
|
invoke the <literal>getAttributes</literal> method. This method returns an
|
|
enumeration of attributes. You can then iterate through the elements in this
|
|
enumeration to retrieve individual <classname>LDAPAttribute</classname> objects.</para>
|
|
<programlisting>/* Get the set of attributes for an entry. */
|
|
LDAPAttributeSet entryAttrs = nextEntry.getAttributeSet();
|
|
|
|
/* Get an enumeration of those attribute. */
|
|
Enumeration enumAttrs = entryAttrs.getAttributes();
|
|
|
|
/* Loop through the enumeration to get each attribute. */
|
|
while (enumAttrs.hasMoreElements()) {
|
|
LDAPAttribute attr = (LDAPAttribute)enumAttrs.nextElement();
|
|
System.out.println("Attribute type: " + attr.getName());
|
|
}</programlisting>
|
|
<para>To determine the number of attributes in the <classname>LDAPAttributeSet</classname> object,
|
|
invoke the <literal>size</literal> method.</para>
|
|
<itemizedlist>
|
|
<para>You can also retrieve a specific attribute from the entry or from the
|
|
attribute set.</para>
|
|
<listitem><para>To get a specific attribute from an <classname>LDAPEntry</classname> object,
|
|
invoke the <literal>getAttribute</literal> method.</para></listitem>
|
|
<listitem><para>To get a specific attribute from an <classname>LDAPAttributeSet</classname> object,
|
|
invoke the <literal>getAttribute</literal> method.</para></listitem>
|
|
</itemizedlist>
|
|
<para>Both methods return an <classname>LDAPAttribute</classname> object.</para>
|
|
<programlisting>LDAPEntry nextEntry = res.next();
|
|
LDAPAttribute anAttr = nextEntry.getAttribute("cn");</programlisting>
|
|
</sect2>
|
|
<sect2 id="searching-results-attr-types-values"><title>Getting Attribute Types
|
|
and Values</title>
|
|
<indexterm>
|
|
<primary>attributes</primary>
|
|
<secondary>getting from search results</secondary>
|
|
</indexterm><indexterm>
|
|
<primary>search results</primary>
|
|
<secondary>getting attribute types</secondary>
|
|
</indexterm><indexterm>
|
|
<primary>search results</primary>
|
|
<secondary>getting attribute values</secondary>
|
|
</indexterm>
|
|
<para>To get the name of an <classname>LDAPAttribute</classname> object, invoke
|
|
the <literal>getName</literal> method.</para>
|
|
<programlisting>LDAPAttribute nextAttr = (LDAPAttribute)enumAttrs.nextElement();
|
|
String attrName = nextAttr.getName();</programlisting>
|
|
<itemizedlist>
|
|
<para>To get the values in an <classname>LDAPAttribute</classname> object,
|
|
you can use the following methods:</para>
|
|
<listitem><para>To get the <classname>String</classname> values, invoke the <literal>
|
|
getStringValues</literal> method.</para></listitem>
|
|
<listitem><para>To get the binary values as byte arrays, invoke the <literal>getByteValues
|
|
</literal> method.</para></listitem>
|
|
</itemizedlist>
|
|
<para>Both methods return an enumeration that you can iterate through to retrieve
|
|
individual results. For example, if an error occurs when you invoke <literal>getStringValues
|
|
</literal>, although the values are binary data, the methods return <constant>null
|
|
</constant>.</para>
|
|
<para>You can also count the number of values in an attribute by invoking
|
|
the <literal>size</literal> method of the <classname>LDAPAttribute</classname> object.
|
|
</para>
|
|
<programlisting>LDAPAttribute nextAttr = (LDAPAttribute)enumAttrs.nextElement();
|
|
|
|
/* Get and print the attribute name. */
|
|
String attrName = nextAttr.getName();
|
|
System.out.println("\t" + attrName + ":");
|
|
|
|
/* Iterate through the attribute's values. */
|
|
Enumeration enumVals = nextAttr.getStringValues();
|
|
if (enumVals != null) {
|
|
while (enumVals.hasMoreElements()) {
|
|
String nextValue = (String)enumVals.nextElement();
|
|
System.out.println("\t\t" + nextValue);
|
|
}
|
|
}</programlisting>
|
|
</sect2>
|
|
</sect1>
|
|
<sect1 id="searching-sorting"><title>Sorting the Search Results With &DirectorySDKForJava;</title>
|
|
<indexterm>
|
|
<primary>search results</primary>
|
|
<secondary>sorting</secondary>
|
|
</indexterm><indexterm>
|
|
<primary>sorting search results</primary>
|
|
</indexterm>
|
|
<itemizedlist>
|
|
<para>With &DirectorySDKForJava;, you can sort the search results in two
|
|
ways.</para>
|
|
<listitem><para>You can specify that the LDAP server should sort the results
|
|
before returning the results to your client.</para><para>Send a server-side
|
|
sort control to the server as described in <olink targetptr="controls">Chapter 10,
|
|
LDAP Controls With Directory SDK for Java</olink>. Server-side sorting might
|
|
work best if you specify a filter that uses an indexed attribute.</para>
|
|
</listitem>
|
|
<listitem><para>After you receive the results from the server, you can sort
|
|
the results on your client.</para><para>Specify the names of the attributes
|
|
that you want to use for sorting. You also need to specify whether or not
|
|
the sorting is done in ascending or descending order.</para></listitem>
|
|
</itemizedlist>
|
|
<para>You can sort the results on the client by invoking the sort method of
|
|
the <classname>LDAPSearchResults</classname> object.</para>
|
|
<para><indexterm>
|
|
<primary><classname>LDAPEntryComparator</classname> interface</primary>
|
|
<secondary>example of</secondary>
|
|
</indexterm><indexterm>
|
|
<primary><classname>LDAPEntryCompareAttrNames</classname> class</primary>
|
|
<secondary>example of</secondary>
|
|
</indexterm>When invoking this method, you need to pass a comparator object,
|
|
which is an object of a class that implements the <classname>LDAPEntryComparator</classname> interface. &DirectorySDKForJava; includes
|
|
an <classname>LDAPCompareAttrNames</classname> class that implements this
|
|
interface. This class specifies how entries are compared with each other and
|
|
sorted.</para>
|
|
<para>To construct an <classname>LDAPCompareAttrNames</classname> object,
|
|
you need to specify the attributes that you want to use for sorting and, optionally,
|
|
the sort order. When sorting on the client side, the attributes used for sorting
|
|
must be returned in the search results. If you are returning only a subset
|
|
of attributes in the search results, include the attributes that you specify
|
|
in the <classname>LDAPCompareAttrNames</classname> constructor. For example,
|
|
the following section of code sorts first by surname, <literal>sn</literal>,
|
|
and then by common name, <literal>cn</literal>, in ascending order:</para>
|
|
<programlisting>LDAPConnection ld = new LDAPConnection();
|
|
ld.connect("localhost", LDAPv3.DEFAULT_PORT);
|
|
LDAPSearchResults res = ld.search("dc=example,dc=com", LDAPv3.SCOPE_SUB,
|
|
"(objectclass=inetOrgPerson)", null, false);
|
|
String[] sortAttrs = {"sn", "cn"};
|
|
boolean[] ascending = {true, true};
|
|
res.sort(new LDAPCompareAttrNames(sortAttrs, ascending));</programlisting>
|
|
<para>If all search results have not yet been returned, the <literal>sort</literal> method
|
|
blocks until all results have been received.</para></sect1>
|
|
<sect1 id="searching-abandoning"><title>Abandoning a Search With &DirectorySDKForJava;</title>
|
|
<indexterm>
|
|
<primary>abandoning a search</primary>
|
|
</indexterm><indexterm>
|
|
<primary>searching the directory</primary>
|
|
<secondary>abandoning a search</secondary>
|
|
</indexterm>
|
|
<para>At any point during a search operation, you can send a request to the
|
|
server to abandon (cancel) the search. To abandon the search, use the <literal>abandon
|
|
</literal> method of the <classname>LDAPConnection</classname> object. Pass
|
|
in the <classname>LDAPSearchResults</classname> object that was returned to
|
|
you when you first invoked the <literal>search</literal> method.</para></sect1>
|
|
<sect1 id="searching-example"><title>Searching the Directory With &DirectorySDKForJava;</title>
|
|
<indexterm>
|
|
<primary>searching the directory</primary>
|
|
<secondary>example of</secondary>
|
|
</indexterm>
|
|
<para>The following example prints the values of all attributes in the entries
|
|
returned by a search.</para>
|
|
<example id="searching-example-code"><title>Searching for a Specific Entry</title>
|
|
<programlisting>import netscape.ldap.*;
|
|
import java.util.*;
|
|
|
|
public class Search {
|
|
public static void main(String[] args) {
|
|
try {
|
|
UserArgs userArgs = new UserArgs("Search", args, false);
|
|
LDAPConnection ld = new LDAPConnection();
|
|
ld.connect(userArgs.getHost(), userArgs.getPort());
|
|
|
|
/* search for all entries with surname of Jensen */
|
|
String MY_FILTER = "sn=Jensen";
|
|
String MY_SEARCHBASE = "dc=example,dc=com";
|
|
|
|
LDAPSearchConstraints cons = ld.getSearchConstraints();
|
|
/* Setting the batchSize to one will cause the result
|
|
enumeration below to block on one result at a time,
|
|
enabling an update of a list or other things as
|
|
results come in. */
|
|
/* This could be set to 0 in order to get all
|
|
results and to block until then. */
|
|
cons.setBatchSize(1);
|
|
LDAPSearchResults res = ld.search(MY_SEARCHBASE,
|
|
LDAPConnection.SCOPE_SUB, MY_FILTER, null, false, cons);
|
|
|
|
/* Loop on results until finished */
|
|
while (res.hasMoreElements()) {
|
|
LDAPEntry findEntry = null;
|
|
try {
|
|
findEntry = res.next();
|
|
} catch (LDAPReferralException e) {
|
|
System.out.println("Search reference: ");
|
|
LDAPUrl refUrls[] = e.getURLs();
|
|
for (int i=0; i<refUrls.length; i++) {
|
|
System.out.println("\t" + refUrls[i].getUrl());
|
|
}
|
|
continue;
|
|
} catch (LDAPException e) {
|
|
System.out.println("Error: " + e.toString());
|
|
continue;
|
|
}
|
|
System.out.println(findEntry.getDN());
|
|
|
|
/* Get the attributes of the entry */
|
|
LDAPAttributeSet findAttrs = findEntry.getAttributeSet();
|
|
Enumeration enumAttrs = findAttrs.getAttributes();
|
|
System.out.println("\tAttributes: ");
|
|
|
|
/* Loop on attributes */
|
|
while (enumAttrs.hasMoreElements()) {
|
|
LDAPAttribute anAttr =
|
|
(LDAPAttribute)enumAttrs.nextElement();
|
|
String attrName = anAttr.getName();
|
|
System.out.println("\t\t" + attrName);
|
|
|
|
/* Loop on values for this attribute */
|
|
Enumeration enumVals = anAttr.getStringValues();
|
|
if (enumVals != null) {
|
|
while (enumVals.hasMoreElements()) {
|
|
String aVal = (String)enumVals.nextElement();
|
|
System.out.println("\t\t\t" + aVal);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
ld.disconnect();
|
|
} catch(LDAPException e) {
|
|
System.out.println("Error: " + e.toString());
|
|
}
|
|
}
|
|
}</programlisting>
|
|
</example>
|
|
</sect1>
|
|
<sect1 id="searching-read"><title>Reading an Entry With &DirectorySDKForJava;</title>
|
|
<indexterm>
|
|
<primary>entries</primary>
|
|
<secondary>reading from directory</secondary>
|
|
</indexterm><indexterm>
|
|
<primary>reading an entry from the directory</primary>
|
|
</indexterm>
|
|
<para>To get a single entry from the directory, use the <literal>read</literal> method
|
|
of the <classname>LDAPConnection</classname> object. You can specify the DN
|
|
of the entry with the attributes that you want to retrieve, instead of retrieving
|
|
all attributes of the entry. You can also specify an LDAP URL that identifies
|
|
the entry that you want to retrieve.</para>
|
|
<para>To retrieve data from the entry, you can use the same classes with their
|
|
methods, as described in <olink targetptr="searching-results-attrs">Getting
|
|
Attributes</olink> and in <olink targetptr="searching-results-attr-types-values">
|
|
Getting Attribute Types and Values</olink>.</para>
|
|
<para>The following example retrieves an entry and prints the values of its
|
|
attributes.</para>
|
|
<example id="searching-example-code-read"><title>Retrieving a Specific Entry</title>
|
|
<programlisting>import netscape.ldap.*;
|
|
import java.util.*;
|
|
|
|
public class RdEntry {
|
|
public static void main(String[] args) {
|
|
try {
|
|
UserArgs userArgs = new UserArgs("PasswordPolicy", args, false);
|
|
LDAPConnection ld = new LDAPConnection();
|
|
ld.connect(userArgs.getHost(), userArgs.getPort());
|
|
|
|
String ENTRYDN = "uid=bjensen, ou=People, dc=example,dc=com";
|
|
|
|
/* Read all attributes */
|
|
LDAPEntry findEntry = ld.read(ENTRYDN);
|
|
System.out.println(findEntry.getDN());
|
|
|
|
/* Get the attributes of the entry */
|
|
LDAPAttributeSet findAttrs = findEntry.getAttributeSet();
|
|
Enumeration enumAttrs = findAttrs.getAttributes();
|
|
System.out.println("\tAttributes: ");
|
|
|
|
/* Loop on attributes */
|
|
while (enumAttrs.hasMoreElements()) {
|
|
LDAPAttribute anAttr =
|
|
(LDAPAttribute)enumAttrs.nextElement();
|
|
String attrName = anAttr.getName();
|
|
System.out.println("\t\t" + attrName);
|
|
|
|
/* Loop on values for this attribute */
|
|
Enumeration enumVals = anAttr.getStringValues();
|
|
if (enumVals != null) {
|
|
while (enumVals.hasMoreElements()) {
|
|
String aVal = (String)enumVals.nextElement();
|
|
System.out.println("\t\t\t" + aVal);
|
|
}
|
|
}
|
|
}
|
|
ld.disconnect();
|
|
} catch(LDAPException e) {
|
|
System.out.println("Error: " + e.toString());
|
|
}
|
|
}
|
|
}</programlisting>
|
|
</example>
|
|
</sect1>
|
|
<sect1 id="searching-child-entries"><title>Listing Child Entries With &DirectorySDKForJava;</title>
|
|
<indexterm>
|
|
<primary>entries</primary>
|
|
<secondary>retrieving child entries of</secondary>
|
|
</indexterm>
|
|
<para>To retrieve the entries directly beneath a particular entry, set the
|
|
starting point of the search to the entry. Also, set the scope of the search
|
|
to <constant>LDAPv3.SCOPE_ONE</constant>.</para>
|
|
<figure id="EWAUN"><title>Using Scope of One to Retrieve Child Entries</title>
|
|
<mediaobject>
|
|
<imageobject><imagedata entityref="hier1lvl" width="100"></imageobject>
|
|
<textobject><simpara>Search for child entries</simpara></textobject>
|
|
</mediaobject>
|
|
</figure>
|
|
<para>The following code performs a one-level search:</para>
|
|
<programlisting>LDAPConnection ld = null;
|
|
try {
|
|
ld = new LDAPConnection();
|
|
ld.connect("localhost", LDAPv3.DEFAULT_PORT);
|
|
|
|
LDAPSearchResults res = ld.search("dc=example,dc=com", LDAPv3.SCOPE_ONE,
|
|
"(objectclass=*)", null, false );
|
|
|
|
/* Loop on results until finished */
|
|
while (res.hasMoreElements()) {
|
|
LDAPEntry findEntry = null;
|
|
try {
|
|
findEntry = res.next();
|
|
|
|
/* If the next result is a referral, print the LDAP URLs. */
|
|
} catch (LDAPReferralException e) {
|
|
System.out.println("Search references: ");
|
|
LDAPUrl refUrls[] = e.getURLs();
|
|
for (int i=0; i < refUrls.length; i++) {
|
|
System.out.println("\t" + refUrls[i].getUrl());
|
|
}
|
|
continue;
|
|
} catch ( LDAPException e ) {
|
|
System.out.println("Error: " + e.toString());
|
|
continue;
|
|
}
|
|
|
|
/* Print the DN of the entry. */
|
|
System.out.println(findEntry.getDN());
|
|
|
|
/* Get the attributes of the entry */
|
|
LDAPAttributeSet findAttrs = findEntry.getAttributeSet();
|
|
Enumeration enumAttrs = findAttrs.getAttributes();
|
|
System.out.println("\tAttributes: ");
|
|
/* Loop on attributes */
|
|
while (enumAttrs.hasMoreElements()) {
|
|
LDAPAttribute anAttr = (LDAPAttribute)enumAttrs.nextElement();
|
|
String attrName = anAttr.getName();
|
|
System.out.println("\t\t" + attrName);
|
|
|
|
/* Loop on values for this attribute */
|
|
Enumeration enumVals = anAttr.getStringValues();
|
|
if (enumVals != null) {
|
|
while (enumVals.hasMoreElements()) {
|
|
String aVal = (String)enumVals.nextElement();
|
|
System.out.println("\t\t\t" + aVal);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} catch( LDAPException e ) {
|
|
System.out.println("Error: " + e.toString());
|
|
}
|
|
|
|
/* Done, so disconnect. */
|
|
if ((ld != null) && ld.isConnected()) {
|
|
try {
|
|
ld.disconnect();
|
|
} catch (LDAPException e) {
|
|
System.out.println("Error: " + e.toString());
|
|
}</programlisting>
|
|
</sect1>
|
|
</chapter>
|