From 78a26a979db4a0b5c1fe178881410c55ece1d758 Mon Sep 17 00:00:00 2001
From: jvergara <jvergara@localhost>
Date: Wed, 27 Jan 2010 22:01:06 +0000
Subject: [PATCH] Fix for issue 4517 (Cannot use control panel to edit entry in replicated base DN after a binary update happened in the entry) Treat the ds-sync-hist in a special manner.  It is an attribute with DirectoryString syntax but it can contain byte[] values expressed in a String format which can completely break the UI and the entry processing.

---
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/LDIFViewEntryPanel.java        |    4 +
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/SimplifiedViewEntryPanel.java  |    4 +
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/ViewEntryPanel.java            |   87 ++++++++++++++++++++++++++++-
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/TableViewEntryPanel.java       |   12 ++-
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/CustomSearchResult.java |   21 +++++-
 opendj-sdk/opends/src/messages/messages/admin_tool.properties                                     |    2 
 6 files changed, 118 insertions(+), 12 deletions(-)

diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/CustomSearchResult.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/CustomSearchResult.java
index be4ed69..76e71fa 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/CustomSearchResult.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/CustomSearchResult.java
@@ -66,7 +66,6 @@
  *
  */
 public class CustomSearchResult implements Comparable<CustomSearchResult> {
-  private Name name;
   private String dn;
   private Map<String, List<Object>> attributes;
   private SortedSet<String> attrNames;
@@ -99,6 +98,7 @@
   throws NamingException
   {
     String sName = sr.getName();
+    Name name;
     if ((baseDN != null) && (baseDN.length() > 0))
     {
       if ((sName != null) && (sName.length() > 0))
@@ -137,8 +137,8 @@
       NamingEnumeration<?> en = attrs.getAll();
       while (en.hasMore()) {
         Attribute attr = (Attribute)en.next();
-        String name = attr.getID();
-        attrNames.add(name);
+        String attrName = attr.getID();
+        attrNames.add(attrName);
         List<Object> values = new ArrayList<Object>();
         for (int i=0; i<attr.size(); i++)
         {
@@ -148,7 +148,7 @@
             values.add(v);
           }
         }
-        attributes.put(name.toLowerCase(), values);
+        attributes.put(attrName.toLowerCase(), values);
       }
     }
     toString = calculateToString();
@@ -206,6 +206,19 @@
   /**
    * {@inheritDoc}
    */
+  public CustomSearchResult clone()
+  {
+    CustomSearchResult sr = new CustomSearchResult(dn);
+    sr.attributes = new HashMap<String, List<Object>>(attributes);
+    sr.attrNames = new TreeSet<String>(attrNames);
+    sr.toString = toString;
+    sr.hashCode = hashCode;
+    return sr;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
   public boolean equals(Object o)
   {
     boolean equals = false;
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/LDIFViewEntryPanel.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/LDIFViewEntryPanel.java
index 1d7a9fa..0867c5f 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/LDIFViewEntryPanel.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/LDIFViewEntryPanel.java
@@ -152,6 +152,10 @@
   public void update(CustomSearchResult sr, boolean isReadOnly, TreePath path)
   {
     boolean sameEntry = false;
+    if (sr != null)
+    {
+      sr = filterSearchResult(sr);
+    }
     if ((searchResult != null) && (sr != null))
     {
       sameEntry = searchResult.getDN().equals(sr.getDN());
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/SimplifiedViewEntryPanel.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/SimplifiedViewEntryPanel.java
index 5dfdded..bf7480e 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/SimplifiedViewEntryPanel.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/SimplifiedViewEntryPanel.java
@@ -433,6 +433,10 @@
   public void update(CustomSearchResult sr, boolean isReadOnly, TreePath path)
   {
     boolean sameEntry = false;
+    if (sr != null)
+    {
+      sr = filterSearchResult(sr);
+    }
     if ((searchResult != null) && (sr != null))
     {
       sameEntry = searchResult.getDN().equals(sr.getDN());
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/TableViewEntryPanel.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/TableViewEntryPanel.java
index 7386aa1..aef18ec 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/TableViewEntryPanel.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/TableViewEntryPanel.java
@@ -174,6 +174,10 @@
   public void update(CustomSearchResult sr, boolean isReadOnly, TreePath path)
   {
     boolean sameEntry = false;
+    if (sr != null)
+    {
+      sr = filterSearchResult(sr);
+    }
     if ((searchResult != null) && (sr != null))
     {
       sameEntry = searchResult.getDN().equals(sr.getDN());
@@ -189,7 +193,7 @@
     this.treePath = path;
     updateTitle(sr, path);
     ignoreEntryChangeEvents = true;
-    tableModel.displayEntry(searchResult);
+    tableModel.displayEntry();
     Utilities.updateTableSizes(table);
     Utilities.updateScrollMode(scroll, table);
     SwingUtilities.invokeLater(new Runnable()
@@ -458,10 +462,10 @@
     private boolean sortAscending = true;
 
     /**
-     * Sets the entry to be displayed by this table model.
-     * @param searchResult the entry to be displayed.
+     * Updates the contents of the table model with the
+     * {@code TableViewEntryPanel.searchResult} object.
      */
-    public void displayEntry(CustomSearchResult searchResult)
+    public void displayEntry()
     {
       updateDataArray();
       fireTableDataChanged();
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/ViewEntryPanel.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/ViewEntryPanel.java
index ca8ccbe..ad80e04 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/ViewEntryPanel.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/ViewEntryPanel.java
@@ -53,6 +53,7 @@
 import org.opends.guitools.controlpanel.util.Utilities;
 import org.opends.messages.Message;
 import org.opends.server.api.AttributeSyntax;
+import org.opends.server.replication.plugin.Historical;
 import org.opends.server.schema.SchemaConstants;
 import org.opends.server.types.AttributeType;
 import org.opends.server.types.AttributeValue;
@@ -517,10 +518,10 @@
    */
   protected boolean isPassword(String attrName)
   {
-    boolean isBinary = false;
+    boolean isPassword = false;
     Schema schema = getInfo().getServerDescriptor().getSchema();
-    isBinary = Utilities.hasPasswordSyntax(attrName, schema);
-    return isBinary;
+    isPassword = Utilities.hasPasswordSyntax(attrName, schema);
+    return isPassword;
   }
 
   /**
@@ -632,4 +633,84 @@
     }
     return isEditable;
   }
+
+  /**
+   * This method is called because the ds-sync-hist attribute has a
+   * DirectoryString syntax, but it contains byte[] on it (if there has been
+   * a modification in a binary value).
+   * @param sr the search result to use.
+   * @return the filtered search result to be used to be displayed.
+   */
+  protected CustomSearchResult filterSearchResult(CustomSearchResult sr)
+  {
+    CustomSearchResult filteredSr;
+    List<Object> values =
+      sr.getAttributeValues(Historical.HISTORICALATTRIBUTENAME);
+    if (values != null)
+    {
+      List<Object> newValues = new ArrayList<Object>();
+      for (Object v : values)
+      {
+        newValues.add(filterStringValue(String.valueOf(v)));
+      }
+      if (newValues.equals(values))
+      {
+        filteredSr = sr;
+      }
+      else
+      {
+        filteredSr = sr.clone();
+        filteredSr.set(Historical.HISTORICALATTRIBUTENAME, newValues);
+      }
+    }
+    else
+    {
+      filteredSr = sr;
+    }
+    return filteredSr;
+  }
+
+  /**
+   * This method is called because the ds-sync-hist attribute has a
+   * DirectoryString syntax, but it contains byte[] on it (if there has been
+   * a modification in a binary value).
+   * @param value the value to be filtered.
+   * @return the value that will actually be displayed.
+   */
+  private String filterStringValue(String value)
+  {
+    String filteredValue;
+    // Parse the value to find out if this corresponds to a change in a
+    // binary attribute.
+    int index = value.indexOf(":");
+    if (index != -1)
+    {
+      String modifiedAttr = value.substring(0, index).trim();
+      modifiedAttr = Utilities.getAttributeNameWithoutOptions(modifiedAttr);
+      if (isBinary(modifiedAttr))
+      {
+        String replTag = "repl:";
+        int index2 = value.indexOf(replTag, index);
+        if (index2 != -1)
+        {
+          filteredValue = value.substring(0, index2+replTag.length()) +
+          INFO_CTRL_PANEL_DS_SYNC_HIST_BINARY_VALUE.get();
+        }
+        else
+        {
+          filteredValue = value.substring(0, index+1) +
+          INFO_CTRL_PANEL_DS_SYNC_HIST_BINARY_VALUE.get();
+        }
+      }
+      else
+      {
+        filteredValue = value;
+      }
+    }
+    else
+    {
+      filteredValue = value;
+    }
+    return filteredValue;
+  }
 }
diff --git a/opendj-sdk/opends/src/messages/messages/admin_tool.properties b/opendj-sdk/opends/src/messages/messages/admin_tool.properties
index 0e59332..1040f78 100644
--- a/opendj-sdk/opends/src/messages/messages/admin_tool.properties
+++ b/opendj-sdk/opends/src/messages/messages/admin_tool.properties
@@ -2969,4 +2969,4 @@
 INFO_CTRL_PANEL_DUPLICATE_ENTRY_DN=Entry DN:
 INFO_CTRL_PANEL_ENTRY_TO_DUPLICATE_HAS_PASSWORD_WARNING=The duplicated entry \
  will contain a password with value '%s'
-
+INFO_CTRL_PANEL_DS_SYNC_HIST_BINARY_VALUE=<Binary Value>

--
Gitblit v1.10.0