org.gluu.site.ldap.persistence.LdifDataUtility.java Source code

Java tutorial

Introduction

Here is the source code for org.gluu.site.ldap.persistence.LdifDataUtility.java

Source

/*
 * oxCore is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.
 *
 * Copyright (c) 2014, Gluu
 */

package org.gluu.site.ldap.persistence;

import com.unboundid.ldap.sdk.ChangeType;
import com.unboundid.ldap.sdk.Entry;
import com.unboundid.ldap.sdk.LDAPConnection;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.LDAPSearchException;
import com.unboundid.ldap.sdk.ResultCode;
import com.unboundid.ldap.sdk.SearchResult;
import com.unboundid.ldap.sdk.SearchResultEntry;
import com.unboundid.ldap.sdk.SearchScope;
import com.unboundid.ldif.LDIFChangeRecord;
import com.unboundid.ldif.LDIFException;
import com.unboundid.ldif.LDIFReader;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.LinkedList;
import java.util.ListIterator;

/**
 * Utility class to import ldif file to LDAP.
 * 
 * @author Yuriy Movchan Date: 08.06.2010
 */
public final class LdifDataUtility {

    private static final Logger log = Logger.getLogger(LdifDataUtility.class);

    //Just define the singleton as a static field in a separate class.
    // The semantics of Java guarantee that the field will not be initialized until the field is referenced,
    // and that any thread which accesses the field will see all of the writes resulting from initializing that field.
    // http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
    private static class Holder {
        static LdifDataUtility instance = new LdifDataUtility();
    }

    private LdifDataUtility() {
    }

    public static LdifDataUtility instance() {
        return Holder.instance;
    }

    /**
     * Performs ldif file import
     * 
     * @param connection
     *            Connection to LDAP server
     * @param ldifFileName
     *            LDIF file
     * @return The result code for the processing that was performed
     */
    public ResultCode importLdifFile(LDAPConnection connection, String ldifFileName) {
        LDIFReader ldifReader = createLdifReader(ldifFileName);
        if (ldifReader == null) {
            return ResultCode.LOCAL_ERROR;
        }
        try {
            return importLdifFile(connection, ldifReader);
        } finally {
            disposeLdifReader(ldifReader);
        }
    }

    /**
     * Performs ldif file conent import
     * 
     * @param connection
     *            Connection to LDAP server
     * @param ldifFileContent
     *            LDIF file
     * @return The result code for the processing that was performed
     */
    public ResultCode importLdifFileContent(LDAPConnection connection, String ldifFileContent) {
        BufferedReader is = null;
        LDIFReader ldifReader = null;
        try {
            is = new BufferedReader(new StringReader(ldifFileContent));
            ldifReader = new LDIFReader(is);

            return importLdifFile(connection, ldifReader);
        } finally {
            IOUtils.closeQuietly(is);
            if (ldifReader != null) {
                disposeLdifReader(ldifReader);
            }
        }
    }

    /**
     * Performs ldif file import
     * 
     * @param connection
     *            Connection to LDAP server
     * @param ldifReader
     *            LDIF reader
     * @return The result code for the processing that was performed
     */
    protected ResultCode importLdifFile(LDAPConnection connection, LDIFReader ldifReader) {
        // Attempt to process and apply the changes to the server
        ResultCode resultCode = ResultCode.SUCCESS;
        while (true) {
            // Read the next change to process
            LDIFChangeRecord ldifRecord = null;
            try {
                ldifRecord = ldifReader.readChangeRecord(true);
            } catch (LDIFException le) {
                log.error("Malformed ldif record", le);
                if (!le.mayContinueReading()) {
                    resultCode = ResultCode.DECODING_ERROR;
                    break;
                }
            } catch (IOException ioe) {
                log.error("I/O error encountered while reading a change record", ioe);
                resultCode = ResultCode.LOCAL_ERROR;
                break;
            }

            // If the change record was null, then it means there are no more
            // changes to be processed.
            if (ldifRecord == null) {
                break;
            }

            // Apply the target change to the server.
            try {
                ldifRecord.processChange(connection);
            } catch (LDAPException le) {
                if (ResultCode.ENTRY_ALREADY_EXISTS.equals(le.getResultCode())) {
                    continue;
                }
                if (ldifRecord.getChangeType().equals(ChangeType.DELETE)) {
                    continue;
                }

                log.error("Failed to inserting ldif record", le);
            }
        }

        return resultCode;
    }

    /**
     * Check if DS has at least one DN simular to specified in ldif file.
     * 
     * @param connection
     *            Connection to LDAP server
     * @param ldifFileName
     *            LDIF file
     * @return true if server contains at least one DN simular to specified in
     *         ldif file.
     */
    public boolean checkIfSerrverHasEntryFromLDIFFile(LDAPConnection connection, String ldifFileName) {
        // Set up the LDIF reader that will be used to read the changes to apply
        LDIFReader ldifReader = createLdifReader(ldifFileName);
        if (ldifReader == null) {
            return true;
        }

        // Check all ldif entries
        while (true) {
            // Read the next change to process.
            Entry entry = null;
            try {
                entry = ldifReader.readEntry();
            } catch (LDIFException le) {
                log.error("Malformed ldif record", le);
                if (!le.mayContinueReading()) {
                    return true;
                }
            } catch (IOException ioe) {
                log.error("I/O error encountered while reading a change record", ioe);
                return true;
            }

            // If the change record was null, then it means there are no more
            // changes to be processed.
            if (entry == null) {
                break;
            }

            // Search entry in the server.
            try {
                SearchResult sr = connection.search(entry.getDN(), SearchScope.BASE, "objectClass=*");
                if ((sr != null) && (sr.getEntryCount() > 0)) {
                    return true;
                }
            } catch (LDAPException le) {
                if (le.getResultCode() != ResultCode.NO_SUCH_OBJECT) {
                    log.error("Failed to search ldif record", le);
                    return true;
                }
            }
        }

        disposeLdifReader(ldifReader);

        return false;
    }

    /**
     * Remove base entry with all sub entries
     * 
     * @param connection
     *            Connection to LDAP server
     * @param baseDN
     *            Base DN entry
     * @return The result code for the processing that was performed.
     */
    public ResultCode deleteEntryWithAllSubs(LDAPConnection connection, String baseDN) {
        ResultCode resultCode = ResultCode.SUCCESS;
        SearchResult searchResult = null;
        try {
            searchResult = connection.search(baseDN, SearchScope.SUB, "objectClass=*");
            if ((searchResult == null) || (searchResult.getEntryCount() == 0)) {
                return ResultCode.LOCAL_ERROR;
            }
        } catch (LDAPSearchException le) {
            log.error("Failed to search subordinate entries", le);
            return ResultCode.LOCAL_ERROR;
        }

        LinkedList<String> dns = new LinkedList<String>();
        for (SearchResultEntry entry : searchResult.getSearchEntries()) {
            dns.add(entry.getDN());
        }

        ListIterator<String> listIterator = dns.listIterator(dns.size());
        while (listIterator.hasPrevious()) {
            try {
                connection.delete(listIterator.previous());
            } catch (LDAPException le) {
                log.error("Failed to delete entry", le);
                resultCode = ResultCode.LOCAL_ERROR;
                break;
            }
        }

        return resultCode;
    }

    private LDIFReader createLdifReader(String ldifFileNamePath) {
        // Set up the LDIF reader that will be used to read the changes to apply
        File ldifFile = new File(ldifFileNamePath);
        LDIFReader ldifReader;
        try {
            if (!ldifFile.exists()) {
                return null;
            }
            ldifReader = new LDIFReader(ldifFile);
        } catch (IOException ex) {
            log.error("I/O error creating the LDIF reader", ex);
            return null;
        }

        return ldifReader;
    }

    private void disposeLdifReader(LDIFReader ldifReader) {
        if (ldifReader != null) {
            try {
                ldifReader.close();
            } catch (IOException ex) {
            }
        }
    }

}