Menu

When performing a search is there a way to tell if an entry has child entries?

2016-01-25
2016-01-26
  • Jason "JRSofty" Reed

    Hello,

    I'm currently attempting to build a TreeView of an underlying directory server. The problem is that it is pretty large and even if I search each branch separately it would take over 5 minutes to complete, which isn't really what you want a GUI. What I would like to do is only search when someone clicks on a specific DN, which does work but then the problem I'm having is showing them that it is worth clicking on a DN.

    Typcially a TreeView has a little + beside the expandible entries. To konw if can put such a + beside an entry I need to know that there are children, but I can't seem to do that without already having searched this branch. I've looked thorugh the JavaDoc but it doesn't seem that the SearchResultEntry provides a "hasChildren" or "hasSubEntries" method is there any other way to identify this?

    Regards,
    Jason Reed

     
  • Neil Wilson

    Neil Wilson - 2016-01-25

    In general, the only reliable, cross-server way to determine whether an entry might have one or more subordinate entries is to perform a search below that entry. For example:

    public boolean entryHasSubordinates(LDAPInterface connection,
                                        String dn)
           throws LDAPSearchException
    {
      // Create a single-level search request that will match any
      // entry immediately below the specified base DN.
      SearchRequest request = new SearchRequest(dn,
           SearchScope.ONE,
           Filter.createPresenceFilter("objectClass"),
           SearchRequest.NO_ATTRIBUTES);
    
      // Set a size limit of one entry for the search request.
      // This will limit the performance impact on the server.
      // You may also want to set a time limit.
      request.setSizeLimit(1);
    
      // Issue the search against the server and see if we get any
      // entries back.
      try
      {
        SearchResult searchResult = connection.search(request);
        return (searchResult.getEntryCount() > 0);
      }
      catch (LDAPSearchException e)
      {
        // If we got a "size limit exceeded" result, the search
        // request matched more than one entry, so it definitely has
        // subordinates.
        if (e.getResultCode() == ResultCode.SIZE_LIMIT_EXCEEDED)
        {
          return true;
        }
    
        // The search failed for some other reason.  In most cases,
        // we we will re-throw the exception as a kind of "I don't
        // know" response.  But if the exception indicates that the
        // search returned any entries, then that confirms that
        // there are subordinates.
        if (e.getEntryCount() > 0)
        {
          return true;
        }
        else
        {
          throw e;
        }
      }
    }
    

    But this really isn't a great approach because (a) it's really inefficient to perform an extra search against each entry that you get back, and (b) it's not uncommon for servers to reject this kind of search, especially against entries that have a lot of subordinates, unless you issue the request as a highly-privileged user.

    If you're targeting a specific type of directory server, then it might have some kind of feature to help with this specific kind of situation. For example, the X.500 specification included a "hasSubordinates" operational attribute, and many LDAP servers implement support for it. And although it never became an official standard, some servers also implement support for the "numSubordinates" operational attribute as described in https://docs.ldap.com/specs/draft-ietf-boreham-numsubordinates-01.txt. These are operational attributes, so you'll have to explicitly include them in the set of attributes to return, but if you do so and get an entry back with a hasSubordinates value of true, or a numSubordinates value greater than zero, then you know that entry has at least one subordinate. If the server you're using supports both, then it's generally better to use hasSubordinates, since it may be cheaper for the server to determine if there is at least one subordinate than to count how many there are.

    But ultimately, the best solution might be to consider a different UI approach. Unless you're certain that your application will only be used against very small directories in which it is reasonable to browse it via a tree structure (and in that case, why not just do a search that will try to retrieve all entries to start with so you know the complete structure from a single request), then maybe it's better to provide a different kind of interface. For example, you could just provide a search bar that allows the user to enter what they're looking for, and then display a table of the matching entries below that (or maybe information that could help the user refine the search if it matches too many entries to display at once).

     
  • Jason "JRSofty" Reed

    Thanks,

    Currently I've implemented the search but not a deep search and while not ideal does seem to work ok. I'll take a look into the support for the optional attributes you mentioned. It could be that they are supported but not documented.

     

Log in to post a comment.