0
votes

Is it possible to sort records from LDAP directory with SortControlDirContextProcessor descending, not ascending?

I based on this: SpringLdap - LdapTemplateSortedSearchITest

public void testSearch_SortControl_ConvenienceMethod() {
    SortControlDirContextProcessor requestControl;

    // Prepare for first search
    requestControl = new SortControlDirContextProcessor("cn");
    tested.search(BASE, FILTER_STRING, searchControls, callbackHandler,
            requestControl);
    int resultCode = requestControl.getResultCode();
    boolean sorted = requestControl.isSorted();
    assertThat("Search result should have been sorted: " + resultCode, sorted).isTrue();
    List list = callbackHandler.getList();
    assertSortedList(list);
}

It works but ascending. How to set descending sort?

2

2 Answers

0
votes

I believe it could be helpful:

public SortKey(String attrID, boolean ascendingOrder, String matchingRuleID)

Creates a sort key for an attribute. Entries will be sorted according to the specified attribute in the specified sort order and using the specified matching rule, if supplied.

Parameters: attrID - The non-null ID of the attribute to be used as a sort key.


ascendingOrder - If true then entries are arranged in ascending order. Otherwise there are arranged in descending order.


matchingRuleID - The possibly null ID of the matching rule to use to order the attribute values. If not specified then the ordering matching rule defined for the sort key attribute is used.

It is from docs: Java doc

Regarding your question: Example code from java doc

And I found one more alternative called unboundid ldap sdk link

0
votes

The solution for me was to implement a custom DirContextProcessor that allowed me to sort on multiple attributes with the desired direction (ascending/descending) by making use of the overload method of the SortControl class that takes an array of SortKeys objects as a parameter.

The implementation must extend the AbstractFallbackRequestAndResponseControlDirContextProcessor and override the createRequestControl method.

The superclass AbstractFallbackRequestAndResponseControlDirContextProcessor will take care of the actual creation of the control. It only expects 2 pieces of information from the subclass.

  1. The fully qualified class name of the control to instantiate
  2. The types and values of the constructor parameters

The fully qualified class name is provided in the subclass property defaultRequestControl, and the types and values of the constructor parameters are provided in the subclass method createRequestControl.

The information of the sorting direction for any particular attribute is provided in the ascendingOrder property of the SortKey object.

public class SortMultipleControlDirContextProcessor extends AbstractFallbackRequestAndResponseControlDirContextProcessor{

    private SortKey[] sortKeys;
    private boolean sorted;
    private int resultCode;

    public SortMultipleControlDirContextProcessor(SortKey ... sortKeys){

        if(ArrayUtils.isEmpty(sortKeys)){
            throw new IllegalArgumentException("At least one key to sort on must be provided.");
        }

        this.sortKeys = sortKeys;
        this.sorted = false;
        this.resultCode = -1;
        this.defaultRequestControl = "javax.naming.ldap.SortControl";
        this.defaultResponseControl = "javax.naming.ldap.SortResponseControl";
        this.fallbackRequestControl = "com.sun.jndi.ldap.ctl.SortControl";
        this.fallbackResponseControl = "com.sun.jndi.ldap.ctl.SortResponseControl";

        loadControlClasses();
    }

    @Override
    public Control createRequestControl(){
        return super.createRequestControl(new Class[]{SortKey[].class,  boolean.class}, new Object[]{sortKeys, critical});
    }

    @Override
    protected void handleResponse(Object control) {

        Boolean result = (Boolean) invokeMethod("isSorted", responseControlClass, control);
        this.sorted = result;

        Integer code = (Integer) invokeMethod("getResultCode", responseControlClass, control);
        this.resultCode = code;
    }

    public SortKey[] getSortKeys(){
        return sortKeys;
    }

    public boolean isSorted(){
        return sorted;
    }

    public int getResultCode(){
        return resultCode;
    }
}

After the implementation, you can use the class to sort the results on multiple attributes in any desired direction:

// SortKey for sorting results on the cn attribute in descending order
SortKey cnSortKey = new SortKey("cn", false, null);

// Instantiate the control
SortMultipleControlDirContextProcessor myCustomControl = new SortMultipleControlDirContextProcessor(cnSortKey);

// Perform the search with the control
List<User> users = ldapTemplate.search("", orFilter.encode(), searchControls, new UserAttributesMapper(), myCustomControl);