From 50ea9b3f016e83c6de04bc3a5b990708f347b464 Mon Sep 17 00:00:00 2001
From: Nicolas Capponi <nicolas.capponi@forgerock.com>
Date: Mon, 23 Dec 2013 12:07:00 +0000
Subject: [PATCH] 

---
 opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/LDIF.java                 |   85 +++++++++++++++++---
 opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties      |    4 +
 opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/LDIFTestCase.java         |  112 ++++++++++++++++++---------
 opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Entries.java              |   24 ++++--
 opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/AbstractLDIFTestCase.java |    4 
 5 files changed, 167 insertions(+), 62 deletions(-)

diff --git a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Entries.java b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Entries.java
index 054cd43..b976318 100644
--- a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Entries.java
+++ b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Entries.java
@@ -33,7 +33,6 @@
 
 import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
 
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -44,6 +43,7 @@
 import java.util.Set;
 
 import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.i18n.LocalizedIllegalArgumentException;
 import org.forgerock.opendj.ldap.controls.PermissiveModifyRequestControl;
 import org.forgerock.opendj.ldap.requests.ModifyRequest;
 import org.forgerock.opendj.ldap.requests.Requests;
@@ -601,10 +601,14 @@
      * @param ldifLines
      *          LDIF lines that contains entry definition.
      * @return an entry
-     * @throws IOException
-     *          If an error occurs.
+     * @throws LocalizedIllegalArgumentException
+     *            If {@code ldifLines} did not contain an LDIF entry, or
+     *            contained multiple entries, or contained malformed LDIF, or
+     *            if the entry could not be decoded using the default schema.
+     * @throws NullPointerException
+     *             If {@code ldifLines} was {@code null}.
      */
-    public static Entry makeEntry(String... ldifLines) throws IOException {
+    public static Entry makeEntry(String... ldifLines) {
         return LDIF.makeEntry(ldifLines);
     }
 
@@ -629,11 +633,15 @@
      * @param ldifLines
      *          LDIF lines that contains entries definition.
      *          Entries are separated by an empty string: {@code ""}.
-     * @return a list of entries
-     * @throws IOException
-     *          If an error occurs.
+     * @return a non empty list of entries
+     * @throws LocalizedIllegalArgumentException
+     *             If {@code ldifLines} did not contain LDIF entries,
+     *             or contained malformed LDIF, or if the entries
+     *             could not be decoded using the default schema.
+     * @throws NullPointerException
+     *             If {@code ldifLines} was {@code null}.
      */
-    public static List<Entry> makeEntries(String... ldifLines) throws IOException {
+    public static List<Entry> makeEntries(String... ldifLines) {
         return LDIF.makeEntries(ldifLines);
     }
 
diff --git a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/LDIF.java b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/LDIF.java
index d053bef..e0f66db 100644
--- a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/LDIF.java
+++ b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldif/LDIF.java
@@ -25,9 +25,7 @@
 
 package org.forgerock.opendj.ldif;
 
-import static com.forgerock.opendj.ldap.CoreMessages.REJECTED_CHANGE_FAIL_DELETE;
-import static com.forgerock.opendj.ldap.CoreMessages.REJECTED_CHANGE_FAIL_MODIFY;
-import static com.forgerock.opendj.ldap.CoreMessages.REJECTED_CHANGE_FAIL_MODIFYDN;
+import static com.forgerock.opendj.ldap.CoreMessages.*;
 import static com.forgerock.opendj.util.StaticUtils.getBytes;
 
 import java.io.IOException;
@@ -42,6 +40,7 @@
 import java.util.SortedMap;
 import java.util.TreeMap;
 
+import org.forgerock.i18n.LocalizedIllegalArgumentException;
 import org.forgerock.opendj.io.ASN1;
 import org.forgerock.opendj.io.LDAP;
 import org.forgerock.opendj.ldap.AVA;
@@ -257,13 +256,40 @@
      *
      * @param ldifLines
      *          LDIF lines that contains entry definition.
-     * @return an entry, or {@code null} if no ldif line is provided
-     * @throws IOException
-     *          If an error occurs.
+     * @return an entry
+     * @throws LocalizedIllegalArgumentException
+     *            If {@code ldifLines} did not contain an LDIF entry, or
+     *            contained multiple entries, or contained malformed LDIF, or
+     *            if the entry could not be decoded using the default schema.
+     * @throws NullPointerException
+     *             If {@code ldifLines} was {@code null}.
      */
-    public static Entry makeEntry(String... ldifLines) throws IOException {
+    public static Entry makeEntry(String... ldifLines) {
+        // returns a non-empty list
         List<Entry> entries = makeEntries(ldifLines);
-        return entries.isEmpty() ? null : entries.get(0);
+        if (entries.size() > 1) {
+            throw new LocalizedIllegalArgumentException(
+                WARN_READ_LDIF_ENTRY_MULTIPLE_ENTRIES_FOUND.get(entries.size()));
+        }
+        return entries.get(0);
+    }
+
+    /**
+     * Builds an entry from the provided lines of LDIF.
+     *
+     * @param ldifLines
+     *            LDIF lines that contains entry definition.
+     * @return an entry
+     * @throws LocalizedIllegalArgumentException
+     *             If {@code ldifLines} did not contain an LDIF entry, or
+     *             contained multiple entries, or contained malformed LDIF, or
+     *             if the entry could not be decoded using the default schema.
+     * @throws NullPointerException
+     *             If {@code ldifLines} was {@code null}.
+     * @see {@code LDIF#makeEntry(String...)}
+     */
+    public static Entry makeEntry(List<String> ldifLines) {
+        return makeEntry(ldifLines.toArray(new String[ldifLines.size()]));
     }
 
     /**
@@ -287,25 +313,56 @@
      * @param ldifLines
      *          LDIF lines that contains entries definition.
      *          Entries are separated by an empty string: {@code ""}.
-     * @return a list of entries
-     * @throws IOException
-     *          If an error occurs.
+     * @return a non empty list of entries
+     * @throws LocalizedIllegalArgumentException
+     *             If {@code ldifLines} did not contain LDIF entries,
+     *             or contained malformed LDIF, or if the entries
+     *             could not be decoded using the default schema.
+     * @throws NullPointerException
+     *             If {@code ldifLines} was {@code null}.
      */
-    public static List<Entry> makeEntries(String... ldifLines) throws IOException {
+    public static List<Entry> makeEntries(String... ldifLines) {
         List<Entry> entries = new ArrayList<Entry>();
-        LDIFEntryReader reader = null;
+        LDIFEntryReader reader = new LDIFEntryReader(ldifLines);
         try {
-            reader = new LDIFEntryReader(ldifLines);
             while (reader.hasNext()) {
                 entries.add(reader.readEntry());
             }
+        } catch (final DecodeException e) {
+            // Badly formed LDIF.
+            throw new LocalizedIllegalArgumentException(e.getMessageObject());
+        } catch (final IOException e) {
+            // This should never happen for a String based reader.
+            throw new LocalizedIllegalArgumentException(WARN_READ_LDIF_RECORD_UNEXPECTED_IO_ERROR.get(e.getMessage()));
         } finally {
             StaticUtils.closeSilently(reader);
         }
+        if (entries.isEmpty()) {
+            throw new LocalizedIllegalArgumentException(WARN_READ_LDIF_ENTRY_NO_ENTRY_FOUND.get());
+        }
         return entries;
     }
 
     /**
+     * Builds a list of entries from the provided lines of LDIF.
+     *
+     * @param ldifLines
+     *            LDIF lines that contains entries definition. Entries are
+     *            separated by an empty string: {@code ""}.
+     * @return a non empty list of entries
+     * @throws LocalizedIllegalArgumentException
+     *             If {@code ldifLines} did not contain LDIF entries, or
+     *             contained malformed LDIF, or if the entries could not be
+     *             decoded using the default schema.
+     * @throws NullPointerException
+     *             If {@code ldifLines} was {@code null}.
+     * @see {@code LDIF#makeEntries(String...)}
+     */
+    public static List<Entry> makeEntries(List<String> ldifLines) {
+        return makeEntries(ldifLines.toArray(new String[ldifLines.size()]));
+    }
+
+    /**
      * Returns an entry reader over the provided entry collection.
      *
      * @param entries
diff --git a/opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties b/opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties
index a09f7d8..9e0eecf 100755
--- a/opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties
+++ b/opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties
@@ -916,6 +916,10 @@
  content did not contain an "%s" change record
 WARN_READ_LDIF_RECORD_UNEXPECTED_IO_ERROR=An unexpected IO error \
  occurred while reading the provided LDIF content: %s
+WARN_READ_LDIF_ENTRY_NO_ENTRY_FOUND=The provided LDIF \
+ content did not contain any entry
+WARN_READ_LDIF_ENTRY_MULTIPLE_ENTRIES_FOUND=The provided LDIF \
+ content contained %d entries, when only one was expected
 #
 # Extension messages
 #
diff --git a/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/AbstractLDIFTestCase.java b/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/AbstractLDIFTestCase.java
index 81f8eb8..35ddf66 100644
--- a/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/AbstractLDIFTestCase.java
+++ b/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/AbstractLDIFTestCase.java
@@ -26,7 +26,7 @@
  */
 package org.forgerock.opendj.ldif;
 
-import org.forgerock.testng.ForgeRockTestCase;
+import org.forgerock.opendj.ldap.SdkTestCase;
 import org.testng.annotations.Test;
 
 /**
@@ -35,7 +35,7 @@
  */
 
 @Test(groups = { "precommit", "types", "sdk" })
-public abstract class AbstractLDIFTestCase extends ForgeRockTestCase {
+public abstract class AbstractLDIFTestCase extends SdkTestCase {
 }
 
 
diff --git a/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/LDIFTestCase.java b/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/LDIFTestCase.java
index cd7cb01..41839f9 100644
--- a/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/LDIFTestCase.java
+++ b/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldif/LDIFTestCase.java
@@ -32,6 +32,7 @@
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
@@ -57,6 +58,8 @@
 import org.forgerock.opendj.ldap.schema.SchemaBuilder;
 import org.testng.annotations.Test;
 
+import com.forgerock.opendj.ldap.CoreMessages;
+
 /**
  * This class tests the LDIF functionality.
  */
@@ -2745,75 +2748,108 @@
         LDIF.patch(null, null);
     }
 
+    // @formatter:off
+    private static final List<String> LDIF_ONE_ENTRY = Arrays.asList(
+        "dn: uid=user.1,ou=People,dc=example,dc=com",
+        "objectClass: top",
+        "objectClass: person",
+        "objectClass: organizationalperson",
+        "objectClass: inetorgperson",
+        "givenName: Eniko",
+        "sn: Atpco",
+        "cn: Eniko Atpco",
+        "uid: user.1");
+    // @formatter:on
+
+    // @formatter:off
+    private static final List<String> LDIF_TWO_ENTRIES = Arrays.asList(
+        "dn: uid=user.1,ou=People,dc=example,dc=com",
+        "objectClass: top",
+        "objectClass: person",
+        "objectClass: organizationalperson",
+        "objectClass: inetorgperson",
+        "givenName: Eniko",
+        "sn: Atpco",
+        "uid: user.1",
+        "",
+        "dn: uid=user.2,ou=People,dc=example,dc=com",
+        "objectClass: top",
+        "objectClass: person",
+        "objectClass: organizationalperson",
+        "objectClass: inetorgperson",
+        "givenName: Aaaron",
+        "sn: Atp",
+        "uid: user.2");
+
     @Test
     public void testMakeEntry() throws Exception {
-        // @formatter:off
-        final Entry entry = LDIF.makeEntry(
-            "dn: uid=user.1,ou=People,dc=example,dc=com",
-            "objectClass: top",
-            "objectClass: person",
-            "objectClass: organizationalperson",
-            "objectClass: inetorgperson",
-            "givenName: Eniko",
-            "sn: Atpco",
-            "cn: Eniko Atpco",
-            "uid: user.1"
-        );
-        // @formatter:on
+        final Entry entry = LDIF.makeEntry(LDIF_ONE_ENTRY);
+        final Entry entry2 = LDIF.makeEntry(LDIF_ONE_ENTRY.toArray(new String[0]));
+
         assertThat(entry.getName().toString()).isEqualTo("uid=user.1,ou=People,dc=example,dc=com");
         assertThat(entry.getAttribute("objectClass").firstValueAsString()).isEqualTo("top");
         assertThat(entry.getAttribute("uid").firstValueAsString()).isEqualTo("user.1");
         assertThat(entry.getAttribute("givenName").firstValueAsString()).isEqualTo("Eniko");
         assertThat(entry.getAttribute("sn").firstValueAsString()).isEqualTo("Atpco");
+        assertThat(entry2).isEqualTo(entry);
     }
 
     @Test
     public void testMakeEntries() throws Exception {
         // @formatter:off
-        final List<Entry> entries = LDIF.makeEntries(
-            "dn: uid=user.1,ou=People,dc=example,dc=com",
-            "objectClass: top",
-            "objectClass: person",
-            "objectClass: organizationalperson",
-            "objectClass: inetorgperson",
-            "givenName: Eniko",
-            "sn: Atpco",
-            "uid: user.1",
-            "",
-            "dn: uid=user.2,ou=People,dc=example,dc=com",
-            "objectClass: top",
-            "objectClass: person",
-            "objectClass: organizationalperson",
-            "objectClass: inetorgperson",
-            "givenName: Aaaron",
-            "sn: Atp",
-            "uid: user.2"
-        );
+        final List<Entry> entries = LDIF.makeEntries(LDIF_TWO_ENTRIES);
+        final List<Entry> entries2 = LDIF.makeEntries(LDIF_TWO_ENTRIES.toArray(new String[0]));
+
         // @formatter:on
         assertThat(entries).hasSize(2);
         assertThat(entries.get(0).getName().toString()).isEqualTo("uid=user.1,ou=People,dc=example,dc=com");
         assertThat(entries.get(1).getName().toString()).isEqualTo("uid=user.2,ou=People,dc=example,dc=com");
+        assertThat(entries2).isEqualTo(entries);
     }
 
     @Test
     public void testMakeEntryEmpty() throws Exception {
-        final Entry entry = LDIF.makeEntry();
-        assertThat(entry).isNull();
+        try {
+            LDIF.makeEntry();
+            failWasExpected(LocalizedIllegalArgumentException.class);
+        } catch (LocalizedIllegalArgumentException e) {
+            assertThat(e.getMessageObject()).isEqualTo(CoreMessages.WARN_READ_LDIF_ENTRY_NO_ENTRY_FOUND.get());
+        }
     }
 
-    @Test(expectedExceptions = DecodeException.class)
+    @Test
+    public void testMakeEntryWithMultipleEntries() throws Exception {
+        try {
+            LDIF.makeEntry(LDIF_TWO_ENTRIES);
+            failWasExpected(LocalizedIllegalArgumentException.class);
+        } catch (LocalizedIllegalArgumentException e) {
+            assertThat(e.getMessageObject()).isEqualTo(
+                CoreMessages.WARN_READ_LDIF_ENTRY_MULTIPLE_ENTRIES_FOUND.get(2));
+        }
+    }
+
+    @Test(expectedExceptions = LocalizedIllegalArgumentException.class)
     public void testMakeEntryBadLDif() throws Exception {
         LDIF.makeEntry("dummy: uid=user.1,ou=People,dc=example,dc=com");
     }
 
     @Test
     public void testMakeEntriesEmpty() throws Exception {
-        final List<Entry> entries = LDIF.makeEntries();
-        assertThat(entries).hasSize(0);
+        try {
+            LDIF.makeEntries();
+            failWasExpected(LocalizedIllegalArgumentException.class);
+        } catch (LocalizedIllegalArgumentException e) {
+            assertThat(e.getMessageObject()).isEqualTo(CoreMessages.WARN_READ_LDIF_ENTRY_NO_ENTRY_FOUND.get());
+        }
     }
 
-    @Test(expectedExceptions = DecodeException.class)
+    @Test(expectedExceptions = LocalizedIllegalArgumentException.class)
     public void testMakeEntriesBadLDif() throws Exception {
         LDIF.makeEntries("dummy: uid=user.1,ou=People,dc=example,dc=com");
     }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testMakeEntriesNull() throws Exception {
+        LDIF.makeEntries((String[]) null);
+    }
 }

--
Gitblit v1.10.0