View Javadoc
1   /*
2    * Copyright 2013-2016 Brian Thomas Matthews
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.btmatthews.maven.plugins.ldap;
18  
19  import com.unboundid.ldap.sdk.*;
20  import com.unboundid.ldif.LDIFChangeRecord;
21  import com.unboundid.ldif.LDIFException;
22  
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.io.OutputStream;
26  import java.util.List;
27  
28  /**
29   * Abstract base class for {@link FormatHandler} objects that import/export directory entries to/from LDAP directory
30   * servers in LDIF and DSML format.
31   *
32   * @author <a href="mailto:brian@btmatthews.com">Brian Matthews</a>
33   * @since 1.2.0
34   */
35  public abstract class AbstractFormatHandler implements FormatHandler {
36  
37      /**
38       * Reads directory entries from the input stream and loads them in the LDAP directory server.
39       *
40       * @param connection   The connection to the LDAP directory server.
41       * @param inputStream  The input stream from which directory entries will be read.
42       * @param ignoreErrors If {@code true} then loading will continue if an error occurs.
43       * @param logger       Used to log information or error messages.
44       */
45      public final void load(final LDAPInterface connection,
46                             final InputStream inputStream,
47                             final boolean ignoreErrors,
48                             final FormatLogger logger) {
49          final FormatReader reader = openReader(inputStream, logger);
50          if (reader != null) {
51              try {
52                  boolean keepReading = true;
53                  do {
54                      try {
55                          final LDIFChangeRecord record = reader.nextRecord();
56                          if (record == null) {
57                              keepReading = false;
58                          } else {
59                              record.processChange(connection);
60                          }
61                      } catch (final LDIFException e) {
62                          if (!ignoreErrors || !e.mayContinueReading()) {
63                              logger.logError("Error parsing directory entry read from the input stream", e);
64                              keepReading = false;
65                          }
66                      } catch (final LDAPException e) {
67                          if (!ignoreErrors) {
68                              logger.logError("Error loading directory entry into the LDAP directory server", e);
69                              keepReading = false;
70                          }
71                      }
72                  } while (keepReading);
73              } catch (final IOException e) {
74                  logger.logError("I/O error reading directory entry from input stream", e);
75              } finally {
76                  try {
77                      reader.close();
78                  } catch (final IOException e) {
79                      logger.logError("I/O error closing the input stream reader", e);
80                  }
81              }
82          }
83      }
84  
85      /**
86       * Dump the results of a search against the LDAP directory server to an output stream.
87       *
88       * @param connection   The connection to the LDAP directory server.
89       * @param base         The base DN from which to start the search.
90       * @param filter       Query used to filter the directory entries.
91       * @param outputStream The output stream to which the directory entries are to be written.
92       * @param logger       Used to log information or error messages.
93       */
94      public final void dump(final LDAPInterface connection,
95                             final String base,
96                             final String filter,
97                             final OutputStream outputStream,
98                             final FormatLogger logger) {
99          final FormatWriter ldapWriter = createWriter(outputStream, logger);
100         if (ldapWriter == null) {
101             logger.logError("Error creating writer for output stream");
102         } else {
103             try {
104                 try {
105                     final SearchRequest request = new SearchRequest(base, SearchScope.SUB, Filter.create(filter));
106                     final SearchResult result = connection.search(request);
107                     if (result.getResultCode() == ResultCode.SUCCESS) {
108                         final List<SearchResultEntry> entries = result.getSearchEntries();
109                         if (entries != null) {
110                             for (final SearchResultEntry entry : entries) {
111                                 ldapWriter.printEntry(entry);
112                             }
113                         } else {
114                             logger.logInfo("Search did not return any directory entries");
115                         }
116                     } else {
117                         logger.logError("Search operation failed");
118                     }
119                 } catch (final LDAPException e) {
120                     logger.logError("Error searching the LDAP directory", e);
121                 } finally {
122                     ldapWriter.close();
123                 }
124             } catch (final IOException e) {
125                 logger.logError("Error writing directory entry to the output stream", e);
126             }
127         }
128     }
129 
130     /**
131      * Create a writer that formats the directory entry before writing it to the output stream.
132      *
133      * @param outputStream The target output stream.
134      * @param logger       Used to log information or error messages.
135      * @return A {@link FormatWriter} object.
136      */
137     protected abstract FormatWriter createWriter(OutputStream outputStream, FormatLogger logger);
138 
139     /**
140      * Create a reader to parse the directory entries as they are read from the input stream.
141      *
142      * @param inputStream The source input stream.
143      * @param logger      Used to log information or error messages.
144      * @return A {@link FormatReader} object.
145      */
146     protected abstract FormatReader openReader(InputStream inputStream, FormatLogger logger);
147 }