mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

matthew_swift
09.31.2010 d9722bcadc7bf619808426fc82cbb0c74b1646b0
sdk/src/org/opends/sdk/ldif/LDIFChangeRecordReader.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2009 Sun Microsystems, Inc.
 *      Copyright 2009-2010 Sun Microsystems, Inc.
 */
package org.opends.sdk.ldif;
@@ -37,6 +37,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;
import org.opends.sdk.*;
import org.opends.sdk.requests.ModifyDNRequest;
@@ -79,9 +80,7 @@
    final LDIFChangeRecordReader reader = new LDIFChangeRecordReader(ldifLines);
    try
    {
      final ChangeRecord record = reader.readChangeRecord();
      if (record == null)
      if (!reader.hasNext())
      {
        // No change record found.
        final LocalizableMessage message = WARN_READ_LDIF_RECORD_NO_CHANGE_RECORD_FOUND
@@ -89,7 +88,9 @@
        throw new LocalizedIllegalArgumentException(message);
      }
      if (reader.readChangeRecord() != null)
      final ChangeRecord record = reader.readChangeRecord();
      if (reader.hasNext())
      {
        // Multiple change records found.
        final LocalizableMessage message = WARN_READ_LDIF_RECORD_MULTIPLE_CHANGE_RECORDS_FOUND
@@ -115,6 +116,13 @@
  private ChangeRecord nextChangeRecord = null;
  // Poison used to indicate end of LDIF.
  private static final ChangeRecord EOF = Requests.newAddRequest(DN.rootDN());
  /**
   * Creates a new LDIF change record reader whose source is the provided input
   * stream.
@@ -169,6 +177,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public void close() throws IOException
  {
    close0();
@@ -178,110 +187,37 @@
  /**
   * {@inheritDoc}
   *
   * @throws DecodeException
   *           If the change record could not be decoded because it was
   *           malformed.
   */
  @Override
  public boolean hasNext() throws DecodeException, IOException
  {
    return getNextChangeRecord() != EOF;
  }
  /**
   * {@inheritDoc}
   *
   * @throws DecodeException
   *           If the entry could not be decoded because it was malformed.
   */
  @Override
  public ChangeRecord readChangeRecord() throws DecodeException, IOException
  {
    // Continue until an unfiltered entry is obtained.
    while (true)
    if (!hasNext())
    {
      LDIFRecord record = null;
      // Read the set of lines that make up the next entry.
      record = readLDIFRecord();
      if (record == null)
      {
        return null;
      }
      // Read the DN of the entry and see if it is one that should be
      // included in the import.
      DN entryDN;
      try
      {
        entryDN = readLDIFRecordDN(record);
        if (entryDN == null)
        {
          // Skip version record.
          continue;
        }
      }
      catch (final DecodeException e)
      {
        rejectLDIFRecord(record, e.getMessageObject());
        continue;
      }
      // Skip if branch containing the entry DN is excluded.
      if (isBranchExcluded(entryDN))
      {
        final LocalizableMessage message = LocalizableMessage
            .raw("Skipping entry because it is in excluded branch");
        skipLDIFRecord(record, message);
        continue;
      }
      ChangeRecord changeRecord = null;
      try
      {
        if (!record.iterator.hasNext())
        {
          // FIXME: improve error.
          final LocalizableMessage message = LocalizableMessage
              .raw("Missing changetype");
          throw DecodeException.error(message);
        }
        final KeyValuePair pair = new KeyValuePair();
        final String ldifLine = readLDIFRecordKeyValuePair(record, pair, false);
        if (!toLowerCase(pair.key).equals("changetype"))
        {
          // Default to add change record.
          changeRecord = parseAddChangeRecordEntry(entryDN, ldifLine, record);
        }
        else
        {
          final String changeType = toLowerCase(pair.value);
          if (changeType.equals("add"))
          {
            changeRecord = parseAddChangeRecordEntry(entryDN, null, record);
          }
          else if (changeType.equals("delete"))
          {
            changeRecord = parseDeleteChangeRecordEntry(entryDN, record);
          }
          else if (changeType.equals("modify"))
          {
            changeRecord = parseModifyChangeRecordEntry(entryDN, record);
          }
          else if (changeType.equals("modrdn"))
          {
            changeRecord = parseModifyDNChangeRecordEntry(entryDN, record);
          }
          else if (changeType.equals("moddn"))
          {
            changeRecord = parseModifyDNChangeRecordEntry(entryDN, record);
          }
          else
          {
            // FIXME: improve error.
            final LocalizableMessage message = ERR_LDIF_INVALID_CHANGETYPE_ATTRIBUTE
                .get(pair.value, "add, delete, modify, moddn, modrdn");
            throw DecodeException.error(message);
          }
        }
      }
      catch (final DecodeException e)
      {
        rejectLDIFRecord(record, e.getMessageObject());
        continue;
      }
      if (changeRecord != null)
      {
        return changeRecord;
      }
      // LDIF reader has completed successfully.
      throw new NoSuchElementException();
    }
    final ChangeRecord changeRecord = nextChangeRecord;
    nextChangeRecord = null;
    return changeRecord;
  }
@@ -309,8 +245,8 @@
   * change records 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.
   *          {@code true} if all user attributes should be excluded, or
   *          {@code false} otherwise.
   * @return A reference to this {@code LDIFChangeRecordReader}.
   */
  public LDIFChangeRecordReader setExcludeAllUserAttributes(
@@ -418,8 +354,8 @@
   * records that are read from LDIF. The default is {@code true} .
   *
   * @param validateSchema
   *          {@code true} if schema validation should be performed, or {@code
   *          false} otherwise.
   *          {@code true} if schema validation should be performed, or
   *          {@code false} otherwise.
   * @return A reference to this {@code LDIFChangeRecordReader}.
   */
  public LDIFChangeRecordReader setValidateSchema(final boolean validateSchema)
@@ -430,6 +366,115 @@
  private ChangeRecord getNextChangeRecord() throws DecodeException,
      IOException
  {
    while (nextChangeRecord == null)
    {
      LDIFRecord record = null;
      // Read the set of lines that make up the next entry.
      record = readLDIFRecord();
      if (record == null)
      {
        nextChangeRecord = EOF;
        break;
      }
      // Read the DN of the entry and see if it is one that should be
      // included in the import.
      DN entryDN;
      try
      {
        entryDN = readLDIFRecordDN(record);
        if (entryDN == null)
        {
          // Skip version record.
          continue;
        }
      }
      catch (final DecodeException e)
      {
        rejectLDIFRecord(record, e.getMessageObject());
        continue;
      }
      // Skip if branch containing the entry DN is excluded.
      if (isBranchExcluded(entryDN))
      {
        final LocalizableMessage message = LocalizableMessage
            .raw("Skipping entry because it is in excluded branch");
        skipLDIFRecord(record, message);
        continue;
      }
      ChangeRecord changeRecord = null;
      try
      {
        if (!record.iterator.hasNext())
        {
          // FIXME: improve error.
          final LocalizableMessage message = LocalizableMessage
              .raw("Missing changetype");
          throw DecodeException.error(message);
        }
        final KeyValuePair pair = new KeyValuePair();
        final String ldifLine = readLDIFRecordKeyValuePair(record, pair, false);
        if (!toLowerCase(pair.key).equals("changetype"))
        {
          // Default to add change record.
          changeRecord = parseAddChangeRecordEntry(entryDN, ldifLine, record);
        }
        else
        {
          final String changeType = toLowerCase(pair.value);
          if (changeType.equals("add"))
          {
            changeRecord = parseAddChangeRecordEntry(entryDN, null, record);
          }
          else if (changeType.equals("delete"))
          {
            changeRecord = parseDeleteChangeRecordEntry(entryDN, record);
          }
          else if (changeType.equals("modify"))
          {
            changeRecord = parseModifyChangeRecordEntry(entryDN, record);
          }
          else if (changeType.equals("modrdn"))
          {
            changeRecord = parseModifyDNChangeRecordEntry(entryDN, record);
          }
          else if (changeType.equals("moddn"))
          {
            changeRecord = parseModifyDNChangeRecordEntry(entryDN, record);
          }
          else
          {
            // FIXME: improve error.
            final LocalizableMessage message = ERR_LDIF_INVALID_CHANGETYPE_ATTRIBUTE
                .get(pair.value, "add, delete, modify, moddn, modrdn");
            throw DecodeException.error(message);
          }
        }
      }
      catch (final DecodeException e)
      {
        rejectLDIFRecord(record, e.getMessageObject());
        continue;
      }
      if (changeRecord != null)
      {
        nextChangeRecord = changeRecord;
      }
    }
    return nextChangeRecord;
  }
  private ChangeRecord parseAddChangeRecordEntry(final DN entryDN,
      final String lastLDIFLine, final LDIFRecord record)
      throws DecodeException
@@ -581,8 +626,8 @@
        {
          // TODO: include line number.
          final LocalizableMessage message = ERR_LDIF_INVALID_CHANGERECORD_ATTRIBUTE
              .get(attributeDescription2.toString(), attributeDescription
                  .toString());
              .get(attributeDescription2.toString(),
                  attributeDescription.toString());
          throw DecodeException.error(message);
        }