Search code examples
javaldapldif

case-preserving LDIF reader/parser/stream


I have to read an LDIF file, split the entries, modify them and then write the result as LDIF files.

I found an LdifReader at the Apache Directory LDAP API (org.apache.directory.api:api-ldap-client-api), so I tried that one like this:

Stream<LdifEntry> stream = StreamSupport.stream(reader.spliterator(), false);
Predicate<LdifEntry> isEnabled = entry -> entry.get("pwdAccountLockedTime") == null;
Map<Boolean, List<LdifEntry>> parts = stream.collect(Collectors.partitioningBy(isEnabled));
List<LdifEntry> enabledAccounts = parts.get(true);
List<LdifEntry> disabledAccounts = parts.get(false);

Works well. However, for some reason all the attribute names/ids are lowercased (“pwdAccountLockedTime” becomes “pwdaccountlockedtime”, etc.) but I need them as they are (preserving the case) – in order to keep the same human readability as before.

Any idea how to do that? If needed I will use a different library.

Note: I would like to improve my question, because I got some downvotes. Please tell me, what’s wrong with it or what’s missing.


Solution

  • I was able to solve my problem by replacing the library with org.springframework.ldap:spring-ldap-ldif-core and writing a little helper.

    public class LdifUtils {
        /**
         * Reads an LDIF file and returns its entries as a collection 
         * of <code>LdapAttributes</code> (LDAP entries).
         * <br>
         * Note: This method is not for huge files, 
         * as the content is loaded completely into memory.
         *
         * @param pathToLdifFile the <code>Path</code> to the LDAP Data Interchange Format file
         * @return a <code>Collection</code> of <code>LdapAttributes</code> (LDAP entries)
         * @throws IOException if reading the file fails
         */
        public static Collection<LdapAttributes> read(final Path pathToLdifFile) throws IOException {
            final LdifParser ldifParser = new LdifParser(pathToLdifFile.toFile());
            ldifParser.open();
            final Collection<LdapAttributes> c = new LinkedList<>();
            while (ldifParser.hasMoreRecords()){
                c.add(ldifParser.getRecord());
            }
            ldifParser.close();
            return c;
        }
    }
    

    usage like before ...

    final Stream<LdapAttributes> stream = LdifUtils.read(path).stream();
    final Predicate<LdapAttributes> isEnabled = entry -> entry.get("pwdAccountLockedTime") == null;
    final Map<Boolean, List<LdapAttributes>> parts = stream.collect(Collectors.partitioningBy(isEnabled));
    final List<LdapAttributes> enabledAccounts = parts.get(true);
    final List<LdapAttributes> disabledAccounts = parts.get(false);
    logger.info("enabled accounts: " + enabledAccounts.size());
    logger.info("disabled accounts: " + disabledAccounts.size());
    

    Note: I would like to improve my answer, because I got some downvotes. Please tell me, what’s wrong with it or what’s missing.