/* See LICENSE for licensing and NOTICE for copyright. */
package org.ldaptive;
import java.time.Duration;
import java.util.Arrays;
import org.ldaptive.handler.SearchEntryHandler;
import org.ldaptive.handler.SearchReferenceHandler;
/**
* Contains the data required to perform an ldap search operation.
*
* @author Middleware Services
*/
public class SearchRequest extends AbstractRequest
{
/** hash code seed. */
private static final int HASH_CODE_SEED = 307;
/** DN to search. */
private String baseDn = "";
/** Search filter to execute. */
private SearchFilter searchFilter;
/** Attributes to return. */
private String[] retAttrs = ReturnAttributes.DEFAULT.value();
/** Search scope. */
private SearchScope searchScope = SearchScope.SUBTREE;
/** Time search operation will block. */
private Duration timeLimit = Duration.ZERO;
/** Number of entries to return. */
private long sizeLimit;
/** How to handle aliases. */
private DerefAliases derefAliases;
/** Whether to return only attribute types. */
private boolean typesOnly;
/** Binary attribute names. */
private String[] binaryAttrs;
/** Sort behavior of results. */
private SortBehavior sortBehavior = SortBehavior.getDefaultSortBehavior();
/** Ldap entry handlers. */
private SearchEntryHandler[] entryHandlers;
/** Search reference handlers. */
private SearchReferenceHandler[] referenceHandlers;
/** Default constructor. */
public SearchRequest() {}
/**
* Creates a new search request.
*
* @param dn to search
* @param filter search filter
*/
public SearchRequest(final String dn, final SearchFilter filter)
{
setBaseDn(dn);
setSearchFilter(filter);
}
/**
* Creates a new search request.
*
* @param dn to search
* @param filter search filter
* @param attrs to return
*/
public SearchRequest(final String dn, final SearchFilter filter, final String... attrs)
{
setBaseDn(dn);
setSearchFilter(filter);
setReturnAttributes(attrs);
}
/**
* Creates a new search request.
*
* @param dn to search
* @param filter search filter
*/
public SearchRequest(final String dn, final String filter)
{
setBaseDn(dn);
setSearchFilter(new SearchFilter(filter));
}
/**
* Creates a new search request.
*
* @param dn to search
* @param filter search filter
* @param attrs to return
*/
public SearchRequest(final String dn, final String filter, final String... attrs)
{
setBaseDn(dn);
setSearchFilter(new SearchFilter(filter));
setReturnAttributes(attrs);
}
/**
* Returns the base DN.
*
* @return base DN
*/
public String getBaseDn()
{
return baseDn;
}
/**
* Sets the base DN.
*
* @param dn base DN
*/
public void setBaseDn(final String dn)
{
baseDn = dn;
}
/**
* Returns the search filter.
*
* @return search filter
*/
public SearchFilter getSearchFilter()
{
return searchFilter;
}
/**
* Sets the search filter.
*
* @param filter search filter
*/
public void setSearchFilter(final SearchFilter filter)
{
searchFilter = filter;
}
/**
* Returns the search return attributes.
*
* @return search return attributes
*/
public String[] getReturnAttributes()
{
return retAttrs;
}
/**
* Sets the search return attributes.
*
* @param attrs search return attributes
*/
public void setReturnAttributes(final String... attrs)
{
retAttrs = ReturnAttributes.parse(attrs);
}
/**
* Gets the search scope.
*
* @return search scope
*/
public SearchScope getSearchScope()
{
return searchScope;
}
/**
* Sets the search scope.
*
* @param scope search scope
*/
public void setSearchScope(final SearchScope scope)
{
searchScope = scope;
}
/**
* Returns the time limit.
*
* @return time limit
*/
public Duration getTimeLimit()
{
return timeLimit;
}
/**
* Sets the time limit.
*
* @param limit time limit
*/
public void setTimeLimit(final Duration limit)
{
if (limit == null || limit.isNegative()) {
throw new IllegalArgumentException("Time limit cannot be null or negative");
}
timeLimit = limit;
}
/**
* Returns the size limit.
*
* @return size limit
*/
public long getSizeLimit()
{
return sizeLimit;
}
/**
* Sets the size limit.
*
* @param limit size limit
*/
public void setSizeLimit(final long limit)
{
sizeLimit = limit;
}
/**
* Returns how to dereference aliases.
*
* @return how to dereference aliases
*/
public DerefAliases getDerefAliases()
{
return derefAliases;
}
/**
* Sets how to dereference aliases.
*
* @param da how to dereference aliases
*/
public void setDerefAliases(final DerefAliases da)
{
derefAliases = da;
}
/**
* Returns whether to return only attribute types.
*
* @return whether to return only attribute types
*/
public boolean getTypesOnly()
{
return typesOnly;
}
/**
* Sets whether to return only attribute types.
*
* @param b whether to return only attribute types
*/
public void setTypesOnly(final boolean b)
{
typesOnly = b;
}
/**
* Returns names of binary attributes.
*
* @return binary attribute names
*/
public String[] getBinaryAttributes()
{
return binaryAttrs;
}
/**
* Sets names of binary attributes.
*
* @param attrs binary attribute names
*/
public void setBinaryAttributes(final String... attrs)
{
binaryAttrs = attrs;
}
/**
* Returns the sort behavior.
*
* @return sort behavior
*/
public SortBehavior getSortBehavior()
{
return sortBehavior;
}
/**
* Sets the sort behavior.
*
* @param sb sort behavior
*/
public void setSortBehavior(final SortBehavior sb)
{
sortBehavior = sb;
}
/**
* Returns the search entry handlers.
*
* @return search entry handlers
*/
public SearchEntryHandler[] getSearchEntryHandlers()
{
return entryHandlers;
}
/**
* Sets the search entry handlers.
*
* @param handlers search entry handlers
*/
public void setSearchEntryHandlers(final SearchEntryHandler... handlers)
{
if (handlers != null) {
for (SearchEntryHandler handler : handlers) {
handler.initializeRequest(this);
}
}
entryHandlers = handlers;
}
/**
* Returns the search reference handlers.
*
* @return search reference handlers
*/
public SearchReferenceHandler[] getSearchReferenceHandlers()
{
return referenceHandlers;
}
/**
* Sets the search reference handlers.
*
* @param handlers search reference handlers
*/
public void setSearchReferenceHandlers(final SearchReferenceHandler... handlers)
{
if (handlers != null) {
for (SearchReferenceHandler handler : handlers) {
handler.initializeRequest(this);
}
}
referenceHandlers = handlers;
}
/**
* Returns a search request initialized for use with an object level search scope.
*
* @param dn of an ldap entry
*
* @return search request
*/
public static SearchRequest newObjectScopeSearchRequest(final String dn)
{
return newObjectScopeSearchRequest(dn, null);
}
/**
* Returns a search request initialized for use with an object level search scope.
*
* @param dn of an ldap entry
* @param attrs to return
*
* @return search request
*/
public static SearchRequest newObjectScopeSearchRequest(final String dn, final String[] attrs)
{
return newObjectScopeSearchRequest(dn, attrs, new SearchFilter("(objectClass=*)"));
}
/**
* Returns a search request initialized for use with an object level search scope.
*
* @param dn of an ldap entry
* @param attrs to return
* @param filter to execute on the ldap entry
*
* @return search request
*/
public static SearchRequest newObjectScopeSearchRequest(
final String dn,
final String[] attrs,
final SearchFilter filter)
{
final SearchRequest request = new SearchRequest();
request.setBaseDn(dn);
request.setSearchFilter(filter);
request.setReturnAttributes(attrs);
request.setSearchScope(SearchScope.OBJECT);
return request;
}
/**
* Returns a search request initialized with the supplied request. Note that stateful ldap entry handlers could cause
* thread safety issues.
*
* @param request search request to read properties from
*
* @return search request
*/
protected static SearchRequest newSearchRequest(final SearchRequest request)
{
final SearchRequest sr = new SearchRequest();
sr.setBaseDn(request.getBaseDn());
sr.setBinaryAttributes(request.getBinaryAttributes());
sr.setDerefAliases(request.getDerefAliases());
sr.setSearchEntryHandlers(request.getSearchEntryHandlers());
sr.setSearchReferenceHandlers(request.getSearchReferenceHandlers());
sr.setReturnAttributes(request.getReturnAttributes());
sr.setSearchFilter(request.getSearchFilter());
sr.setSearchScope(request.getSearchScope());
sr.setSizeLimit(request.getSizeLimit());
sr.setSortBehavior(request.getSortBehavior());
sr.setTimeLimit(request.getTimeLimit());
sr.setTypesOnly(request.getTypesOnly());
sr.setControls(request.getControls());
sr.setReferralHandler(request.getReferralHandler());
sr.setIntermediateResponseHandlers(request.getIntermediateResponseHandlers());
return sr;
}
@Override
public boolean equals(final Object o)
{
if (o == this) {
return true;
}
if (o instanceof SearchRequest) {
final SearchRequest v = (SearchRequest) o;
return LdapUtils.areEqual(baseDn, v.baseDn) &&
LdapUtils.areEqual(binaryAttrs, v.binaryAttrs) &&
LdapUtils.areEqual(derefAliases, v.derefAliases) &&
LdapUtils.areEqual(entryHandlers, v.entryHandlers) &&
LdapUtils.areEqual(referenceHandlers, v.referenceHandlers) &&
LdapUtils.areEqual(retAttrs, v.retAttrs) &&
LdapUtils.areEqual(searchFilter, v.searchFilter) &&
LdapUtils.areEqual(searchScope, v.searchScope) &&
LdapUtils.areEqual(sizeLimit, v.sizeLimit) &&
LdapUtils.areEqual(sortBehavior, v.sortBehavior) &&
LdapUtils.areEqual(timeLimit, v.timeLimit) &&
LdapUtils.areEqual(typesOnly, v.typesOnly) &&
LdapUtils.areEqual(getControls(), v.getControls()) &&
LdapUtils.areEqual(getReferralHandler(), v.getReferralHandler()) &&
LdapUtils.areEqual(getIntermediateResponseHandlers(), v.getIntermediateResponseHandlers());
}
return false;
}
@Override
public int hashCode()
{
return
LdapUtils.computeHashCode(
HASH_CODE_SEED,
baseDn,
binaryAttrs,
derefAliases,
entryHandlers,
referenceHandlers,
retAttrs,
searchFilter,
searchScope,
sizeLimit,
sortBehavior,
timeLimit,
typesOnly,
getControls(),
getReferralHandler(),
getIntermediateResponseHandlers());
}
@Override
public String toString()
{
return
String.format(
"[%s@%d::baseDn=%s, searchFilter=%s, returnAttributes=%s, " +
"searchScope=%s, timeLimit=%s, sizeLimit=%s, derefAliases=%s, " +
"typesOnly=%s, binaryAttributes=%s, sortBehavior=%s, " +
"searchEntryHandlers=%s, searchReferenceHandlers=%s, controls=%s, " +
"referralHandler=%s, intermediateResponseHandlers=%s]",
getClass().getName(),
hashCode(),
baseDn,
searchFilter,
Arrays.toString(retAttrs),
searchScope,
timeLimit,
sizeLimit,
derefAliases,
typesOnly,
Arrays.toString(binaryAttrs),
sortBehavior,
Arrays.toString(entryHandlers),
Arrays.toString(referenceHandlers),
Arrays.toString(getControls()),
getReferralHandler(),
Arrays.toString(getIntermediateResponseHandlers()));
}
}