001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2006-2009 Sun Microsystems, Inc.
015 * Portions Copyright 2012-2016 ForgeRock AS.
016 */
017package org.opends.server.types;
018
019import org.forgerock.opendj.ldap.DN;
020import org.forgerock.opendj.ldap.schema.AttributeType;
021
022import static org.opends.messages.UtilityMessages.*;
023
024import java.io.*;
025import java.util.*;
026import java.util.zip.GZIPInputStream;
027
028import org.forgerock.i18n.LocalizableMessageDescriptor.Arg1;
029import org.opends.server.tools.makeldif.MakeLDIFInputStream;
030import org.opends.server.tools.makeldif.TemplateFile;
031import org.opends.server.util.CollectionUtils;
032import org.opends.server.util.StaticUtils;
033
034/**
035 * This class defines a data structure for holding configuration
036 * information to use when performing an LDIF import.
037 */
038@org.opends.server.types.PublicAPI(
039     stability=org.opends.server.types.StabilityLevel.VOLATILE,
040     mayInstantiate=true,
041     mayExtend=false,
042     mayInvoke=true)
043public final class LDIFImportConfig extends OperationConfig
044                                    implements Closeable
045{
046
047  /** The default buffer size that will be used when reading LDIF data. */
048  private static final int DEFAULT_BUFFER_SIZE = 8192;
049
050  /**
051   * Indicates whether to include the objectclasses in the entries
052   * read from the import.
053   */
054  private boolean includeObjectClasses = true;
055
056  /** Indicates whether to invoke LDIF import plugins whenever an entry is read. */
057  private boolean invokeImportPlugins;
058  /** Indicates whether the import is compressed. */
059  private boolean isCompressed;
060  /** Indicates whether the import is encrypted. */
061  private boolean isEncrypted;
062  /** Indicates whether to clear all base DNs in a backend. */
063  private boolean clearBackend;
064  /** Indicates whether to perform schema validation on the entries read. */
065  private boolean validateSchema = true;
066
067  /** The buffered reader from which the LDIF data should be read. */
068  private BufferedReader reader;
069  /** The buffered writer to which rejected entries should be written. */
070  private BufferedWriter rejectWriter;
071  /** The buffered writer to which rejected entries should be written. */
072  private BufferedWriter skipWriter;
073  /** The input stream to use to read the data to import. */
074  private InputStream ldifInputStream;
075
076  /** The buffer size to use when reading data from the LDIF file. */
077  private int bufferSize = DEFAULT_BUFFER_SIZE;
078
079  /** The iterator used to read through the set of LDIF files. */
080  private Iterator<String> ldifFileIterator;
081
082  /** The set of base DNs to exclude from the import. */
083  private Set<DN> excludeBranches = new HashSet<>(0);
084  /** The set of base DNs to include from the import. */
085  private Set<DN> includeBranches = new HashSet<>(0);
086
087  /** The set of search filters for entries to exclude from the import. */
088  private List<SearchFilter> excludeFilters = new ArrayList<>(0);
089  /** The set of search filters for entries to include in the import. */
090  private List<SearchFilter> includeFilters = new ArrayList<>(0);
091
092  /** The set of LDIF files to be imported. */
093  private List<String> ldifFiles;
094
095  /** The set of attribute types that should be excluded from the import. */
096  private Set<AttributeType> excludeAttributes = new HashSet<>(0);
097  /** The set of attribute types that should be included in the import. */
098  private Set<AttributeType> includeAttributes = new HashSet<>(0);
099
100  /** Indicates whether all the user attributes should be included. */
101  private boolean includeAllUserAttrs;
102  /** Indicates whether all the operational attributes should be included. */
103  private boolean includeAllOpAttrs;
104  /** Indicates whether all the user attributes should be excluded. */
105  private boolean excludeAllUserAttrs;
106  /** Indicates whether all the operational attributes should be excluded. */
107  private boolean excludeAllOpAttrs;
108
109  private String tmpDirectory;
110  private boolean skipDNValidation;
111  private int threadCount;
112
113  /** Indicates the memory size, in megabytes, to use for off-heap buffers. */
114  private int offHeapSize;
115
116
117  /**
118   * Creates a new LDIF import configuration that will read from the
119   * specified LDIF file.
120   *
121   * @param  ldifFile  The path to the LDIF file with the data to
122   *                   import.
123   */
124  public LDIFImportConfig(String ldifFile)
125  {
126    ldifFiles = CollectionUtils.newArrayList(ldifFile);
127    ldifFileIterator = ldifFiles.iterator();
128  }
129
130  /**
131   * Creates a new LDIF import configuration that will read from the
132   * specified LDIF files.  The files will be imported in the order
133   * they are specified in the provided list.
134   *
135   * @param  ldifFiles  The paths to the LDIF files with the data to
136   *                    import.
137   */
138  public LDIFImportConfig(List<String> ldifFiles)
139  {
140    this.ldifFiles = ldifFiles;
141    ldifFileIterator = ldifFiles.iterator();
142  }
143
144  /**
145   * Creates a new LDIF import configuration that will read from the
146   * provided input stream.
147   *
148   * @param  ldifInputStream  The input stream from which to read the
149   *                          LDIF data.
150   */
151  public LDIFImportConfig(InputStream ldifInputStream)
152  {
153    this.ldifInputStream   = ldifInputStream;
154  }
155
156  /**
157   * Creates a new LDIF import configuration that will read from the
158   * provided reader.
159   *
160   * @param  ldifInputReader  The input stream from which to read the
161   *                          LDIF data.
162   */
163  public LDIFImportConfig(Reader ldifInputReader)
164  {
165    reader                 = getBufferedReader(ldifInputReader);
166  }
167
168  /**
169   * Wrap reader in a BufferedReader if necessary.
170   *
171   * @param reader the reader to buffer
172   * @return reader as a BufferedReader
173   */
174  private BufferedReader getBufferedReader(Reader reader) {
175    if (reader instanceof BufferedReader) {
176      return (BufferedReader)reader;
177    } else {
178      return new BufferedReader(reader);
179    }
180  }
181
182  /**
183   * Creates a new LDIF import configuration that will generate
184   * entries using the given MakeLDIF template file rather than
185   * reading them from an existing LDIF file.
186   *
187   * @param  templateFile  The template file to use to generate the
188   *                       entries.
189   */
190  public LDIFImportConfig(TemplateFile templateFile)
191  {
192    this(new MakeLDIFInputStream(templateFile));
193  }
194
195
196
197  /**
198   * Retrieves the reader that should be used to read the LDIF data.
199   * Note that if the LDIF file is compressed and/or encrypted, then
200   * that must be indicated before this method is called for the first
201   * time.
202   *
203   * @return  The reader that should be used to read the LDIF data.
204   *
205   * @throws  IOException  If a problem occurs while obtaining the
206   *                       reader.
207   */
208  public BufferedReader getReader()
209         throws IOException
210  {
211    if (reader == null)
212    {
213      InputStream inputStream;
214      if (ldifInputStream != null)
215      {
216        inputStream = ldifInputStream;
217      }
218      else
219      {
220        inputStream = ldifInputStream =
221             new FileInputStream(ldifFileIterator.next());
222      }
223
224      if (isEncrypted)
225      {
226        // FIXME -- Add support for encryption with a cipher input
227        //          stream.
228      }
229
230      if (isCompressed)
231      {
232        inputStream = new GZIPInputStream(inputStream);
233      }
234
235      reader = new BufferedReader(new InputStreamReader(inputStream),
236                                  bufferSize);
237    }
238
239    return reader;
240  }
241
242
243
244  /**
245   * Retrieves the LDIF reader configured to read from the next LDIF
246   * file in the list.
247   *
248   * @return  The reader that should be used to read the LDIF data, or
249   *          <CODE>null</CODE> if there are no more files to read.
250   *
251   * @throws  IOException  If a problem occurs while obtaining the reader.
252   */
253  public BufferedReader nextReader()
254         throws IOException
255  {
256    if (ldifFileIterator == null || !ldifFileIterator.hasNext())
257    {
258      return null;
259    }
260
261    reader.close();
262
263    InputStream inputStream = ldifInputStream =
264         new FileInputStream(ldifFileIterator.next());
265
266    if (isEncrypted)
267    {
268      // FIXME -- Add support for encryption with a cipher input stream.
269    }
270
271    if (isCompressed)
272    {
273      inputStream = new GZIPInputStream(inputStream);
274    }
275
276    reader = new BufferedReader(new InputStreamReader(inputStream), bufferSize);
277    return reader;
278  }
279
280
281
282  /**
283   * Retrieves the writer that should be used to write entries that
284   * are rejected rather than imported for some reason.
285   *
286   * @return  The reject writer, or <CODE>null</CODE> if none is to be used.
287   */
288  public BufferedWriter getRejectWriter()
289  {
290    return rejectWriter;
291  }
292
293  /**
294   * Retrieves the writer that should be used to write entries that
295   * are skipped because they don't match the criteria.
296   *
297   * @return  The skip writer, or <CODE>null</CODE> if none is to be used.
298   */
299  public BufferedWriter getSkipWriter()
300  {
301    return skipWriter;
302  }
303
304  /**
305   * Indicates that rejected entries should be written to the
306   * specified file.  Note that this applies only to entries that are
307   * rejected because they are invalid (e.g., are malformed or don't
308   * conform to schema requirements), and not to entries that are
309   * rejected because they matched exclude criteria.
310   *
311   * @param  rejectFile            The path to the file to which
312   *                               reject information should be written.
313   * @param  existingFileBehavior  Indicates how to treat an existing file.
314   *
315   * @throws  IOException  If a problem occurs while opening the
316   *                       reject file for writing.
317   */
318  public void writeRejectedEntries(String rejectFile,
319                   ExistingFileBehavior existingFileBehavior)
320         throws IOException
321  {
322    if (rejectFile == null)
323    {
324      closeRejectWriter();
325      return;
326    }
327
328    final BufferedWriter writer = newBufferedWriter(rejectFile, existingFileBehavior, ERR_REJECT_FILE_EXISTS);
329    if (writer != null)
330    {
331      rejectWriter = writer;
332    }
333  }
334
335  private BufferedWriter newBufferedWriter(String file, ExistingFileBehavior existingFileBehavior,
336      Arg1<Object> fileExistsErrorMsg) throws IOException
337  {
338    switch (existingFileBehavior)
339    {
340    case APPEND:
341      return new BufferedWriter(new FileWriter(file, true));
342    case OVERWRITE:
343      return new BufferedWriter(new FileWriter(file, false));
344    case FAIL:
345      File f = new File(file);
346      if (f.exists())
347      {
348        throw new IOException(fileExistsErrorMsg.get(file).toString());
349      }
350      return new BufferedWriter(new FileWriter(file));
351    default:
352      return null;
353    }
354  }
355
356  /**
357   * Indicates that rejected entries should be written to the provided
358   * output stream.  Note that this applies only to entries that are
359   * rejected because they are invalid (e.g., are malformed or don't
360   * conform to schema requirements), and not to entries that are
361   * rejected because they matched exclude criteria.
362   *
363   * @param  outputStream  The output stream to which rejected entries
364   *                       should be written.
365   */
366  public void writeRejectedEntries(OutputStream outputStream)
367  {
368    if (outputStream == null)
369    {
370      closeRejectWriter();
371      return;
372    }
373
374    rejectWriter =
375         new BufferedWriter(new OutputStreamWriter(outputStream));
376  }
377
378  private void closeRejectWriter()
379  {
380    if (rejectWriter != null)
381    {
382      StaticUtils.close(rejectWriter);
383      rejectWriter = null;
384    }
385  }
386
387  /**
388   * Indicates that skipped entries should be written to the
389   * specified file.  Note that this applies only to entries that are
390   * skipped because they matched exclude criteria.
391   *
392   * @param  skipFile              The path to the file to which
393   *                               skipped information should be written.
394   * @param  existingFileBehavior  Indicates how to treat an existing file.
395   *
396   * @throws  IOException  If a problem occurs while opening the
397   *                       skip file for writing.
398   */
399  public void writeSkippedEntries(String skipFile,
400                   ExistingFileBehavior existingFileBehavior)
401         throws IOException
402  {
403    if (skipFile == null)
404    {
405      closeSkipWriter();
406      return;
407    }
408
409    final BufferedWriter writer = newBufferedWriter(skipFile, existingFileBehavior, ERR_SKIP_FILE_EXISTS);
410    if (writer != null)
411    {
412      skipWriter = writer;
413    }
414  }
415
416  private void closeSkipWriter()
417  {
418    if (skipWriter != null)
419    {
420      StaticUtils.close(skipWriter);
421      skipWriter = null;
422    }
423  }
424
425  /**
426   * Indicates that skipped entries should be written to the provided
427   * output stream.  Note that this does not apply to entries that are
428   * rejected because they are invalid (e.g., are malformed or don't
429   * conform to schema requirements), but only apply to entries that
430   * are skipped because they matched exclude criteria.
431   *
432   * @param  outputStream  The output stream to which skipped entries
433   *                       should be written.
434   */
435  public void writeSkippedEntries(OutputStream outputStream)
436  {
437    if (outputStream == null)
438    {
439      closeSkipWriter();
440      return;
441    }
442    skipWriter =
443         new BufferedWriter(new OutputStreamWriter(outputStream));
444  }
445
446
447
448  /**
449   * Indicates whether any LDIF import plugins registered with the
450   * server should be invoked during the import operation.
451   *
452   * @return  <CODE>true</CODE> if registered LDIF import plugins
453   *          should be invoked during the import operation, or
454   *          <CODE>false</CODE> if they should not be invoked.
455   */
456  public boolean invokeImportPlugins()
457  {
458    return invokeImportPlugins;
459  }
460
461
462
463  /**
464   * Specifies whether any LDIF import plugins registered with the
465   * server should be invoked during the import operation.
466   *
467   * @param  invokeImportPlugins  Specifies whether any LDIF import
468   *                              plugins registered with the server
469   *                              should be invoked during the import
470   *                              operation.
471   */
472  public void setInvokeImportPlugins(boolean invokeImportPlugins)
473  {
474    this.invokeImportPlugins = invokeImportPlugins;
475  }
476
477
478
479  /**
480   * Indicates whether the input LDIF source is expected to be
481   * compressed.
482   *
483   * @return  <CODE>true</CODE> if the LDIF source is expected to be
484   *          compressed, or <CODE>false</CODE> if not.
485   */
486  public boolean isCompressed()
487  {
488    return isCompressed;
489  }
490
491
492
493  /**
494   * Specifies whether the input LDIF source is expected to be
495   * compressed.  If compression is used, then this must be set prior
496   * to the initial call to <CODE>getReader</CODE>.
497   *
498   * @param  isCompressed  Indicates whether the input LDIF source is
499   *                       expected to be compressed.
500   */
501  public void setCompressed(boolean isCompressed)
502  {
503    this.isCompressed = isCompressed;
504  }
505
506
507
508  /**
509   * Indicates whether the input LDIF source is expected to be
510   * encrypted.
511   *
512   * @return  <CODE>true</CODE> if the LDIF source is expected to be
513   *          encrypted, or <CODE>false</CODE> if not.
514   */
515  public boolean isEncrypted()
516  {
517    return isEncrypted;
518  }
519
520
521
522  /**
523   * Specifies whether the input LDIF source is expected to be
524   * encrypted.  If encryption is used, then this must be set prior to
525   * the initial call to <CODE>getReader</CODE>.
526   *
527   * @param  isEncrypted  Indicates whether the input LDIF source is
528   *                      expected to be encrypted.
529   */
530  public void setEncrypted(boolean isEncrypted)
531  {
532    this.isEncrypted = isEncrypted;
533  }
534
535
536
537  /**
538   * Indicates whether to clear the entire backend if importing to a
539   * backend with more than one base DNs.
540   *
541   * @return <CODE>true</code> if the entire backend should be
542   * cleared or <CODE>false</CODE> if not.
543   */
544  public boolean clearBackend()
545  {
546    return clearBackend;
547  }
548
549
550
551  /**
552   * Specifies whether to clear the entire backend if importing to a
553   * backend.
554   *
555   * @param clearBackend Indicates whether to clear the entire
556   * backend.
557   */
558  public void setClearBackend(boolean clearBackend)
559  {
560    this.clearBackend = clearBackend;
561  }
562
563
564
565  /**
566   * Indicates whether to perform schema validation on entries as they
567   * are read.
568   *
569   * @return  <CODE>true</CODE> if schema validation should be
570   *          performed on the entries as they are read, or
571   *          <CODE>false</CODE> if not.
572   */
573  public boolean validateSchema()
574  {
575    return validateSchema;
576  }
577
578
579
580  /**
581   * Specifies whether to perform schema validation on entries as they
582   * are read.
583   *
584   * @param  validateSchema  Indicates whether to perform schema
585   *                         validation on entries as they are read.
586   */
587  public void setValidateSchema(boolean validateSchema)
588  {
589    this.validateSchema = validateSchema;
590  }
591
592
593
594  /**
595   * Retrieves the set of base DNs that specify the set of entries to
596   * exclude from the import.  The contents of the returned list may
597   * be altered by the caller.
598   *
599   * @return  The set of base DNs that specify the set of entries to
600   *          exclude from the import.
601   */
602  public Set<DN> getExcludeBranches()
603  {
604    return excludeBranches;
605  }
606
607
608
609  /**
610   * Specifies the set of base DNs that specify the set of entries to
611   * exclude from the import.
612   *
613   * @param  excludeBranches  The set of base DNs that specify the set
614   *                          of entries to exclude from the import.
615   */
616  public void setExcludeBranches(Set<DN> excludeBranches)
617  {
618    this.excludeBranches = getSet(excludeBranches);
619  }
620
621  private <T> Set<T> getSet(Set<T> set)
622  {
623    return set != null ? set : new HashSet<T>(0);
624  }
625
626
627  /**
628   * Retrieves the set of base DNs that specify the set of entries to
629   * include in the import.  The contents of the returned list may be
630   * altered by the caller.
631   *
632   * @return  The set of base DNs that specify the set of entries to
633   *          include in the import.
634   */
635  public Set<DN> getIncludeBranches()
636  {
637    return includeBranches;
638  }
639
640
641
642  /**
643   * Specifies the set of base DNs that specify the set of entries to
644   * include in the import.
645   *
646   * @param  includeBranches  The set of base DNs that specify the set
647   *                          of entries to include in the import.
648   */
649  public void setIncludeBranches(Set<DN> includeBranches)
650  {
651    this.includeBranches = getSet(includeBranches);
652  }
653
654  /**
655   * Indicates whether to include the entry with the specified DN in
656   * the import.
657   *
658   * @param  dn  The DN of the entry for which to make the
659   *             determination.
660   *
661   * @return  <CODE>true</CODE> if the entry with the specified DN
662   *          should be included in the import, or <CODE>false</CODE>
663   *          if not.
664   */
665  public boolean includeEntry(DN dn)
666  {
667    if (! excludeBranches.isEmpty())
668    {
669      for (DN excludeBranch : excludeBranches)
670      {
671        if (excludeBranch.isSuperiorOrEqualTo(dn))
672        {
673          return false;
674        }
675      }
676    }
677
678    if (! includeBranches.isEmpty())
679    {
680      for (DN includeBranch : includeBranches)
681      {
682        if (includeBranch.isSuperiorOrEqualTo(dn))
683        {
684          return true;
685        }
686      }
687
688      return false;
689    }
690
691    return true;
692  }
693
694
695
696  /**
697   * Indicates whether the set of objectclasses should be included in
698   * the entries read from the LDIF.
699   *
700   * @return  <CODE>true</CODE> if the set of objectclasses should be
701   *          included in the entries read from the LDIF, or
702   *          <CODE>false</CODE> if not.
703   */
704  public boolean includeObjectClasses()
705  {
706    return includeObjectClasses;
707  }
708
709
710
711  /**
712   * Specifies whether the set of objectclasses should be included in
713   * the entries read from the LDIF.
714   *
715   * @param  includeObjectClasses  Indicates whether the set of
716   *                               objectclasses should be included in
717   *                               the entries read from the LDIF.
718   */
719  public void setIncludeObjectClasses(boolean includeObjectClasses)
720  {
721    this.includeObjectClasses = includeObjectClasses;
722  }
723
724
725
726  /**
727   * Retrieves the set of attributes that should be excluded from the
728   * entries read from the LDIF.  The contents of the returned set may
729   * be modified by the caller.
730   *
731   * @return  The set of attributes that should be excluded from the
732   *          entries read from the LDIF.
733   */
734  public Set<AttributeType> getExcludeAttributes()
735  {
736    return excludeAttributes;
737  }
738
739
740
741  /**
742   * Specifies the set of attributes that should be excluded from the
743   * entries read from the LDIF.
744   *
745   * @param  excludeAttributes  The set of attributes that should be
746   *                            excluded from the entries read from
747   *                            the LDIF.
748   */
749  public void setExcludeAttributes(Set<AttributeType> excludeAttributes)
750  {
751    this.excludeAttributes = getSet(excludeAttributes);
752  }
753
754  /**
755   * Retrieves the set of attributes that should be included in the
756   * entries read from the LDIF.  The contents of the returned set may
757   * be modified by the caller.
758   *
759   * @return  The set of attributes that should be included in the
760   *          entries read from the LDIF.
761   */
762  public Set<AttributeType> getIncludeAttributes()
763  {
764    return includeAttributes;
765  }
766
767
768
769  /**
770   * Specifies the set of attributes that should be included in the
771   * entries read from the LDIF.
772   *
773   * @param  includeAttributes  The set of attributes that should be
774   *                            included in the entries read from the
775   *                            LDIF.
776   */
777  public void setIncludeAttributes(Set<AttributeType> includeAttributes)
778  {
779    this.includeAttributes = getSet(includeAttributes);
780  }
781
782  /**
783   * Indicates whether the specified attribute should be included in
784   * the entries read from the LDIF.
785   *
786   * @param  attributeType  The attribute type for which to make the
787   *                        determination.
788   *
789   * @return  <CODE>true</CODE> if the specified attribute should be
790   *          included in the entries read from the LDIF, or
791   *         <CODE>false</CODE> if not.
792   */
793  public boolean includeAttribute(AttributeType attributeType)
794  {
795    if (!excludeAttributes.isEmpty()
796        && excludeAttributes.contains(attributeType))
797    {
798      return false;
799    }
800
801     if((excludeAllOpAttrs && attributeType.isOperational())
802         || (excludeAllUserAttrs && !attributeType.isOperational()))
803    {
804      return false;
805    }
806
807    if((includeAllUserAttrs && !attributeType.isOperational())
808        || (includeAllOpAttrs && attributeType.isOperational()))
809    {
810      return true;
811    }
812
813    if (! includeAttributes.isEmpty())
814    {
815      return includeAttributes.contains(attributeType);
816    }
817    else if((includeAllUserAttrs && attributeType.isOperational())
818        || (includeAllOpAttrs && !attributeType.isOperational()))
819    {
820      return false;
821    }
822    return true;
823  }
824
825
826
827  /**
828   * Retrieves the set of search filters that should be used to
829   * determine which entries to exclude from the LDIF.  The contents
830   * of the returned list may be modified by the caller.
831   *
832   * @return  The set of search filters that should be used to
833   *          determine which entries to exclude from the LDIF.
834   */
835  public List<SearchFilter> getExcludeFilters()
836  {
837    return excludeFilters;
838  }
839
840
841
842  /**
843   * Specifies the set of search filters that should be used to
844   * determine which entries to exclude from the LDIF.
845   *
846   * @param  excludeFilters  The set of search filters that should be
847   *                         used to determine which entries to
848   *                         exclude from the LDIF.
849   */
850  public void setExcludeFilters(List<SearchFilter> excludeFilters)
851  {
852    this.excludeFilters = getList(excludeFilters);
853  }
854
855  /**
856   * Retrieves the set of search filters that should be used to
857   * determine which entries to include in the LDIF.  The contents of
858   * the returned list may be modified by  the caller.
859   *
860   * @return  The set of search filters that should be used to
861   *          determine which entries to include in the LDIF.
862   */
863  public List<SearchFilter> getIncludeFilters()
864  {
865    return includeFilters;
866  }
867
868
869
870  /**
871   * Specifies the set of search filters that should be used to
872   * determine which entries to include in the LDIF.
873   *
874   * @param  includeFilters  The set of search filters that should be
875   *                         used to determine which entries to
876   *                         include in the LDIF.
877   */
878  public void setIncludeFilters(List<SearchFilter> includeFilters)
879  {
880    this.includeFilters = getList(includeFilters);
881  }
882
883  private <T> List<T> getList(List<T> list)
884  {
885    return list != null ? list : new ArrayList<T>(0);
886  }
887
888  /**
889   * Indicates whether the specified entry should be included in the
890   * import based on the configured set of include and exclude
891   * filters.
892   *
893   * @param  entry  The entry for which to make the determination.
894   *
895   * @return  <CODE>true</CODE> if the specified entry should be
896   *          included in the import, or <CODE>false</CODE> if not.
897   *
898   * @throws  DirectoryException  If there is a problem with any of
899   *                              the search filters used to make the
900   *                              determination.
901   */
902  public boolean includeEntry(Entry entry)
903         throws DirectoryException
904  {
905    if (! excludeFilters.isEmpty())
906    {
907      for (SearchFilter filter : excludeFilters)
908      {
909        if (filter.matchesEntry(entry))
910        {
911          return false;
912        }
913      }
914    }
915
916    if (! includeFilters.isEmpty())
917    {
918      for (SearchFilter filter : includeFilters)
919      {
920        if (filter.matchesEntry(entry))
921        {
922          return true;
923        }
924      }
925
926      return false;
927    }
928
929    return true;
930  }
931
932
933
934  /**
935   * Retrieves the buffer size that should be used when reading LDIF
936   * data.
937   *
938   * @return  The buffer size that should be used when reading LDIF
939   *          data.
940   */
941  public int getBufferSize()
942  {
943    return bufferSize;
944  }
945
946
947
948  /**
949   * Specifies the buffer size that should be used when reading LDIF
950   * data.
951   *
952   * @param  bufferSize  The buffer size that should be used when
953   *                     reading LDIF data.
954   */
955  public void setBufferSize(int bufferSize)
956  {
957    this.bufferSize = bufferSize;
958  }
959
960
961
962    /**
963   * Specifies whether all the user attributes should be excluded.
964   *
965   * @param  excludeAllUserAttrs  Specifies all user attributes to
966   *         be excluded.
967   */
968  public void setExcludeAllUserAttributes(boolean excludeAllUserAttrs)
969  {
970    this.excludeAllUserAttrs = excludeAllUserAttrs;
971  }
972
973
974
975  /**
976   * Specifies whether all the operational attributes should be
977   * excluded.
978   *
979   * @param  excludeAllOpAttrs  Specifies whether all the
980   *                            operational attributes
981   *                            should be excluded.
982   */
983  public void setExcludeAllOperationalAttributes(boolean excludeAllOpAttrs)
984  {
985    this.excludeAllOpAttrs = excludeAllOpAttrs;
986  }
987
988
989
990  /**
991   * Specifies whether all the operational attributes should be
992   * included.
993   *
994   * @param  includeAllOpAttrs  Specifies whether all
995   *         the operation attributes should be included.
996   *
997   */
998  public void setIncludeAllOpAttributes(boolean includeAllOpAttrs)
999  {
1000    this.includeAllOpAttrs = includeAllOpAttrs;
1001  }
1002
1003
1004
1005  /**
1006   * Specifies whether all the user attributes should be included.
1007   *
1008   * @param  includeAllUserAttrs  Specifies whether all the
1009   *                              user attributes should be
1010   *                              included.
1011   */
1012  public void setIncludeAllUserAttributes(boolean includeAllUserAttrs)
1013  {
1014    this.includeAllUserAttrs = includeAllUserAttrs;
1015  }
1016
1017
1018
1019  /** Closes any resources that this import config might have open. */
1020  @Override
1021  public void close()
1022  {
1023    StaticUtils.close(reader, rejectWriter, skipWriter);
1024  }
1025
1026  /**
1027   * Set the temporary directory to the specified path.
1028   *
1029   * @param path The path to set the temporary directory to.
1030   */
1031  public void setTmpDirectory(String path)
1032  {
1033    tmpDirectory = path;
1034  }
1035
1036  /**
1037   * Return the temporary directory path.
1038   *
1039   * @return  The temporary directory string.
1040   */
1041  public String getTmpDirectory()
1042  {
1043    return tmpDirectory;
1044  }
1045
1046  /**
1047   * Set the dn check in phase two boolean to the specified value.
1048   *
1049   * @param v The value to set the dn check in phase two boolean to.
1050   */
1051  public void setSkipDNValidation(boolean v)
1052  {
1053    skipDNValidation = v;
1054  }
1055
1056  /**
1057   * Return the dn check in phase two boolean.
1058   *
1059   * @return Return the dn check in phase two boolean value.
1060   */
1061  public boolean getSkipDNValidation()
1062  {
1063    return skipDNValidation;
1064  }
1065
1066
1067  /**
1068   * Set the memory size available for off-heap buffers.
1069   *
1070   * @param sizeInMb The memory size available expressed in megabytes.
1071   */
1072  public void setOffHeapSize(int sizeInMb)
1073  {
1074    this.offHeapSize = sizeInMb;
1075  }
1076
1077  /**
1078   * Get the memory size available for off-heap buffers.
1079   *
1080   * @return The memory size in megabytes.
1081   */
1082  public int getOffHeapSize()
1083  {
1084    return offHeapSize;
1085  }
1086
1087  /**
1088   * Set the thread count.
1089   *
1090   * @param c The thread count value.
1091   */
1092  public void setThreadCount(int c)
1093  {
1094    this.threadCount = c;
1095  }
1096
1097  /**
1098   * Return the specified thread count.
1099   *
1100   * @return The thread count.
1101   */
1102  public int getThreadCount()
1103  {
1104    return this.threadCount;
1105  }
1106}