From ad8075db9d1ed81528a069d446c27c7e2edbf1d9 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Mon, 11 Sep 2006 17:03:04 +0000
Subject: [PATCH] Implement a test suite for the LDIFReader class. Performed refactoring to reduce the amount of code duplication and improve the coupling between the LDIFReader class and the ChangeRecordEntry classes.
---
opendj-sdk/opends/src/server/org/opends/server/util/LDIFReader.java | 1833 +++++++++++++++++++---------------------------------------
1 files changed, 611 insertions(+), 1,222 deletions(-)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/util/LDIFReader.java b/opendj-sdk/opends/src/server/org/opends/server/util/LDIFReader.java
index b5d93d0..ed42f27 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/util/LDIFReader.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/util/LDIFReader.java
@@ -28,11 +28,17 @@
+import static org.opends.server.loggers.Debug.*;
+import static org.opends.server.loggers.Error.logError;
+import static org.opends.server.messages.MessageHandler.getMessage;
+import static org.opends.server.messages.UtilityMessages.*;
+import static org.opends.server.util.StaticUtils.toLowerCase;
+
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
@@ -45,25 +51,22 @@
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.PluginConfigManager;
import org.opends.server.protocols.asn1.ASN1OctetString;
+import org.opends.server.protocols.ldap.LDAPAttribute;
+import org.opends.server.protocols.ldap.LDAPModification;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
+import org.opends.server.types.DN;
import org.opends.server.types.DebugLogCategory;
import org.opends.server.types.DebugLogSeverity;
-import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.ErrorLogCategory;
import org.opends.server.types.ErrorLogSeverity;
import org.opends.server.types.LDIFImportConfig;
+import org.opends.server.types.ModificationType;
import org.opends.server.types.ObjectClass;
import org.opends.server.types.RDN;
-import static org.opends.server.loggers.Debug.*;
-import static org.opends.server.loggers.Error.*;
-import static org.opends.server.messages.MessageHandler.*;
-import static org.opends.server.messages.UtilityMessages.*;
-import static org.opends.server.util.StaticUtils.*;
-
/**
@@ -71,7 +74,7 @@
* provides support for both standard entries and change entries (as would be
* used with a tool like ldapmodify).
*/
-public class LDIFReader
+public final class LDIFReader
{
/**
* The fully-qualified name of this class for debugging purposes.
@@ -310,28 +313,7 @@
String message = getMessage(msgID, String.valueOf(entryDN),
lastEntryLineNumber,
invalidReason.toString());
-
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "readEntry", e);
- }
- }
-
+ logToRejectWriter(lines, message);
entriesRejected++;
throw new LDIFException(msgID, message, lastEntryLineNumber, true);
}
@@ -391,19 +373,19 @@
{
if(changeType.equals("add"))
{
- entry = new AddChangeRecordEntry(entryDN, this);
+ entry = parseAddChangeRecordEntry(entryDN, lines);
} else if (changeType.equals("delete"))
{
- entry = new DeleteChangeRecordEntry(entryDN, this);
+ entry = parseDeleteChangeRecordEntry(entryDN, lines);
} else if (changeType.equals("modify"))
{
- entry = new ModifyChangeRecordEntry(entryDN, this);
+ entry = parseModifyChangeRecordEntry(entryDN, lines);
} else if (changeType.equals("modrdn"))
{
- entry = new ModifyDNChangeRecordEntry(entryDN, this);
+ entry = parseModifyDNChangeRecordEntry(entryDN, lines);
} else if (changeType.equals("moddn"))
{
- entry = new ModifyDNChangeRecordEntry(entryDN, this);
+ entry = parseModifyDNChangeRecordEntry(entryDN, lines);
} else
{
int msgID = MSGID_LDIF_INVALID_CHANGETYPE_ATTRIBUTE;
@@ -416,7 +398,7 @@
// default to "add"?
if(defaultAdd)
{
- entry = new AddChangeRecordEntry(entryDN, this);
+ entry = parseAddChangeRecordEntry(entryDN, lines);
} else
{
int msgID = MSGID_LDIF_INVALID_CHANGETYPE_ATTRIBUTE;
@@ -426,16 +408,12 @@
}
}
- // Parse the lines to populate the change record entry data structures.
- entry.parse(lines, lastEntryLineNumber);
-
return entry;
}
}
-
/**
* Reads a set of lines from the next entry in the LDIF source.
*
@@ -512,23 +490,7 @@
{
int msgID = MSGID_LDIF_INVALID_LEADING_SPACE;
String message = getMessage(msgID, lineNumber, line);
-
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.write(line);
- rejectWriter.newLine();
- rejectWriter.newLine();
- }
-
+ logToRejectWriter(lines, message);
throw new LDIFException(msgID, message, lineNumber, false);
}
}
@@ -584,26 +546,7 @@
int msgID = MSGID_LDIF_NO_ATTR_NAME;
String message = getMessage(msgID, lastEntryLineNumber, line.toString());
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "readDN", e);
- }
- }
+ logToRejectWriter(lines, message);
throw new LDIFException(msgID, message, lastEntryLineNumber, true);
}
@@ -619,26 +562,7 @@
int msgID = MSGID_LDIF_NO_DN;
String message = getMessage(msgID, lastEntryLineNumber, line.toString());
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "readDN", e);
- }
- }
+ logToRejectWriter(lines, message);
throw new LDIFException(msgID, message, lastEntryLineNumber, true);
}
@@ -679,26 +603,7 @@
String message = getMessage(msgID, lastEntryLineNumber, line,
String.valueOf(e));
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e2)
- {
- assert debugException(CLASS_NAME, "readDN", e2);
- }
- }
+ logToRejectWriter(lines, message);
throw new LDIFException(msgID, message, lastEntryLineNumber, true, e);
}
@@ -715,26 +620,7 @@
String message = getMessage(msgID, lastEntryLineNumber, line.toString(),
de.getErrorMessage());
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "readDN", e);
- }
- }
+ logToRejectWriter(lines, message);
throw new LDIFException(msgID, message, lastEntryLineNumber, true, de);
}
@@ -746,26 +632,7 @@
String message = getMessage(msgID, lastEntryLineNumber, line.toString(),
String.valueOf(e));
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e2)
- {
- assert debugException(CLASS_NAME, "readDN", e2);
- }
- }
+ logToRejectWriter(lines, message);
throw new LDIFException(msgID, message, lastEntryLineNumber, true, e);
}
@@ -794,26 +661,7 @@
String message = getMessage(msgID, lastEntryLineNumber, line.toString(),
de.getErrorMessage());
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "readDN", e);
- }
- }
+ logToRejectWriter(lines, message);
throw new LDIFException(msgID, message, lastEntryLineNumber, true, de);
}
@@ -825,26 +673,7 @@
String message = getMessage(msgID, lastEntryLineNumber, line.toString(),
String.valueOf(e));
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e2)
- {
- assert debugException(CLASS_NAME, "readDN", e2);
- }
- }
+ logToRejectWriter(lines, message);
throw new LDIFException(msgID, message, lastEntryLineNumber, true, e);
}
@@ -852,6 +681,7 @@
}
+
/**
* Reads the changetype of the entry from the provided list of lines. If
* there is no changetype attribute then an add is assumed.
@@ -882,28 +712,7 @@
{
int msgID = MSGID_LDIF_NO_ATTR_NAME;
String message = getMessage(msgID, lastEntryLineNumber, line.toString());
-
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "readChangeType", e);
- }
- }
-
+ logToRejectWriter(lines, message);
throw new LDIFException(msgID, message, lastEntryLineNumber, true);
}
@@ -915,7 +724,7 @@
} else
{
// Remove the line
- StringBuilder ln = lines.remove();
+ lines.remove();
}
@@ -957,28 +766,7 @@
int msgID = MSGID_LDIF_COULD_NOT_BASE64_DECODE_DN;
String message = getMessage(msgID, lastEntryLineNumber, line,
String.valueOf(e));
-
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e2)
- {
- assert debugException(CLASS_NAME, "readChangeType", e2);
- }
- }
-
+ logToRejectWriter(lines, message);
throw new LDIFException(msgID, message, lastEntryLineNumber, true, e);
}
@@ -1027,270 +815,24 @@
HashMap<AttributeType,List<Attribute>> operationalAttributes)
throws LDIFException
{
- assert debugEnter(CLASS_NAME, "readAttribute", String.valueOf(line),
- String.valueOf(entryDN), String.valueOf(objectClasses),
- String.valueOf(userAttributes),
- String.valueOf(operationalAttributes));
+ assert debugEnter(CLASS_NAME, "readAttribute",
+ String.valueOf(line),
+ String.valueOf(entryDN),
+ String.valueOf(objectClasses),
+ String.valueOf(userAttributes),
+ String.valueOf(operationalAttributes));
-
- int colonPos = line.indexOf(":");
- if (colonPos <= 0)
- {
- int msgID = MSGID_LDIF_NO_ATTR_NAME;
- String message = getMessage(msgID, lastEntryLineNumber, line.toString());
-
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "readAttribute", e);
- }
- }
-
- throw new LDIFException(msgID, message, lastEntryLineNumber, true);
- }
-
- LinkedHashSet<String> options;
- String attrName = line.substring(0, colonPos);
- int semicolonPos = attrName.indexOf(';');
- if (semicolonPos > 0)
- {
- options = new LinkedHashSet<String>();
- int nextPos = attrName.indexOf(';', semicolonPos+1);
- while (nextPos > 0)
- {
- String option = attrName.substring(semicolonPos+1, nextPos);
- if (option.length() > 0)
- {
- options.add(option);
- semicolonPos = nextPos;
- nextPos = attrName.indexOf(';', semicolonPos+1);
- }
- }
-
- String option = attrName.substring(semicolonPos+1);
- if (option.length() > 0)
- {
- options.add(option);
- }
-
- attrName = attrName.substring(0, attrName.indexOf(';'));
- }
- else
- {
- options = null;
- }
+ // Parse the attribute type description.
+ int colonPos = parseColonPosition(lines, line);
+ String attrDescr = line.substring(0, colonPos);
+ Attribute attribute = parseAttrDescription(attrDescr);
+ String attrName = attribute.getName();
String lowerName = toLowerCase(attrName);
+ LinkedHashSet<String> options = attribute.getOptions();
-
- // Look at the character immediately after the colon. If there is none,
- // then assume an attribute with an empty value. If it is another colon,
- // then the value must be base64-encoded. If it is a less-than sign, then
- // assume that it is a URL. Otherwise, it is a regular value.
- int length = line.length();
- ASN1OctetString value;
- if (colonPos == (length-1))
- {
- value = new ASN1OctetString();
- }
- else
- {
- char c = line.charAt(colonPos+1);
- if (c == ':')
- {
- // 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++;
- }
-
- try
- {
- value = new ASN1OctetString(Base64.decode(line.substring(pos)));
- }
- catch (Exception e)
- {
- // The value did not have a valid base64-encoding.
- assert debugException(CLASS_NAME, "readAttribute", e);
-
- int msgID = MSGID_LDIF_COULD_NOT_BASE64_DECODE_ATTR;
- String message = getMessage(msgID, String.valueOf(entryDN),
- lastEntryLineNumber, line,
- String.valueOf(e));
-
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e2)
- {
- assert debugException(CLASS_NAME, "readAttribute", e2);
- }
- }
-
- throw new LDIFException(msgID, message, lastEntryLineNumber, true, e);
- }
- }
- else if (c == '<')
- {
- // 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++;
- }
-
- URL contentURL;
- try
- {
- contentURL = new URL(line.substring(pos));
- }
- catch (Exception e)
- {
- // The URL was malformed or had an invalid protocol.
- assert debugException(CLASS_NAME, "readAttribute", e);
-
- int msgID = MSGID_LDIF_INVALID_URL;
- String message = getMessage(msgID, String.valueOf(entryDN),
- lastEntryLineNumber,
- String.valueOf(attrName),
- String.valueOf(e));
-
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e2)
- {
- assert debugException(CLASS_NAME, "readAttribute", e2);
- }
- }
-
- throw new LDIFException(msgID, message, lastEntryLineNumber, true, e);
- }
-
-
- InputStream inputStream = null;
- ByteArrayOutputStream outputStream = null;
- try
- {
- outputStream = new ByteArrayOutputStream();
- inputStream = contentURL.openConnection().getInputStream();
-
- int bytesRead;
- while ((bytesRead = inputStream.read(buffer)) > 0)
- {
- outputStream.write(buffer, 0, bytesRead);
- }
-
- value = new ASN1OctetString(outputStream.toByteArray());
- }
- catch (Exception e)
- {
- // We were unable to read the contents of that URL for some reason.
- assert debugException(CLASS_NAME, "readAttribute", e);
-
- int msgID = MSGID_LDIF_URL_IO_ERROR;
- String message = getMessage(msgID, String.valueOf(entryDN),
- lastEntryLineNumber,
- String.valueOf(attrName),
- String.valueOf(contentURL),
- String.valueOf(e));
-
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e2)
- {
- assert debugException(CLASS_NAME, "readAttribute", e2);
- }
- }
-
- throw new LDIFException(msgID, message, lastEntryLineNumber, true, e);
- }
- finally
- {
- if (outputStream != null)
- {
- try
- {
- outputStream.close();
- } catch (Exception e) {}
- }
-
- if (inputStream != null)
- {
- try
- {
- inputStream.close();
- } catch (Exception e) {}
- }
- }
- }
- else
- {
- // 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++;
- }
-
- value = new ASN1OctetString(line.substring(pos));
- }
- }
-
+ // Now parse the attribute value.
+ ASN1OctetString value = parseSingleValue(lines, line, entryDN,
+ colonPos, attrName);
// See if this is an objectclass or an attribute. Then get the
// corresponding definition and add the value to the appropriate hash.
@@ -1348,45 +890,7 @@
}
- AttributeValue attributeValue;
- try
- {
- attributeValue = new AttributeValue(attrType, value);
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "readAttribute", e);
-
- int msgID = MSGID_LDIF_INVALID_ATTR_SYNTAX;
- String message = getMessage(msgID, String.valueOf(entryDN),
- lastEntryLineNumber, value.stringValue(),
- attrName, String.valueOf(e));
-
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e2)
- {
- assert debugException(CLASS_NAME, "readAttribute", e2);
- }
- }
-
- throw new LDIFException(msgID, message, lastEntryLineNumber, true, e);
- }
-
-
+ AttributeValue attributeValue = new AttributeValue(attrType, value);
List<Attribute> attrList;
if (attrType.isOperational())
{
@@ -1433,28 +937,7 @@
String message = getMessage(msgID, String.valueOf(entryDN),
lastEntryLineNumber, attrName,
value.stringValue());
-
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "readAttribute", e);
- }
- }
-
+ logToRejectWriter(lines, message);
throw new LDIFException(msgID, message, lastEntryLineNumber, true);
}
else if (attrType.isSingleValue() && (! valueSet.isEmpty()))
@@ -1462,28 +945,7 @@
int msgID = MSGID_LDIF_MULTIPLE_VALUES_FOR_SINGLE_VALUED_ATTR;
String message = getMessage(msgID, String.valueOf(entryDN),
lastEntryLineNumber, attrName);
-
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "readAttribute", e);
- }
- }
-
+ logToRejectWriter(lines, message);
throw new LDIFException(msgID, message, lastEntryLineNumber, true);
}
else
@@ -1506,367 +968,6 @@
}
- /**
- * Decodes the provided line as an LDIF attribute and adds it to the
- * appropriate hash.
- *
- * @param lines The full set of lines that comprise the
- * entry (used for writing reject information).
- * @param line The line to decode.
- * @param entryDN The DN of the entry being decoded.
- * @param entryAttributes The set of attributes decoded so far
- * for the current entry.
- *
- * @throws LDIFException If a problem occurs while trying to decode the
- * attribute contained in the provided entry.
- */
- public void readAttribute(LinkedList<StringBuilder> lines,
- StringBuilder line, DN entryDN,
- HashMap<AttributeType,ArrayList<Attribute>> entryAttributes)
- throws LDIFException
- {
- assert debugEnter(CLASS_NAME, "readAttribute", String.valueOf(line),
- String.valueOf(entryDN),
- String.valueOf(entryAttributes));
-
-
- int colonPos = line.indexOf(":");
- if (colonPos <= 0)
- {
- int msgID = MSGID_LDIF_NO_ATTR_NAME;
- String message = getMessage(msgID, lastEntryLineNumber, line.toString());
-
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "readAttribute", e);
- }
- }
-
- throw new LDIFException(msgID, message, lastEntryLineNumber, true);
- }
-
- String attrDescr = line.substring(0, colonPos);
- Attribute attribute = parseAttrDescription(attrDescr);
- String attrName = attribute.getName();
- LinkedHashSet<String> options = attribute.getOptions();
-
- // Look at the character immediately after the colon. If there is none,
- // then assume an attribute with an empty value. If it is another colon,
- // then the value must be base64-encoded. If it is a less-than sign, then
- // assume that it is a URL. Otherwise, it is a regular value.
- int length = line.length();
- ASN1OctetString value;
- if (colonPos == (length-1))
- {
- value = new ASN1OctetString();
- }
- else
- {
- char c = line.charAt(colonPos+1);
- if (c == ':')
- {
- // 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++;
- }
-
- try
- {
- value = new ASN1OctetString(Base64.decode(line.substring(pos)));
- }
- catch (Exception e)
- {
- // The value did not have a valid base64-encoding.
- assert debugException(CLASS_NAME, "readAttribute", e);
-
- int msgID = MSGID_LDIF_COULD_NOT_BASE64_DECODE_ATTR;
- String message = getMessage(msgID, String.valueOf(entryDN),
- lastEntryLineNumber, line,
- String.valueOf(e));
-
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e2)
- {
- assert debugException(CLASS_NAME, "readAttribute", e2);
- }
- }
-
- throw new LDIFException(msgID, message, lastEntryLineNumber, true, e);
- }
- }
- else if (c == '<')
- {
- // 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++;
- }
-
- URL contentURL;
- try
- {
- contentURL = new URL(line.substring(pos));
- }
- catch (Exception e)
- {
- // The URL was malformed or had an invalid protocol.
- assert debugException(CLASS_NAME, "readAttribute", e);
-
- int msgID = MSGID_LDIF_INVALID_URL;
- String message = getMessage(msgID, String.valueOf(entryDN),
- lastEntryLineNumber,
- String.valueOf(attrName),
- String.valueOf(e));
-
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e2)
- {
- assert debugException(CLASS_NAME, "readAttribute", e2);
- }
- }
-
- throw new LDIFException(msgID, message, lastEntryLineNumber, true, e);
- }
-
-
- InputStream inputStream = null;
- ByteArrayOutputStream outputStream = null;
- try
- {
- outputStream = new ByteArrayOutputStream();
- inputStream = contentURL.openConnection().getInputStream();
-
- int bytesRead;
- while ((bytesRead = inputStream.read(buffer)) > 0)
- {
- outputStream.write(buffer, 0, bytesRead);
- }
-
- value = new ASN1OctetString(outputStream.toByteArray());
- }
- catch (Exception e)
- {
- // We were unable to read the contents of that URL for some reason.
- assert debugException(CLASS_NAME, "readAttribute", e);
-
- int msgID = MSGID_LDIF_URL_IO_ERROR;
- String message = getMessage(msgID, String.valueOf(entryDN),
- lastEntryLineNumber,
- String.valueOf(attrName),
- String.valueOf(contentURL),
- String.valueOf(e));
-
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e2)
- {
- assert debugException(CLASS_NAME, "readAttribute", e2);
- }
- }
-
- throw new LDIFException(msgID, message, lastEntryLineNumber, true, e);
- }
- finally
- {
- if (outputStream != null)
- {
- try
- {
- outputStream.close();
- } catch (Exception e) {}
- }
-
- if (inputStream != null)
- {
- try
- {
- inputStream.close();
- } catch (Exception e) {}
- }
- }
- }
- else
- {
- // 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++;
- }
-
- value = new ASN1OctetString(line.substring(pos));
- }
- }
-
- AttributeType attrType = attribute.getAttributeType();
-
-
- AttributeValue attributeValue;
- try
- {
- attributeValue = new AttributeValue(attrType, value);
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "readAttribute", e);
-
- int msgID = MSGID_LDIF_INVALID_ATTR_SYNTAX;
- String message = getMessage(msgID, String.valueOf(entryDN),
- lastEntryLineNumber, value.stringValue(),
- attrName, String.valueOf(e));
-
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e2)
- {
- assert debugException(CLASS_NAME, "readAttribute", e2);
- }
- }
-
- throw new LDIFException(msgID, message, lastEntryLineNumber, true, e);
- }
-
-
- ArrayList<Attribute> attrList;
- attrList = entryAttributes.get(attrType);
- if (attrList == null)
- {
- attribute.getValues().add(attributeValue);
-
- attrList = new ArrayList<Attribute>();
- attrList.add(attribute);
- entryAttributes.put(attrType, attrList);
- return;
- }
-
-
- // Check to see if any of the attributes in the list have the same set of
- // options. If so, then try to add a value to that attribute.
- for (Attribute a : attrList)
- {
- if (a.optionsEqual(options))
- {
- LinkedHashSet<AttributeValue> valueSet = a.getValues();
- if (valueSet.contains(attributeValue))
- {
- int msgID = MSGID_LDIF_DUPLICATE_ATTR;
- String message = getMessage(msgID, String.valueOf(entryDN),
- lastEntryLineNumber, attrName,
- value.stringValue());
-
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "readAttribute", e);
- }
- }
-
- throw new LDIFException(msgID, message, lastEntryLineNumber, true);
- }
- else
- {
- valueSet.add(attributeValue);
- return;
- }
- }
- }
-
-
- // No set of matching options was found, so create a new one and add it to
- // the list.
- attribute.getValues().add(attributeValue);
- attrList.add(attribute);
- return;
- }
/**
* Decodes the provided line as an LDIF attribute and returns the
@@ -1885,295 +986,36 @@
* entry or if the parsed attribute name does
* not match the specified attribute name.
*/
- public Attribute readSingleValueAttribute(
+ private Attribute readSingleValueAttribute(
LinkedList<StringBuilder> lines, StringBuilder line, DN entryDN,
String attributeName) throws LDIFException
{
- assert debugEnter(CLASS_NAME, "readAttribute", String.valueOf(lines),
- String.valueOf(line),
- String.valueOf(entryDN),
- String.valueOf(attributeName));
+ assert debugEnter(CLASS_NAME, "readSingleValueAttribute",
+ String.valueOf(lines),
+ String.valueOf(line),
+ String.valueOf(entryDN),
+ String.valueOf(attributeName));
-
- int colonPos = line.indexOf(":");
- if (colonPos <= 0)
- {
- int msgID = MSGID_LDIF_NO_ATTR_NAME;
- String message = getMessage(msgID, lastEntryLineNumber, line.toString());
-
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "readAttribute", e);
- }
- }
-
- throw new LDIFException(msgID, message, lastEntryLineNumber, true);
- }
-
+ // Parse the attribute type description.
+ int colonPos = parseColonPosition(lines, line);
String attrDescr = line.substring(0, colonPos);
Attribute attribute = parseAttrDescription(attrDescr);
String attrName = attribute.getName();
String lowerName = toLowerCase(attrName);
- if(attributeName != null && !attributeName.toLowerCase().equals(lowerName))
+ if(attributeName != null && !toLowerCase(attributeName).equals(lowerName))
{
int msgID = MSGID_LDIF_INVALID_CHANGERECORD_ATTRIBUTE;
String message = getMessage(msgID, lowerName, attributeName);
throw new LDIFException(msgID, message, lastEntryLineNumber, false);
}
-
- // Look at the character immediately after the colon. If there is none,
- // then assume an attribute with an empty value. If it is another colon,
- // then the value must be base64-encoded. If it is a less-than sign, then
- // assume that it is a URL. Otherwise, it is a regular value.
- int length = line.length();
- ASN1OctetString value;
- if (colonPos == (length-1))
- {
- value = new ASN1OctetString();
- }
- else
- {
- char c = line.charAt(colonPos+1);
- if (c == ':')
- {
- // 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++;
- }
-
- try
- {
- value = new ASN1OctetString(Base64.decode(line.substring(pos)));
- }
- catch (Exception e)
- {
- // The value did not have a valid base64-encoding.
- assert debugException(CLASS_NAME, "readAttribute", e);
-
- int msgID = MSGID_LDIF_COULD_NOT_BASE64_DECODE_ATTR;
- String message = getMessage(msgID, String.valueOf(entryDN),
- lastEntryLineNumber, line,
- String.valueOf(e));
-
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e2)
- {
- assert debugException(CLASS_NAME, "readAttribute", e2);
- }
- }
-
- throw new LDIFException(msgID, message, lastEntryLineNumber, true, e);
- }
- }
- else if (c == '<')
- {
- // 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++;
- }
-
- URL contentURL;
- try
- {
- contentURL = new URL(line.substring(pos));
- }
- catch (Exception e)
- {
- // The URL was malformed or had an invalid protocol.
- assert debugException(CLASS_NAME, "readAttribute", e);
-
- int msgID = MSGID_LDIF_INVALID_URL;
- String message = getMessage(msgID, String.valueOf(entryDN),
- lastEntryLineNumber,
- String.valueOf(attrName),
- String.valueOf(e));
-
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e2)
- {
- assert debugException(CLASS_NAME, "readAttribute", e2);
- }
- }
-
- throw new LDIFException(msgID, message, lastEntryLineNumber, true, e);
- }
-
-
- InputStream inputStream = null;
- ByteArrayOutputStream outputStream = null;
- try
- {
- outputStream = new ByteArrayOutputStream();
- inputStream = contentURL.openConnection().getInputStream();
-
- int bytesRead;
- while ((bytesRead = inputStream.read(buffer)) > 0)
- {
- outputStream.write(buffer, 0, bytesRead);
- }
-
- value = new ASN1OctetString(outputStream.toByteArray());
- }
- catch (Exception e)
- {
- // We were unable to read the contents of that URL for some reason.
- assert debugException(CLASS_NAME, "readAttribute", e);
-
- int msgID = MSGID_LDIF_URL_IO_ERROR;
- String message = getMessage(msgID, String.valueOf(entryDN),
- lastEntryLineNumber,
- String.valueOf(attrName),
- String.valueOf(contentURL),
- String.valueOf(e));
-
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e2)
- {
- assert debugException(CLASS_NAME, "readAttribute", e2);
- }
- }
-
- throw new LDIFException(msgID, message, lastEntryLineNumber, true, e);
- }
- finally
- {
- if (outputStream != null)
- {
- try
- {
- outputStream.close();
- } catch (Exception e) {}
- }
-
- if (inputStream != null)
- {
- try
- {
- inputStream.close();
- } catch (Exception e) {}
- }
- }
- }
- else
- {
- // 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++;
- }
-
- value = new ASN1OctetString(line.substring(pos));
- }
- }
+ // Now parse the attribute value.
+ ASN1OctetString value = parseSingleValue(lines, line, entryDN,
+ colonPos, attrName);
AttributeType attrType = attribute.getAttributeType();
-
-
- AttributeValue attributeValue;
- try
- {
- attributeValue = new AttributeValue(attrType, value);
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "readAttribute", e);
-
- int msgID = MSGID_LDIF_INVALID_ATTR_SYNTAX;
- String message = getMessage(msgID, String.valueOf(entryDN),
- lastEntryLineNumber, value.stringValue(),
- attrName, String.valueOf(e));
-
- BufferedWriter rejectWriter = importConfig.getRejectWriter();
- if (rejectWriter != null)
- {
- try
- {
- rejectWriter.write("# " + message);
- rejectWriter.newLine();
- for (StringBuilder sb : lines)
- {
- rejectWriter.write(sb.toString());
- rejectWriter.newLine();
- }
-
- rejectWriter.newLine();
- }
- catch (Exception e2)
- {
- assert debugException(CLASS_NAME, "readAttribute", e2);
- }
- }
-
- throw new LDIFException(msgID, message, lastEntryLineNumber, true, e);
- }
-
+ AttributeValue attributeValue = new AttributeValue(attrType, value);
attribute.getValues().add(attributeValue);
return attribute;
@@ -2216,7 +1058,8 @@
{
try
{
- rejectWriter.write("# " + message);
+ rejectWriter.write("# ");
+ rejectWriter.write(message);
rejectWriter.newLine();
for (StringBuilder sb : lastEntryHeaderLines)
@@ -2260,7 +1103,7 @@
* @return A new attribute with no values, representing the attribute type
* and its options.
*/
- public static Attribute parseAttrDescription(String attrDescr)
+ private static Attribute parseAttrDescription(String attrDescr)
{
assert debugEnter(CLASS_NAME, "parseAttributeDescription",
String.valueOf(attrDescr));
@@ -2354,5 +1197,551 @@
return entriesRejected;
}
+
+
+
+ /**
+ * Parse a modifyDN change record entry from LDIF.
+ *
+ * @param entryDN
+ * The name of the entry being modified.
+ * @param lines
+ * The lines to parse.
+ * @return Returns the parsed modifyDN change record entry.
+ * @throws LDIFException
+ * If there was an error when parsing the change record.
+ */
+ private ChangeRecordEntry parseModifyDNChangeRecordEntry(DN entryDN,
+ LinkedList<StringBuilder> lines) throws LDIFException {
+ assert debugEnter(CLASS_NAME, "parseModifyDNChangeRecordEntry",
+ String.valueOf(entryDN),
+ String.valueOf(lines),
+ String.valueOf(lineNumber));
+
+ DN newSuperiorDN = null;
+ RDN newRDN = null;
+ boolean deleteOldRDN = false;
+
+ if(lines.isEmpty())
+ {
+ int msgID = MSGID_LDIF_NO_MOD_DN_ATTRIBUTES;
+ String message = getMessage(msgID);
+ throw new LDIFException(msgID, message, lineNumber, true);
+ }
+
+ StringBuilder line = lines.remove();
+ String rdnStr = getModifyDNAttributeValue(lines, line, entryDN, "newrdn");
+
+ try
+ {
+ newRDN = RDN.decode(rdnStr);
+ } catch (DirectoryException de)
+ {
+ assert debugException(CLASS_NAME, "parse", de);
+ int msgID = MSGID_LDIF_INVALID_DN;
+ String message = getMessage(msgID, lineNumber, line.toString(),
+ de.getErrorMessage());
+ throw new LDIFException(msgID, message, lineNumber, true);
+ } catch (Exception e)
+ {
+ assert debugException(CLASS_NAME, "parse", e);
+ int msgID = MSGID_LDIF_INVALID_DN;
+ String message = getMessage(msgID, lineNumber, line.toString(),
+ e.getMessage());
+ throw new LDIFException(msgID, message, lineNumber, true);
+ }
+
+ if(lines.isEmpty())
+ {
+ int msgID = MSGID_LDIF_NO_DELETE_OLDRDN_ATTRIBUTE;
+ String message = getMessage(msgID);
+ throw new LDIFException(msgID, message, lineNumber, true);
+ }
+ lineNumber++;
+
+ line = lines.remove();
+ String delStr = getModifyDNAttributeValue(lines, line,
+ entryDN, "deleteoldrdn");
+
+ if(delStr.equalsIgnoreCase("false") ||
+ delStr.equalsIgnoreCase("no") ||
+ delStr.equalsIgnoreCase("0"))
+ {
+ deleteOldRDN = false;
+ } else if(delStr.equalsIgnoreCase("true") ||
+ delStr.equalsIgnoreCase("yes") ||
+ delStr.equalsIgnoreCase("1"))
+ {
+ deleteOldRDN = true;
+ } else
+ {
+ int msgID = MSGID_LDIF_INVALID_DELETE_OLDRDN_ATTRIBUTE;
+ String message = getMessage(msgID, delStr);
+ throw new LDIFException(msgID, message, lineNumber, true);
+ }
+
+ if(!lines.isEmpty())
+ {
+ lineNumber++;
+
+ line = lines.remove();
+
+ String dnStr = getModifyDNAttributeValue(lines, line,
+ entryDN, "newsuperior");
+ try
+ {
+ newSuperiorDN = DN.decode(dnStr);
+ } catch (DirectoryException de)
+ {
+ assert debugException(CLASS_NAME, "parse", de);
+ int msgID = MSGID_LDIF_INVALID_DN;
+ String message = getMessage(msgID, lineNumber, line.toString(),
+ de.getErrorMessage());
+ throw new LDIFException(msgID, message, lineNumber, true);
+ } catch (Exception e)
+ {
+ assert debugException(CLASS_NAME, "parse", e);
+ int msgID = MSGID_LDIF_INVALID_DN;
+ String message = getMessage(msgID, lineNumber, line.toString(),
+ e.getMessage());
+ throw new LDIFException(msgID, message, lineNumber, true);
+ }
+ }
+
+ return new ModifyDNChangeRecordEntry(entryDN, newSuperiorDN,
+ newRDN, deleteOldRDN);
+ }
+
+
+
+ /**
+ * Return the string value for the specified attribute name which only
+ * has one value.
+ *
+ * @param lines
+ * The set of lines for this change record entry.
+ * @param line
+ * The line currently being examined.
+ * @param entryDN
+ * The name of the entry being modified.
+ * @param attributeName
+ * The attribute name
+ * @return the string value for the attribute name.
+ * @throws LDIFException
+ * If a problem occurs while attempting to determine the
+ * attribute value.
+ */
+
+ private String getModifyDNAttributeValue(LinkedList<StringBuilder> lines,
+ StringBuilder line,
+ DN entryDN,
+ String attributeName) throws LDIFException
+ {
+ assert debugEnter(CLASS_NAME, "getModifyDNAttributeValue",
+ String.valueOf(lines),
+ String.valueOf(line),
+ String.valueOf(entryDN),
+ String.valueOf(attributeName));
+
+ Attribute attr =
+ readSingleValueAttribute(lines, line, entryDN, attributeName);
+ LinkedHashSet<AttributeValue> values = attr.getValues();
+
+ // Get the attribute value
+ Object[] vals = values.toArray();
+ return (((AttributeValue)vals[0]).getStringValue());
+ }
+
+
+
+ /**
+ * Parse a modify change record entry from LDIF.
+ *
+ * @param entryDN
+ * The name of the entry being modified.
+ * @param lines
+ * The lines to parse.
+ * @return Returns the parsed modify change record entry.
+ * @throws LDIFException
+ * If there was an error when parsing the change record.
+ */
+ private ChangeRecordEntry parseModifyChangeRecordEntry(DN entryDN,
+ LinkedList<StringBuilder> lines) throws LDIFException {
+ assert debugEnter(CLASS_NAME, "parseModifyChangeRecordEntry",
+ String.valueOf(entryDN),
+ String.valueOf(lines),
+ String.valueOf(lineNumber));
+
+ List<LDAPModification> modifications = new ArrayList<LDAPModification>();
+ while(!lines.isEmpty())
+ {
+ ModificationType modType = null;
+
+ StringBuilder line = lines.remove();
+ Attribute attr =
+ readSingleValueAttribute(lines, line, entryDN, null);
+ String name = attr.getName();
+ LinkedHashSet<AttributeValue> values = attr.getValues();
+
+ // Get the attribute description
+ String attrDescr = values.iterator().next().getStringValue();
+
+ String lowerName = toLowerCase(name);
+ if(lowerName.equals("add"))
+ {
+ modType = ModificationType.ADD;
+ } else if(lowerName.equals("delete"))
+ {
+ modType = ModificationType.DELETE;
+ } else if(lowerName.equals("replace"))
+ {
+ modType = ModificationType.REPLACE;
+ } else if(lowerName.equals("increment"))
+ {
+ modType = ModificationType.INCREMENT;
+ } else
+ {
+ // Invalid attribute name.
+ int msgID = MSGID_LDIF_INVALID_MODIFY_ATTRIBUTE;
+ String message = getMessage(msgID, name,
+ "add, delete, replace, increment");
+ throw new LDIFException(msgID, message, lineNumber, true);
+ }
+
+ // Now go through the rest of the attributes till the "-" line is
+ // reached.
+ Attribute modAttr = LDIFReader.parseAttrDescription(attrDescr);
+ while (! lines.isEmpty())
+ {
+ line = lines.remove();
+ if(line.toString().equals("-"))
+ {
+ break;
+ }
+ Attribute a =
+ readSingleValueAttribute(lines, line, entryDN, attrDescr);
+ modAttr.getValues().addAll(a.getValues());
+ }
+
+ LDAPAttribute ldapAttr = new LDAPAttribute(modAttr);
+ LDAPModification mod = new LDAPModification(modType, ldapAttr);
+ modifications.add(mod);
+ }
+
+ return new ModifyChangeRecordEntry(entryDN, modifications);
+ }
+
+
+
+ /**
+ * Parse a delete change record entry from LDIF.
+ *
+ * @param entryDN
+ * The name of the entry being deleted.
+ * @param lines
+ * The lines to parse.
+ * @return Returns the parsed delete change record entry.
+ * @throws LDIFException
+ * If there was an error when parsing the change record.
+ */
+ private ChangeRecordEntry parseDeleteChangeRecordEntry(DN entryDN,
+ LinkedList<StringBuilder> lines) throws LDIFException {
+ assert debugEnter(CLASS_NAME, "parseDeleteChangeRecordEntry",
+ String.valueOf(entryDN),
+ String.valueOf(lines),
+ String.valueOf(lineNumber));
+
+ if(!lines.isEmpty())
+ {
+ int msgID = MSGID_LDIF_INVALID_DELETE_ATTRIBUTES;
+ String message = getMessage(msgID);
+
+ throw new LDIFException(msgID, message, lineNumber, true);
+ }
+
+ return new DeleteChangeRecordEntry(entryDN);
+ }
+
+
+
+ /**
+ * Parse an add change record entry from LDIF.
+ *
+ * @param entryDN
+ * The name of the entry being added.
+ * @param lines
+ * The lines to parse.
+ * @return Returns the parsed add change record entry.
+ * @throws LDIFException
+ * If there was an error when parsing the change record.
+ */
+ private ChangeRecordEntry parseAddChangeRecordEntry(DN entryDN,
+ LinkedList<StringBuilder> lines) throws LDIFException {
+ assert debugEnter(CLASS_NAME, "parseAddChangeRecordEntry",
+ String.valueOf(entryDN),
+ String.valueOf(lines),
+ String.valueOf(lineNumber));
+
+ HashMap<ObjectClass,String> objectClasses =
+ new HashMap<ObjectClass,String>();
+ HashMap<AttributeType,List<Attribute>> attributes =
+ new HashMap<AttributeType, List<Attribute>>();
+ for(StringBuilder line : lines)
+ {
+ readAttribute(lines, line, entryDN, objectClasses,
+ attributes, attributes);
+ }
+
+ // Reconstruct the object class attribute.
+ AttributeType ocType = DirectoryServer.getObjectClassAttributeType();
+ LinkedHashSet<AttributeValue> ocValues =
+ new LinkedHashSet<AttributeValue>(objectClasses.size());
+ for (String value : objectClasses.values()) {
+ AttributeValue av = new AttributeValue(ocType, value);
+ ocValues.add(av);
+ }
+ Attribute ocAttr = new Attribute(ocType, "objectClass", ocValues);
+ List<Attribute> ocAttrList = new ArrayList<Attribute>(1);
+ ocAttrList.add(ocAttr);
+ attributes.put(ocType, ocAttrList);
+
+ return new AddChangeRecordEntry(entryDN, attributes);
+ }
+
+
+
+ /**
+ * Parse colon position in an attribute description.
+ *
+ * @param lines
+ * The current set of lines.
+ * @param line
+ * The current line.
+ * @return The colon position.
+ * @throws LDIFException
+ * If the colon was badly placed or not found.
+ */
+ private int parseColonPosition(LinkedList<StringBuilder> lines,
+ StringBuilder line) throws LDIFException {
+ assert debugEnter(CLASS_NAME, "parseColonPosition",
+ String.valueOf(lines),
+ String.valueOf(lineNumber));
+
+ int colonPos = line.indexOf(":");
+ if (colonPos <= 0)
+ {
+ int msgID = MSGID_LDIF_NO_ATTR_NAME;
+ String message = getMessage(msgID, lastEntryLineNumber, line.toString());
+ logToRejectWriter(lines, message);
+ throw new LDIFException(msgID, message, lastEntryLineNumber, true);
+ }
+ return colonPos;
+ }
+
+
+
+ /**
+ * Parse a single attribute value from a line of LDIF.
+ *
+ * @param lines
+ * The current set of lines.
+ * @param line
+ * The current line.
+ * @param entryDN
+ * The DN of the entry being parsed.
+ * @param colonPos
+ * The position of the separator colon in the line.
+ * @param attrName
+ * The name of the attribute being parsed.
+ * @return The parsed attribute value.
+ * @throws LDIFException
+ * If an error occurred when parsing the attribute value.
+ */
+ private ASN1OctetString parseSingleValue(
+ LinkedList<StringBuilder> lines,
+ StringBuilder line,
+ DN entryDN,
+ int colonPos,
+ String attrName) throws LDIFException {
+ assert debugEnter(CLASS_NAME, "parseSingleValue",
+ String.valueOf(lines),
+ String.valueOf(line),
+ String.valueOf(entryDN),
+ String.valueOf(colonPos),
+ String.valueOf(attrName));
+
+ // Look at the character immediately after the colon. If there is
+ // none, then assume an attribute with an empty value. If it is another
+ // colon, then the value must be base64-encoded. If it is a less-than
+ // sign, then assume that it is a URL. Otherwise, it is a regular value.
+ int length = line.length();
+ ASN1OctetString value;
+ if (colonPos == (length-1))
+ {
+ value = new ASN1OctetString();
+ }
+ else
+ {
+ char c = line.charAt(colonPos+1);
+ if (c == ':')
+ {
+ // 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++;
+ }
+
+ try
+ {
+ value = new ASN1OctetString(Base64.decode(line.substring(pos)));
+ }
+ catch (Exception e)
+ {
+ // The value did not have a valid base64-encoding.
+ assert debugException(CLASS_NAME, "readAttribute", e);
+
+ int msgID = MSGID_LDIF_COULD_NOT_BASE64_DECODE_ATTR;
+ String message = getMessage(msgID, String.valueOf(entryDN),
+ lastEntryLineNumber, line,
+ String.valueOf(e));
+ logToRejectWriter(lines, message);
+ throw new LDIFException(msgID, message, lastEntryLineNumber, true, e);
+ }
+ }
+ else if (c == '<')
+ {
+ // 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++;
+ }
+
+ URL contentURL;
+ try
+ {
+ contentURL = new URL(line.substring(pos));
+ }
+ catch (Exception e)
+ {
+ // The URL was malformed or had an invalid protocol.
+ assert debugException(CLASS_NAME, "readAttribute", e);
+
+ int msgID = MSGID_LDIF_INVALID_URL;
+ String message = getMessage(msgID, String.valueOf(entryDN),
+ lastEntryLineNumber,
+ String.valueOf(attrName),
+ String.valueOf(e));
+ logToRejectWriter(lines, message);
+ throw new LDIFException(msgID, message, lastEntryLineNumber, true, e);
+ }
+
+
+ InputStream inputStream = null;
+ ByteArrayOutputStream outputStream = null;
+ try
+ {
+ outputStream = new ByteArrayOutputStream();
+ inputStream = contentURL.openConnection().getInputStream();
+
+ int bytesRead;
+ while ((bytesRead = inputStream.read(buffer)) > 0)
+ {
+ outputStream.write(buffer, 0, bytesRead);
+ }
+
+ value = new ASN1OctetString(outputStream.toByteArray());
+ }
+ catch (Exception e)
+ {
+ // We were unable to read the contents of that URL for some
+ // reason.
+ assert debugException(CLASS_NAME, "readAttribute", e);
+
+ int msgID = MSGID_LDIF_URL_IO_ERROR;
+ String message = getMessage(msgID, String.valueOf(entryDN),
+ lastEntryLineNumber,
+ String.valueOf(attrName),
+ String.valueOf(contentURL),
+ String.valueOf(e));
+ logToRejectWriter(lines, message);
+ throw new LDIFException(msgID, message, lastEntryLineNumber, true, e);
+ }
+ finally
+ {
+ if (outputStream != null)
+ {
+ try
+ {
+ outputStream.close();
+ } catch (Exception e) {}
+ }
+
+ if (inputStream != null)
+ {
+ try
+ {
+ inputStream.close();
+ } catch (Exception e) {}
+ }
+ }
+ }
+ else
+ {
+ // 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++;
+ }
+
+ value = new ASN1OctetString(line.substring(pos));
+ }
+ }
+ return value;
+ }
+
+
+
+ /**
+ * Log a message to the reject writer if one is configured.
+ *
+ * @param lines
+ * The set of rejected lines.
+ * @param message
+ * The associated error message.
+ */
+ private void logToRejectWriter(LinkedList<StringBuilder> lines,
+ String message) {
+ assert debugEnter(CLASS_NAME, "logToRejectWriter",
+ String.valueOf(lines),
+ String.valueOf(message));
+
+ BufferedWriter rejectWriter = importConfig.getRejectWriter();
+ if (rejectWriter != null)
+ {
+ try
+ {
+ rejectWriter.write("# ");
+ rejectWriter.write(message);
+ rejectWriter.newLine();
+ for (StringBuilder sb : lines)
+ {
+ rejectWriter.write(sb.toString());
+ rejectWriter.newLine();
+ }
+
+ rejectWriter.newLine();
+ }
+ catch (Exception e)
+ {
+ assert debugException(CLASS_NAME, "logToRejectWriter", e);
+ }
+ }
+ }
}
--
Gitblit v1.10.0