blob: 07e29b7a36fb3c5fa5cb7567de5eaec151a4cb79 [file] [log] [blame]
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.ldap;
import java.io.IOException;
import com.sun.jndi.ldap.Ber;
import com.sun.jndi.ldap.BerEncoder;
/**
* Requests that the results of a search operation be returned by the LDAP
* server in batches of a specified size.
* The requestor controls the rate at which batches are returned by the rate
* at which it invokes search operations.
* <p>
* The following code sample shows how the class may be used:
* <pre>
*
* // Open an LDAP association
* LdapContext ctx = new InitialLdapContext();
*
* // Activate paged results
* int pageSize = 20; // 20 entries per page
* byte[] cookie = null;
* int total;
* ctx.setRequestControls(new Control[]{
* new PagedResultsControl(pageSize, Control.CRITICAL) });
*
* do {
* // Perform the search
* NamingEnumeration results =
* ctx.search("", "(objectclass=*)", new SearchControls());
*
* // Iterate over a batch of search results
* while (results != null && results.hasMore()) {
* // Display an entry
* SearchResult entry = (SearchResult)results.next();
* System.out.println(entry.getName());
* System.out.println(entry.getAttributes());
*
* // Handle the entry's response controls (if any)
* if (entry instanceof HasControls) {
* // ((HasControls)entry).getControls();
* }
* }
* // Examine the paged results control response
* Control[] controls = ctx.getResponseControls();
* if (controls != null) {
* for (int i = 0; i < controls.length; i++) {
* if (controls[i] instanceof PagedResultsResponseControl) {
* PagedResultsResponseControl prrc =
* (PagedResultsResponseControl)controls[i];
* total = prrc.getResultSize();
* cookie = prrc.getCookie();
* } else {
* // Handle other response controls (if any)
* }
* }
* }
*
* // Re-activate paged results
* ctx.setRequestControls(new Control[]{
* new PagedResultsControl(pageSize, cookie, Control.CRITICAL) });
* } while (cookie != null);
*
* // Close the LDAP association
* ctx.close();
* ...
*
* </pre>
* <p>
* This class implements the LDAPv3 Control for paged-results as defined in
* <a href="http://www.ietf.org/rfc/rfc2696.txt">RFC 2696</a>.
*
* The control's value has the following ASN.1 definition:
* <pre>
*
* realSearchControlValue ::= SEQUENCE {
* size INTEGER (0..maxInt),
* -- requested page size from client
* -- result set size estimate from server
* cookie OCTET STRING
* }
*
* </pre>
*
* @since 1.5
* @see PagedResultsResponseControl
* @author Vincent Ryan
*/
final public class PagedResultsControl extends BasicControl {
/**
* The paged-results control's assigned object identifier
* is 1.2.840.113556.1.4.319.
*/
public static final String OID = "1.2.840.113556.1.4.319";
private static final byte[] EMPTY_COOKIE = new byte[0];
private static final long serialVersionUID = 6684806685736844298L;
/**
* Constructs a control to set the number of entries to be returned per
* page of results.
*
* @param pageSize The number of entries to return in a page.
* @param criticality If true then the server must honor the control
* and return search results as indicated by
* pageSize or refuse to perform the search.
* If false, then the server need not honor the
* control.
* @exception IOException If an error was encountered while encoding the
* supplied arguments into a control.
*/
public PagedResultsControl(int pageSize, boolean criticality)
throws IOException {
super(OID, criticality, null);
value = setEncodedValue(pageSize, EMPTY_COOKIE);
}
/**
* Constructs a control to set the number of entries to be returned per
* page of results. The cookie is provided by the server and may be
* obtained from the paged-results response control.
* <p>
* A sequence of paged-results can be abandoned by setting the pageSize
* to zero and setting the cookie to the last cookie received from the
* server.
*
* @param pageSize The number of entries to return in a page.
* @param cookie A possibly null server-generated cookie.
* @param criticality If true then the server must honor the control
* and return search results as indicated by
* pageSize or refuse to perform the search.
* If false, then the server need not honor the
* control.
* @exception IOException If an error was encountered while encoding the
* supplied arguments into a control.
*/
public PagedResultsControl(int pageSize, byte[] cookie,
boolean criticality) throws IOException {
super(OID, criticality, null);
if (cookie == null) {
cookie = EMPTY_COOKIE;
}
value = setEncodedValue(pageSize, cookie);
}
/*
* Encodes the paged-results control's value using ASN.1 BER.
* The result includes the BER tag and length for the control's value but
* does not include the control's object identifier and criticality setting.
*
* @param pageSize The number of entries to return in a page.
* @param cookie A non-null server-generated cookie.
* @return A possibly null byte array representing the ASN.1 BER encoded
* value of the LDAP paged-results control.
* @exception IOException If a BER encoding error occurs.
*/
private byte[] setEncodedValue(int pageSize, byte[] cookie)
throws IOException {
// build the ASN.1 encoding
BerEncoder ber = new BerEncoder(10 + cookie.length);
ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
ber.encodeInt(pageSize);
ber.encodeOctetString(cookie, Ber.ASN_OCTET_STR);
ber.endSeq();
return ber.getTrimmedBuf();
}
}