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

Jean-Noel Rouvignac
22.57.2013 4c6a4c3e78a13b9237a46cc1e7ef8680c1c55a90
LDIFReader.java:
Extracted methods findFirstNonSpaceCharPosition(), base64Decode() and decodeDN().
In readAttribute(), moved common code out of if/else branches.
Used early exits.
Removed useless parenthesis.
Condensed code and comments on one line where possible.

LDIFWriter.java:
Extracted methods writeDN(), writeAttribute().
In writeEntries(), simplified the code.
In writeModifyChangeRecord(), removed useless switch statement.
In appendLDIFSeparatorAndValue(), removed duplicate code.
Removed useless parenthesis.
Comments => javadocs
Condensed code and comments on one line where possible.
2 files modified
560 ■■■■■ changed files
opends/src/server/org/opends/server/util/LDIFReader.java 345 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/util/LDIFWriter.java 215 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/util/LDIFReader.java
@@ -606,8 +606,7 @@
          logToRejectWriter(lines, message);
          throw new LDIFException(message, lastEntryLineNumber, true);
        }
        //Add any superior objectclass(s) missing in an entries
        //objectclass map.
        //Add any superior objectclass(s) missing in an entries objectclass map.
        addSuperiorObjectClasses(entry.getObjectClasses());
      }
@@ -734,35 +733,26 @@
        // This must mean that we have reached the end of the LDIF source.
        // If the set of lines read so far is empty, then move onto the next
        // file or return null.  Otherwise, break out of this loop.
        if (lines.isEmpty())
        {
          reader = importConfig.nextReader();
          if (reader == null)
          {
            return null;
          }
          else
          {
            return readEntryLines();
          }
        }
        else
        if (!lines.isEmpty())
        {
          break;
        }
        reader = importConfig.nextReader();
        if (reader != null)
        {
          return readEntryLines();
        }
        return null;
      }
      else if (line.length() == 0)
      {
        // This is a blank line.  If the set of lines read so far is empty,
        // then just skip over it.  Otherwise, break out of this loop.
        if (lines.isEmpty())
        {
          continue;
        }
        else
        if (!lines.isEmpty())
        {
          break;
        }
        continue;
      }
      else if (line.charAt(0) == '#')
      {
@@ -868,8 +858,7 @@
    // Look at the character immediately after the colon.  If there is none,
    // then assume the null DN.  If it is another colon, then the DN must be
    // base64-encoded.  Otherwise, it may be one or more spaces.
    int length = line.length();
    if (colonPos == (length-1))
    if (colonPos == line.length() - 1)
    {
      return DN.nullDN();
    }
@@ -878,115 +867,90 @@
    {
      // The DN is base64-encoded.  Find the first non-blank character and
      // take the rest of the line, base64-decode it, and parse it as a DN.
      int pos = colonPos+2;
      while ((pos < length) && (line.charAt(pos) == ' '))
      {
        pos++;
      }
      String encodedDNStr = line.substring(pos);
      String dnStr;
      try
      {
        dnStr = new String(Base64.decode(encodedDNStr), "UTF-8");
      }
      catch (Exception e)
      {
        // The value did not have a valid base64-encoding.
        if (debugEnabled())
        {
          TRACER.debugInfo("Base64 decode failed for dn: ",
                            line.substring(pos));
        }
        Message message =
                ERR_LDIF_COULD_NOT_BASE64_DECODE_DN.get(
                        lastEntryLineNumber, line,
                        String.valueOf(e));
        logToRejectWriter(lines, message);
        throw new LDIFException(message, lastEntryLineNumber, true, e);
      }
      try
      {
        return DN.decode(dnStr);
      }
      catch (DirectoryException de)
      {
        if (debugEnabled())
        {
          TRACER.debugInfo("DN decode failed for: ", dnStr);
        }
        Message message = ERR_LDIF_INVALID_DN.get(
                lastEntryLineNumber, line.toString(),
                de.getMessageObject());
        logToRejectWriter(lines, message);
        throw new LDIFException(message, lastEntryLineNumber, true, de);
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugInfo("DN decode failed for: ", dnStr);
        }
        Message message = ERR_LDIF_INVALID_DN.get(
                lastEntryLineNumber, line.toString(),
                String.valueOf(e));
        logToRejectWriter(lines, message);
        throw new LDIFException(message, lastEntryLineNumber, true, e);
      }
      int pos = findFirstNonSpaceCharPosition(line, colonPos + 2);
      String dnStr = base64Decode(line.substring(pos), lines, line);
      return decodeDN(dnStr, lines, line);
    }
    else
    {
      // The rest of the value should be the DN.  Skip over any spaces and
      // attempt to decode the rest of the line as the DN.
      int pos = colonPos+1;
      while ((pos < length) && (line.charAt(pos) == ' '))
      {
        pos++;
      }
      String dnString = line.substring(pos);
      try
      {
        return DN.decode(dnString);
      }
      catch (DirectoryException de)
      {
        if (debugEnabled())
        {
          TRACER.debugInfo("DN decode failed for: ", line.substring(pos));
        }
        Message message = ERR_LDIF_INVALID_DN.get(
                lastEntryLineNumber, line.toString(), de.getMessageObject());
        logToRejectWriter(lines, message);
        throw new LDIFException(message, lastEntryLineNumber, true, de);
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugInfo("DN decode failed for: ", line.substring(pos));
        }
        Message message = ERR_LDIF_INVALID_DN.get(
                lastEntryLineNumber, line.toString(),
                String.valueOf(e));
        logToRejectWriter(lines, message);
        throw new LDIFException(message, lastEntryLineNumber, true, e);
      }
      int pos = findFirstNonSpaceCharPosition(line, colonPos + 1);
      return decodeDN(line.substring(pos), lines, line);
    }
  }
  private int findFirstNonSpaceCharPosition(StringBuilder line, int startPos)
  {
    final int length = line.length();
    int pos = startPos;
    while ((pos < length) && (line.charAt(pos) == ' '))
    {
      pos++;
    }
    return pos;
  }
  private String base64Decode(String encodedStr, List<StringBuilder> lines,
      StringBuilder line) throws LDIFException
  {
    try
    {
      return new String(Base64.decode(encodedStr), "UTF-8");
    }
    catch (Exception e)
    {
      // The value did not have a valid base64-encoding.
      final String stackTrace = StaticUtils.stackTraceToSingleLineString(e);
      if (debugEnabled())
      {
        TRACER.debugInfo(
            "Base64 decode failed for dn '%s', exception stacktrace: %s",
            encodedStr, stackTrace);
      }
      Message message = ERR_LDIF_COULD_NOT_BASE64_DECODE_DN.get(
          lastEntryLineNumber, line, stackTrace);
      logToRejectWriter(lines, message);
      throw new LDIFException(message, lastEntryLineNumber, true, e);
    }
  }
  private DN decodeDN(String dnString, List<StringBuilder> lines,
      StringBuilder line) throws LDIFException
  {
    try
    {
      return DN.decode(dnString);
    }
    catch (DirectoryException de)
    {
      if (debugEnabled())
      {
        TRACER.debugInfo("DN decode failed for: ", dnString);
      }
      Message message = ERR_LDIF_INVALID_DN.get(
              lastEntryLineNumber, line.toString(),
              de.getMessageObject());
      logToRejectWriter(lines, message);
      throw new LDIFException(message, lastEntryLineNumber, true, de);
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugInfo("DN decode failed for: ", dnString);
      }
      Message message = ERR_LDIF_INVALID_DN.get(
              lastEntryLineNumber, line.toString(),
              String.valueOf(e));
      logToRejectWriter(lines, message);
      throw new LDIFException(message, lastEntryLineNumber, true, e);
    }
  }
  /**
   * Reads the changetype of the entry from the provided list of lines.  If
@@ -1025,11 +989,9 @@
    {
      // No changetype attribute - return null
      return null;
    } else
    {
      // Remove the line
      lines.remove();
    }
    // Remove the line
    lines.remove();
    // Look at the character immediately after the colon.  If there is none,
@@ -1044,51 +1006,16 @@
    if (line.charAt(colonPos+1) == ':')
    {
      // The change type is base64-encoded.  Find the first non-blank
      // character and
      // take the rest of the line, and base64-decode it.
      int pos = colonPos+2;
      while ((pos < length) && (line.charAt(pos) == ' '))
      {
        pos++;
      }
      String encodedChangeTypeStr = line.substring(pos);
      String changeTypeStr;
      try
      {
        changeTypeStr = new String(Base64.decode(encodedChangeTypeStr),
            "UTF-8");
      }
      catch (Exception e)
      {
        // The value did not have a valid base64-encoding.
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        Message message = ERR_LDIF_COULD_NOT_BASE64_DECODE_DN.get(
                lastEntryLineNumber, line,
                String.valueOf(e));
        logToRejectWriter(lines, message);
        throw new LDIFException(message, lastEntryLineNumber, true, e);
      }
      return changeTypeStr;
      // The change type is base64-encoded.  Find the first non-blank character
      // and take the rest of the line, and base64-decode it.
      int pos = findFirstNonSpaceCharPosition(line, colonPos + 2);
      return base64Decode(line.substring(pos), lines, line);
    }
    else
    {
      // The rest of the value should be the changetype.
      // Skip over any spaces and
      // attempt to decode the rest of the line as the changetype string.
      int pos = colonPos+1;
      while ((pos < length) && (line.charAt(pos) == ' '))
      {
        pos++;
      }
      // The rest of the value should be the changetype. Skip over any spaces
      // and attempt to decode the rest of the line as the changetype string.
      int pos = findFirstNonSpaceCharPosition(line, colonPos + 1);
      return line.substring(pos);
    }
  }
@@ -1215,40 +1142,30 @@
          else
          {
            logToRejectWriter(lines, message);
            throw new LDIFException(message, lastEntryLineNumber,
                                    true);
            throw new LDIFException(message, lastEntryLineNumber, true);
          }
        }
      }
      AttributeValue attributeValue =
          AttributeValues.create(attrType, value);
      List<AttributeBuilder> attrList;
      AttributeValue attributeValue = AttributeValues.create(attrType, value);
      final Map<AttributeType, List<AttributeBuilder>> attrBuilders;
      if (attrType.isOperational())
      {
        attrList = operationalAttrBuilders.get(attrType);
        if (attrList == null)
        {
          AttributeBuilder builder = new AttributeBuilder(attribute, true);
          builder.add(attributeValue);
          attrList = new ArrayList<AttributeBuilder>();
          attrList.add(builder);
          operationalAttrBuilders.put(attrType, attrList);
          return;
        }
        attrBuilders = operationalAttrBuilders;
      }
      else
      {
        attrList = userAttrBuilders.get(attrType);
        if (attrList == null)
        {
          AttributeBuilder builder = new AttributeBuilder(attribute, true);
          builder.add(attributeValue);
          attrList = new ArrayList<AttributeBuilder>();
          attrList.add(builder);
          userAttrBuilders.put(attrType, attrList);
          return;
        }
        attrBuilders = userAttrBuilders;
      }
      List<AttributeBuilder> attrList = attrBuilders.get(attrType);
      if (attrList == null)
      {
        AttributeBuilder builder = new AttributeBuilder(attribute, true);
        builder.add(attributeValue);
        attrList = new ArrayList<AttributeBuilder>();
        attrList.add(builder);
        attrBuilders.put(attrType, attrList);
        return;
      }
      // Check to see if any of the attributes in the list have the same set of
@@ -1264,8 +1181,7 @@
                      lastEntryLineNumber, attrName,
                      value.toString());
              logToRejectWriter(lines, message);
              throw new LDIFException(message, lastEntryLineNumber,
                      true);
            throw new LDIFException(message, lastEntryLineNumber, true);
          }
          if (attrType.isSingleValue() && (a.size() > 1)  && checkSchema)
          {
@@ -1422,8 +1338,7 @@
          rejectWriter.write(message.toString());
          rejectWriter.newLine();
        }
        String dnStr = e.getDN().toString();
        rejectWriter.write(dnStr);
        rejectWriter.write(e.getDN().toString());
        rejectWriter.newLine();
        List<StringBuilder> eLDIF = e.toLDIF();
        for(StringBuilder l : eLDIF) {
@@ -1710,16 +1625,14 @@
    List<RawModification> modifications = new ArrayList<RawModification>();
    while(!lines.isEmpty())
    {
      ModificationType modType;
      StringBuilder line = lines.remove();
      Attribute attr =
        readSingleValueAttribute(lines, line, entryDN, null);
      Attribute attr = readSingleValueAttribute(lines, line, entryDN, null);
      String name = attr.getName();
      // Get the attribute description
      String attrDescr = attr.iterator().next().getValue().toString();
      ModificationType modType;
      String lowerName = toLowerCase(name);
      if (lowerName.equals("add"))
      {
@@ -1745,8 +1658,7 @@
        throw new LDIFException(message, lineNumber, true);
      }
      // Now go through the rest of the attributes till the "-" line is
      // reached.
      // Now go through the rest of the attributes till the "-" line is reached.
      Attribute modAttr = LDIFReader.parseAttrDescription(attrDescr);
      AttributeBuilder builder = new AttributeBuilder(modAttr, true);
      while (! lines.isEmpty())
@@ -1821,8 +1733,7 @@
    AttributeType ocType = DirectoryServer.getObjectClassAttributeType();
    AttributeBuilder builder = new AttributeBuilder(ocType, "objectClass");
    for (String value : objectClasses.values()) {
      AttributeValue av = AttributeValues.create(ocType, value);
      builder.add(av);
      builder.add(AttributeValues.create(ocType, value));
    }
    Map<AttributeType, List<Attribute>> attributes =
        toAttributesMap(attrBuilders);
@@ -1851,7 +1762,6 @@
   */
  private int parseColonPosition(List<StringBuilder> lines,
      StringBuilder line) throws LDIFException {
    int colonPos = line.indexOf(":");
    if (colonPos <= 0)
    {
@@ -1906,11 +1816,7 @@
      {
        // The value is base64-encoded. Find the first non-blank
        // character, take the rest of the line, and base64-decode it.
        int pos = colonPos+2;
        while ((pos < length) && (line.charAt(pos) == ' '))
        {
          pos++;
        }
        int pos = findFirstNonSpaceCharPosition(line, colonPos + 2);
        try
        {
@@ -1936,11 +1842,7 @@
      {
        // Find the first non-blank character, decode the rest of the
        // line as a URL, and read its contents.
        int pos = colonPos+2;
        while ((pos < length) && (line.charAt(pos) == ' '))
        {
          pos++;
        }
        int pos = findFirstNonSpaceCharPosition(line, colonPos + 2);
        URL contentURL;
        try
@@ -1976,8 +1878,7 @@
        }
        catch (Exception e)
        {
          // We were unable to read the contents of that URL for some
          // reason.
          // We were unable to read the contents of that URL for some reason.
          if (debugEnabled())
          {
            TRACER.debugCaught(DebugLogLevel.ERROR, e);
@@ -2000,12 +1901,7 @@
      {
        // The rest of the line should be the value. Skip over any
        // spaces and take the rest of the line as the value.
        int pos = colonPos+1;
        while ((pos < length) && (line.charAt(pos) == ' '))
        {
          pos++;
        }
        int pos = findFirstNonSpaceCharPosition(line, colonPos + 1);
        value = ByteString.valueOf(line.substring(pos));
      }
    }
@@ -2154,4 +2050,3 @@
    }
  }
}
opends/src/server/org/opends/server/util/LDIFWriter.java
@@ -27,15 +27,13 @@
 */
package org.opends.server.util;
import java.io.BufferedWriter;
import java.io.Closeable;
import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;
import java.util.Collection;
import org.opends.messages.Message;
import org.opends.server.tools.makeldif.TemplateEntry;
@@ -44,7 +42,6 @@
import static org.opends.server.util.StaticUtils.*;
import static org.opends.server.util.Validator.*;
/**
 * This class provides a mechanism for writing entries in LDIF form to a file or
 * an output stream.
@@ -59,15 +56,13 @@
  // FIXME -- Add support for generating a hash when writing the data.
  // FIXME -- Add support for signing the hash that is generated.
  // The writer to which the LDIF information will be written.
  /** The writer to which the LDIF information will be written. */
  private BufferedWriter writer;
  // The configuration to use for the export.
  /** The configuration to use for the export. */
  private LDIFExportConfig exportConfig;
  // Regular expression used for splitting comments on line-breaks.
  /** Regular expression used for splitting comments on line-breaks. */
  private static final Pattern SPLIT_NEWLINE = Pattern.compile("\\r?\\n");
@@ -151,7 +146,7 @@
outerLoop:
          while (startPos < l.length())
          {
            if ((startPos+breakColumn) >= l.length())
            if (startPos + breakColumn >= l.length())
            {
              writer.write("# ");
@@ -210,15 +205,17 @@
 * @throws LDIFException If a problem occurs while trying to determine
 *                         whether to include the entry in the export.
 */
public boolean writeEntries(Collection <Entry> entries)
  throws IOException, LDIFException {
     boolean ret=true;
     Iterator<Entry> i = entries.iterator();
     while(ret && i.hasNext()) {
         ret=writeEntry(i.next());
     }
      return ret;
  public boolean writeEntries(Collection<Entry> entries) throws IOException,
      LDIFException
  {
    for (Entry entry : entries)
    {
      if (!writeEntry(entry))
      {
        return false;
      }
    }
    return true;
  }
@@ -265,8 +262,6 @@
  throws IOException, LDIFException
  {
    ensureNotNull(templateEntry);
    //  Delegate to TemplateEntry.toLDIF(...)
    return templateEntry.toLDIF(exportConfig);
  }
@@ -286,15 +281,11 @@
    // Get the information necessary to write the LDIF.
    BufferedWriter writer     = exportConfig.getWriter();
    int            wrapColumn = exportConfig.getWrapColumn();
    boolean        wrapLines  = (wrapColumn > 1);
    boolean        wrapLines  = wrapColumn > 1;
    // First, write the DN.
    StringBuilder dnLine = new StringBuilder();
    dnLine.append("dn");
    appendLDIFSeparatorAndValue(dnLine,
        ByteString.valueOf(changeRecord.getDN().toString()));
    writeLDIFLine(dnLine, writer, wrapLines, wrapColumn);
    writeDN("dn", changeRecord.getDN(), writer, wrapLines, wrapColumn);
    // Figure out what type of change it is and act accordingly.
@@ -308,10 +299,8 @@
      {
        for (AttributeValue v : a)
        {
          StringBuilder line = new StringBuilder();
          line.append(a.getNameWithOptions());
          appendLDIFSeparatorAndValue(line, v.getValue());
          writeLDIFLine(line, writer, wrapLines, wrapColumn);
          final String attrName = a.getNameWithOptions();
          writeAttribute(attrName, v, writer, wrapLines, wrapColumn);
        }
      }
    }
@@ -342,10 +331,9 @@
        for (ByteString s : a.getValues())
        {
          StringBuilder valueLine = new StringBuilder();
          StringBuilder valueLine = new StringBuilder(attrName);
          String stringValue = s.toString();
          valueLine.append(attrName);
          if (needsBase64Encoding(stringValue))
          {
            valueLine.append(":: ");
@@ -375,28 +363,18 @@
      ModifyDNChangeRecordEntry modifyDNRecord =
           (ModifyDNChangeRecordEntry) changeRecord;
      StringBuilder newRDNLine = new StringBuilder();
      newRDNLine.append("newrdn: ");
      StringBuilder newRDNLine = new StringBuilder("newrdn: ");
      modifyDNRecord.getNewRDN().toString(newRDNLine);
      writeLDIFLine(newRDNLine, writer, wrapLines, wrapColumn);
      StringBuilder deleteOldRDNLine = new StringBuilder();
      deleteOldRDNLine.append("deleteoldrdn: ");
      if (modifyDNRecord.deleteOldRDN())
      {
        deleteOldRDNLine.append("1");
      }
      else
      {
        deleteOldRDNLine.append("0");
      }
      StringBuilder deleteOldRDNLine = new StringBuilder("deleteoldrdn: ");
      deleteOldRDNLine.append(modifyDNRecord.deleteOldRDN() ? "1" : "0");
      writeLDIFLine(deleteOldRDNLine, writer, wrapLines, wrapColumn);
      DN newSuperiorDN = modifyDNRecord.getNewSuperiorDN();
      if (newSuperiorDN != null)
      {
        StringBuilder newSuperiorLine = new StringBuilder();
        newSuperiorLine.append("newsuperior: ");
        StringBuilder newSuperiorLine = new StringBuilder("newsuperior: ");
        newSuperiorDN.toString(newSuperiorLine);
        writeLDIFLine(newSuperiorLine, writer, wrapLines, wrapColumn);
      }
@@ -428,15 +406,11 @@
    // Get the information necessary to write the LDIF.
    BufferedWriter writer     = exportConfig.getWriter();
    int            wrapColumn = exportConfig.getWrapColumn();
    boolean        wrapLines  = (wrapColumn > 1);
    boolean        wrapLines  = wrapColumn > 1;
    // First, write the DN.
    StringBuilder dnLine = new StringBuilder();
    dnLine.append("dn");
    appendLDIFSeparatorAndValue(dnLine,
        ByteString.valueOf(entry.getDN().toString()));
    writeLDIFLine(dnLine, writer, wrapLines, wrapColumn);
    writeDN("dn", entry.getDN(), writer, wrapLines, wrapColumn);
    // Next, the changetype.
@@ -457,8 +431,7 @@
    // Finally, the set of user attributes.
    for (AttributeType attrType : entry.getUserAttributes().keySet())
    {
      List<Attribute> attrList = entry.getUserAttribute(attrType);
      for (Attribute a : attrList)
      for (Attribute a : entry.getUserAttribute(attrType))
      {
        StringBuilder attrName = new StringBuilder(a.getName());
        for (String o : a.getOptions())
@@ -469,10 +442,7 @@
        for (AttributeValue v : a)
        {
          StringBuilder attrLine = new StringBuilder();
          attrLine.append(attrName);
          appendLDIFSeparatorAndValue(attrLine, v.getValue());
          writeLDIFLine(attrLine, writer, wrapLines, wrapColumn);
          writeAttribute(attrName, v, writer, wrapLines, wrapColumn);
        }
      }
    }
@@ -505,15 +475,11 @@
    // Get the information necessary to write the LDIF.
    BufferedWriter writer     = exportConfig.getWriter();
    int            wrapColumn = exportConfig.getWrapColumn();
    boolean        wrapLines  = (wrapColumn > 1);
    boolean        wrapLines  = wrapColumn > 1;
    // Add the DN and changetype lines.
    StringBuilder dnLine = new StringBuilder();
    dnLine.append("dn");
    appendLDIFSeparatorAndValue(dnLine,
        ByteString.valueOf(entry.getDN().toString()));
    writeLDIFLine(dnLine, writer, wrapLines, wrapColumn);
    writeDN("dn", entry.getDN(), writer, wrapLines, wrapColumn);
    StringBuilder changeTypeLine = new StringBuilder("changetype: delete");
    writeLDIFLine(changeTypeLine, writer, wrapLines, wrapColumn);
@@ -535,8 +501,7 @@
      // Write the set of user attributes.
      for (AttributeType attrType : entry.getUserAttributes().keySet())
      {
        List<Attribute> attrList = entry.getUserAttribute(attrType);
        for (Attribute a : attrList)
        for (Attribute a : entry.getUserAttribute(attrType))
        {
          StringBuilder attrName = new StringBuilder();
          attrName.append("# ");
@@ -549,10 +514,7 @@
          for (AttributeValue v : a)
          {
            StringBuilder attrLine = new StringBuilder();
            attrLine.append(attrName);
            appendLDIFSeparatorAndValue(attrLine, v.getValue());
            writeLDIFLine(attrLine, writer, wrapLines, wrapColumn);
            writeAttribute(attrName, v, writer, wrapLines, wrapColumn);
          }
        }
      }
@@ -591,14 +553,11 @@
    // Get the information necessary to write the LDIF.
    BufferedWriter writer     = exportConfig.getWriter();
    int            wrapColumn = exportConfig.getWrapColumn();
    boolean        wrapLines  = (wrapColumn > 1);
    boolean        wrapLines  = wrapColumn > 1;
    // Write the DN and changetype.
    StringBuilder dnLine = new StringBuilder();
    dnLine.append("dn");
    appendLDIFSeparatorAndValue(dnLine, ByteString.valueOf(dn.toString()));
    writeLDIFLine(dnLine, writer, wrapLines, wrapColumn);
    writeDN("dn", dn, writer, wrapLines, wrapColumn);
    StringBuilder changeTypeLine = new StringBuilder("changetype: modify");
    writeLDIFLine(changeTypeLine, writer, wrapLines, wrapColumn);
@@ -620,36 +579,14 @@
      String  name = nameBuffer.toString();
      StringBuilder modTypeLine = new StringBuilder();
      switch (m.getModificationType())
      {
        case ADD:
          modTypeLine.append("add: ");
          modTypeLine.append(name);
          break;
        case DELETE:
          modTypeLine.append("delete: ");
          modTypeLine.append(name);
          break;
        case REPLACE:
          modTypeLine.append("replace: ");
          modTypeLine.append(name);
          break;
        case INCREMENT:
          modTypeLine.append("increment: ");
          modTypeLine.append(name);
          break;
        default:
          // We have no idea what the changetype is, so we can't write anything.
          continue;
      }
      modTypeLine.append(m.getModificationType().getLDIFName());
      modTypeLine.append(": ");
      modTypeLine.append(name);
      writeLDIFLine(modTypeLine, writer, wrapLines, wrapColumn);
      for (AttributeValue v : a)
      {
        StringBuilder valueLine = new StringBuilder();
        valueLine.append(name);
        appendLDIFSeparatorAndValue(valueLine, v.getValue());
        writeLDIFLine(valueLine, writer, wrapLines, wrapColumn);
        writeAttribute(name, v, writer, wrapLines, wrapColumn);
      }
@@ -658,12 +595,8 @@
      if (iterator.hasNext())
      {
        writer.write("-");
        writer.newLine();
      }
      else
      {
        writer.newLine();
      }
      writer.newLine();
    }
  }
@@ -695,14 +628,11 @@
    // Get the information necessary to write the LDIF.
    BufferedWriter writer     = exportConfig.getWriter();
    int            wrapColumn = exportConfig.getWrapColumn();
    boolean        wrapLines  = (wrapColumn > 1);
    boolean        wrapLines  = wrapColumn > 1;
    // Write the current DN.
    StringBuilder dnLine = new StringBuilder();
    dnLine.append("dn");
    appendLDIFSeparatorAndValue(dnLine, ByteString.valueOf(dn.toString()));
    writeLDIFLine(dnLine, writer, wrapLines, wrapColumn);
    writeDN("dn", dn, writer, wrapLines, wrapColumn);
    // Write the changetype.  Some older tools may not support the "moddn"
@@ -721,8 +651,7 @@
    // Write the newRDN element.
    StringBuilder rdnLine = new StringBuilder();
    rdnLine.append("newrdn");
    StringBuilder rdnLine = new StringBuilder("newrdn");
    appendLDIFSeparatorAndValue(rdnLine, ByteString.valueOf(newRDN.toString()));
    writeLDIFLine(rdnLine, writer, wrapLines, wrapColumn);
@@ -735,11 +664,7 @@
    if (newSuperior != null)
    {
      StringBuilder newSuperiorLine = new StringBuilder();
      newSuperiorLine.append("newsuperior");
      appendLDIFSeparatorAndValue(newSuperiorLine,
          ByteString.valueOf(newSuperior.toString()));
      writeLDIFLine(newSuperiorLine, writer, wrapLines, wrapColumn);
      writeDN("newsuperior", newSuperior, writer, wrapLines, wrapColumn);
    }
@@ -747,7 +672,22 @@
    writer.newLine();
  }
  private void writeDN(String attrType, DN dn, BufferedWriter writer,
      boolean wrapLines, int wrapColumn) throws IOException
  {
    final StringBuilder newLine = new StringBuilder(attrType);
    appendLDIFSeparatorAndValue(newLine, ByteString.valueOf(dn.toString()));
    writeLDIFLine(newLine, writer, wrapLines, wrapColumn);
  }
  private void writeAttribute(CharSequence attrName, AttributeValue v,
      BufferedWriter writer, boolean wrapLines, int wrapColumn)
      throws IOException
  {
    StringBuilder newLine = new StringBuilder(attrName);
    appendLDIFSeparatorAndValue(newLine, v.getValue());
    writeLDIFLine(newLine, writer, wrapLines, wrapColumn);
  }
  /**
   * Flushes the data written to the output stream or underlying file.
@@ -767,6 +707,7 @@
   *
   * @throws  IOException  If a problem occurs while closing the writer.
   */
  @Override
  public void close()
         throws IOException
  {
@@ -815,32 +756,22 @@
    // If the value is empty, then just append a single colon (the URL '<' if
    // required) and a single space.
    if ((valueBytes == null) || (valueBytes.length() == 0))
    {
      if (isURL)
      {
        buffer.append(":< ");
      }
      else if (isBase64)
      {
        buffer.append(":: ");
      }
      else
      {
        buffer.append(": ");
      }
      return;
    }
    final boolean valueIsEmpty = valueBytes == null || valueBytes.length() == 0;
    if (isURL)
    {
      buffer.append(":< ");
      buffer.append(valueBytes.toString());
      if (!valueIsEmpty)
      {
        buffer.append(valueBytes.toString());
      }
    }
    else if (isBase64)
    {
      buffer.append(":: ");
      buffer.append(valueBytes.toString());
      if (!valueIsEmpty)
      {
        buffer.append(valueBytes.toString());
      }
    }
    else if (needsBase64Encoding(valueBytes))
    {
@@ -850,7 +781,10 @@
    else
    {
      buffer.append(": ");
      buffer.append(valueBytes.toString());
      if (!valueIsEmpty)
      {
        buffer.append(valueBytes.toString());
      }
    }
  }
@@ -875,7 +809,7 @@
    ensureNotNull(line, writer);
    int length = line.length();
    if (wrapLines && (length > wrapColumn))
    if (wrapLines && length > wrapColumn)
    {
      writer.write(line.substring(0, wrapColumn));
      writer.newLine();
@@ -898,4 +832,3 @@
    }
  }
}