From 5bd8fa4ffc02593312ad3fca9651730b060c56e3 Mon Sep 17 00:00:00 2001
From: Jean-Noel Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Thu, 30 Oct 2014 11:09:26 +0000
Subject: [PATCH] OPENDJ-1613 (CR-5064) NullPointerException while searching on ch=changelog

---
 opendj3-server-dev/src/server/org/opends/server/replication/server/changelog/je/JEReplicaDBCursor.java |   38 +++++++++++++++++++++++++++++---------
 1 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/opendj3-server-dev/src/server/org/opends/server/replication/server/changelog/je/JEReplicaDBCursor.java b/opendj3-server-dev/src/server/org/opends/server/replication/server/changelog/je/JEReplicaDBCursor.java
index c759d67..af75e57 100644
--- a/opendj3-server-dev/src/server/org/opends/server/replication/server/changelog/je/JEReplicaDBCursor.java
+++ b/opendj3-server-dev/src/server/org/opends/server/replication/server/changelog/je/JEReplicaDBCursor.java
@@ -48,8 +48,13 @@
   private JEReplicaDB replicaDB;
   private final CSN startCSN;
   private CSN lastNonNullCurrentCSN;
+  /**
+   * The underlying replica DB cursor.
+   * <p>
+   * Initially <code>null</code>, the first call to {@link #next()} will
+   * populate it. A call to {@link #close()} will set it to null again.
+   */
   private ReplServerDBCursor cursor;
-  private UpdateMsg currentChange;
 
   /**
    * Creates a new {@link JEReplicaDBCursor}. All created cursor must be
@@ -84,14 +89,24 @@
   @Override
   public UpdateMsg getRecord()
   {
-    return currentChange;
+    if (!isClosed() && cursor != null)
+    {
+      return cursor.getRecord();
+    }
+    return null;
   }
 
   /** {@inheritDoc} */
   @Override
   public boolean next() throws ChangelogException
   {
-    if (currentChange == null)
+    if (isClosed())
+    {
+      return false;
+    }
+
+    final ReplServerDBCursor previousCursor = cursor;
+    if (getRecord() == null)
     {
       synchronized (this)
       {
@@ -112,16 +127,16 @@
     }
 
     // For ON_MATCHING_KEY, do not call next() if the cursor has just been initialized.
-    if (positionStrategy == ON_MATCHING_KEY && currentChange != null
+    if (positionStrategy == ON_MATCHING_KEY && previousCursor != null
         || positionStrategy == AFTER_MATCHING_KEY)
     {
       cursor.next();
     }
-    currentChange = cursor.getRecord();
 
-    if (currentChange != null)
+    final UpdateMsg currentRecord = cursor.getRecord();
+    if (currentRecord != null)
     {
-      lastNonNullCurrentCSN = currentChange.getCSN();
+      lastNonNullCurrentCSN = currentRecord.getCSN();
       return true;
     }
     return false;
@@ -138,13 +153,17 @@
     }
   }
 
+  private boolean isClosed()
+  {
+    return replicaDB == null;
+  }
+
   private void closeCursor()
   {
     if (cursor != null)
     {
       cursor.close();
       cursor = null;
-      currentChange = null;
     }
   }
 
@@ -164,8 +183,9 @@
   public String toString()
   {
     return getClass().getSimpleName()
+        + " currentChange=" + cursor.getRecord()
         + " positionStrategy=" + positionStrategy
-        + " currentChange=" + currentChange
+        + " matchingStrategy=" + matchingStrategy
         + " replicaDB=" + replicaDB;
   }
 }

--
Gitblit v1.10.0