org.springframework.ldap.control.PagedResultsDirContextProcessor Maven / Gradle / Ivy
/*
* Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.control;
import javax.naming.ldap.Control;
/**
* DirContextProcessor implementation for managing the paged results control.
* Note that due to the internal workings of LdapTemplate
, the
* target connection is closed after each LDAP call. The PagedResults control
* require the same connection be used for each call, which means we need to
* make sure the target connection is never actually closed. There's basically
* two ways of making this happen: use the SingleContextSource
* implementation or make sure all calls happen within a single LDAP transaction
* (using ContextSourceTransactionManager
).
*
* @author Mattias Hellborg Arthursson
* @author Ulrik Sandberg
*/
public class PagedResultsDirContextProcessor extends AbstractFallbackRequestAndResponseControlDirContextProcessor {
private static final String DEFAULT_REQUEST_CONTROL = "javax.naming.ldap.PagedResultsControl";
private static final String FALLBACK_REQUEST_CONTROL = "com.sun.jndi.ldap.ctl.PagedResultsControl";
private static final String DEFAULT_RESPONSE_CONTROL = "javax.naming.ldap.PagedResultsResponseControl";
private static final String FALLBACK_RESPONSE_CONTROL = "com.sun.jndi.ldap.ctl.PagedResultsResponseControl";
private int pageSize;
private PagedResultsCookie cookie;
private int resultSize;
/**
* Constructs a new instance. This constructor should be used when
* performing the first paged search operation, when no other results have
* been retrieved.
*
* @param pageSize the page size.
*/
public PagedResultsDirContextProcessor(int pageSize) {
this(pageSize, null);
}
/**
* Constructs a new instance with the supplied page size and cookie. The
* cookie must be the exact same instance as received from a previous paged
* results search, or null
if it is the first in an operation
* sequence.
*
* @param pageSize the page size.
* @param cookie the cookie, as received from a previous search.
*/
public PagedResultsDirContextProcessor(int pageSize, PagedResultsCookie cookie) {
this.pageSize = pageSize;
this.cookie = cookie;
defaultRequestControl = DEFAULT_REQUEST_CONTROL;
defaultResponseControl = DEFAULT_RESPONSE_CONTROL;
fallbackRequestControl = FALLBACK_REQUEST_CONTROL;
fallbackResponseControl = FALLBACK_RESPONSE_CONTROL;
loadControlClasses();
}
/**
* Get the cookie.
*
* @return the cookie.
*/
public PagedResultsCookie getCookie() {
return cookie;
}
/**
* Get the page size.
*
* @return the page size.
*/
public int getPageSize() {
return pageSize;
}
/**
* Get the total estimated number of entries that matches the issued search.
* Note that this value is optional for the LDAP server to return, so it
* does not always contain any valid data.
*
* @return the estimated result size, if returned from the server.
*/
public int getResultSize() {
return resultSize;
}
/*
* @see
* org.springframework.ldap.control.AbstractRequestControlDirContextProcessor
* #createRequestControl()
*/
public Control createRequestControl() {
byte[] actualCookie = null;
if (cookie != null) {
actualCookie = cookie.getCookie();
}
return super.createRequestControl(new Class[] { int.class, byte[].class, boolean.class },
new Object[] {new Integer(pageSize), actualCookie, Boolean.valueOf(critical)});
}
/*
* @seeorg.springframework.ldap.control.
* AbstractFallbackRequestAndResponseControlDirContextProcessor
* #handleResponse(java.lang.Object)
*/
protected void handleResponse(Object control) {
byte[] result = (byte[]) invokeMethod("getCookie", responseControlClass, control);
this.cookie = new PagedResultsCookie(result);
Integer wrapper = (Integer) invokeMethod("getResultSize", responseControlClass, control);
this.resultSize = wrapper.intValue();
}
}