/*
* Copyright (c) 2010 Lockheed Martin Corporation
*
* 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.eurekastreams.server.persistence.mappers.ldap;
import javax.naming.directory.SearchControls;
import org.apache.commons.logging.Log;
import org.eurekastreams.commons.logging.LogFactory;
import org.springframework.ldap.control.PagedResultsDirContextProcessor;
import org.springframework.ldap.core.CollectingNameClassPairCallbackHandler;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;
/**
* This strategy allows for searching ldap with a {@link PagedResultsDirContextProcessor}. This strategy will only work
* in Ldap environments configured to allow paging. If paging is not supported in the target ldap environment, configure
* the DefaultLdapSearchStrategy which does not use paging.
*
* This strategy provides a mechanism for setting the page size or using a default of 100. This could be a performance
* optimization for the target environment if a page size is too large or small.
*
*/
public class PagedLdapSearchStrategy implements LdapSearchStrategy
{
/**
* Logging instance.
*/
private final Log logger = LogFactory.make();
/**
* Max LDAP results per page.
*/
private static final int DEFAULT_RESULTS_PER_PAGE = 100;
/**
* The number of results per page.
*/
private final int resultsPerPage;
/**
* Default constructor which sets the results per page to the default of 100.
*/
public PagedLdapSearchStrategy()
{
resultsPerPage = DEFAULT_RESULTS_PER_PAGE;
}
/**
* Constructor.
*
* @param inPageSize
* - page size to use when querying ldap.
*/
public PagedLdapSearchStrategy(final int inPageSize)
{
resultsPerPage = inPageSize;
}
/**
* {@inheritDoc}
*
* This method provides the implementation for searching ldap with a {@link PagedResultsDirContextProcessor}.
*/
@Override
public void searchLdap(final LdapTemplate inLdapTemplate, final String inEncodedFilter,
final SearchControls inSearchControls, final CollectingNameClassPairCallbackHandler inHandler)
{
PagedResultsDirContextProcessor pager = new PagedResultsDirContextProcessor(resultsPerPage);
if (logger.isTraceEnabled())
{
logger.trace("Beginning paged ldap search with " + resultsPerPage + " results per page. Filter: "
+ inEncodedFilter + " using dc: "
+ ((LdapContextSource) inLdapTemplate.getContextSource()).getUrls()[0] + " using baseLdapPath: "
+ ((LdapContextSource) inLdapTemplate.getContextSource()).getBaseLdapPathAsString());
}
do
{
// Although the SearchControls object contains a limit on the max results for the
// search, the paging processor works over the entire result set so the loop is
// cut short manually.
inLdapTemplate.search("", inEncodedFilter, inSearchControls, inHandler, pager);
pager = new PagedResultsDirContextProcessor(resultsPerPage, pager.getCookie());
}
while (pager.getCookie() != null && pager.getCookie().getCookie() != null
&& inHandler.getList().size() < inSearchControls.getCountLimit());
if (logger.isTraceEnabled())
{
logger.trace("Paged ldap search complete with " + inHandler.getList().size() + " results retrieved");
}
}
}