When writing a directory-enabled application, you can let the directory server do a lot of the work for you, and in many cases that’s appropriate. However, there are times when it might be better to do some of that processing on the client rather than the server (e.g., because of the performance hit of the additional requests, or because some target servers might not support all of the features you want to use). In other cases it might be useful to perform client-side validation prior to sending a request to the server to reduce the likelihood of a failure or to provide better information about what needs to be fixed. The UnboundID LDAP SDK for Java provides support for several types of client side processing, as described in this post.
Comparing Entries
The com.unboundid.ldap.sdk.Entry
class includes a diff
method that can be used to compare two entries. The complete definition for this method is:
public static List<Modification> diff(Entry sourceEntry, Entry targetEntry, boolean ignoreRDN, String... attributes)
It can be used to compare the contents of the two provided entries and will return a list of the modifications that can be applied to the source entry in order to make it look like the target. You can optionally ignore differences in the RDN attribute, and you can optionally restrict the comparison to a specified set of attributes.
There are many uses for this capability. For example, if you have an application that allows a user to alter the contents of entries, then this method may be used to compare a local copy of the updated entry with the original entry in order to determine the modifications to apply to the server. Alternately, you could use this to compare an entry in two different servers to determine whether they are in sync.
Schema Validation
The LDAP SDK provides enhanced support for parsing server schema definitions, and can use that to perform a number of types of client-side processing. One such capability is exposed through the com.unboundid.ldap.sdk.schema.EntryValidator
class. This class may be initialized with schema read from the server and provides the following method:
public boolean entryIsValid(Entry entry, List<String> invalidReasons)
This method may be used to determine whether the given entry conforms to the schema constraints defined in the server. The basic checks that it can perform include:
- Ensure that the entry has a valid DN
- Ensure that the entry has exactly one structural object class
- Ensure that all of the entry’s object classes are defined in the schema
- Ensure that all of the entry’s attributes are defined in the schema
- Ensure that all of the attributes required by any of the entry’s object classes are present
- Ensure that all of the attributes contained in the entry are allowed by at least one of that entry’s object classes
- Ensure that all of the attribute values conform to the syntax defined for that attribute
- Ensure that all of the attributes with multiple values are defined as multi-valued in the server schema
In addition, if there is a DIT content rule associated with the entry’s structural object class, then it will be used to ensure that all of the auxiliary object classes in the entry are allowed and that the entry doesn’t contain any prohibited attributes, and it may also allow additional attributes not allowed by any of the object classes. If there is a name form associated with the entry’s structural object class, then the entry validator will use it to ensure that the entry’s RDN includes all of the required attributes, and that all attributes included in the entry’s RDN are allowed.
All of these checks may be individually enabled or disabled, which makes it possible to tailor the types of validation to perform. In addition, the entryIsValid
method is threadsafe, so it can be called concurrently by multiple threads. If the entry is invalid, then this method will return false
, and the provided list will include one or more human-readable messages detailing the problems identified with the entry. It will also collect summary statistics about all of the entries examined so that if a number of entries are processed it is easy to understand the types of problems (if any) that were encountered.
One of the example programs provided with the LDAP SDK is a validate-ldif
tool which uses the EntryValidator
class to perform this validation for all entries in an LDIF file. This can provide a useful way to validate that the entries contained in an LDIF file are valid without needing to actually import the data into a server. If there are any problems, then the summary provided by the tool may be easier to interpret than the errors reported by the server.
Sorting
Many directory servers provide support for the server-side sort control as defined in RFC 2891. However, some servers may not support this control, and of the servers that do support it, some of them may require special configuration or indexing, and the client may require special permissions to be allowed to request it. In addition, for small result sets, it may be significantly more efficient (and less resource-intensive on the server) to perform sorting on the client rather than asking the server to do it.
The UnboundID LDAP SDK for Java provides a com.unboundid.ldap.sdk.EntrySorter
class that can be used to accomplish this. It includes the following method that makes it possible to sort a collection of entries:
public SortedSet<Entry> sort(Collection<? extends Entry> entries)
This class also implements the Comparator<Entry>
interface, so it can be used with any type of Java collection that can use comparators.
It is possible to define the sort criteria, including specifying which attributes should be used and indicating whether to sort in reverse order. It can also be configured to take the entry’s position in the DIT into consideration when sorting so that entries can be sorted by hierarchy instead of or in addition to performing attribute-based sorting.
For best results, the entry sorter is able to use schema read from the directory server in order to better understand which matching rules it should use for sorting, but if no schema is available it will simply assume that all sorting should be done using case-ignore ordering.
Filter Evaluation
There are a number of cases in which it might be useful to determine whether an entry matches a given set of criteria, and search filters provide a convenient way to express that criteria. If the entry exists in a directory server, then of course a search operation may be used to make the determination, but if the client has a local copy of the entry then it may be more convenient or efficient to perform the evaluation on the client. Further, there may be cases (e.g., for an entry read from an LDIF file) in which the entry isn’t available in a server. To provide this capability, the com.unboundid.ldap.sdk.Filter
class includes the following methods:
public boolean matchesEntry(Entry entry) public boolean matchesEntry(Entry entry, Schema schema)
If a schema object is provided, then it will be used to perform more accurate evaluation, but if no schema is available then it will work using case-ignore matching. This method currently supports all types of filter evaluation except approximate and extensible matching.