mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

ludovicp
31.55.2010 6411dcff8da8710f140a8782967ddf0876f52b81
Provide the necessary operational attributes for External Changelog entries, to make them LDAP compliant and to allow browsing them through the Control-Panel.
Improve browsing in the Control-Panel to make use of hasSubordinates as well as numSubordinates operational attributes.
Improve Control-Panel look and feel when browsing the ECL
11 files modified
562 ■■■■ changed files
opends/src/guitools/org/opends/guitools/controlpanel/browser/BrowserController.java 117 ●●●●● patch | view | raw | blame | history
opends/src/guitools/org/opends/guitools/controlpanel/browser/NodeRefresher.java 8 ●●●●● patch | view | raw | blame | history
opends/src/guitools/org/opends/guitools/controlpanel/task/DeleteEntryTask.java 2 ●●● patch | view | raw | blame | history
opends/src/guitools/org/opends/guitools/controlpanel/ui/AbstractBrowseEntriesPanel.java 31 ●●●● patch | view | raw | blame | history
opends/src/guitools/org/opends/guitools/controlpanel/ui/LDAPEntryPanel.java 12 ●●●● patch | view | raw | blame | history
opends/src/guitools/org/opends/guitools/controlpanel/ui/SimplifiedViewEntryPanel.java 13 ●●●●● patch | view | raw | blame | history
opends/src/guitools/org/opends/guitools/controlpanel/ui/nodes/BasicNode.java 22 ●●●●● patch | view | raw | blame | history
opends/src/guitools/org/opends/guitools/controlpanel/ui/nodes/BrowserNodeInfo.java 8 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/monitors/BackendMonitor.java 4 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/types/Entry.java 4 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/workflowelement/externalchangelog/ECLSearchOperation.java 341 ●●●●● patch | view | raw | blame | history
opends/src/guitools/org/opends/guitools/controlpanel/browser/BrowserController.java
@@ -33,6 +33,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
@@ -59,6 +60,7 @@
import org.opends.admin.ads.ADSContext;
import org.opends.admin.ads.util.ConnectionUtils;
import org.opends.guitools.controlpanel.datamodel.CustomSearchResult;
import org.opends.guitools.controlpanel.datamodel.ServerDescriptor;
import org.opends.guitools.controlpanel.event.BrowserEvent;
import org.opends.guitools.controlpanel.event.BrowserEventListener;
@@ -1276,6 +1278,7 @@
    v.add("objectClass");
    v.add("numsubordinates");
    v.add("hassubordinates");
    v.add("ref");
    if ((displayFlags & DISPLAY_ACI_COUNT) != 0) {
      v.add("aci");
@@ -1315,6 +1318,7 @@
      return new String[] {
          "objectClass",
          "numsubordinates",
          "hassubordinates",
          "ref",
          "aci",
          displayAttribute};
@@ -1322,6 +1326,7 @@
      return new String[] {
          "objectClass",
          "numsubordinates",
          "hassubordinates",
          "ref",
          "aci"
      };
@@ -1656,9 +1661,8 @@
      // numSubOrdinates attribute. If the child entry's DN
      // is found in the hacker's list, then we ignore
      // the numSubordinate attribute... :((
      int numSubOrdinates = child.getNumSubOrdinates();
      boolean hasNoSubOrdinates;
      if ((numSubOrdinates == 0) && dontTrust) {
      if (!child.hasSubOrdinates() && dontTrust) {
        LDAPURL childUrl = findUrlForDisplayedEntry(child);
        if (numSubordinateHacker.contains(childUrl)) {
          // The numSubOrdinates we have is unreliable.
@@ -1673,7 +1677,7 @@
        }
      }
      else {
        hasNoSubOrdinates = (numSubOrdinates == 0);
        hasNoSubOrdinates = !child.hasSubOrdinates();
      }
@@ -1740,6 +1744,15 @@
    if (entry != null) {
      // Get the numsubordinates
      node.setNumSubOrdinates(getNumSubOrdinates(entry));
      if (node.getNumSubOrdinates() > 0)
      {
        node.setHasSubOrdinates(true);
      }
      else
      {
        // Calculate based also in the hasSubordinates attribute
        node.setHasSubOrdinates(getHasSubOrdinates(entry));
      }
      node.setReferral(getReferral(entry));
      Set<String> ocValues = ConnectionUtils.getValues(entry, "objectClass");
      if (ocValues != null) {
@@ -1766,7 +1779,7 @@
    // Select the icon according the objectClass,...
    int modifiers = 0;
    if (node.isLeaf() && (node.getNumSubOrdinates() <= 0)) {
    if (node.isLeaf() && !node.hasSubOrdinates()) {
      modifiers |= IconPool.MODIFIER_LEAF;
    }
    if (node.getReferral() != null) {
@@ -2073,6 +2086,91 @@
    return result;
  }
  /**
   * Returns whether the entry has subordinates or not.  It uses an algorithm
   * based in hassubordinates and numsubordinates attributes.
   * @param entry the entry to analyze.
   * @throws NamingException if an error occurs.
   * @return {@code true} if the entry has subordinates according to the values
   * of hasSubordinates and numSubordinates, returns {@code false} if none of
   * the attributes could be found.
   */
  public static boolean getHasSubOrdinates(SearchResult entry)
  throws NamingException
  {
    boolean result;
    String v = ConnectionUtils.getFirstValue(entry, "hassubordinates");
    if (v == null) {
      result = getNumSubOrdinates(entry) > 0;
    }
    else {
      result = "true".equalsIgnoreCase(v);
    }
    return result;
  }
  /**
   * Get the value of the numsubordinates attribute.
   * If numsubordinates is not present, returns 0.
   * @param entry the entry to analyze.
   * @return the value of the numsubordinate attribute.  0 if the attribute
   * could not be found.
   */
  public static int getNumSubOrdinates(CustomSearchResult entry)
  {
    int result;
    List<Object> vs = entry.getAttributeValues("numsubordinates");
    String v = null;
    if (vs != null && !vs.isEmpty())
    {
      v = vs.get(0).toString();
    }
    if (v == null) {
      result = 0;
    }
    else {
      try {
        result = Integer.parseInt(v);
      }
      catch(NumberFormatException x) {
        result = 0;
      }
    }
    return result;
  }
  /**
   * Returns whether the entry has subordinates or not.  It uses an algorithm
   * based in hassubordinates and numsubordinates attributes.
   * @param entry the entry to analyze.
   * @return {@code true} if the entry has subordinates according to the values
   * of hasSubordinates and numSubordinates, returns {@code false} if none of
   * the attributes could be found.
   */
  public static boolean getHasSubOrdinates(CustomSearchResult entry)
  {
    boolean result;
    List<Object> vs = entry.getAttributeValues("hassubordinates");
    String v = null;
    if (vs != null && !vs.isEmpty())
    {
      v = vs.get(0).toString();
    }
    if (v == null) {
      result = getNumSubOrdinates(entry) > 0;
    }
    else {
      result = "true".equalsIgnoreCase(v);
    }
    return result;
  }
  /**
   * Returns the value of the 'ref' attribute.
@@ -2210,6 +2308,7 @@
    boolean isRootNode;
    String[] referral;
    int numSubOrdinates;
    boolean hasSubOrdinates;
    int errorType;
    Exception errorException;
    Object errorArg;
@@ -2229,6 +2328,7 @@
      isSuffix = node instanceof SuffixNode;
      referral = node.getReferral();
      numSubOrdinates = node.getNumSubOrdinates();
      hasSubOrdinates = node.hasSubOrdinates();
      objectClassValues = node.getObjectClassValues();
      if (node.getError() != null) {
        BasicNodeError error = node.getError();
@@ -2319,6 +2419,15 @@
    }
    /**
     * Returns whether the entry has subordinates or not.
     * @return {@code true} if the entry has subordinates and {@code false}
     * otherwise.
     */
    public boolean hasSubOrdinates() {
      return hasSubOrdinates;
    }
    /**
     * Returns the error type associated we got when refreshing the node.
     * <CODE>null</CODE> if no error was found.
     * @return the error type associated we got when refreshing the node.
opends/src/guitools/org/opends/guitools/controlpanel/browser/NodeRefresher.java
@@ -406,6 +406,7 @@
      {
        localEntry = s.next();
        localEntry.setName(node.getDN());
      }
      if (localEntry == null) {
        /* Not enough rights to read the entry or the entry simply does not
@@ -606,7 +607,7 @@
    }
    else {
      SearchResult entry = getDisplayedEntry();
      isLeafNode = (BrowserController.getNumSubOrdinates(entry) == 0);
      isLeafNode = !BrowserController.getHasSubOrdinates(entry);
    }
  }
@@ -670,8 +671,8 @@
  private boolean isNumSubOrdinatesUsable() throws NamingException {
    boolean result;
    SearchResult entry = getDisplayedEntry();
    int numSubOrdinates = BrowserController.getNumSubOrdinates(entry);
    if (numSubOrdinates == 0) { // We must check
    boolean hasSubOrdinates = BrowserController.getHasSubOrdinates(entry);
    if (!hasSubOrdinates) { // We must check
      LDAPURL url = getDisplayedUrl();
      if (controller.getNumSubordinateHacker().contains(url)) {
        // The numSubOrdinate we have is unreliable.
@@ -699,6 +700,7 @@
    InitialLdapContext ctx = null;
    BasicNode parentNode = getNode();
    parentNode.setSizeLimitReached(false);
    try {
      // Send an LDAP search
      SearchControls ctls = controller.getBasicSearchControls();
opends/src/guitools/org/opends/guitools/controlpanel/task/DeleteEntryTask.java
@@ -239,7 +239,7 @@
            InitialLdapContext ctx =
              controller.findConnectionForDisplayedEntry(node);
            useAdminCtx = controller.isConfigurationNode(node);
            if (node.getNumSubOrdinates() > 0)
            if (node.hasSubOrdinates())
            {
              deleteSubtreeWithControl(ctx, dn, path, toNotify);
            }
opends/src/guitools/org/opends/guitools/controlpanel/ui/AbstractBrowseEntriesPanel.java
@@ -756,11 +756,19 @@
        }
        else if (!added && !displayAll)
        {
          BasicNode rootNode =
            (BasicNode)controller.getTree().getModel().getRoot();
          if (controller.findChildNode(rootNode, s) == -1)
          if (isChangeLog(theDN))
          {
            controller.addNodeUnderRoot(s);
            // Consider it a suffix
            controller.addSuffix(s, null);
          }
          else
          {
            BasicNode rootNode =
              (BasicNode)controller.getTree().getModel().getRoot();
            if (controller.findChildNode(rootNode, s) == -1)
            {
              controller.addNodeUnderRoot(s);
            }
          }
        }
      }
@@ -776,6 +784,21 @@
    }
  }
  private boolean isChangeLog(DN theDN)
  {
    try
    {
      return theDN.equals(
          DN.decode(ServerConstants.DN_EXTERNAL_CHANGELOG_ROOT));
    }
    catch (Throwable t)
    {
      // Bug
      t.printStackTrace();
    }
    return false;
  }
  /**
   * Returns the LDAP filter built based in the parameters provided by the user.
   * @return the LDAP filter built based in the parameters provided by the user.
opends/src/guitools/org/opends/guitools/controlpanel/ui/LDAPEntryPanel.java
@@ -36,7 +36,6 @@
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JPanel;
@@ -627,15 +626,8 @@
  {
    final ArrayList<Message> errors = new ArrayList<Message>();
    // Check that the entry is correct.
    // Rely in numsubordinates...
    boolean isLeaf = true;
    List<Object> o = searchResult.getAttributeValues("numsubordinates");
    if (!o.isEmpty())
    {
      int numsubordinates = Integer.parseInt((String)o.iterator().next());
      isLeaf = numsubordinates <= 0;
    }
    // Rely in numsubordinates and hassubordinates
    boolean isLeaf = !BrowserController.getHasSubOrdinates(searchResult);
    if (treePath != null)
    {
opends/src/guitools/org/opends/guitools/controlpanel/ui/SimplifiedViewEntryPanel.java
@@ -483,6 +483,17 @@
        else
        {
          gbc.anchor = GridBagConstraints.WEST;
          if (values.size() == 1)
          {
            Object v = values.get(0);
            if (v instanceof String)
            {
              if (((String)v).indexOf("\n") != -1)
              {
                gbc.anchor = GridBagConstraints.NORTHWEST;
              }
            }
          }
        }
        gbc.insets.left = 0;
        gbc.gridwidth = GridBagConstraints.RELATIVE;
@@ -739,7 +750,7 @@
    Schema schema = getInfo().getServerDescriptor().getSchema();
    if (isRootEntry)
    {
      String[] attrsNotToAdd = {"entryuuid", "hasnumsubordinates",
      String[] attrsNotToAdd = {"entryuuid", "hassubordinates",
          "numsubordinates", "subschemasubentry", "entrydn",
      "hassubordinates"};
      for (String attr : sr.getAttributeNames())
opends/src/guitools/org/opends/guitools/controlpanel/ui/nodes/BasicNode.java
@@ -57,6 +57,10 @@
  private String[] referral;
  private int numSubOrdinates;
  // This is required for the case where there is an undefined number of
  // subordinates (for instance in the case of the changelog).
  private boolean hasSubOrdinates;
  private String displayName;
  private Icon icon;
  private int fontStyle;
@@ -76,6 +80,7 @@
    isLeaf = true;
    refreshNeededOnExpansion = true;
    numSubOrdinates = -1;
    hasSubOrdinates = false;
    displayName = "";
  }
@@ -277,6 +282,23 @@
  }
  /**
   * Returns whether the entry has subordinates or not.
   * @return {@code true} if the entry has subordinates and {@code false}
   * otherwise.
   */
  public boolean hasSubOrdinates() {
    return hasSubOrdinates;
  }
  /**
   * Sets the whether the entry has subordinates or not.
   * @param hasSubOrdinates whether the entry has subordinates or not.
   */
  public void setHasSubOrdinates(boolean hasSubOrdinates) {
    this.hasSubOrdinates = hasSubOrdinates;
  }
  /**
   * Returns the referrals of the entry. Returns <CODE>null</CODE> if this node
   * is not a referral.
   * @return the referrals of the entry. Returns <CODE>null</CODE> if this node
opends/src/guitools/org/opends/guitools/controlpanel/ui/nodes/BrowserNodeInfo.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2008 Sun Microsystems, Inc.
 *      Copyright 2008-2010 Sun Microsystems, Inc.
 */
package org.opends.guitools.controlpanel.ui.nodes;
@@ -84,6 +84,12 @@
  /**
   * Returns the value of hassubordinates for the entry.
   * @return the value of hassubordinates for the entry.
   */
  public boolean hasSubOrdinates();
  /**
   * Returns the referrals attached to the displayed entry.
   * This is the value of the 'ref' attribute.
   * Returns <CODE>null</CODE> if the attribute is not present.
opends/src/server/org/opends/server/monitors/BackendMonitor.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Copyright 2006-2010 Sun Microsystems, Inc.
 */
package org.opends.server.monitors;
@@ -222,7 +222,7 @@
    else
    {
      // This is done to avoid recalculating the number of entries
      // using the hasNumSubordinates method in the case where the
      // using the numSubordinates method in the case where the
      // backend has a single base DN.
      String s = backendCount + " " + baseDNs[0].toString();
      builder.add(AttributeValues.create(baseDNEntryCountType, s));
opends/src/server/org/opends/server/types/Entry.java
@@ -5427,8 +5427,8 @@
            AttributeType t = e.getKey();
            if (t.hasNameOrOID(lowerName))
            {
              mergeAttributeLists(e.getValue(), userAttrsCopy, t,
                  attrName, options, omitValues, omitReal,
              mergeAttributeLists(e.getValue(), operationalAttrsCopy,
                  t, attrName, options, omitValues, omitReal,
                  omitVirtual);
              continue;
            }
opends/src/server/org/opends/server/workflowelement/externalchangelog/ECLSearchOperation.java
@@ -40,6 +40,7 @@
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@@ -112,6 +113,7 @@
import org.opends.server.types.operation.SearchReferenceSearchOperation;
import org.opends.server.util.Base64;
import org.opends.server.util.ServerConstants;
import org.opends.server.config.ConfigConstants;
@@ -605,39 +607,43 @@
    // Start a specific ECL session
    eclSession = replicationServer.createECLSession(startECLSessionMsg);
    if (!getScope().equals(SearchScope.SINGLE_LEVEL))
    {
      // Root entry
      Entry entry = createRootEntry();
      if (matchFilter(entry))
        returnEntry(entry, null);
    }
    if (true)
    {
      // Loop on result entries
      int INITIAL=0;
      int PSEARCH=1;
      int phase=INITIAL;
      boolean returnedRoot = false;
      while (true)
      {
        // Check for a request to cancel this operation.
        checkIfCanceled(false);
        ECLUpdateMsg update = eclSession.getNextUpdate();
        if (update!=null)
        {
          if (!returnedRoot)
          {
            returnRootEntryIfRequired(true);
            returnedRoot = true;
          }
          if (phase==INITIAL)
          {
            if (!buildAndReturnEntry(update))
            {
              // Abandon, Size limit reached
              eclSession.close();
              break;
            }
          }
        }
        else
        {
          if (!returnedRoot)
          {
            returnRootEntryIfRequired(false);
            returnedRoot = true;
          }
          if (phase==INITIAL)
          {
            if (this.persistentSearch == null)
@@ -656,6 +662,18 @@
    }
  }
  private void returnRootEntryIfRequired(boolean hasSubordinates)
  throws DirectoryException
  {
    if (!getScope().equals(SearchScope.SINGLE_LEVEL))
    {
      // Root entry
      Entry entry = createRootEntry(hasSubordinates);
      if (matchFilter(entry))
        returnEntry(entry, null);
    }
  }
  private boolean supportsControl(String oid)
  {
    return ((supportedControls != null) &&
@@ -849,22 +867,68 @@
  /**
   * Creates the root entry of the external changelog.
   * @param hasSubordinates whether the root entry has subordinates or not.
   * @return The root entry created.
   */
  private Entry createRootEntry()
  private Entry createRootEntry(boolean hasSubordinates)
  {
    HashMap<ObjectClass,String> oclasses =
      new LinkedHashMap<ObjectClass,String>(3);
    oclasses.putAll(eclObjectClasses);
    // Objectclass
    HashMap<ObjectClass,String> rootObjectClasses =
      new LinkedHashMap<ObjectClass,String>(2);
    ObjectClass topOC = DirectoryServer.getObjectClass(OC_TOP, true);
    rootObjectClasses.put(topOC, OC_TOP);
    ObjectClass containerOC = DirectoryServer.getObjectClass("container", true);
    rootObjectClasses.put(containerOC, "container");
    oclasses.putAll(rootObjectClasses);
    HashMap<AttributeType,List<Attribute>> userAttrs =
      new LinkedHashMap<AttributeType,List<Attribute>>();
    HashMap<AttributeType,List<Attribute>> operationalAttrs =
      new LinkedHashMap<AttributeType,List<Attribute>>();
    Entry e = new Entry(this.rootBaseDN, oclasses, userAttrs,
        operationalAttrs);
    // subSchemaSubentry
    AttributeType aType =
      DirectoryServer.getAttributeType(ATTR_SUBSCHEMA_SUBENTRY_LC);
    if (aType == null)
      aType = DirectoryServer.getDefaultAttributeType(ATTR_SUBSCHEMA_SUBENTRY);
    Attribute a = Attributes.create(ATTR_SUBSCHEMA_SUBENTRY,
        ConfigConstants.DN_DEFAULT_SCHEMA_ROOT);
    List<Attribute> attrList = Collections.singletonList(a);
    if (aType.isOperational())
      operationalAttrs.put(aType, attrList);
    else
      userAttrs.put(aType, attrList);
    // TODO:numSubordinates
    // hasSubordinates
    if (hasSubordinates)
    {
      aType = DirectoryServer.getAttributeType("hassubordinates");
      if (aType == null)
        aType = DirectoryServer.getDefaultAttributeType("hasSubordinates");
      a = Attributes.create("hasSubordinates", "true");
      attrList = Collections.singletonList(a);
      if (aType.isOperational())
        operationalAttrs.put(aType, attrList);
      else
        userAttrs.put(aType, attrList);
    }
    // entryDN
    aType = DirectoryServer.getAttributeType("entrydn");
    if (aType == null)
      aType = DirectoryServer.getDefaultAttributeType("entryDN");
    a = Attributes.create("entryDN", rootBaseDN.toNormalizedString());
    attrList = Collections.singletonList(a);
    if (aType.isOperational())
      operationalAttrs.put(aType, attrList);
    else
      userAttrs.put(aType, attrList);
    Entry e = new Entry(this.rootBaseDN, oclasses, userAttrs, operationalAttrs);
    return e;
  }
@@ -901,7 +965,7 @@
      String delInitiatorsName)
  throws DirectoryException
  {
    AttributeType attributeType;
    AttributeType aType;
    String dnString = "";
    String pattern;
@@ -909,7 +973,7 @@
    {
      // Draft uncompat mode
      dnString = "replicationcsn="+ changeNumber +"," + serviceID
        + "," + ServerConstants.DN_EXTERNAL_CHANGELOG_ROOT;
      + "," + ServerConstants.DN_EXTERNAL_CHANGELOG_ROOT;
    }
    else
    {
@@ -917,6 +981,8 @@
      dnString = "changenumber="+ draftChangenumber + "," +
      ServerConstants.DN_EXTERNAL_CHANGELOG_ROOT;
    }
    // Objectclass
    HashMap<ObjectClass,String> oClasses =
      new LinkedHashMap<ObjectClass,String>(3);
    oClasses.putAll(eclObjectClasses);
@@ -931,40 +997,80 @@
    HashMap<AttributeType,List<Attribute>> operationalAttrs =
      new LinkedHashMap<AttributeType,List<Attribute>>();
    ArrayList<Attribute> attrList = new ArrayList<Attribute>(1);
    // Operational standard attributes
    // subSchemaSubentry
    aType = DirectoryServer.getAttributeType(ATTR_SUBSCHEMA_SUBENTRY_LC);
    if (aType == null)
    aType = DirectoryServer.getDefaultAttributeType(ATTR_SUBSCHEMA_SUBENTRY_LC);
    Attribute a = Attributes.create(ATTR_SUBSCHEMA_SUBENTRY_LC,
        ConfigConstants.DN_DEFAULT_SCHEMA_ROOT);
    List<Attribute> attrList = Collections.singletonList(a);
    if (aType.isOperational())
      operationalAttrs.put(aType, attrList);
    else
      uAttrs.put(aType, attrList);
    // numSubordinates
    aType = DirectoryServer.getAttributeType("numsubordinates");
    if (aType == null)
      aType = DirectoryServer.getDefaultAttributeType("numSubordinates");
    a = Attributes.create("numSubordinates", "0");
    attrList = Collections.singletonList(a);
    if (aType.isOperational())
      operationalAttrs.put(aType, attrList);
    else
      uAttrs.put(aType, attrList);
    // hasSubordinates
    aType = DirectoryServer.getAttributeType("hassubordinates");
    if (aType == null)
      aType = DirectoryServer.getDefaultAttributeType("hasSubordinates");
    a = Attributes.create("hasSubordinates", "false");
    attrList = Collections.singletonList(a);
    if (aType.isOperational())
      operationalAttrs.put(aType, attrList);
    else
      uAttrs.put(aType, attrList);
    // entryDN
    aType = DirectoryServer.getAttributeType("entrydn");
    if (aType == null)
      aType = DirectoryServer.getDefaultAttributeType("entryDN");
    a = Attributes.create("entryDN", dnString);
    attrList = Collections.singletonList(a);
    if (aType.isOperational())
      operationalAttrs.put(aType, attrList);
    else
      uAttrs.put(aType, attrList);
    // REQUIRED attributes
    // ECL Changelog draft change number
    if((attributeType =
      DirectoryServer.getAttributeType("changenumber")) == null)
      attributeType =
          DirectoryServer.getDefaultAttributeType("changenumber");
    Attribute a = Attributes.create("changenumber",
        String.valueOf(draftChangenumber));
    if((aType = DirectoryServer.getAttributeType("changenumber")) == null)
      aType = DirectoryServer.getDefaultAttributeType("changenumber");
    a = Attributes.create("changenumber", String.valueOf(draftChangenumber));
    attrList = new ArrayList<Attribute>(1);
    attrList.add(a);
    if(attributeType.isOperational())
      operationalAttrs.put(attributeType, attrList);
    if(aType.isOperational())
      operationalAttrs.put(aType, attrList);
    else
      uAttrs.put(attributeType, attrList);
      uAttrs.put(aType, attrList);
    //
    if((attributeType =
      DirectoryServer.getAttributeType("changetime")) == null)
      attributeType =
          DirectoryServer.getDefaultAttributeType("changetime");
    if((aType = DirectoryServer.getAttributeType("changetime")) == null)
      aType = DirectoryServer.getDefaultAttributeType("changetime");
    SimpleDateFormat dateFormat;
    dateFormat = new SimpleDateFormat(DATE_FORMAT_GMT_TIME);
    dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); // ??
    a = Attributes.create(attributeType,
    a = Attributes.create(aType,
        dateFormat.format(new Date(changeNumber.getTime())));
    attrList = new ArrayList<Attribute>(1);
    attrList.add(a);
    if(attributeType.isOperational())
      operationalAttrs.put(attributeType, attrList);
    if(aType.isOperational())
      operationalAttrs.put(aType, attrList);
    else
      uAttrs.put(attributeType, attrList);
      uAttrs.put(aType, attrList);
    /* Change time in a friendly format
    Date date = new Date(changeNumber.getTime());
@@ -975,77 +1081,65 @@
     */
    //
    if((attributeType =
      DirectoryServer.getAttributeType("changetype")) == null)
      attributeType =
          DirectoryServer.getDefaultAttributeType("changetype");
    a = Attributes.create(attributeType, changetype);
    if((aType = DirectoryServer.getAttributeType("changetype")) == null)
      aType = DirectoryServer.getDefaultAttributeType("changetype");
    a = Attributes.create(aType, changetype);
    attrList = new ArrayList<Attribute>(1);
    attrList.add(a);
    if(attributeType.isOperational())
      operationalAttrs.put(attributeType, attrList);
    if(aType.isOperational())
      operationalAttrs.put(aType, attrList);
    else
      uAttrs.put(attributeType, attrList);
      uAttrs.put(aType, attrList);
    //
    if((attributeType =
      DirectoryServer.getAttributeType("targetdn")) == null)
      attributeType =
          DirectoryServer.getDefaultAttributeType("targetdn");
    a = Attributes.create(attributeType,
        targetDN.toNormalizedString());
    if((aType = DirectoryServer.getAttributeType("targetdn")) == null)
      aType = DirectoryServer.getDefaultAttributeType("targetdn");
    a = Attributes.create(aType, targetDN.toNormalizedString());
    attrList = new ArrayList<Attribute>(1);
    attrList.add(a);
    if(attributeType.isOperational())
      operationalAttrs.put(attributeType, attrList);
    if(aType.isOperational())
      operationalAttrs.put(aType, attrList);
    else
      uAttrs.put(attributeType, attrList);
      uAttrs.put(aType, attrList);
    // NON REQUESTED attributes
    if((attributeType =
            DirectoryServer.getAttributeType("replicationcsn")) == null)
        attributeType =
                DirectoryServer.getDefaultAttributeType("replicationcsn");
    a = Attributes.create(attributeType, changeNumber.toString());
    if((aType = DirectoryServer.getAttributeType("replicationcsn")) == null)
      aType = DirectoryServer.getDefaultAttributeType("replicationcsn");
    a = Attributes.create(aType, changeNumber.toString());
    attrList = new ArrayList<Attribute>(1);
    attrList.add(a);
    if(attributeType.isOperational())
      operationalAttrs.put(attributeType, attrList);
    if(aType.isOperational())
      operationalAttrs.put(aType, attrList);
    else
      uAttrs.put(attributeType, attrList);
      uAttrs.put(aType, attrList);
    //
    if((attributeType =
      DirectoryServer.getAttributeType("replicaidentifier")) == null)
      attributeType =
          DirectoryServer.getDefaultAttributeType("replicaidentifier");
    a = Attributes.create(attributeType,
        Integer.toString(changeNumber.getServerId()));
    if((aType = DirectoryServer.getAttributeType("replicaidentifier")) == null)
      aType = DirectoryServer.getDefaultAttributeType("replicaidentifier");
    a = Attributes.create(aType, Integer.toString(changeNumber.getServerId()));
    attrList = new ArrayList<Attribute>(1);
    attrList.add(a);
    if(attributeType.isOperational())
      operationalAttrs.put(attributeType, attrList);
    if(aType.isOperational())
      operationalAttrs.put(aType, attrList);
    else
      uAttrs.put(attributeType, attrList);
      uAttrs.put(aType, attrList);
    if (clearLDIFchanges != null)
    {
      if (changetype.equals("add"))
      {
        if((attributeType =
          DirectoryServer.getAttributeType("changes")) == null)
          attributeType =
            DirectoryServer.getDefaultAttributeType("changes");
        if((aType = DirectoryServer.getAttributeType("changes")) == null)
          aType = DirectoryServer.getDefaultAttributeType("changes");
        a = Attributes.create(attributeType, clearLDIFchanges + "\n");
        a = Attributes.create(aType, clearLDIFchanges + "\n");
        // force base64
        attrList = new ArrayList<Attribute>(1);
        attrList.add(a);
        if(attributeType.isOperational())
          operationalAttrs.put(attributeType, attrList);
        if(aType.isOperational())
          operationalAttrs.put(aType, attrList);
        else
          uAttrs.put(attributeType, attrList);
          uAttrs.put(aType, attrList);
        pattern = "creatorsName: ";
        try
@@ -1058,17 +1152,17 @@
            String creatorsName =
              clearLDIFchanges.substring(start_val_cr+2, end_val_cr);
            if((attributeType =
            if((aType =
              DirectoryServer.getAttributeType("changeInitiatorsName")) == null)
              attributeType =
              aType =
                DirectoryServer.getDefaultAttributeType("changeInitiatorsName");
            a = Attributes.create(attributeType, creatorsName);
            a = Attributes.create(aType, creatorsName);
            attrList = new ArrayList<Attribute>(1);
            attrList.add(a);
            if(attributeType.isOperational())
              operationalAttrs.put(attributeType, attrList);
            if(aType.isOperational())
              operationalAttrs.put(aType, attrList);
            else
              uAttrs.put(attributeType, attrList);
              uAttrs.put(aType, attrList);
          }
        }
        catch(Exception e)
@@ -1084,19 +1178,17 @@
      {
        if (changetype.equals("modify"))
        {
          if((attributeType =
            DirectoryServer.getAttributeType("changes")) == null)
            attributeType =
              DirectoryServer.getDefaultAttributeType("changes");
          if((aType = DirectoryServer.getAttributeType("changes")) == null)
            aType = DirectoryServer.getDefaultAttributeType("changes");
          a = Attributes.create(attributeType, clearLDIFchanges + "\n");
          a = Attributes.create(aType, clearLDIFchanges + "\n");
          // force base64
          attrList = new ArrayList<Attribute>(1);
          attrList.add(a);
          if(attributeType.isOperational())
            operationalAttrs.put(attributeType, attrList);
          if(aType.isOperational())
            operationalAttrs.put(aType, attrList);
          else
            uAttrs.put(attributeType, attrList);
            uAttrs.put(aType, attrList);
        }
        pattern = "modifiersName: ";
@@ -1110,17 +1202,17 @@
            String modifiersName =
              clearLDIFchanges.substring(start_val_cr, end_val_cr);
            if((attributeType =
            if((aType =
              DirectoryServer.getAttributeType("changeInitiatorsName")) == null)
              attributeType =
              aType =
                DirectoryServer.getDefaultAttributeType("changeInitiatorsName");
            a = Attributes.create(attributeType, modifiersName);
            a = Attributes.create(aType, modifiersName);
            attrList = new ArrayList<Attribute>(1);
            attrList.add(a);
            if(attributeType.isOperational())
              operationalAttrs.put(attributeType, attrList);
            if(aType.isOperational())
              operationalAttrs.put(aType, attrList);
            else
              uAttrs.put(attributeType, attrList);
              uAttrs.put(aType, attrList);
          }
        }
        catch(Exception e)
@@ -1136,40 +1228,35 @@
    if (changetype.equals("delete") && (delInitiatorsName!=null))
    {
      if((attributeType =
        DirectoryServer.getAttributeType("changeInitiatorsName")) == null)
        attributeType =
          DirectoryServer.getDefaultAttributeType("changeInitiatorsName");
      a = Attributes.create(attributeType, delInitiatorsName);
      if((aType = DirectoryServer.getAttributeType("changeInitiatorsName"))
          == null)
        aType = DirectoryServer.getDefaultAttributeType("changeInitiatorsName");
      a = Attributes.create(aType, delInitiatorsName);
      attrList = new ArrayList<Attribute>(1);
      attrList.add(a);
      if(attributeType.isOperational())
        operationalAttrs.put(attributeType, attrList);
      if(aType.isOperational())
        operationalAttrs.put(aType, attrList);
      else
        uAttrs.put(attributeType, attrList);
        uAttrs.put(aType, attrList);
    }
    if (targetUUID != null)
    {
      if((attributeType =
        DirectoryServer.getAttributeType("targetentryuuid")) == null)
        attributeType =
            DirectoryServer.getDefaultAttributeType("targetentryuuid");
      a = Attributes.create(attributeType, targetUUID);
      if((aType = DirectoryServer.getAttributeType("targetentryuuid")) == null)
        aType = DirectoryServer.getDefaultAttributeType("targetentryuuid");
      a = Attributes.create(aType, targetUUID);
      attrList = new ArrayList<Attribute>(1);
      attrList.add(a);
      if(attributeType.isOperational())
        operationalAttrs.put(attributeType, attrList);
      if(aType.isOperational())
        operationalAttrs.put(aType, attrList);
      else
        uAttrs.put(attributeType, attrList);
        uAttrs.put(aType, attrList);
      if (draftChangenumber>0)
      {
        // compat mode
        if((attributeType =
          DirectoryServer.getAttributeType("targetuniqueid")) == null)
          attributeType =
              DirectoryServer.getDefaultAttributeType("targetuniqueid");
        if((aType = DirectoryServer.getAttributeType("targetuniqueid")) == null)
          aType = DirectoryServer.getDefaultAttributeType("targetuniqueid");
        String dseeValue = null;
        try
        {
@@ -1191,28 +1278,26 @@
        // or not return this entry.
        if (dseeValue != null)
        {
          a = Attributes.create(attributeType, dseeValue);
          a = Attributes.create(aType, dseeValue);
          attrList = new ArrayList<Attribute>(1);
          attrList.add(a);
          if(attributeType.isOperational())
            operationalAttrs.put(attributeType, attrList);
          if(aType.isOperational())
            operationalAttrs.put(aType, attrList);
          else
            uAttrs.put(attributeType, attrList);
            uAttrs.put(aType, attrList);
        }
      }
    }
    if((attributeType =
      DirectoryServer.getAttributeType("changelogcookie")) == null)
      attributeType =
          DirectoryServer.getDefaultAttributeType("changelogcookie");
    a = Attributes.create(attributeType, cookie);
    if((aType = DirectoryServer.getAttributeType("changelogcookie")) == null)
      aType = DirectoryServer.getDefaultAttributeType("changelogcookie");
    a = Attributes.create(aType, cookie);
    attrList = new ArrayList<Attribute>(1);
    attrList.add(a);
    if(attributeType.isOperational())
      operationalAttrs.put(attributeType, attrList);
    if(aType.isOperational())
      operationalAttrs.put(aType, attrList);
    else
      uAttrs.put(attributeType, attrList);
      uAttrs.put(aType, attrList);
    if (histEntryAttributes != null)
    {