001 /*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License"). You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at
010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012 * See the License for the specific language governing permissions
013 * and limitations under the License.
014 *
015 * When distributing Covered Code, include this CDDL HEADER in each
016 * file and include the License file at
017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
018 * add the following below this CDDL HEADER, with the fields enclosed
019 * by brackets "[]" replaced with your own identifying information:
020 * Portions Copyright [yyyy] [name of copyright owner]
021 *
022 * CDDL HEADER END
023 *
024 *
025 * Copyright 2006-2008 Sun Microsystems, Inc.
026 */
027 package org.opends.server.types;
028
029
030
031 import java.io.BufferedReader;
032 import java.io.BufferedWriter;
033 import java.io.File;
034 import java.io.FileInputStream;
035 import java.io.FileWriter;
036 import java.io.InputStream;
037 import java.io.InputStreamReader;
038 import java.io.IOException;
039 import java.io.OutputStream;
040 import java.io.OutputStreamWriter;
041 import java.io.Reader;
042 import java.util.ArrayList;
043 import java.util.HashSet;
044 import java.util.Iterator;
045 import java.util.List;
046 import java.util.Set;
047 import java.util.zip.GZIPInputStream;
048
049 import org.opends.server.tools.makeldif.MakeLDIFInputStream;
050 import org.opends.server.tools.makeldif.TemplateFile;
051
052 import static org.opends.server.loggers.debug.DebugLogger.*;
053 import org.opends.server.loggers.debug.DebugTracer;
054 import static org.opends.messages.UtilityMessages.*;
055
056
057
058 /**
059 * This class defines a data structure for holding configuration
060 * information to use when performing an LDIF import.
061 */
062 @org.opends.server.types.PublicAPI(
063 stability=org.opends.server.types.StabilityLevel.VOLATILE,
064 mayInstantiate=true,
065 mayExtend=false,
066 mayInvoke=true)
067 public final class LDIFImportConfig extends OperationConfig
068 {
069 /**
070 * The tracer object for the debug logger.
071 */
072 private static final DebugTracer TRACER = getTracer();
073
074
075
076
077 /**
078 * The default buffer size that will be used when reading LDIF data.
079 */
080 private static final int DEFAULT_BUFFER_SIZE = 8192;
081
082
083
084 // Indicates whether to append to the existing data set rather than
085 // replacing it.
086 private boolean appendToExistingData;
087
088 // Indicates whether to include the objectclasses in the entries
089 // read from the import.
090 private boolean includeObjectClasses;
091
092 // Indicates whether to invoke LDIF import plugins whenever an entry
093 // is read.
094 private boolean invokeImportPlugins;
095
096 // Indicates whether the import is compressed.
097 private boolean isCompressed;
098
099 // Indicates whether the import is encrypted.
100 private boolean isEncrypted;
101
102 // Indicates whether to clear all base DNs in a backend.
103 private boolean clearBackend;
104
105 // Indicates whether to replace existing entries when appending
106 // data.
107 private boolean replaceExistingEntries;
108
109 // Indicates whether to perform schema validation on the entries
110 // read.
111 private boolean validateSchema;
112
113 // The buffered reader from which the LDIF data should be read.
114 private BufferedReader reader;
115
116 // The buffered writer to which rejected entries should be written.
117 private BufferedWriter rejectWriter;
118
119 // The buffered writer to which rejected entries should be written.
120 private BufferedWriter skipWriter;
121
122 // The input stream to use to read the data to import.
123 private InputStream ldifInputStream;
124
125 // The buffer size to use when reading data from the LDIF file.
126 private int bufferSize;
127
128 // The iterator used to read through the set of LDIF files.
129 private Iterator<String> ldifFileIterator;
130
131 // The set of base DNs to exclude from the import.
132 private List<DN> excludeBranches;
133
134 // The set of base DNs to include from the import.
135 private List<DN> includeBranches;
136
137 // The set of search filters for entries to exclude from the import.
138 private List<SearchFilter> excludeFilters;
139
140 // The set of search filters for entries to include in the import.
141 private List<SearchFilter> includeFilters;
142
143 // The set of LDIF files to be imported.
144 private List<String> ldifFiles;
145
146 // The set of attribute types that should be excluded from the
147 // import.
148 private Set<AttributeType> excludeAttributes;
149
150 // The set of attribute types that should be included in the import.
151 private Set<AttributeType> includeAttributes;
152
153 // Indicates whether all the user attributes should be included.
154 private boolean includeAllUserAttrs;
155
156 //Indicates whether all the operational attributes should be
157 // included.
158 private boolean includeAllOpAttrs;
159
160 //Indicates whether all the user attributes should be excluded.
161 private boolean excludeAllUserAttrs;
162
163 //Indicates whether all the operational attributes should be
164 // excluded.
165 private boolean excludeAllOpAttrs;
166
167
168
169 /**
170 * Creates a new LDIF import configuration that will read from the
171 * specified LDIF file.
172 *
173 * @param ldifFile The path to the LDIF file with the data to
174 * import.
175 */
176 public LDIFImportConfig(String ldifFile)
177 {
178 ldifFiles = new ArrayList<String>(1);
179 ldifFiles.add(ldifFile);
180 ldifFileIterator = ldifFiles.iterator();
181
182 ldifInputStream = null;
183 bufferSize = DEFAULT_BUFFER_SIZE;
184 excludeBranches = new ArrayList<DN>();
185 includeBranches = new ArrayList<DN>();
186 excludeFilters = new ArrayList<SearchFilter>();
187 includeFilters = new ArrayList<SearchFilter>();
188 appendToExistingData = false;
189 replaceExistingEntries = false;
190 includeObjectClasses = true;
191 invokeImportPlugins = false;
192 isCompressed = false;
193 isEncrypted = false;
194 clearBackend = false;
195 validateSchema = true;
196 reader = null;
197 rejectWriter = null;
198 skipWriter = null;
199 excludeAttributes = new HashSet<AttributeType>();
200 includeAttributes = new HashSet<AttributeType>();
201 includeAllUserAttrs = false;
202 includeAllOpAttrs = false;
203 excludeAllUserAttrs = false;
204 excludeAllOpAttrs = false;
205
206 }
207
208
209
210 /**
211 * Creates a new LDIF import configuration that will read from the
212 * specified LDIF files. The files will be imported in the order
213 * they are specified in the provided list.
214 *
215 * @param ldifFiles The paths to the LDIF files with the data to
216 * import.
217 */
218 public LDIFImportConfig(List<String> ldifFiles)
219 {
220 this.ldifFiles = ldifFiles;
221 ldifFileIterator = ldifFiles.iterator();
222
223 ldifInputStream = null;
224 bufferSize = DEFAULT_BUFFER_SIZE;
225 excludeBranches = new ArrayList<DN>();
226 includeBranches = new ArrayList<DN>();
227 excludeFilters = new ArrayList<SearchFilter>();
228 includeFilters = new ArrayList<SearchFilter>();
229 appendToExistingData = false;
230 replaceExistingEntries = false;
231 includeObjectClasses = true;
232 invokeImportPlugins = false;
233 isCompressed = false;
234 isEncrypted = false;
235 validateSchema = true;
236 reader = null;
237 rejectWriter = null;
238 skipWriter = null;
239 excludeAttributes = new HashSet<AttributeType>();
240 includeAttributes = new HashSet<AttributeType>();
241 includeAllUserAttrs = false;
242 includeAllOpAttrs = false;
243 excludeAllUserAttrs = false;
244 excludeAllOpAttrs = false;
245
246 }
247
248
249
250 /**
251 * Creates a new LDIF import configuration that will read from the
252 * provided input stream.
253 *
254 * @param ldifInputStream The input stream from which to read the
255 * LDIF data.
256 */
257 public LDIFImportConfig(InputStream ldifInputStream)
258 {
259 this.ldifInputStream = ldifInputStream;
260 bufferSize = DEFAULT_BUFFER_SIZE;
261 ldifFiles = null;
262 ldifFileIterator = null;
263
264 excludeBranches = new ArrayList<DN>();
265 includeBranches = new ArrayList<DN>();
266 excludeFilters = new ArrayList<SearchFilter>();
267 includeFilters = new ArrayList<SearchFilter>();
268 appendToExistingData = false;
269 replaceExistingEntries = false;
270 includeObjectClasses = true;
271 invokeImportPlugins = false;
272 isCompressed = false;
273 isEncrypted = false;
274 reader = null;
275 rejectWriter = null;
276 skipWriter = null;
277 excludeAttributes = new HashSet<AttributeType>();
278 includeAttributes = new HashSet<AttributeType>();
279 includeAllUserAttrs = false;
280 includeAllOpAttrs = false;
281 excludeAllUserAttrs = false;
282 excludeAllOpAttrs = false;
283
284 }
285
286 /**
287 * Creates a new LDIF import configuration that will read from the
288 * provided reader.
289 *
290 * @param ldifInputReader The input stream from which to read the
291 * LDIF data.
292 */
293 public LDIFImportConfig(Reader ldifInputReader)
294 {
295 ldifInputStream = null;
296 bufferSize = DEFAULT_BUFFER_SIZE;
297 ldifFiles = null;
298 ldifFileIterator = null;
299
300 excludeBranches = new ArrayList<DN>();
301 includeBranches = new ArrayList<DN>();
302 excludeFilters = new ArrayList<SearchFilter>();
303 includeFilters = new ArrayList<SearchFilter>();
304 appendToExistingData = false;
305 replaceExistingEntries = false;
306 includeObjectClasses = true;
307 invokeImportPlugins = false;
308 isCompressed = false;
309 isEncrypted = false;
310 reader = getBufferedReader(ldifInputReader);
311 rejectWriter = null;
312 skipWriter = null;
313 excludeAttributes = new HashSet<AttributeType>();
314 includeAttributes = new HashSet<AttributeType>();
315 includeAllUserAttrs = false;
316 includeAllOpAttrs = false;
317 excludeAllUserAttrs = false;
318 excludeAllOpAttrs = false;
319
320 }
321
322 /**
323 * Wrap reader in a BufferedReader if necessary.
324 *
325 * @param reader the reader to buffer
326 * @return reader as a BufferedReader
327 */
328 private BufferedReader getBufferedReader(Reader reader) {
329 if (reader instanceof BufferedReader) {
330 return (BufferedReader)reader;
331 } else {
332 return new BufferedReader(reader);
333 }
334 }
335
336 /**
337 * Creates a new LDIF import configuration that will generate
338 * entries using the given MakeLDIF template file rather than
339 * reading them from an existing LDIF file.
340 *
341 * @param templateFile The template file to use to generate the
342 * entries.
343 */
344 public LDIFImportConfig(TemplateFile templateFile)
345 {
346 this(new MakeLDIFInputStream(templateFile));
347
348
349 }
350
351
352
353 /**
354 * Retrieves the reader that should be used to read the LDIF data.
355 * Note that if the LDIF file is compressed and/or encrypted, then
356 * that must be indicated before this method is called for the first
357 * time.
358 *
359 * @return The reader that should be used to read the LDIF data.
360 *
361 * @throws IOException If a problem occurs while obtaining the
362 * reader.
363 */
364 public BufferedReader getReader()
365 throws IOException
366 {
367 if (reader == null)
368 {
369 InputStream inputStream;
370 if (ldifInputStream == null)
371 {
372 inputStream = ldifInputStream =
373 new FileInputStream(ldifFileIterator.next());
374 }
375 else
376 {
377 inputStream = ldifInputStream;
378 }
379
380 if (isEncrypted)
381 {
382 // FIXME -- Add support for encryption with a cipher input
383 // stream.
384 }
385
386 if (isCompressed)
387 {
388 inputStream = new GZIPInputStream(inputStream);
389 }
390
391 reader = new BufferedReader(new InputStreamReader(inputStream),
392 bufferSize);
393 }
394
395 return reader;
396 }
397
398
399
400 /**
401 * Retrieves the LDIF reader configured to read from the next LDIF
402 * file in the list.
403 *
404 * @return The reader that should be used to read the LDIF data, or
405 * <CODE>null</CODE> if there are no more files to read.
406 *
407 * @throws IOException If a problem occurs while obtaining the
408 * reader.
409 */
410 public BufferedReader nextReader()
411 throws IOException
412 {
413 if ((ldifFileIterator == null) || (! ldifFileIterator.hasNext()))
414 {
415 return null;
416 }
417 else
418 {
419 reader.close();
420
421 InputStream inputStream = ldifInputStream =
422 new FileInputStream(ldifFileIterator.next());
423
424 if (isEncrypted)
425 {
426 // FIXME -- Add support for encryption with a cipher input
427 // stream.
428 }
429
430 if (isCompressed)
431 {
432 inputStream = new GZIPInputStream(inputStream);
433 }
434
435 reader = new BufferedReader(new InputStreamReader(inputStream),
436 bufferSize);
437 return reader;
438 }
439 }
440
441
442
443 /**
444 * Retrieves the writer that should be used to write entries that
445 * are rejected rather than imported for some reason.
446 *
447 * @return The reject writer, or <CODE>null</CODE> if none is to be
448 * used.
449 */
450 public BufferedWriter getRejectWriter()
451 {
452 return rejectWriter;
453 }
454
455 /**
456 * Retrieves the writer that should be used to write entries that
457 * are skipped because they don't match the criteri.
458 *
459 * @return The skip writer, or <CODE>null</CODE> if none is to be
460 * used.
461 */
462 public BufferedWriter getSkipWriter()
463 {
464 return skipWriter;
465 }
466
467 /**
468 * Indicates that rejected entries should be written to the
469 * specified file. Note that this applies only to entries that are
470 * rejected because they are invalid (e.g., are malformed or don't
471 * conform to schema requirements), and not to entries that are
472 * rejected because they matched exclude criteria.
473 *
474 * @param rejectFile The path to the file to which
475 * reject information should be
476 * written.
477 * @param existingFileBehavior Indicates how to treat an existing
478 * file.
479 *
480 * @throws IOException If a problem occurs while opening the
481 * reject file for writing.
482 */
483 public void writeRejectedEntries(String rejectFile,
484 ExistingFileBehavior existingFileBehavior)
485 throws IOException
486 {
487 if (rejectFile == null)
488 {
489 if (rejectWriter != null)
490 {
491 try
492 {
493 rejectWriter.close();
494 } catch (Exception e) {}
495
496 rejectWriter = null;
497 }
498
499 return;
500 }
501
502 switch (existingFileBehavior)
503 {
504 case APPEND:
505 rejectWriter =
506 new BufferedWriter(new FileWriter(rejectFile, true));
507 break;
508 case OVERWRITE:
509 rejectWriter =
510 new BufferedWriter(new FileWriter(rejectFile, false));
511 break;
512 case FAIL:
513 File f = new File(rejectFile);
514 if (f.exists())
515 {
516 throw new IOException(
517 ERR_REJECT_FILE_EXISTS.get(rejectFile).toString());
518 }
519 else
520 {
521 rejectWriter =
522 new BufferedWriter(new FileWriter(rejectFile));
523 }
524 break;
525 }
526 }
527
528
529
530 /**
531 * Indicates that rejected entries should be written to the provided
532 * output stream. Note that this applies only to entries that are
533 * rejected because they are invalid (e.g., are malformed or don't
534 * conform to schema requirements), and not to entries that are
535 * rejected because they matched exclude criteria.
536 *
537 * @param outputStream The output stream to which rejected entries
538 * should be written.
539 */
540 public void writeRejectedEntries(OutputStream outputStream)
541 {
542 if (outputStream == null)
543 {
544 if (rejectWriter != null)
545 {
546 try
547 {
548 rejectWriter.close();
549 } catch (Exception e) {}
550
551 rejectWriter = null;
552 }
553
554 return;
555 }
556
557 rejectWriter =
558 new BufferedWriter(new OutputStreamWriter(outputStream));
559 }
560
561 /**
562 * Indicates that skipped entries should be written to the
563 * specified file. Note that this applies only to entries that are
564 * skipped because they matched exclude criteria.
565 *
566 * @param skipFile The path to the file to which
567 * skipped information should be
568 * written.
569 * @param existingFileBehavior Indicates how to treat an existing
570 * file.
571 *
572 * @throws IOException If a problem occurs while opening the
573 * skip file for writing.
574 */
575 public void writeSkippedEntries(String skipFile,
576 ExistingFileBehavior existingFileBehavior)
577 throws IOException
578 {
579 if (skipFile == null)
580 {
581 if (skipWriter != null)
582 {
583 try
584 {
585 skipWriter.close();
586 } catch (Exception e) {}
587
588 skipWriter = null;
589 }
590
591 return;
592 }
593
594 switch (existingFileBehavior)
595 {
596 case APPEND:
597 skipWriter =
598 new BufferedWriter(new FileWriter(skipFile, true));
599 break;
600 case OVERWRITE:
601 skipWriter =
602 new BufferedWriter(new FileWriter(skipFile, false));
603 break;
604 case FAIL:
605 File f = new File(skipFile);
606 if (f.exists())
607 {
608 throw new IOException(
609 ERR_SKIP_FILE_EXISTS.get(skipFile).toString());
610 }
611 else
612 {
613 skipWriter =
614 new BufferedWriter(new FileWriter(skipFile));
615 }
616 break;
617 }
618 }
619
620
621
622 /**
623 * Indicates that skipped entries should be written to the provided
624 * output stream. Note that this does not apply to entries that are
625 * rejected because they are invalid (e.g., are malformed or don't
626 * conform to schema requirements), but only apply to entries that
627 * are skipped because they matched exclude criteria.
628 *
629 * @param outputStream The output stream to which skipped entries
630 * should be written.
631 */
632 public void writeSkippedEntries(OutputStream outputStream)
633 {
634 if (outputStream == null)
635 {
636 if (skipWriter != null)
637 {
638 try
639 {
640 skipWriter.close();
641 } catch (Exception e) {}
642
643 skipWriter = null;
644 }
645
646 return;
647 }
648
649 skipWriter =
650 new BufferedWriter(new OutputStreamWriter(outputStream));
651 }
652
653 /**
654 * Indicates whether to append to an existing data set or completely
655 * replace it.
656 *
657 * @return <CODE>true</CODE> if the import should append to an
658 * existing data set, or <CODE>false</CODE> if not.
659 */
660 public boolean appendToExistingData()
661 {
662 return appendToExistingData;
663 }
664
665
666
667 /**
668 * Specifies whether to append to an existing data set or completely
669 * replace it.
670 *
671 * @param appendToExistingData Indicates whether to append to an
672 * existing data set or completely
673 * replace it.
674 */
675 public void setAppendToExistingData(boolean appendToExistingData)
676 {
677 this.appendToExistingData = appendToExistingData;
678 }
679
680
681
682 /**
683 * Indicates whether to replace the existing entry if a duplicate is
684 * found or to reject the new entry. This only applies when
685 * appending to an existing data set.
686 *
687 * @return <CODE>true</CODE> if an existing entry should be
688 * replaced with the new entry from the provided data set,
689 * or <CODE>false</CODE> if the new entry should be
690 * rejected.
691 */
692 public boolean replaceExistingEntries()
693 {
694 return replaceExistingEntries;
695 }
696
697
698
699 /**
700 * Specifies whether to replace the existing entry if a duplicate is
701 * found or to reject the new entry. This only applies when
702 * appending to an existing data set.
703 *
704 * @param replaceExistingEntries Indicates whether to replace the
705 * existing entry if a duplicate is
706 * found or to reject the new entry.
707 */
708 public void setReplaceExistingEntries(
709 boolean replaceExistingEntries)
710 {
711 this.replaceExistingEntries = replaceExistingEntries;
712 }
713
714
715
716 /**
717 * Indicates whether any LDIF import plugins registered with the
718 * server should be invoked during the import operation.
719 *
720 * @return <CODE>true</CODE> if registered LDIF import plugins
721 * should be invoked during the import operation, or
722 * <CODE>false</CODE> if they should not be invoked.
723 */
724 public boolean invokeImportPlugins()
725 {
726 return invokeImportPlugins;
727 }
728
729
730
731 /**
732 * Specifies whether any LDIF import plugins registered with the
733 * server should be invoked during the import operation.
734 *
735 * @param invokeImportPlugins Specifies whether any LDIF import
736 * plugins registered with the server
737 * should be invoked during the import
738 * operation.
739 */
740 public void setInvokeImportPlugins(boolean invokeImportPlugins)
741 {
742 this.invokeImportPlugins = invokeImportPlugins;
743 }
744
745
746
747 /**
748 * Indicates whether the input LDIF source is expected to be
749 * compressed.
750 *
751 * @return <CODE>true</CODE> if the LDIF source is expected to be
752 * compressed, or <CODE>false</CODE> if not.
753 */
754 public boolean isCompressed()
755 {
756 return isCompressed;
757 }
758
759
760
761 /**
762 * Specifies whether the input LDIF source is expected to be
763 * compressed. If compression is used, then this must be set prior
764 * to the initial call to <CODE>getReader</CODE>.
765 *
766 * @param isCompressed Indicates whether the input LDIF source is
767 * expected to be compressed.
768 */
769 public void setCompressed(boolean isCompressed)
770 {
771 this.isCompressed = isCompressed;
772 }
773
774
775
776 /**
777 * Indicates whether the input LDIF source is expected to be
778 * encrypted.
779 *
780 * @return <CODE>true</CODE> if the LDIF source is expected to be
781 * encrypted, or <CODE>false</CODE> if not.
782 */
783 public boolean isEncrypted()
784 {
785 return isEncrypted;
786 }
787
788
789
790 /**
791 * Specifies whether the input LDIF source is expected to be
792 * encrypted. If encryption is used, then this must be set prior to
793 * the initial call to <CODE>getReader</CODE>.
794 *
795 * @param isEncrypted Indicates whether the input LDIF source is
796 * expected to be encrypted.
797 */
798 public void setEncrypted(boolean isEncrypted)
799 {
800 this.isEncrypted = isEncrypted;
801 }
802
803
804
805 /**
806 * Indicates whether to clear the entire backend if importing to a
807 * backend with more than one base DNs.
808 *
809 * @return <CODE>true</code> if the entire backend should be
810 * cleared or <CODE>false</CODE> if not.
811 */
812 public boolean clearBackend()
813 {
814 return clearBackend;
815 }
816
817
818
819 /**
820 * Specifies whether to clear the entire backend if importing to a
821 * backend.
822 *
823 * @param clearBackend Indicates whether to clear the entire
824 * backend.
825 */
826 public void setClearBackend(boolean clearBackend)
827 {
828 this.clearBackend = clearBackend;
829 }
830
831
832
833 /**
834 * Indicates whether to perform schema validation on entries as they
835 * are read.
836 *
837 * @return <CODE>true</CODE> if schema validation should be
838 * performed on the entries as they are read, or
839 * <CODE>false</CODE> if not.
840 */
841 public boolean validateSchema()
842 {
843 return validateSchema;
844 }
845
846
847
848 /**
849 * Specifies whether to perform schema validation on entries as they
850 * are read.
851 *
852 * @param validateSchema Indicates whether to perform schema
853 * validation on entries as they are read.
854 */
855 public void setValidateSchema(boolean validateSchema)
856 {
857 this.validateSchema = validateSchema;
858 }
859
860
861
862 /**
863 * Retrieves the set of base DNs that specify the set of entries to
864 * exclude from the import. The contents of the returned list may
865 * be altered by the caller.
866 *
867 * @return The set of base DNs that specify the set of entries to
868 * exclude from the import.
869 */
870 public List<DN> getExcludeBranches()
871 {
872 return excludeBranches;
873 }
874
875
876
877 /**
878 * Specifies the set of base DNs that specify the set of entries to
879 * exclude from the import.
880 *
881 * @param excludeBranches The set of base DNs that specify the set
882 * of entries to exclude from the import.
883 */
884 public void setExcludeBranches(List<DN> excludeBranches)
885 {
886 if (excludeBranches == null)
887 {
888 this.excludeBranches = new ArrayList<DN>(0);
889 }
890 else
891 {
892 this.excludeBranches = excludeBranches;
893 }
894 }
895
896
897
898 /**
899 * Retrieves the set of base DNs that specify the set of entries to
900 * include in the import. The contents of the returned list may be
901 * altered by the caller.
902 *
903 * @return The set of base DNs that specify the set of entries to
904 * include in the import.
905 */
906 public List<DN> getIncludeBranches()
907 {
908 return includeBranches;
909 }
910
911
912
913 /**
914 * Specifies the set of base DNs that specify the set of entries to
915 * include in the import.
916 *
917 * @param includeBranches The set of base DNs that specify the set
918 * of entries to include in the import.
919 */
920 public void setIncludeBranches(List<DN> includeBranches)
921 {
922 if (includeBranches == null)
923 {
924 this.includeBranches = new ArrayList<DN>(0);
925 }
926 else
927 {
928 this.includeBranches = includeBranches;
929 }
930 }
931
932
933
934 /**
935 * Indicates whether to include the entry with the specified DN in
936 * the import.
937 *
938 * @param dn The DN of the entry for which to make the
939 * determination.
940 *
941 * @return <CODE>true</CODE> if the entry with the specified DN
942 * should be included in the import, or <CODE>false</CODE>
943 * if not.
944 */
945 public boolean includeEntry(DN dn)
946 {
947 if (! excludeBranches.isEmpty())
948 {
949 for (DN excludeBranch : excludeBranches)
950 {
951 if (excludeBranch.isAncestorOf(dn))
952 {
953 return false;
954 }
955 }
956 }
957
958 if (! includeBranches.isEmpty())
959 {
960 for (DN includeBranch : includeBranches)
961 {
962 if (includeBranch.isAncestorOf(dn))
963 {
964 return true;
965 }
966 }
967
968 return false;
969 }
970
971 return true;
972 }
973
974
975
976 /**
977 * Indicates whether the set of objectclasses should be included in
978 * the entries read from the LDIF.
979 *
980 * @return <CODE>true</CODE> if the set of objectclasses should be
981 * included in the entries read from the LDIF, or
982 * <CODE>false</CODE> if not.
983 */
984 public boolean includeObjectClasses()
985 {
986 return includeObjectClasses;
987 }
988
989
990
991 /**
992 * Specifies whether the set of objectclasses should be included in
993 * the entries read from the LDIF.
994 *
995 * @param includeObjectClasses Indicates whether the set of
996 * objectclasses should be included in
997 * the entries read from the LDIF.
998 */
999 public void setIncludeObjectClasses(boolean includeObjectClasses)
1000 {
1001 this.includeObjectClasses = includeObjectClasses;
1002 }
1003
1004
1005
1006 /**
1007 * Retrieves the set of attributes that should be excluded from the
1008 * entries read from the LDIF. The contents of the returned set may
1009 * be modified by the caller.
1010 *
1011 * @return The set of attributes that should be excluded from the
1012 * entries read from the LDIF.
1013 */
1014 public Set<AttributeType> getExcludeAttributes()
1015 {
1016 return excludeAttributes;
1017 }
1018
1019
1020
1021 /**
1022 * Specifies the set of attributes that should be excluded from the
1023 * entries read from the LDIF.
1024 *
1025 * @param excludeAttributes The set of attributes that should be
1026 * excluded from the entries read from
1027 * the LDIF.
1028 */
1029 public void setExcludeAttributes(
1030 Set<AttributeType> excludeAttributes)
1031 {
1032 if (excludeAttributes == null)
1033 {
1034 this.excludeAttributes = new HashSet<AttributeType>(0);
1035 }
1036 else
1037 {
1038 this.excludeAttributes = excludeAttributes;
1039 }
1040 }
1041
1042
1043
1044 /**
1045 * Retrieves the set of attributes that should be included in the
1046 * entries read from the LDIF. The contents of the returned set may
1047 * be modified by the caller.
1048 *
1049 * @return The set of attributes that should be included in the
1050 * entries read from the LDIF.
1051 */
1052 public Set<AttributeType> getIncludeAttributes()
1053 {
1054 return includeAttributes;
1055 }
1056
1057
1058
1059 /**
1060 * Specifies the set of attributes that should be included in the
1061 * entries read from the LDIF.
1062 *
1063 * @param includeAttributes The set of attributes that should be
1064 * included in the entries read from the
1065 * LDIF.
1066 */
1067 public void setIncludeAttributes(
1068 Set<AttributeType> includeAttributes)
1069 {
1070 if (includeAttributes == null)
1071 {
1072 this.includeAttributes = new HashSet<AttributeType>(0);
1073 }
1074 else
1075 {
1076 this.includeAttributes = includeAttributes;
1077 }
1078 }
1079
1080
1081
1082 /**
1083 * Indicates whether the specified attribute should be included in
1084 * the entries read from the LDIF.
1085 *
1086 * @param attributeType The attribute type for which to make the
1087 * determination.
1088 *
1089 * @return <CODE>true</CODE> if the specified attribute should be
1090 * included in the entries read from the LDIF, or
1091 * <CODE>false</CODE> if not.
1092 */
1093 public boolean includeAttribute(AttributeType attributeType)
1094 {
1095 if ((! excludeAttributes.isEmpty()) &&
1096 excludeAttributes.contains(attributeType))
1097 {
1098 return false;
1099 }
1100
1101 if(excludeAllOpAttrs && attributeType.isOperational() ||
1102 excludeAllUserAttrs && !attributeType.isOperational())
1103 {
1104 return false;
1105 }
1106
1107 if(includeAllUserAttrs && !attributeType.isOperational() ||
1108 includeAllOpAttrs && attributeType.isOperational())
1109 {
1110 return true;
1111 }
1112
1113 if (! includeAttributes.isEmpty())
1114 {
1115 return includeAttributes.contains(attributeType);
1116 }
1117 else
1118 {
1119 if(includeAllUserAttrs && attributeType.isOperational() ||
1120 includeAllOpAttrs && !attributeType.isOperational())
1121 {
1122 return false;
1123 }
1124 }
1125 return true;
1126 }
1127
1128
1129
1130 /**
1131 * Retrieves the set of search filters that should be used to
1132 * determine which entries to exclude from the LDIF. The contents
1133 * of the returned list may be modified by the caller.
1134 *
1135 * @return The set of search filters that should be used to
1136 * determine which entries to exclude from the LDIF.
1137 */
1138 public List<SearchFilter> getExcludeFilters()
1139 {
1140 return excludeFilters;
1141 }
1142
1143
1144
1145 /**
1146 * Specifies the set of search filters that should be used to
1147 * determine which entries to exclude from the LDIF.
1148 *
1149 * @param excludeFilters The set of search filters that should be
1150 * used to determine which entries to
1151 * exclude from the LDIF.
1152 */
1153 public void setExcludeFilters(List<SearchFilter> excludeFilters)
1154 {
1155 if (excludeFilters == null)
1156 {
1157 this.excludeFilters = new ArrayList<SearchFilter>(0);
1158 }
1159 else
1160 {
1161 this.excludeFilters = excludeFilters;
1162 }
1163 }
1164
1165
1166
1167 /**
1168 * Retrieves the set of search filters that should be used to
1169 * determine which entries to include in the LDIF. The contents of
1170 * the returned list may be modified by the caller.
1171 *
1172 * @return The set of search filters that should be used to
1173 * determine which entries to include in the LDIF.
1174 */
1175 public List<SearchFilter> getIncludeFilters()
1176 {
1177 return includeFilters;
1178 }
1179
1180
1181
1182 /**
1183 * Specifies the set of search filters that should be used to
1184 * determine which entries to include in the LDIF.
1185 *
1186 * @param includeFilters The set of search filters that should be
1187 * used to determine which entries to
1188 * include in the LDIF.
1189 */
1190 public void setIncludeFilters(List<SearchFilter> includeFilters)
1191 {
1192 if (includeFilters == null)
1193 {
1194 this.includeFilters = new ArrayList<SearchFilter>(0);
1195 }
1196 else
1197 {
1198 this.includeFilters = includeFilters;
1199 }
1200 }
1201
1202
1203
1204 /**
1205 * Indicates whether the specified entry should be included in the
1206 * import based on the configured set of include and exclude
1207 * filters.
1208 *
1209 * @param entry The entry for which to make the determination.
1210 *
1211 * @return <CODE>true</CODE> if the specified entry should be
1212 * included in the import, or <CODE>false</CODE> if not.
1213 *
1214 * @throws DirectoryException If there is a problem with any of
1215 * the search filters used to make the
1216 * determination.
1217 */
1218 public boolean includeEntry(Entry entry)
1219 throws DirectoryException
1220 {
1221 if (! excludeFilters.isEmpty())
1222 {
1223 for (SearchFilter filter : excludeFilters)
1224 {
1225 if (filter.matchesEntry(entry))
1226 {
1227 return false;
1228 }
1229 }
1230 }
1231
1232 if (! includeFilters.isEmpty())
1233 {
1234 for (SearchFilter filter : includeFilters)
1235 {
1236 if (filter.matchesEntry(entry))
1237 {
1238 return true;
1239 }
1240 }
1241
1242 return false;
1243 }
1244
1245 return true;
1246 }
1247
1248
1249
1250 /**
1251 * Retrieves the buffer size that should be used when reading LDIF
1252 * data.
1253 *
1254 * @return The buffer size that should be used when reading LDIF
1255 * data.
1256 */
1257 public int getBufferSize()
1258 {
1259 return bufferSize;
1260 }
1261
1262
1263
1264 /**
1265 * Specifies the buffer size that should be used when reading LDIF
1266 * data.
1267 *
1268 * @param bufferSize The buffer size that should be used when
1269 * reading LDIF data.
1270 */
1271 public void setBufferSize(int bufferSize)
1272 {
1273 this.bufferSize = bufferSize;
1274 }
1275
1276
1277
1278 /**
1279 * Specifies whether all the user attributes should be excluded.
1280 *
1281 * @param excludeAllUserAttrs Specifies all user attributes to
1282 * be excluded.
1283 */
1284 public void setExcludeAllUserAttributes(boolean excludeAllUserAttrs)
1285 {
1286 this.excludeAllUserAttrs = excludeAllUserAttrs;
1287 }
1288
1289
1290
1291 /**
1292 * Specifies whether all the operational attributes should be
1293 * excluded.
1294 *
1295 * @param excludeAllOpAttrs Specifies whether all the
1296 * operational attributes
1297 * should be excluded.
1298 */
1299 public void setExcludeAllOperationalAttributes(
1300 boolean excludeAllOpAttrs)
1301 {
1302 this.excludeAllOpAttrs = excludeAllOpAttrs;
1303 }
1304
1305
1306
1307 /**
1308 * Specifies whether all the operational attributes should be
1309 * included.
1310 *
1311 * @param includeAllOpAttrs Specifies whether all
1312 * the operation attributes should be included.
1313 *
1314 */
1315 public void setIncludeAllOpAttributes(boolean includeAllOpAttrs)
1316 {
1317 this.includeAllOpAttrs = includeAllOpAttrs;
1318 }
1319
1320
1321
1322 /**
1323 * Specifies whether all the user attributes should be included.
1324 *
1325 * @param includeAllUserAttrs Specifies whether all the
1326 * user attributes should be
1327 * included.
1328 */
1329 public void setIncludeAllUserAttributes(boolean includeAllUserAttrs)
1330 {
1331 this.includeAllUserAttrs = includeAllUserAttrs;
1332 }
1333
1334
1335
1336 /**
1337 * Closes any resources that this import config might have open.
1338 */
1339 public void close()
1340 {
1341 try
1342 {
1343 reader.close();
1344 }
1345 catch (Exception e)
1346 {
1347 if (debugEnabled())
1348 {
1349 TRACER.debugCaught(DebugLogLevel.ERROR, e);
1350 }
1351 }
1352
1353 if (rejectWriter != null)
1354 {
1355 try
1356 {
1357 rejectWriter.close();
1358 }
1359 catch (Exception e)
1360 {
1361 if (debugEnabled())
1362 {
1363 TRACER.debugCaught(DebugLogLevel.ERROR, e);
1364 }
1365 }
1366 }
1367
1368 if (skipWriter != null)
1369 {
1370 try
1371 {
1372 skipWriter.close();
1373 }
1374 catch (Exception e)
1375 {
1376 if (debugEnabled())
1377 {
1378 TRACER.debugCaught(DebugLogLevel.ERROR, e);
1379 }
1380 }
1381 }
1382 }
1383 }
1384