if (!dn2uri.returnSearchReferences(searchOperation))
{
if (pageRequest != null)
{
// Indicate no more pages.
PagedResultsControl control;
control = new PagedResultsControl(pageRequest.isCritical(), 0,
null);
searchOperation.getResponseControls().add(control);
}
}
}
}
/*
* We will iterate forwards through a range of the dn2id keys to
* find subordinates of the target entry from the top of the tree
* downwards. For example, any subordinates of "dc=example,dc=com" appear
* in dn2id with a key ending in ",dc=example,dc=com". The entry
* "cn=joe,ou=people,dc=example,dc=com" will appear after the entry
* "ou=people,dc=example,dc=com".
*/
byte[] baseDNKey = JebFormat.dnToDNKey(baseDN,
this.baseDN.getNumComponents());
byte[] suffix = Arrays.copyOf(baseDNKey, baseDNKey.length+1);
suffix[suffix.length-1] = 0x00;
/*
* Set the ending value to a value of equal length but slightly
* greater than the suffix. Since keys are compared in
* reverse order we must set the first byte (the comma).
* No possibility of overflow here.
*/
byte[] end = suffix.clone();
end[end.length-1] = (byte) (end[end.length-1] + 1);
// Set the starting value.
byte[] begin;
if (pageRequest != null && pageRequest.getCookie().length() != 0)
{
// The cookie contains the DN of the next entry to be returned.
try
{
DN lastDN = DN.decode(pageRequest.getCookie());
begin = StaticUtils.getBytes(lastDN.toNormalizedString());
}
catch (Exception e)
{
if (debugEnabled())
{
TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
String str = pageRequest.getCookie().toHex();
Message msg = ERR_JEB_INVALID_PAGED_RESULTS_COOKIE.get(str);
throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
msg, e);
}
}
else
{
// Set the starting value to the suffix.
begin = suffix;
}
DatabaseEntry data = new DatabaseEntry();
DatabaseEntry key = new DatabaseEntry(begin);
List<Lock> lockList = new ArrayList<Lock>(1);
int lookthroughCount = 0;
int lookthroughLimit =
searchOperation.getClientConnection().getLookthroughLimit();
try
{
Cursor cursor = dn2id.openCursor(null, null);
try
{
OperationStatus status;
// Initialize the cursor very close to the starting value.
status = cursor.getSearchKeyRange(key, data, LockMode.DEFAULT);
// Step forward until we pass the ending value.
while (status == OperationStatus.SUCCESS)
{
if(lookthroughLimit > 0 && lookthroughCount > lookthroughLimit)
{
//Lookthrough limit exceeded
searchOperation.setResultCode(ResultCode.ADMIN_LIMIT_EXCEEDED);
searchOperation.appendErrorMessage(
NOTE_JEB_LOOKTHROUGH_LIMIT_EXCEEDED.get(lookthroughLimit));
return;
}
int cmp = dn2id.getComparator().compare(key.getData(), end);
if (cmp >= 0)
{
// We have gone past the ending value.
break;
}
// We have found a subordinate entry.
EntryID entryID = new EntryID(data);
boolean isInScope = true;
if (searchScope == SearchScope.SINGLE_LEVEL)
{
// Check if this entry is an immediate child.
if(JebFormat.findDNKeyParent(key.getData(), 0,
key.getSize()) != baseDNKey.length)
{
isInScope = false;
}
}
if (isInScope)
{
Entry entry;
Entry cacheEntry;
// Try the entry cache first. Note no need to take a lock.
lockList.clear();
cacheEntry = entryCache.getEntry(backend, entryID.longValue(),
LockType.NONE, lockList);
if (cacheEntry == null)
{
entry = id2entry.get(null, entryID, LockMode.DEFAULT);
}
else
{
entry = cacheEntry;
}
// Process the candidate entry.
if (entry != null)
{
lookthroughCount++;
if (manageDsaIT || entry.getReferralURLs() == null)
{
// Filter the entry.
if (searchOperation.getFilter().matchesEntry(entry))
{
if (pageRequest != null &&
searchOperation.getEntriesSent() ==
pageRequest.getSize())
{
// The current page is full.
// Set the cookie to remember where we were.
ByteString cookie = ByteString.wrap(key.getData());
PagedResultsControl control;
control = new PagedResultsControl(pageRequest.isCritical(),
0, cookie);
searchOperation.getResponseControls().add(control);
return;
}
if (!searchOperation.returnEntry(entry, null))
{
// We have been told to discontinue processing of the
// search. This could be due to size limit exceeded or
// operation cancelled.
return;
}
}
}
}
}
searchOperation.checkIfCanceled(false);
// Move to the next record.
status = cursor.getNext(key, data, LockMode.DEFAULT);
}
}
finally
{
cursor.close();
}
}
catch (DatabaseException e)
{
if (debugEnabled())
{
TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
}
if (pageRequest != null)
{
// Indicate no more pages.
PagedResultsControl control;
control = new PagedResultsControl(pageRequest.isCritical(), 0, null);
searchOperation.getResponseControls().add(control);
}
}