Skip to content

Commit

Permalink
Add support for using SearchResultHandler with send.
Browse files Browse the repository at this point in the history
Add enum to define whether a SearchResultHandler is being used with the send or execute method.
Update DefaultSearchOperationHandle to process handlers configured for send.
  • Loading branch information
dfish3r committed Sep 12, 2024
1 parent 9b71aa8 commit 3c5be3c
Show file tree
Hide file tree
Showing 8 changed files with 249 additions and 35 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* See LICENSE for licensing and NOTICE for copyright. */
package org.ldaptive.handler;

/**
* Base class for search result handlers.
*
* @author Middleware Services
*/
public abstract class AbstractSearchResultHandler implements SearchResultHandler
{

/** Handler usage. */
private final Usage usage;


/**
* Creates a new abstract search result handler.
*
* @param u handler usage
*/
public AbstractSearchResultHandler(final Usage u)
{
usage = u;
}


@Override
public Usage getUsage()
{
return usage;
}


@Override
public String toString()
{
return getClass().getName() + "@" + hashCode() + "::" + "usage=" + usage;
}
}
30 changes: 26 additions & 4 deletions core/src/main/java/org/ldaptive/handler/FreezeResultHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,31 @@
*
* @author Middleware Services
*/
public class FreezeResultHandler implements SearchResultHandler
public class FreezeResultHandler extends AbstractSearchResultHandler
{

/** hash code seed. */
private static final int HASH_CODE_SEED = 859;


/** Default constructor. */
public FreezeResultHandler()
{
this(Usage.SYNC);
}


/**
* Creates a new freeze result handler.
*
* @param u handler usage
*/
public FreezeResultHandler(final Usage u)
{
super(u);
}


@Override
public SearchResponse apply(final SearchResponse response)
{
Expand All @@ -30,20 +48,24 @@ public boolean equals(final Object o)
if (o == this) {
return true;
}
return o instanceof FreezeResultHandler;
if (o instanceof FreezeResultHandler) {
final FreezeResultHandler v = (FreezeResultHandler) o;
return LdapUtils.areEqual(getUsage(), v.getUsage());
}
return false;
}


@Override
public int hashCode()
{
return LdapUtils.computeHashCode(HASH_CODE_SEED);
return LdapUtils.computeHashCode(HASH_CODE_SEED, getUsage());
}


@Override
public String toString()
{
return "[" + getClass().getName() + "@" + hashCode() + "]";
return "[" + super.toString() + "]";
}
}
30 changes: 26 additions & 4 deletions core/src/main/java/org/ldaptive/handler/MergeResultHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,31 @@
*
* @author Miguel Martinez de Espronceda
*/
public class MergeResultHandler implements SearchResultHandler
public class MergeResultHandler extends AbstractSearchResultHandler
{

/** hash code seed. */
private static final int HASH_CODE_SEED = 857;


/** Default constructor. */
public MergeResultHandler()
{
this(Usage.SYNC);
}


/**
* Creates a new merge result handler.
*
* @param u handler usage
*/
public MergeResultHandler(final Usage u)
{
super(u);
}


@Override
public SearchResponse apply(final SearchResponse searchResponse)
{
Expand Down Expand Up @@ -82,20 +100,24 @@ public boolean equals(final Object o)
if (o == this) {
return true;
}
return o instanceof MergeResultHandler;
if (o instanceof MergeResultHandler) {
final MergeResultHandler v = (MergeResultHandler) o;
return LdapUtils.areEqual(getUsage(), v.getUsage());
}
return false;
}


@Override
public int hashCode()
{
return LdapUtils.computeHashCode(HASH_CODE_SEED);
return LdapUtils.computeHashCode(HASH_CODE_SEED, getUsage());
}


@Override
public String toString()
{
return "[" + getClass().getName() + "@" + hashCode() + "]";
return "[" + super.toString() + "]";
}
}
25 changes: 24 additions & 1 deletion core/src/main/java/org/ldaptive/handler/SearchResultHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,27 @@
*
* @author Middleware Services
*/
public interface SearchResultHandler extends Function<SearchResponse, SearchResponse> {}
public interface SearchResultHandler extends Function<SearchResponse, SearchResponse>
{


/** Intended usage of the handler. */
enum Usage {
/** Use this handler with {@link org.ldaptive.SearchOperation#send()}*/
ASYNC,

/** Use this handler with {@link org.ldaptive.SearchOperation#execute()}*/
SYNC
}


/**
* Returns the usage for this handler.
*
* @return handler usage
*/
default Usage getUsage()
{
return Usage.SYNC;
}
}
30 changes: 26 additions & 4 deletions core/src/main/java/org/ldaptive/handler/SortResultHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,31 @@
*
* @author Middleware Services
*/
public class SortResultHandler implements SearchResultHandler
public class SortResultHandler extends AbstractSearchResultHandler
{

/** hash code seed. */
private static final int HASH_CODE_SEED = 853;


/** Default constructor. */
public SortResultHandler()
{
this(Usage.SYNC);
}


/**
* Creates a new sort result handler.
*
* @param u handler usage
*/
public SortResultHandler(final Usage u)
{
super(u);
}


@Override
public SearchResponse apply(final SearchResponse response)
{
Expand All @@ -29,20 +47,24 @@ public boolean equals(final Object o)
if (o == this) {
return true;
}
return o instanceof SortResultHandler;
if (o instanceof SortResultHandler) {
final SortResultHandler v = (SortResultHandler) o;
return LdapUtils.areEqual(getUsage(), v.getUsage());
}
return false;
}


@Override
public int hashCode()
{
return LdapUtils.computeHashCode(HASH_CODE_SEED);
return LdapUtils.computeHashCode(HASH_CODE_SEED, getUsage());
}


@Override
public String toString()
{
return "[" + getClass().getName() + "@" + hashCode() + "]";
return "[" + super.toString() + "]";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,18 @@ public void sent()
* @param r result
*/
public void result(final S r)
{
processResult(r);
finalizeResult(r);
}


/**
* Perform checks on the supplied result and invoke any configured {@link #onResult} handlers.
*
* @param r to process
*/
protected void processResult(final S r)
{
if (result != null) {
throw new IllegalStateException("Result already received.");
Expand All @@ -626,6 +638,16 @@ public void result(final S r)
}
}
}
}


/**
* Sets {@link #result}, notifies that message has been consumed and invokes {@link #complete()}.
*
* @param r to finalize
*/
protected void finalizeResult(final S r)
{
result = r;
consumedMessage(r);
complete();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,32 +106,29 @@ public SearchResponse await()
throws LdapException
{
SearchResponse done = super.await();
done.addEntries(result.getEntries());
done.addReferences(result.getReferences());
if (SORT_RESULTS) {
done = SearchResponse.sort(done);
}
if (onSearchResult != null) {
for (SearchResultHandler func : onSearchResult) {
final SearchResponse handlerResponse;
try {
handlerResponse = func.apply(done);
} catch (Exception ex) {
if (ex.getCause() instanceof LdapException) {
throw (LdapException) ex.getCause();
if (func.getUsage() == SearchResultHandler.Usage.SYNC) {
final SearchResponse handlerResponse;
try {
handlerResponse = func.apply(done);
} catch (Exception ex) {
if (ex.getCause() instanceof LdapException) {
throw (LdapException) ex.getCause();
}
throw new IllegalStateException("Search result handler " + func + " threw exception", ex);
}
throw new IllegalStateException("Search result handler " + func + " threw exception", ex);
}
if (handlerResponse == null) {
throw new IllegalStateException("Search result handler " + func + " returned null result");
} else if (!handlerResponse.equalsResult(done) &&
// FollowSearchReferralHandler can be used as a referral handler and a search result handler for convenience
// allow it to modify the search response
!(ResultCode.REFERRAL == done.getResultCode() && FollowSearchReferralHandler.class.equals(func.getClass())))
{
throw new IllegalStateException("Cannot modify search result instance with handler " + func);
if (handlerResponse == null) {
throw new IllegalStateException("Search result handler " + func + " returned null result");
} else if (!handlerResponse.equalsResult(done) &&
// FollowSearchReferralHandler can be used as a referral handler and a search result handler for convenience
// allow it to modify the search response
!(ResultCode.REFERRAL == done.getResultCode() && FollowSearchReferralHandler.class.equals(func.getClass())))
{
throw new IllegalStateException("Cannot modify search result instance with handler " + func);
}
done = handlerResponse;
}
done = handlerResponse;
}
}
super.evaluateThrowCondition(done);
Expand Down Expand Up @@ -323,6 +320,42 @@ public void reference(final SearchResultReference r)
}


@Override
public void result(final SearchResponse r)
{
processResult(r);
r.addEntries(result.getEntries());
r.addReferences(result.getReferences());
SearchResponse done = r;
if (SORT_RESULTS) {
done = SearchResponse.sort(r);
}
if (onSearchResult != null) {
for (SearchResultHandler func : onSearchResult) {
if (func.getUsage() == SearchResultHandler.Usage.ASYNC) {
final SearchResponse handlerResponse;
try {
handlerResponse = func.apply(done);
if (handlerResponse == null) {
throw new IllegalStateException("Search result handler " + func + " returned null result");
} else if (!handlerResponse.equalsResult(done)) {
throw new IllegalStateException("Cannot modify search result instance with handler " + func);
}
done = handlerResponse;
} catch (Exception ex) {
if (ex.getCause() instanceof LdapException) {
exception((LdapException) ex.getCause());
} else {
logger.warn("Search result function {} in handle {} threw an exception", func, this, ex);
}
}
}
}
}
finalizeResult(done);
}


@Override
public String toString()
{
Expand Down
Loading

0 comments on commit 3c5be3c

Please sign in to comment.