From d436398b7fc0b5642a8b0f5c77cab4accec9c056 Mon Sep 17 00:00:00 2001
From: Jean-Noel Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Tue, 03 Feb 2015 14:25:17 +0000
Subject: [PATCH] (CR-5887) Decouple LDIFReader from JE's import
---
opendj3-server-dev/src/server/org/opends/server/backends/jeb/importLDIF/ImportLDIFReader.java | 275 ++++++++++++++++++
opendj3-server-dev/src/server/org/opends/server/backends/jeb/importLDIF/Importer.java | 5
opendj3-server-dev/src/server/org/opends/server/util/LDIFReader.java | 567 +++++++++++--------------------------
3 files changed, 450 insertions(+), 397 deletions(-)
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/importLDIF/ImportLDIFReader.java b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/importLDIF/ImportLDIFReader.java
new file mode 100644
index 0000000..8b43c4a
--- /dev/null
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/importLDIF/ImportLDIFReader.java
@@ -0,0 +1,275 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at legal-notices/CDDLv1_0.txt.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * Copyright 2015 ForgeRock AS
+ */
+package org.opends.server.backends.jeb.importLDIF;
+
+import static org.opends.messages.UtilityMessages.*;
+import static org.opends.server.util.StaticUtils.*;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.i18n.LocalizableMessageBuilder;
+import org.forgerock.i18n.slf4j.LocalizedLogger;
+import org.forgerock.util.Reject;
+import org.opends.server.api.plugin.PluginResult;
+import org.opends.server.backends.jeb.EntryID;
+import org.opends.server.backends.jeb.RootContainer;
+import org.opends.server.types.AttributeBuilder;
+import org.opends.server.types.AttributeType;
+import org.opends.server.types.DN;
+import org.opends.server.types.Entry;
+import org.opends.server.types.LDIFImportConfig;
+import org.opends.server.types.ObjectClass;
+import org.opends.server.util.LDIFException;
+import org.opends.server.util.LDIFReader;
+
+/**
+ * This class specializes the LDIFReader for imports.
+ */
+public final class ImportLDIFReader extends LDIFReader
+{
+ private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
+
+ private final RootContainer rootContainer;
+
+ /**
+ * Creates a new LDIF reader that will read information from the specified file.
+ *
+ * @param importConfig
+ * The import configuration for this LDIF reader. It must not be <CODE>null</CODE>.
+ * @param rootContainer
+ * The root container needed to get the next entry ID.
+ * @throws IOException
+ * If a problem occurs while opening the LDIF file for reading.
+ */
+ public ImportLDIFReader(LDIFImportConfig importConfig, RootContainer rootContainer) throws IOException
+ {
+ super(importConfig);
+ Reject.ifNull(importConfig, rootContainer);
+ this.rootContainer = rootContainer;
+ }
+
+ /**
+ * Reads the next entry from the LDIF source.
+ *
+ * @return The next entry read from the LDIF source, or <CODE>null</CODE> if the end of the LDIF
+ * data is reached.
+ * @param suffixesMap
+ * A map of suffixes instances.
+ * @param entryInfo
+ * A object to hold information about the entry ID and what suffix was selected.
+ * @throws IOException
+ * If an I/O problem occurs while reading from the file.
+ * @throws LDIFException
+ * If the information read cannot be parsed as an LDIF entry.
+ */
+ public final Entry readEntry(Map<DN, Suffix> suffixesMap, Importer.EntryInformation entryInfo) throws IOException,
+ LDIFException
+ {
+ final boolean checkSchema = importConfig.validateSchema();
+ while (true)
+ {
+ LinkedList<StringBuilder> lines;
+ DN entryDN;
+ EntryID entryID;
+ Suffix suffix;
+ synchronized (this)
+ {
+ // Read the set of lines that make up the next entry.
+ lines = readEntryLines();
+ if (lines == null)
+ {
+ return null;
+ }
+ lastEntryBodyLines = lines;
+ lastEntryHeaderLines = new LinkedList<StringBuilder>();
+
+ // Read the DN of the entry and see if it is one that should be included
+ // in the import.
+ try
+ {
+ entryDN = readDN(lines);
+ }
+ catch (LDIFException e)
+ {
+ logger.traceException(e);
+ continue;
+ }
+
+ if (entryDN == null)
+ {
+ // This should only happen if the LDIF starts with the "version:" line
+ // and has a blank line immediately after that. In that case, simply
+ // read and return the next entry.
+ continue;
+ }
+ else if (!importConfig.includeEntry(entryDN))
+ {
+ logger.trace("Skipping entry %s because the DN is not one that "
+ + "should be included based on the include and exclude branches.", entryDN);
+ entriesRead.incrementAndGet();
+ logToSkipWriter(lines, ERR_LDIF_SKIP.get(entryDN));
+ continue;
+ }
+ suffix = Importer.getMatchSuffix(entryDN, suffixesMap);
+ if (suffix == null)
+ {
+ logger.trace("Skipping entry %s because the DN is not one that "
+ + "should be included based on a suffix match check.", entryDN);
+ entriesRead.incrementAndGet();
+ logToSkipWriter(lines, ERR_LDIF_SKIP.get(entryDN));
+ continue;
+ }
+ entriesRead.incrementAndGet();
+ entryID = rootContainer.getNextEntryID();
+ suffix.addPending(entryDN);
+ }
+
+ // Create the entry and see if it is one that should be included in the import
+ final Entry entry = createEntry(lines, entryDN, checkSchema, suffix);
+ if (entry == null
+ || !isIncludedInImport(entry, suffix, lines)
+ || !invokeImportPlugins(entry, suffix, lines)
+ || (checkSchema && !isValidAgainstSchema(entry, suffix, lines)))
+ {
+ continue;
+ }
+ entryInfo.setEntryID(entryID);
+ entryInfo.setSuffix(suffix);
+ // The entry should be included in the import, so return it.
+ return entry;
+ }
+ }
+
+ private Entry createEntry(List<StringBuilder> lines, DN entryDN, boolean checkSchema, Suffix suffix)
+ {
+ // Read the set of attributes from the entry.
+ Map<ObjectClass, String> objectClasses = new HashMap<ObjectClass, String>();
+ Map<AttributeType, List<AttributeBuilder>> userAttrBuilders =
+ new HashMap<AttributeType, List<AttributeBuilder>>();
+ Map<AttributeType, List<AttributeBuilder>> operationalAttrBuilders =
+ new HashMap<AttributeType, List<AttributeBuilder>>();
+ try
+ {
+ for (StringBuilder line : lines)
+ {
+ readAttribute(lines, line, entryDN, objectClasses, userAttrBuilders, operationalAttrBuilders, checkSchema);
+ }
+ }
+ catch (LDIFException e)
+ {
+ if (logger.isTraceEnabled())
+ {
+ logger.trace("Skipping entry %s because reading" + "its attributes failed.", entryDN);
+ }
+ logToSkipWriter(lines, ERR_LDIF_READ_ATTR_SKIP.get(entryDN, e.getMessage()));
+ suffix.removePending(entryDN);
+ return null;
+ }
+
+ final Entry entry = new Entry(entryDN, objectClasses,
+ toAttributesMap(userAttrBuilders), toAttributesMap(operationalAttrBuilders));
+ logger.trace("readEntry(), created entry: %s", entry);
+ return entry;
+ }
+
+ private boolean isIncludedInImport(Entry entry, Suffix suffix, LinkedList<StringBuilder> lines)
+ {
+ final DN entryDN = entry.getName();
+ try
+ {
+ if (!importConfig.includeEntry(entry))
+ {
+ if (logger.isTraceEnabled())
+ {
+ logger.trace("Skipping entry %s because the DN is not one that "
+ + "should be included based on the include and exclude filters.", entryDN);
+ }
+ logToSkipWriter(lines, ERR_LDIF_SKIP.get(entryDN));
+ suffix.removePending(entryDN);
+ return false;
+ }
+ }
+ catch (Exception e)
+ {
+ logger.traceException(e);
+ suffix.removePending(entryDN);
+ logToSkipWriter(lines,
+ ERR_LDIF_COULD_NOT_EVALUATE_FILTERS_FOR_IMPORT.get(entry.getName(), lastEntryLineNumber, e));
+ suffix.removePending(entryDN);
+ return false;
+ }
+ return true;
+ }
+
+ private boolean invokeImportPlugins(final Entry entry, Suffix suffix, LinkedList<StringBuilder> lines)
+ {
+ if (importConfig.invokeImportPlugins())
+ {
+ PluginResult.ImportLDIF pluginResult = pluginConfigManager.invokeLDIFImportPlugins(importConfig, entry);
+ if (!pluginResult.continueProcessing())
+ {
+ final DN entryDN = entry.getName();
+ LocalizableMessage m;
+ LocalizableMessage rejectMessage = pluginResult.getErrorMessage();
+ if (rejectMessage == null)
+ {
+ m = ERR_LDIF_REJECTED_BY_PLUGIN_NOMESSAGE.get(entryDN);
+ }
+ else
+ {
+ m = ERR_LDIF_REJECTED_BY_PLUGIN.get(entryDN, rejectMessage);
+ }
+
+ logToRejectWriter(lines, m);
+ suffix.removePending(entryDN);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean isValidAgainstSchema(Entry entry, Suffix suffix, LinkedList<StringBuilder> lines)
+ {
+ final DN entryDN = entry.getName();
+ addRDNAttributesIfNecessary(entryDN, entry.getUserAttributes(), entry.getOperationalAttributes());
+ // Add any superior objectclass(s) missing in the objectclass map.
+ addSuperiorObjectClasses(entry.getObjectClasses());
+
+ LocalizableMessageBuilder invalidReason = new LocalizableMessageBuilder();
+ if (!entry.conformsToSchema(null, false, true, false, invalidReason))
+ {
+ LocalizableMessage message = ERR_LDIF_SCHEMA_VIOLATION.get(entryDN, lastEntryLineNumber, invalidReason);
+ logToRejectWriter(lines, message);
+ suffix.removePending(entryDN);
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/importLDIF/Importer.java b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/importLDIF/Importer.java
index debf086..992590a 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/importLDIF/Importer.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/importLDIF/Importer.java
@@ -61,7 +61,6 @@
import org.opends.server.core.DirectoryServer;
import org.opends.server.extensions.DiskSpaceMonitor;
import org.opends.server.types.*;
-import org.opends.server.util.LDIFReader;
import org.opends.server.util.Platform;
import org.opends.server.util.StaticUtils;
@@ -141,7 +140,7 @@
private final LocalDBBackendCfg backendConfiguration;
/** LDIF reader. */
- private LDIFReader reader;
+ private ImportLDIFReader reader;
/** Migrated entry count. */
private int migratedCount;
@@ -853,7 +852,7 @@
try {
try
{
- reader = new LDIFReader(importConfiguration, rootContainer);
+ reader = new ImportLDIFReader(importConfiguration, rootContainer);
}
catch (IOException ioe)
{
diff --git a/opendj3-server-dev/src/server/org/opends/server/util/LDIFReader.java b/opendj3-server-dev/src/server/org/opends/server/util/LDIFReader.java
index 3e5bc58..5538b5b 100644
--- a/opendj3-server-dev/src/server/org/opends/server/util/LDIFReader.java
+++ b/opendj3-server-dev/src/server/org/opends/server/util/LDIFReader.java
@@ -22,13 +22,25 @@
*
*
* Copyright 2006-2010 Sun Microsystems, Inc.
- * Portions Copyright 2012-2014 ForgeRock AS
+ * Portions Copyright 2012-2015 ForgeRock AS
*/
package org.opends.server.util;
-import java.io.*;
+import static org.forgerock.util.Reject.*;
+import static org.opends.messages.UtilityMessages.*;
+import static org.opends.server.util.StaticUtils.*;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
import java.net.URL;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import org.forgerock.i18n.LocalizableMessage;
@@ -38,20 +50,22 @@
import org.forgerock.opendj.ldap.ByteStringBuilder;
import org.forgerock.opendj.ldap.ModificationType;
import org.opends.server.api.plugin.PluginResult;
-import org.opends.server.backends.jeb.EntryID;
-import org.opends.server.backends.jeb.RootContainer;
-import org.opends.server.backends.jeb.importLDIF.Importer;
-import org.opends.server.backends.jeb.importLDIF.Suffix;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.PluginConfigManager;
import org.opends.server.protocols.ldap.LDAPAttribute;
import org.opends.server.protocols.ldap.LDAPModification;
-import org.opends.server.types.*;
-
-import static org.forgerock.util.Reject.*;
-import static org.opends.messages.UtilityMessages.*;
-import static org.opends.server.util.StaticUtils.*;
-
+import org.opends.server.types.AcceptRejectWarn;
+import org.opends.server.types.Attribute;
+import org.opends.server.types.AttributeBuilder;
+import org.opends.server.types.AttributeType;
+import org.opends.server.types.Attributes;
+import org.opends.server.types.DN;
+import org.opends.server.types.DirectoryException;
+import org.opends.server.types.Entry;
+import org.opends.server.types.LDIFImportConfig;
+import org.opends.server.types.ObjectClass;
+import org.opends.server.types.RDN;
+import org.opends.server.types.RawModification;
/**
* This class provides the ability to read information from an LDIF file. It
@@ -63,7 +77,7 @@
mayInstantiate=true,
mayExtend=false,
mayInvoke=true)
-public final class LDIFReader implements Closeable
+public class LDIFReader implements Closeable
{
private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
@@ -71,16 +85,16 @@
private BufferedReader reader;
/** The import configuration that specifies what should be imported. */
- private LDIFImportConfig importConfig;
+ protected LDIFImportConfig importConfig;
/** The lines that comprise the body of the last entry read. */
- private List<StringBuilder> lastEntryBodyLines;
+ protected List<StringBuilder> lastEntryBodyLines;
/**
* The lines that comprise the header (DN and any comments) for the last entry
* read.
*/
- private List<StringBuilder> lastEntryHeaderLines;
+ protected List<StringBuilder> lastEntryHeaderLines;
/**
@@ -94,13 +108,13 @@
* those that were ignored because they didn't match the criteria, and
* including those that were rejected because they were invalid in some way.
*/
- private final AtomicLong entriesRead = new AtomicLong();
+ protected final AtomicLong entriesRead = new AtomicLong();
/** The number of entries that have been rejected by this LDIF reader. */
private final AtomicLong entriesRejected = new AtomicLong();
/** The line number on which the last entry started. */
- private long lastEntryLineNumber;
+ protected long lastEntryLineNumber = -1;
/**
* The line number of the last line read from the LDIF file, starting with 1.
@@ -111,10 +125,7 @@
* The plugin config manager that will be used if we are to invoke plugins on
* the entries as they are read.
*/
- private PluginConfigManager pluginConfigManager;
-
- private RootContainer rootContainer;
-
+ protected PluginConfigManager pluginConfigManager;
/**
* Creates a new LDIF reader that will read information from the specified
@@ -133,8 +144,6 @@
this.importConfig = importConfig;
reader = importConfig.getReader();
- lineNumber = 0;
- lastEntryLineNumber = -1;
lastEntryBodyLines = new LinkedList<StringBuilder>();
lastEntryHeaderLines = new LinkedList<StringBuilder>();
pluginConfigManager = DirectoryServer.getPluginConfigManager();
@@ -148,42 +157,6 @@
/**
- * Creates a new LDIF reader that will read information from the
- * specified file.
- *
- * @param importConfig
- * The import configuration for this LDIF reader. It must not
- * be <CODE>null</CODE>.
- * @param rootContainer The root container needed to get the next entry ID.
- *
- * @throws IOException
- * If a problem occurs while opening the LDIF file for
- * reading.
- */
- public LDIFReader(LDIFImportConfig importConfig, RootContainer rootContainer)
- throws IOException
- {
- ifNull(importConfig);
- this.importConfig = importConfig;
- this.reader = importConfig.getReader();
- this.lineNumber = 0;
- this.lastEntryLineNumber = -1;
- this.lastEntryBodyLines = new LinkedList<StringBuilder>();
- this.lastEntryHeaderLines = new LinkedList<StringBuilder>();
- this.pluginConfigManager = DirectoryServer.getPluginConfigManager();
- this.rootContainer = rootContainer;
- // If we should invoke import plugins, then do so.
- if (importConfig.invokeImportPlugins())
- {
- // Inform LDIF import plugins that an import session is ending
- this.pluginConfigManager.invokeLDIFImportBeginPlugins(importConfig);
- }
- }
-
-
-
-
- /**
* Reads the next entry from the LDIF source.
*
* @return The next entry read from the LDIF source, or <CODE>null</CODE> if
@@ -205,240 +178,6 @@
/**
* Reads the next entry from the LDIF source.
*
- * @return The next entry read from the LDIF source, or <CODE>null</CODE> if
- * the end of the LDIF data is reached.
- *
- * @param map A map of suffixes instances.
- *
- * @param entryInfo A object to hold information about the entry ID and what
- * suffix was selected.
- *
- * @throws IOException If an I/O problem occurs while reading from the file.
- *
- * @throws LDIFException If the information read cannot be parsed as an LDIF
- * entry.
- */
- public final Entry readEntry(Map<DN, Suffix> map,
- Importer.EntryInformation entryInfo)
- throws IOException, LDIFException
- {
- return readEntry(importConfig.validateSchema(), map, entryInfo);
- }
-
-
-
- private Entry readEntry(boolean checkSchema, Map<DN, Suffix> map,
- Importer.EntryInformation entryInfo)
- throws IOException, LDIFException
- {
- while (true)
- {
- LinkedList<StringBuilder> lines;
- DN entryDN;
- EntryID entryID;
- Suffix suffix;
- synchronized (this)
- {
- // Read the set of lines that make up the next entry.
- lines = readEntryLines();
- if (lines == null)
- {
- return null;
- }
- lastEntryBodyLines = lines;
- lastEntryHeaderLines = new LinkedList<StringBuilder>();
-
-
- // Read the DN of the entry and see if it is one that should be included
- // in the import.
-
- try
- {
- entryDN = readDN(lines);
- } catch (LDIFException le) {
- continue;
- }
- if (entryDN == null)
- {
- // This should only happen if the LDIF starts with the "version:" line
- // and has a blank line immediately after that. In that case, simply
- // read and return the next entry.
- continue;
- }
- else if (!importConfig.includeEntry(entryDN))
- {
- if (logger.isTraceEnabled())
- {
- logger.trace("Skipping entry %s because the DN isn't" +
- "one that should be included based on the include and " +
- "exclude branches.", entryDN);
- }
- entriesRead.incrementAndGet();
- logToSkipWriter(lines, ERR_LDIF_SKIP.get(entryDN));
- continue;
- }
- entryID = rootContainer.getNextEntryID();
- suffix = Importer.getMatchSuffix(entryDN, map);
- if(suffix == null)
- {
- if (logger.isTraceEnabled())
- {
- logger.trace("Skipping entry %s because the DN isn't" +
- "one that should be included based on a suffix match" +
- "check." ,entryDN);
- }
- entriesRead.incrementAndGet();
- logToSkipWriter(lines, ERR_LDIF_SKIP.get(entryDN));
- continue;
- }
- entriesRead.incrementAndGet();
- suffix.addPending(entryDN);
- }
- // Read the set of attributes from the entry.
- Map<ObjectClass, String> objectClasses =
- new HashMap<ObjectClass,String>();
- Map<AttributeType, List<AttributeBuilder>> userAttrBuilders =
- new HashMap<AttributeType,List<AttributeBuilder>>();
- Map<AttributeType, List<AttributeBuilder>> operationalAttrBuilders =
- new HashMap<AttributeType,List<AttributeBuilder>>();
- try
- {
- for (StringBuilder line : lines)
- {
- readAttribute(lines, line, entryDN, objectClasses, userAttrBuilders,
- operationalAttrBuilders, checkSchema);
- }
- }
- catch (LDIFException e)
- {
- if (logger.isTraceEnabled())
- {
- logger.trace("Skipping entry %s because reading" +
- "its attributes failed.", entryDN);
- }
- logToSkipWriter(lines, ERR_LDIF_READ_ATTR_SKIP.get(entryDN, e.getMessage()));
- suffix.removePending(entryDN);
- continue;
- }
-
- // Create the entry and see if it is one that should be included in the
- // import.
- Map<AttributeType, List<Attribute>> userAttributes =
- toAttributesMap(userAttrBuilders);
- Map<AttributeType, List<Attribute>> operationalAttributes =
- toAttributesMap(operationalAttrBuilders);
- Entry entry = new Entry(entryDN, objectClasses, userAttributes,
- operationalAttributes);
- logger.trace("readEntry1(), created entry: %s", entry);
-
- try
- {
- if (! importConfig.includeEntry(entry))
- {
- if (logger.isTraceEnabled())
- {
- logger.trace("Skipping entry %s because the DN is not one " +
- "that should be included based on the include and exclude " +
- "filters.", entryDN);
- }
- logToSkipWriter(lines, ERR_LDIF_SKIP.get(entryDN));
- suffix.removePending(entryDN);
- continue;
- }
- }
- catch (Exception e)
- {
- logger.traceException(e);
- suffix.removePending(entryDN);
- logToSkipWriter(lines,
- ERR_LDIF_COULD_NOT_EVALUATE_FILTERS_FOR_IMPORT.get(entry.getName(), lastEntryLineNumber, e));
- suffix.removePending(entryDN);
- continue;
- }
-
-
- // If we should invoke import plugins, then do so.
- if (importConfig.invokeImportPlugins())
- {
- PluginResult.ImportLDIF pluginResult =
- pluginConfigManager.invokeLDIFImportPlugins(importConfig, entry);
- if (! pluginResult.continueProcessing())
- {
- LocalizableMessage m;
- LocalizableMessage rejectMessage = pluginResult.getErrorMessage();
- if (rejectMessage == null)
- {
- m = ERR_LDIF_REJECTED_BY_PLUGIN_NOMESSAGE.get(entryDN);
- }
- else
- {
- m = ERR_LDIF_REJECTED_BY_PLUGIN.get(entryDN, rejectMessage);
- }
-
- logToRejectWriter(lines, m);
- suffix.removePending(entryDN);
- continue;
- }
- }
-
-
- // Make sure that the entry is valid as per the server schema if it is
- // appropriate to do so.
- if (checkSchema)
- {
- //Add the RDN attributes.
- addRDNAttributesIfNecessary(entryDN,userAttributes,
- operationalAttributes);
- //Add any superior objectclass(s) missing in the objectclass map.
- addSuperiorObjectClasses(objectClasses);
-
- LocalizableMessageBuilder invalidReason = new LocalizableMessageBuilder();
- if (! entry.conformsToSchema(null, false, true, false, invalidReason))
- {
- LocalizableMessage message = ERR_LDIF_SCHEMA_VIOLATION.get(
- entryDN, lastEntryLineNumber, invalidReason);
- logToRejectWriter(lines, message);
- suffix.removePending(entryDN);
- continue;
- }
- }
- entryInfo.setEntryID(entryID);
- entryInfo.setSuffix(suffix);
- // The entry should be included in the import, so return it.
- return entry;
- }
- }
-
-
- private Map<AttributeType, List<Attribute>> toAttributesMap(
- Map<AttributeType, List<AttributeBuilder>> attrBuilders)
- {
- Map<AttributeType, List<Attribute>> attributes =
- new HashMap<AttributeType, List<Attribute>>(attrBuilders.size());
- for (Map.Entry<AttributeType, List<AttributeBuilder>>
- attrTypeEntry : attrBuilders.entrySet())
- {
- AttributeType attrType = attrTypeEntry.getKey();
- List<Attribute> attrList = toAttributesList(attrTypeEntry.getValue());
- attributes.put(attrType, attrList);
- }
- return attributes;
- }
-
- private List<Attribute> toAttributesList(List<AttributeBuilder> builders)
- {
- List<Attribute> results = new ArrayList<Attribute>(builders.size());
- for (AttributeBuilder builder : builders)
- {
- results.add(builder.toAttribute());
- }
- return results;
- }
-
-
- /**
- * Reads the next entry from the LDIF source.
- *
* @param checkSchema Indicates whether this reader should perform schema
* checking on the entry before returning it to the
* caller. Note that some basic schema checking (like
@@ -481,12 +220,8 @@
}
else if (!importConfig.includeEntry(entryDN))
{
- if (logger.isTraceEnabled())
- {
- logger.trace("Skipping entry %s because the DN is not one that " +
- "should be included based on the include and exclude branches.",
- entryDN);
- }
+ logger.trace("Skipping entry %s because the DN is not one that "
+ + "should be included based on the include and exclude branches.", entryDN);
entriesRead.incrementAndGet();
logToSkipWriter(lines, ERR_LDIF_SKIP.get(entryDN));
continue;
@@ -496,99 +231,142 @@
entriesRead.incrementAndGet();
}
- // Read the set of attributes from the entry.
- Map<ObjectClass,String> objectClasses =
- new HashMap<ObjectClass,String>();
- Map<AttributeType,List<AttributeBuilder>> userAttrBuilders =
- new HashMap<AttributeType,List<AttributeBuilder>>();
- Map<AttributeType,List<AttributeBuilder>> operationalAttrBuilders =
- new HashMap<AttributeType,List<AttributeBuilder>>();
- for (StringBuilder line : lines)
+ // Create the entry and see if it is one that should be included in the import.
+ final Entry entry = createEntry(entryDN, lines, checkSchema);
+ if (!isIncludedInImport(entry,lines)
+ || !invokeImportPlugins(entry, lines))
{
- readAttribute(lines, line, entryDN, objectClasses, userAttrBuilders,
- operationalAttrBuilders, checkSchema);
+ continue;
}
-
- // Create the entry and see if it is one that should be included in the
- // import.
- Map<AttributeType, List<Attribute>> userAttributes =
- toAttributesMap(userAttrBuilders);
- Map<AttributeType, List<Attribute>> operationalAttributes =
- toAttributesMap(operationalAttrBuilders);
- Entry entry = new Entry(entryDN, objectClasses, userAttributes,
- operationalAttributes);
- logger.trace("readEntry2(), created entry: %s", entry);
-
- try
- {
- if (! importConfig.includeEntry(entry))
- {
- if (logger.isTraceEnabled())
- {
- logger.trace("Skipping entry %s because the DN is not one " +
- "that should be included based on the include and exclude " +
- "filters.", entryDN);
- }
- logToSkipWriter(lines, ERR_LDIF_SKIP.get(entryDN));
- continue;
- }
- }
- catch (Exception e)
- {
- logger.traceException(e);
-
- LocalizableMessage message = ERR_LDIF_COULD_NOT_EVALUATE_FILTERS_FOR_IMPORT.
- get(entry.getName(), lastEntryLineNumber, e);
- throw new LDIFException(message, lastEntryLineNumber, true, e);
- }
-
-
- // If we should invoke import plugins, then do so.
- if (importConfig.invokeImportPlugins())
- {
- PluginResult.ImportLDIF pluginResult =
- pluginConfigManager.invokeLDIFImportPlugins(importConfig, entry);
- if (! pluginResult.continueProcessing())
- {
- LocalizableMessage m;
- LocalizableMessage rejectMessage = pluginResult.getErrorMessage();
- if (rejectMessage == null)
- {
- m = ERR_LDIF_REJECTED_BY_PLUGIN_NOMESSAGE.get(entryDN);
- }
- else
- {
- m = ERR_LDIF_REJECTED_BY_PLUGIN.get(entryDN, rejectMessage);
- }
-
- logToRejectWriter(lines, m);
- continue;
- }
- }
-
-
- // Make sure that the entry is valid as per the server schema if it is
- // appropriate to do so.
- if (checkSchema)
- {
- LocalizableMessageBuilder invalidReason = new LocalizableMessageBuilder();
- if (! entry.conformsToSchema(null, false, true, false, invalidReason))
- {
- LocalizableMessage message = ERR_LDIF_SCHEMA_VIOLATION.get(
- entryDN, lastEntryLineNumber, invalidReason);
- logToRejectWriter(lines, message);
- throw new LDIFException(message, lastEntryLineNumber, true);
- }
- //Add any superior objectclass(s) missing in an entries objectclass map.
- addSuperiorObjectClasses(entry.getObjectClasses());
- }
-
+ validateAgainstSchemaIfNeeded(checkSchema, entry, lines);
// The entry should be included in the import, so return it.
return entry;
}
}
+ private Entry createEntry(DN entryDN, List<StringBuilder> lines, boolean checkSchema) throws LDIFException
+ {
+ Map<ObjectClass, String> objectClasses = new HashMap<ObjectClass, String>();
+ Map<AttributeType, List<AttributeBuilder>> userAttrBuilders = new HashMap<AttributeType, List<AttributeBuilder>>();
+ Map<AttributeType, List<AttributeBuilder>> operationalAttrBuilders =
+ new HashMap<AttributeType, List<AttributeBuilder>>();
+ for (StringBuilder line : lines)
+ {
+ readAttribute(lines, line, entryDN, objectClasses, userAttrBuilders, operationalAttrBuilders, checkSchema);
+ }
+
+ final Entry entry = new Entry(entryDN, objectClasses,
+ toAttributesMap(userAttrBuilders), toAttributesMap(operationalAttrBuilders));
+ logger.trace("readEntry(), created entry: %s", entry);
+ return entry;
+ }
+
+ private boolean isIncludedInImport(Entry entry, LinkedList<StringBuilder> lines) throws LDIFException
+ {
+ try
+ {
+ if (!importConfig.includeEntry(entry))
+ {
+ final DN entryDN = entry.getName();
+ logger.trace("Skipping entry %s because the DN is not one that "
+ + "should be included based on the include and exclude filters.", entryDN);
+ logToSkipWriter(lines, ERR_LDIF_SKIP.get(entryDN));
+ return false;
+ }
+ }
+ catch (Exception e)
+ {
+ logger.traceException(e);
+
+ LocalizableMessage message =
+ ERR_LDIF_COULD_NOT_EVALUATE_FILTERS_FOR_IMPORT.get(entry.getName(), lastEntryLineNumber, e);
+ throw new LDIFException(message, lastEntryLineNumber, true, e);
+ }
+ return true;
+ }
+
+ private boolean invokeImportPlugins(Entry entry, LinkedList<StringBuilder> lines)
+ {
+ if (importConfig.invokeImportPlugins())
+ {
+ PluginResult.ImportLDIF pluginResult =
+ pluginConfigManager.invokeLDIFImportPlugins(importConfig, entry);
+ if (!pluginResult.continueProcessing())
+ {
+ final DN entryDN = entry.getName();
+ LocalizableMessage m;
+ LocalizableMessage rejectMessage = pluginResult.getErrorMessage();
+ if (rejectMessage == null)
+ {
+ m = ERR_LDIF_REJECTED_BY_PLUGIN_NOMESSAGE.get(entryDN);
+ }
+ else
+ {
+ m = ERR_LDIF_REJECTED_BY_PLUGIN.get(entryDN, rejectMessage);
+ }
+
+ logToRejectWriter(lines, m);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private void validateAgainstSchemaIfNeeded(boolean checkSchema, final Entry entry, LinkedList<StringBuilder> lines)
+ throws LDIFException
+ {
+ if (checkSchema)
+ {
+ LocalizableMessageBuilder invalidReason = new LocalizableMessageBuilder();
+ if (!entry.conformsToSchema(null, false, true, false, invalidReason))
+ {
+ final DN entryDN = entry.getName();
+ LocalizableMessage message = ERR_LDIF_SCHEMA_VIOLATION.get(entryDN, lastEntryLineNumber, invalidReason);
+ logToRejectWriter(lines, message);
+ throw new LDIFException(message, lastEntryLineNumber, true);
+ }
+ // Add any superior objectclass(s) missing in an entries objectclass map.
+ addSuperiorObjectClasses(entry.getObjectClasses());
+ }
+ }
+
+ /**
+ * Returns a new Map where the provided Map with AttributeBuilders is converted to another Map
+ * with Attributes.
+ *
+ * @param attrBuilders
+ * the provided Map containing AttributeBuilders
+ * @return a new Map containing Attributes
+ */
+ protected Map<AttributeType, List<Attribute>> toAttributesMap(Map<AttributeType, List<AttributeBuilder>> attrBuilders)
+ {
+ Map<AttributeType, List<Attribute>> attributes = new HashMap<AttributeType, List<Attribute>>(attrBuilders.size());
+ for (Map.Entry<AttributeType, List<AttributeBuilder>> attrTypeEntry : attrBuilders.entrySet())
+ {
+ AttributeType attrType = attrTypeEntry.getKey();
+ List<Attribute> attrList = toAttributesList(attrTypeEntry.getValue());
+ attributes.put(attrType, attrList);
+ }
+ return attributes;
+ }
+
+ /**
+ * Converts the provided List of AttributeBuilders to a new list of Attributes.
+ *
+ * @param builders the list of AttributeBuilders
+ * @return a new list of Attributes
+ */
+ protected List<Attribute> toAttributesList(List<AttributeBuilder> builders)
+ {
+ List<Attribute> results = new ArrayList<Attribute>(builders.size());
+ for (AttributeBuilder builder : builders)
+ {
+ results.add(builder.toAttribute());
+ }
+ return results;
+ }
+
/**
* Reads the next change record from the LDIF source.
*
@@ -684,8 +462,7 @@
*
* @throws LDIFException If the information read is not valid LDIF.
*/
- private LinkedList<StringBuilder> readEntryLines()
- throws IOException, LDIFException
+ protected LinkedList<StringBuilder> readEntryLines() throws IOException, LDIFException
{
// Read the entry lines into a buffer.
LinkedList<StringBuilder> lines = new LinkedList<StringBuilder>();
@@ -789,8 +566,7 @@
* second after the LDIF version), or if a problem
* occurs while trying to parse it.
*/
- private DN readDN(LinkedList<StringBuilder> lines)
- throws LDIFException
+ protected DN readDN(LinkedList<StringBuilder> lines) throws LDIFException
{
if (lines.isEmpty())
{
@@ -1011,7 +787,7 @@
* @throws LDIFException If a problem occurs while trying to decode the
* attribute contained in the provided entry.
*/
- private void readAttribute(List<StringBuilder> lines,
+ protected void readAttribute(List<StringBuilder> lines,
StringBuilder line, DN entryDN,
Map<ObjectClass,String> objectClasses,
Map<AttributeType,List<AttributeBuilder>> userAttrBuilders,
@@ -1846,7 +1622,7 @@
* @param message
* The associated error message.
*/
- private void logToRejectWriter(List<StringBuilder> lines, LocalizableMessage message)
+ protected void logToRejectWriter(List<StringBuilder> lines, LocalizableMessage message)
{
entriesRejected.incrementAndGet();
BufferedWriter rejectWriter = importConfig.getRejectWriter();
@@ -1864,7 +1640,7 @@
* @param message
* The associated error message.
*/
- private void logToSkipWriter(List<StringBuilder> lines, LocalizableMessage message)
+ protected void logToSkipWriter(List<StringBuilder> lines, LocalizableMessage message)
{
entriesIgnored.incrementAndGet();
BufferedWriter skipWriter = importConfig.getSkipWriter();
@@ -1912,8 +1688,11 @@
/**
* Adds any missing RDN attributes to the entry that is being imported.
+ * @param entryDN the entry DN
+ * @param userAttributes the user attributes
+ * @param operationalAttributes the operational attributes
*/
- private void addRDNAttributesIfNecessary(DN entryDN,
+ protected void addRDNAttributesIfNecessary(DN entryDN,
Map<AttributeType,List<Attribute>>userAttributes,
Map<AttributeType,List<Attribute>> operationalAttributes)
{
--
Gitblit v1.10.0