ldifLines) {
super(ldifLines);
}
/**
* Creates a new LDIF entry reader whose source is the provided character
* stream reader.
*
* @param reader
* The character stream reader to use.
* @throws NullPointerException
* If {@code reader} was {@code null}.
*/
public LDIFEntryReader(final Reader reader) {
super(reader);
}
/**
* Creates a new LDIF entry reader which will read lines of LDIF from the
* provided array of LDIF lines.
*
* @param ldifLines
* The lines of LDIF to be read.
* @throws NullPointerException
* If {@code ldifLines} was {@code null}.
*/
public LDIFEntryReader(final String... ldifLines) {
super(Arrays.asList(ldifLines));
}
/**
* {@inheritDoc}
*/
@Override
public void close() throws IOException {
close0();
}
/**
* {@inheritDoc}
*
* @throws DecodeException
* If the entry could not be decoded because it was malformed.
*/
@Override
public boolean hasNext() throws DecodeException, IOException {
return getNextEntry() != EOF;
}
/**
* {@inheritDoc}
*
* @throws DecodeException
* If the entry could not be decoded because it was malformed.
*/
@Override
public Entry readEntry() throws DecodeException, IOException {
if (!hasNext()) {
// LDIF reader has completed successfully.
throw new NoSuchElementException();
}
final Entry entry = nextEntry;
nextEntry = null;
return entry;
}
/**
* Specifies whether or not all operational attributes should be excluded
* from any entries that are read from LDIF. The default is {@code false}.
*
* @param excludeOperationalAttributes
* {@code true} if all operational attributes should be excluded,
* or {@code false} otherwise.
* @return A reference to this {@code LDIFEntryReader}.
*/
public LDIFEntryReader setExcludeAllOperationalAttributes(
final boolean excludeOperationalAttributes) {
this.excludeOperationalAttributes = excludeOperationalAttributes;
return this;
}
/**
* Specifies whether or not all user attributes should be excluded from any
* entries that are read from LDIF. The default is {@code false}.
*
* @param excludeUserAttributes
* {@code true} if all user attributes should be excluded, or
* {@code false} otherwise.
* @return A reference to this {@code LDIFEntryReader}.
*/
public LDIFEntryReader setExcludeAllUserAttributes(final boolean excludeUserAttributes) {
this.excludeUserAttributes = excludeUserAttributes;
return this;
}
/**
* Excludes the named attribute from any entries that are read from LDIF. By
* default all attributes are included unless explicitly excluded.
*
* @param attributeDescription
* The name of the attribute to be excluded.
* @return A reference to this {@code LDIFEntryReader}.
*/
public LDIFEntryReader setExcludeAttribute(final AttributeDescription attributeDescription) {
Validator.ensureNotNull(attributeDescription);
excludeAttributes.add(attributeDescription);
return this;
}
/**
* Excludes all entries beneath the named entry (inclusive) from being read
* from LDIF. By default all entries are written unless explicitly excluded
* or included by branches or filters.
*
* @param excludeBranch
* The distinguished name of the branch to be excluded.
* @return A reference to this {@code LDIFEntryReader}.
*/
public LDIFEntryReader setExcludeBranch(final DN excludeBranch) {
Validator.ensureNotNull(excludeBranch);
excludeBranches.add(excludeBranch);
return this;
}
/**
* Excludes all entries which match the provided filter matcher from being
* read from LDIF. By default all entries are read unless explicitly
* excluded or included by branches or filters.
*
* @param excludeFilter
* The filter matcher.
* @return A reference to this {@code LDIFEntryReader}.
*/
public LDIFEntryReader setExcludeFilter(final Matcher excludeFilter) {
Validator.ensureNotNull(excludeFilter);
excludeFilters.add(excludeFilter);
return this;
}
/**
* Ensures that the named attribute is not excluded from any entries that
* are read from LDIF. By default all attributes are included unless
* explicitly excluded.
*
* @param attributeDescription
* The name of the attribute to be included.
* @return A reference to this {@code LDIFEntryReader}.
*/
public LDIFEntryReader setIncludeAttribute(final AttributeDescription attributeDescription) {
Validator.ensureNotNull(attributeDescription);
includeAttributes.add(attributeDescription);
return this;
}
/**
* Ensures that all entries beneath the named entry (inclusive) are read
* from LDIF. By default all entries are written unless explicitly excluded
* or included by branches or filters.
*
* @param includeBranch
* The distinguished name of the branch to be included.
* @return A reference to this {@code LDIFEntryReader}.
*/
public LDIFEntryReader setIncludeBranch(final DN includeBranch) {
Validator.ensureNotNull(includeBranch);
includeBranches.add(includeBranch);
return this;
}
/**
* Ensures that all entries which match the provided filter matcher are read
* from LDIF. By default all entries are read unless explicitly excluded or
* included by branches or filters.
*
* @param includeFilter
* The filter matcher.
* @return A reference to this {@code LDIFEntryReader}.
*/
public LDIFEntryReader setIncludeFilter(final Matcher includeFilter) {
Validator.ensureNotNull(includeFilter);
includeFilters.add(includeFilter);
return this;
}
/**
* Sets the rejected record listener which should be notified whenever an
* LDIF record is skipped, malformed, or fails schema validation.
*
* By default the {@link RejectedLDIFListener#FAIL_FAST} listener is used.
*
* @param listener
* The rejected record listener.
* @return A reference to this {@code LDIFEntryReader}.
*/
public LDIFEntryReader setRejectedLDIFListener(final RejectedLDIFListener listener) {
this.rejectedRecordListener = listener;
return this;
}
/**
* Sets the schema which should be used for decoding entries that are read
* from LDIF. The default schema is used if no other is specified.
*
* @param schema
* The schema which should be used for decoding entries that are
* read from LDIF.
* @return A reference to this {@code LDIFEntryReader}.
*/
public LDIFEntryReader setSchema(final Schema schema) {
Validator.ensureNotNull(schema);
this.schema =
schemaValidationPolicy.checkAttributesAndObjectClasses().needsChecking() ? schema
.asStrictSchema() : schema.asNonStrictSchema();
return this;
}
/**
* Specifies the schema validation which should be used when reading LDIF
* entry records. If attribute value validation is enabled then all checks
* will be performed.
*
* Schema validation is disabled by default.
*
* NOTE: this method copies the provided policy so changes made to it
* after this method has been called will have no effect.
*
* @param policy
* The schema validation which should be used when reading LDIF
* entry records.
* @return A reference to this {@code LDIFEntryReader}.
*/
public LDIFEntryReader setSchemaValidationPolicy(final SchemaValidationPolicy policy) {
this.schemaValidationPolicy = SchemaValidationPolicy.copyOf(policy);
this.schema =
schemaValidationPolicy.checkAttributesAndObjectClasses().needsChecking() ? schema
.asStrictSchema() : schema.asNonStrictSchema();
return this;
}
private Entry getNextEntry() throws DecodeException, IOException {
while (nextEntry == null) {
// Read the set of lines that make up the next entry.
final LDIFRecord record = readLDIFRecord();
if (record == null) {
nextEntry = EOF;
break;
}
try {
/*
* Read the DN of the entry and see if it is one that should be
* included in the import.
*/
final DN entryDN = readLDIFRecordDN(record);
if (entryDN == null) {
// Skip version record.
continue;
}
// Skip if branch containing the entry DN is excluded.
if (isBranchExcluded(entryDN)) {
final LocalizableMessage message =
ERR_LDIF_ENTRY_EXCLUDED_BY_DN
.get(record.lineNumber, entryDN.toString());
handleSkippedRecord(record, message);
continue;
}
// Use an Entry for the AttributeSequence.
final Entry entry = new LinkedHashMapEntry(entryDN);
boolean schemaValidationFailure = false;
final List schemaErrors = new LinkedList();
while (record.iterator.hasNext()) {
final String ldifLine = record.iterator.next();
if (!readLDIFRecordAttributeValue(record, ldifLine, entry, schemaErrors)) {
schemaValidationFailure = true;
}
}
// Skip if the entry is excluded by any filters.
if (isEntryExcluded(entry)) {
final LocalizableMessage message =
ERR_LDIF_ENTRY_EXCLUDED_BY_FILTER.get(record.lineNumber, entryDN
.toString());
handleSkippedRecord(record, message);
continue;
}
if (!schema.validateEntry(entry, schemaValidationPolicy, schemaErrors)) {
schemaValidationFailure = true;
}
if (schemaValidationFailure) {
handleSchemaValidationFailure(record, schemaErrors);
continue;
}
if (!schemaErrors.isEmpty()) {
handleSchemaValidationWarning(record, schemaErrors);
}
nextEntry = entry;
} catch (final DecodeException e) {
handleMalformedRecord(record, e.getMessageObject());
continue;
}
}
return nextEntry;
}
}