From 4c1d8f0481ec73e1ab75458cc82af73bf937e498 Mon Sep 17 00:00:00 2001
From: Ludovic Poitou <ludovic.poitou@forgerock.com>
Date: Mon, 13 Jun 2011 10:09:55 +0000
Subject: [PATCH] Fix to OPENDJ-197: In the StaticGroup cache, keep members as strings (ByteString) rather than DN objects. These are much more compact. DNs are built from the ByteString only when needed.

---
 opendj-sdk/opends/src/messages/messages/extension.properties                                 |   18 ---
 opendj-sdk/opends/src/messages/messages/extension_es.properties                              |   18 ---
 opendj-sdk/opends/src/server/org/opends/server/extensions/SimpleStaticGroupMemberList.java   |   34 ++++++--
 opendj-sdk/opends/src/server/org/opends/server/extensions/StaticGroup.java                   |   96 +++++++++++++++--------
 opendj-sdk/opends/src/messages/messages/extension_fr.properties                              |   17 ---
 opendj-sdk/opends/src/server/org/opends/server/extensions/FilteredStaticGroupMemberList.java |   32 ++++++-
 opendj-sdk/opends/src/server/org/opends/server/api/Group.java                                |    5 +
 7 files changed, 125 insertions(+), 95 deletions(-)

diff --git a/opendj-sdk/opends/src/messages/messages/extension.properties b/opendj-sdk/opends/src/messages/messages/extension.properties
index ee34cfe..b70ff7e 100644
--- a/opendj-sdk/opends/src/messages/messages/extension.properties
+++ b/opendj-sdk/opends/src/messages/messages/extension.properties
@@ -21,6 +21,7 @@
 # CDDL HEADER END
 #
 #      Copyright 2006-2010 Sun Microsystems, Inc.
+#      Portions Copyright 2011 ForgeRock AS
 
 
 
@@ -901,10 +902,6 @@
 NOTICE_ERRORLOG_ACCTNOTHANDLER_NOTIFICATION_375=Account-Status-Notification \
  type='%s' userdn='%s' id=%d msg='%s'
 
-
-
-
-
 MILD_ERR_SASLCRAMMD5_CANNOT_GET_REVERSIBLE_PASSWORDS_377=An error occurred \
  while attempting to retrieve the clear-text password(s) for user %s in order \
  to perform SASL CRAM-MD5 authentication:  %s
@@ -948,9 +945,6 @@
  perform an internal modification to update the group:  %s
 MILD_ERR_EXTOP_PASSMOD_INSUFFICIENT_PRIVILEGES_392=You do not have sufficient \
  privileges to perform password reset operations
-
-
-
 MILD_ERR_SASLDIGESTMD5_EMPTY_AUTHZID_393=The provided authorization ID was \
  empty, which is not allowed for DIGEST-MD5 authentication
 MILD_ERR_SASLDIGESTMD5_AUTHZID_INVALID_DN_394=The provided authorization ID \
@@ -963,14 +957,6 @@
  find any entry corresponding to authorization ID %s
 MILD_ERR_SASLDIGESTMD5_CANNOT_MAP_AUTHZID_399=An error occurred while \
  attempting to map authorization ID %s to a user entry:  %s
-
-
-
-
-
-
-
-
 MILD_ERR_SASLPLAIN_AUTHZID_INVALID_DN_400=The provided authorization ID %s \
  contained an invalid DN:  %s
 MILD_ERR_SASLPLAIN_AUTHZID_INSUFFICIENT_PRIVILEGES_401=The authenticating \
@@ -1439,3 +1425,5 @@
 MILD_ERR_CHARSET_VALIDATOR_TOO_FEW_OPTIONAL_CHAR_SETS_581=The provided \
  password did not contain characters from at least %d of the following \
  character sets: %s
+MILD_ERR_STATICMEMBERS_CANNOT_DECODE_DN_582=An error occurred while \
+ attempting to decode member's DN %s of static group %s:  %s
diff --git a/opendj-sdk/opends/src/messages/messages/extension_es.properties b/opendj-sdk/opends/src/messages/messages/extension_es.properties
index dd66651..a3983cd 100644
--- a/opendj-sdk/opends/src/messages/messages/extension_es.properties
+++ b/opendj-sdk/opends/src/messages/messages/extension_es.properties
@@ -21,6 +21,7 @@
 # CDDL HEADER END
 #
 #      Copyright 2006-2010 Sun Microsystems, Inc.
+#      Portions Copyright 2011 ForgeRock AS
 
 
 
@@ -321,10 +322,6 @@
 MILD_ERR_ERRORLOG_ACCTNOTHANDLER_CANNOT_GET_NOTIFICATION_TYPES_374=Se produjo un error al intentar determinar los tipos de notificaci\u00f3n de estado de cuenta a partir de la entrada de configuraci\u00f3n %s:  %s
 NOTICE_ERRORLOG_ACCTNOTHANDLER_NOTIFICATION_375=Tipo Account-Status-Notification='%s' userdn='%s' id=%d msg='%s'
 
-
-
-
-
 MILD_ERR_SASLCRAMMD5_CANNOT_GET_REVERSIBLE_PASSWORDS_377=Se produjo un error al intentar recuperar la(s) contrase\u00f1a(s) no cifrada(s) para el usuario %s de cara a realizar la autenticaci\u00f3n SASL CRAM-MD5:  %s
 MILD_ERR_SASLPLAIN_CANNOT_CHECK_PASSWORD_VALIDITY_378=Se produjo un error al intentar verificar la contrase\u00f1a para el usuario %s durante la autenticaci\u00f3n SASL PLAIN:  %s
 MILD_ERR_STARTTLS_ERROR_SENDING_CLEAR_RESPONSE_379=Se produjo un error inesperado al intentar enviar la respuesta no cifrada al cliente despu\u00e9s de iniciar la negociaci\u00f3n TLS:  %s
@@ -341,23 +338,12 @@
 MILD_ERR_STATICGROUP_ADD_MEMBER_UPDATE_FAILED_390=No se puede agregar al usuario %s como miembro nuevo del grupo est\u00e1tico %s porque se produjo un error al intentar realizar una modificaci\u00f3n interna para actualizar el grupo:  %s
 MILD_ERR_STATICGROUP_REMOVE_MEMBER_UPDATE_FAILED_391=No se puede agregar al usuario %s como miembro del grupo est\u00e1tico %s porque se produjo un error al intentar realizar una modificaci\u00f3n interna para actualizar el grupo:  %s
 MILD_ERR_EXTOP_PASSMOD_INSUFFICIENT_PRIVILEGES_392=No dispone de los privilegios suficientes para realizar operaciones de restablecimiento de contrase\u00f1a
-
-
-
 MILD_ERR_SASLDIGESTMD5_EMPTY_AUTHZID_393=El ID de autorizaci\u00f3n proporcionado estaba vac\u00edo, lo cual no est\u00e1 permitido para la autenticaci\u00f3n DIGEST-MD5
 MILD_ERR_SASLDIGESTMD5_AUTHZID_INVALID_DN_394=El ID de autorizaci\u00f3n proporcionado %s conten\u00eda un ND no v\u00e1lido:  %s
 MILD_ERR_SASLDIGESTMD5_AUTHZID_NO_SUCH_ENTRY_396=La entrada %s especificada como identidad de autorizaci\u00f3n no existe
 MILD_ERR_SASLDIGESTMD5_AUTHZID_CANNOT_GET_ENTRY_397=No se puede recuperar la entrada %s, que se especific\u00f3 como identidad de la autorizaci\u00f3n:  %s
 MILD_ERR_SASLDIGESTMD5_AUTHZID_NO_MAPPED_ENTRY_398=El servidor no pudo encontrar ninguna entrada que se correspondiera con el ID de autorizaci\u00f3n %s
 MILD_ERR_SASLDIGESTMD5_CANNOT_MAP_AUTHZID_399=Se produjo un error al intentar asignar el ID de autorizaci\u00f3n %s a una entrada de usuario:  %s
-
-
-
-
-
-
-
-
 MILD_ERR_SASLPLAIN_AUTHZID_INVALID_DN_400=El ID de autorizaci\u00f3n proporcionado %s conten\u00eda un ND no v\u00e1lido:  %s
 MILD_ERR_SASLPLAIN_AUTHZID_INSUFFICIENT_PRIVILEGES_401=El usuario que intenta la autenticaci\u00f3n %s no dispone de los privilegios suficientes para especificar un ID de autorizaci\u00f3n alternativo
 MILD_ERR_SASLPLAIN_AUTHZID_NO_SUCH_ENTRY_402=La entrada correspondiente al ND de autorizaci\u00f3n %s no existe en Directory Server
@@ -528,3 +514,5 @@
 INFO_GSSAPI_STOPPED_575=El controlador del mecanismo GSSAPI (SASL) se ha detenido
 MILD_ERR_COLLECTIVEATTRIBUTESUBENTRIES_VATTR_NOT_SEARCHABLE_576=El atributo %s no permite su b\u00fasqueda y no se deber\u00eda incluir en filtros de b\u00fasqueda no indizados
 MILD_ERR_PASSWORDPOLICYSUBENTRY_VATTR_NOT_SEARCHABLE_577=El atributo %s no permite su b\u00fasqueda y no se deber\u00eda incluir en filtros de b\u00fasqueda no indizados
+MILD_ERR_STATICMEMBERS_CANNOT_DECODE_DN_582=Se produjo un error al intentar analizar el ND del miembro %s del grupo est\u00e1tico %s:  %s
+
diff --git a/opendj-sdk/opends/src/messages/messages/extension_fr.properties b/opendj-sdk/opends/src/messages/messages/extension_fr.properties
index bde696a..3275eb8 100644
--- a/opendj-sdk/opends/src/messages/messages/extension_fr.properties
+++ b/opendj-sdk/opends/src/messages/messages/extension_fr.properties
@@ -21,6 +21,7 @@
 # CDDL HEADER END
 #
 #      Copyright 2006-2010 Sun Microsystems, Inc.
+#      Portions Copyright 2011 ForgeRock AS
 
 
 
@@ -321,10 +322,6 @@
 MILD_ERR_ERRORLOG_ACCTNOTHANDLER_CANNOT_GET_NOTIFICATION_TYPES_374=Une erreur s'est produite lors de la d\u00e9termination des types de notification statut de compte \u00e0 partir de l'entr\u00e9e de configuration %s\u00a0: %s
 NOTICE_ERRORLOG_ACCTNOTHANDLER_NOTIFICATION_375=Account-Status-Notification type='%s' userdn='%s' id=%d msg='%s'
 
-
-
-
-
 MILD_ERR_SASLCRAMMD5_CANNOT_GET_REVERSIBLE_PASSWORDS_377=Une erreur s'est produite lors de la r\u00e9cup\u00e9ration d'au moins un mot de passe en texte clair pour l'utilisateur %s \u00e0 des fins d'authentification SASL CRAM-MD5\u00a0: %s
 MILD_ERR_SASLPLAIN_CANNOT_CHECK_PASSWORD_VALIDITY_378=Une erreur s'est produite lors de la v\u00e9rification du mot de passe pour l'utilisateur %s lors de l'authentification SASL PLAIN\u00a0: %s
 MILD_ERR_STARTTLS_ERROR_SENDING_CLEAR_RESPONSE_379=Une erreur inattendue s'est produite lors de l'envoi d'une r\u00e9ponse en texte clair au client apr\u00e8s le d\u00e9marrage de la n\u00e9gociation TLS\u00a0: %s
@@ -341,23 +338,12 @@
 MILD_ERR_STATICGROUP_ADD_MEMBER_UPDATE_FAILED_390=Impossible d'ajouter l'utilisateur %s comme nouveau membre du groupe statique %s car une erreur s'est produite lors de la modification interne destin\u00e9e \u00e0 mettre \u00e0 jour le groupe\u00a0: %s
 MILD_ERR_STATICGROUP_REMOVE_MEMBER_UPDATE_FAILED_391=Impossible de supprimer l'utilisateur %s comme membre du groupe statique %s car une erreur s'est produite lors de la modification interne destin\u00e9e \u00e0 mettre \u00e0 jour le groupe\u00a0: %s
 MILD_ERR_EXTOP_PASSMOD_INSUFFICIENT_PRIVILEGES_392=Vous ne disposez pas des privil\u00e8ges suffisants pour ex\u00e9cuter des op\u00e9rations de r\u00e9initialisation de mot de passe
-
-
-
 MILD_ERR_SASLDIGESTMD5_EMPTY_AUTHZID_393=L'ID d'autorisation fournie est vide, ce qui n'est pas autoris\u00e9 dans le cadre de l'authentification DIGEST-MD5
 MILD_ERR_SASLDIGESTMD5_AUTHZID_INVALID_DN_394=L'ID d'autorisation fournie %s contient un DN non valide\u00a0: %s
 MILD_ERR_SASLDIGESTMD5_AUTHZID_NO_SUCH_ENTRY_396=L'entr\u00e9e %s sp\u00e9cifi\u00e9e comme identit\u00e9 d'autorisation n'existe pas
 MILD_ERR_SASLDIGESTMD5_AUTHZID_CANNOT_GET_ENTRY_397=Impossible de r\u00e9cup\u00e9rer l'entr\u00e9e %s sp\u00e9cifi\u00e9e comme identit\u00e9 d'autorisation\u00a0: %s
 MILD_ERR_SASLDIGESTMD5_AUTHZID_NO_MAPPED_ENTRY_398=Impossible pour le serveur de trouver une entr\u00e9e correspondant \u00e0 l'ID d'autorisation %s
 MILD_ERR_SASLDIGESTMD5_CANNOT_MAP_AUTHZID_399=Une erreur s'est produite lors du mappage de l'ID d'autorisation %s \u00e0 une entr\u00e9e utilisateur\u00a0: %s
-
-
-
-
-
-
-
-
 MILD_ERR_SASLPLAIN_AUTHZID_INVALID_DN_400=L'ID d'autorisation fournie %s contient un DN non valide\u00a0: %s
 MILD_ERR_SASLPLAIN_AUTHZID_INSUFFICIENT_PRIVILEGES_401=L'utilisateur en cours d'authentification %s ne poss\u00e8de pas les privil\u00e8ges suffisants pour sp\u00e9cifier une ID d'autorisation de remplacement
 MILD_ERR_SASLPLAIN_AUTHZID_NO_SUCH_ENTRY_402=L'entr\u00e9e correspondant au DN d'autorisation %s n'existe pas dans Directory Server
@@ -529,3 +515,4 @@
 MILD_ERR_COLLECTIVEATTRIBUTESUBENTRIES_VATTR_NOT_SEARCHABLE_576=L'attribut %s ne peut pas faire l'objet d'une recherche et ne doit pas \u00eatre inclus dans des filtres de recherche non index\u00e9s
 MILD_ERR_PASSWORDPOLICYSUBENTRY_VATTR_NOT_SEARCHABLE_577=L'attribut %s ne peut pas faire l'objet d'une recherche et ne doit pas \u00eatre inclus dans des filtres de recherche non index\u00e9s
 MILD_ERR_PWSCHEME_INVALID_BASE64_DECODED_STORED_PASSWORD_578=La valeur du mot de passe %s a \u00e9t\u00e9 d\u00e9cod\u00e9 en base64, mais est trop courte pour \u00eatre valide
+MILD_ERR_STATICMEMBERS_CANNOT_DECODE_DN_582=Une erreur s'est produite lors du d\u00e9codage du DN %s, membre du groupe statique %s\u00a0: %s
diff --git a/opendj-sdk/opends/src/server/org/opends/server/api/Group.java b/opendj-sdk/opends/src/server/org/opends/server/api/Group.java
index d3bf5d6..85c1750 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/api/Group.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/api/Group.java
@@ -23,6 +23,7 @@
  *
  *
  *      Copyright 2006-2010 Sun Microsystems, Inc.
+ *      Portions Copyright 2011 ForgeRock AS
  */
 package org.opends.server.api;
 import org.opends.messages.Message;
@@ -299,7 +300,9 @@
   public boolean isMember(DN userDN)
          throws DirectoryException
   {
-    return isMember(userDN, new HashSet<DN>());
+    if (userDN != null)
+      return isMember(userDN, new HashSet<DN>());
+    return false;
   }
 
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/extensions/FilteredStaticGroupMemberList.java b/opendj-sdk/opends/src/server/org/opends/server/extensions/FilteredStaticGroupMemberList.java
index 9395e6e..fb565ac 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/extensions/FilteredStaticGroupMemberList.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/extensions/FilteredStaticGroupMemberList.java
@@ -23,8 +23,10 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2011 ForgeRock AS
  */
 package org.opends.server.extensions;
+import org.opends.server.types.ByteString;
 import org.opends.messages.Message;
 
 
@@ -76,11 +78,11 @@
   private Entry nextMatchingEntry;
 
   // The iterator used to traverse the set of member DNs.
-  private Iterator<DN> memberDNIterator;
+  private Iterator<ByteString> memberDNIterator;
 
   // The set of DNs for the users that are members of the associated static
   // group.
-  private LinkedList<DN> memberDNs;
+  private LinkedList<ByteString> memberDNs;
 
   // The membership exception that should be thrown the next time a member is
   // requested.
@@ -111,13 +113,14 @@
    *                    match.  If this is {@code null}, then all members will
    *                    be considered eligible.
    */
-  public FilteredStaticGroupMemberList(DN groupDN, Set<DN> memberDNs, DN baseDN,
-                                       SearchScope scope, SearchFilter filter)
+  public FilteredStaticGroupMemberList(DN groupDN, Set<ByteString> memberDNs,
+                                       DN baseDN, SearchScope scope,
+                                       SearchFilter filter)
   {
     ensureNotNull(groupDN, memberDNs);
 
     this.groupDN   = groupDN;
-    this.memberDNs = new LinkedList<DN>(memberDNs);
+    this.memberDNs = new LinkedList<ByteString>(memberDNs);
     memberDNIterator = memberDNs.iterator();
 
     this.baseDN = baseDN;
@@ -152,8 +155,25 @@
   {
     while (memberDNIterator.hasNext())
     {
-      DN nextDN = memberDNIterator.next();
+      DN nextDN = null;
+      try
+      {
+        nextDN = DN.decode(memberDNIterator.next());
+      }
+      catch (DirectoryException de)
+      {
+        if (debugEnabled())
+        {
+          TRACER.debugCaught(DebugLogLevel.ERROR, de);
+        }
 
+        Message message = ERR_STATICMEMBERS_CANNOT_DECODE_DN.
+            get(String.valueOf(nextDN), String.valueOf(groupDN),
+                String.valueOf(de.getMessageObject()));
+        nextMembershipException =
+             new MembershipException(message, true, de);
+        return;
+      }
 
       // Check to see if we can eliminate the entry as a possible match purely
       // based on base DN and scope.
diff --git a/opendj-sdk/opends/src/server/org/opends/server/extensions/SimpleStaticGroupMemberList.java b/opendj-sdk/opends/src/server/org/opends/server/extensions/SimpleStaticGroupMemberList.java
index b582c06..7b0ccfc 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/extensions/SimpleStaticGroupMemberList.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/extensions/SimpleStaticGroupMemberList.java
@@ -23,6 +23,7 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2011 ForgeRock AS
  */
 package org.opends.server.extensions;
 import org.opends.messages.Message;
@@ -33,6 +34,7 @@
 import java.util.LinkedList;
 import java.util.Set;
 
+import org.opends.server.types.ByteString;
 import org.opends.server.types.DirectoryConfig;
 import org.opends.server.types.DirectoryException;
 import org.opends.server.types.DN;
@@ -68,11 +70,11 @@
   private DN groupDN;
 
   // The iterator used to traverse the set of member DNs.
-  private Iterator<DN> memberDNIterator;
+  private Iterator<ByteString> memberDNIterator;
 
   // The set of DNs for the users that are members of the associated static
   // group.
-  private LinkedList<DN> memberDNs;
+  private LinkedList<ByteString> memberDNs;
 
 
 
@@ -85,12 +87,12 @@
    * @param  memberDNs  The set of DNs for the users that are members of the
    *                    associated static group.
    */
-  public SimpleStaticGroupMemberList(DN groupDN, Set<DN> memberDNs)
+  public SimpleStaticGroupMemberList(DN groupDN, Set<ByteString> memberDNs)
   {
     ensureNotNull(groupDN, memberDNs);
 
     this.groupDN   = groupDN;
-    this.memberDNs = new LinkedList<DN>(memberDNs);
+    this.memberDNs = new LinkedList<ByteString>(memberDNs);
     memberDNIterator = memberDNs.iterator();
   }
 
@@ -114,12 +116,28 @@
   public DN nextMemberDN()
          throws MembershipException
   {
+    DN dn = null;
+
     if (memberDNIterator.hasNext())
     {
-      return memberDNIterator.next();
+      try{
+        dn = DN.decode(memberDNIterator.next());
+      }
+      catch (DirectoryException de)
+      {
+        // Should not happen
+        if (debugEnabled())
+        {
+          TRACER.debugCaught(DebugLogLevel.ERROR, de);
+        }
+        Message message = ERR_STATICMEMBERS_CANNOT_DECODE_DN.
+            get(String.valueOf(dn), String.valueOf(groupDN),
+                String.valueOf(de.getMessageObject()));
+        throw new MembershipException(message, true, de);
+      }
     }
 
-    return null;
+    return dn;
   }
 
 
@@ -133,11 +151,11 @@
   {
     if (memberDNIterator.hasNext())
     {
-      DN memberDN = memberDNIterator.next();
+      ByteString memberDN = memberDNIterator.next();
 
       try
       {
-        Entry memberEntry = DirectoryConfig.getEntry(memberDN);
+        Entry memberEntry = DirectoryConfig.getEntry(DN.decode(memberDN));
         if (memberEntry == null)
         {
           Message message = ERR_STATICMEMBERS_NO_SUCH_ENTRY.get(
diff --git a/opendj-sdk/opends/src/server/org/opends/server/extensions/StaticGroup.java b/opendj-sdk/opends/src/server/org/opends/server/extensions/StaticGroup.java
index 49ed4bc..ab43e6e 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/extensions/StaticGroup.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/extensions/StaticGroup.java
@@ -23,6 +23,7 @@
  *
  *
  *      Copyright 2008-2010 Sun Microsystems, Inc.
+ *      Portions Copyright 2011 ForgeRock AS
  */
 package org.opends.server.extensions;
 
@@ -49,6 +50,7 @@
 import org.opends.server.types.AttributeType;
 import org.opends.server.types.AttributeValue;
 import org.opends.server.types.Attributes;
+import org.opends.server.types.ByteString;
 import org.opends.server.types.Control;
 import org.opends.server.types.DebugLogLevel;
 import org.opends.server.types.DirectoryConfig;
@@ -74,11 +76,12 @@
 
 /**
  * This class provides a static group implementation, in which the DNs
- * of all members are explicitly listed.  There are two variants of
- * static groups:  one based on the {@code groupOfNames} object class,
- * which stores the member list in the {@code member} attribute, and
- * one based on the {@code groupOfUniqueNames} object class, which
- * stores the member list in the {@code uniqueMember} attribute.
+ * of all members are explicitly listed.  There are three variants of
+ * static groups:  two based on the {@code groupOfNames} and
+ * {@code groupOfEntries} object classes, which store the member list in
+ * the {@code member} attribute, and one based on the
+ * {@code groupOfUniqueNames} object class, which stores the member list
+ * in the {@code uniqueMember} attribute.
  */
 public class StaticGroup
        extends Group<StaticGroupImplementationCfg>
@@ -95,7 +98,7 @@
   private DN groupEntryDN;
 
   // The set of the DNs of the members for this group.
-  private LinkedHashSet<DN> memberDNs;
+  private LinkedHashSet<ByteString> memberDNs;
 
   //The list of nested group DNs for this group.
   private LinkedList<DN> nestedGroups = new LinkedList<DN>();
@@ -132,7 +135,7 @@
    *                              group.
    */
   public StaticGroup(DN groupEntryDN, AttributeType memberAttributeType,
-                     LinkedHashSet<DN> memberDNs)
+                     LinkedHashSet<ByteString> memberDNs)
   {
     super();
 
@@ -170,9 +173,9 @@
     ensureNotNull(groupEntry);
 
 
-    // Determine whether it is a groupOfNames or groupOfUniqueNames entry.  If
-    // neither, then that's a problem.
-    AttributeType memberAttributeType;
+    // Determine whether it is a groupOfNames, groupOfEntries or
+    // groupOfUniqueNames entry.  If not, then that's a problem.
+    AttributeType someMemberAttributeType;
     ObjectClass groupOfEntriesClass =
          DirectoryConfig.getObjectClass(OC_GROUP_OF_ENTRIES_LC, true);
     ObjectClass groupOfNamesClass =
@@ -196,7 +199,8 @@
         throw new DirectoryException(ResultCode.OBJECTCLASS_VIOLATION, message);
       }
 
-      memberAttributeType = DirectoryConfig.getAttributeType(ATTR_MEMBER, true);
+      someMemberAttributeType = DirectoryConfig
+              .getAttributeType(ATTR_MEMBER, true);
     }
     else if (groupEntry.hasObjectClass(groupOfNamesClass))
     {
@@ -208,11 +212,12 @@
         throw new DirectoryException(ResultCode.OBJECTCLASS_VIOLATION, message);
       }
 
-      memberAttributeType = DirectoryConfig.getAttributeType(ATTR_MEMBER, true);
+      someMemberAttributeType = DirectoryConfig
+              .getAttributeType(ATTR_MEMBER, true);
     }
     else if (groupEntry.hasObjectClass(groupOfUniqueNamesClass))
     {
-      memberAttributeType =
+      someMemberAttributeType =
            DirectoryConfig.getAttributeType(ATTR_UNIQUE_MEMBER_LC, true);
     }
     else
@@ -223,10 +228,19 @@
       throw new DirectoryException(ResultCode.OBJECTCLASS_VIOLATION, message);
     }
 
-
-    LinkedHashSet<DN> memberDNs = new LinkedHashSet<DN>();
     List<Attribute> memberAttrList =
-         groupEntry.getAttribute(memberAttributeType);
+         groupEntry.getAttribute(someMemberAttributeType);
+    int membersCount = 0;
+    if (memberAttrList != null)
+    {
+      for (Attribute a : memberAttrList)
+      {
+        membersCount += a.size();
+      }
+    }
+    LinkedHashSet<ByteString> someMemberDNs =
+            new LinkedHashSet<ByteString>(membersCount);
+
     if (memberAttrList != null)
     {
       for (Attribute a : memberAttrList)
@@ -235,8 +249,7 @@
         {
           try
           {
-            DN memberDN = DN.decode(v.getValue());
-            memberDNs.add(memberDN);
+            someMemberDNs.add(v.getNormalizedValue());
           }
           catch (DirectoryException de)
           {
@@ -246,7 +259,8 @@
             }
 
             Message message = ERR_STATICGROUP_CANNOT_DECODE_MEMBER_VALUE_AS_DN.
-                get(v.getValue().toString(), memberAttributeType.getNameOrOID(),
+                get(v.getValue().toString(),
+                    someMemberAttributeType.getNameOrOID(),
                     String.valueOf(groupEntry.getDN()), de.getMessageObject());
             ErrorLogger.logError(message);
           }
@@ -255,7 +269,8 @@
     }
 
 
-    return new StaticGroup(groupEntry.getDN(), memberAttributeType, memberDNs);
+    return new StaticGroup(groupEntry.getDN(),
+            someMemberAttributeType, someMemberDNs);
   }
 
 
@@ -433,8 +448,9 @@
       newNestedGroups.add(nestedGroupDN);
       nestedGroups = newNestedGroups;
       //Add it to the member DN list.
-      LinkedHashSet<DN> newMemberDNs = new LinkedHashSet<DN>(memberDNs);
-      newMemberDNs.add(nestedGroupDN);
+      LinkedHashSet<ByteString> newMemberDNs =
+              new LinkedHashSet<ByteString>(memberDNs);
+      newMemberDNs.add(ByteString.valueOf(nestedGroupDN.toNormalizedString()));
       memberDNs = newMemberDNs;
     }
   }
@@ -493,8 +509,10 @@
       newNestedGroups.remove(nestedGroupDN);
       nestedGroups = newNestedGroups;
       //Remove it from the member DN list.
-      LinkedHashSet<DN> newMemberDNs = new LinkedHashSet<DN>(memberDNs);
-      newMemberDNs.remove(nestedGroupDN);
+      LinkedHashSet<ByteString> newMemberDNs =
+              new LinkedHashSet<ByteString>(memberDNs);
+      newMemberDNs.remove(
+              ByteString.valueOf(nestedGroupDN.toNormalizedString()));
       memberDNs = newMemberDNs;
     }
   }
@@ -509,7 +527,8 @@
           throws DirectoryException
   {
     reloadIfNeeded();
-    if(memberDNs.contains(userDN))
+    ByteString userDNString = ByteString.valueOf(userDN.toNormalizedString());
+    if(memberDNs.contains(userDNString))
     {
       return true;
     }
@@ -570,18 +589,21 @@
                   ERR_STATICGROUP_GROUP_INSTANCE_INVALID.get(
                     String.valueOf(groupEntryDN)));
         } else if(thisGroup != this) {
-          LinkedHashSet<DN> newMemberDNs = new LinkedHashSet<DN>();
+          LinkedHashSet<ByteString> newMemberDNs =
+                  new LinkedHashSet<ByteString>();
           MemberList memberList=thisGroup.getMembers();
           while (memberList.hasMoreMembers()) {
             try {
-              newMemberDNs.add(memberList.nextMemberDN());
+              newMemberDNs.add(ByteString.valueOf(
+                      memberList.nextMemberDN().toNormalizedString()));
             } catch (MembershipException ex) {}
           }
           memberDNs=newMemberDNs;
         }
         LinkedList<DN> newNestedGroups = new LinkedList<DN>();
-        for(DN dn : memberDNs)
+        for(ByteString dnString : memberDNs)
         {
+          DN dn = DN.decode(dnString);
           Group gr=DirectoryServer.getGroupManager().getGroupInstance(dn);
           if(gr != null)
           {
@@ -654,7 +676,9 @@
     synchronized (this)
     {
       DN userDN = userEntry.getDN();
-      if (memberDNs.contains(userDN))
+      ByteString userDNString = ByteString.valueOf(userDN.toNormalizedString());
+
+      if (memberDNs.contains(userDNString))
       {
         Message message = ERR_STATICGROUP_ADD_MEMBER_ALREADY_EXISTS.get(
             String.valueOf(userDN), String.valueOf(groupEntryDN));
@@ -687,10 +711,10 @@
       }
 
 
-      LinkedHashSet<DN> newMemberDNs =
-           new LinkedHashSet<DN>(memberDNs.size()+1);
+      LinkedHashSet<ByteString> newMemberDNs =
+           new LinkedHashSet<ByteString>(memberDNs.size()+1);
       newMemberDNs.addAll(memberDNs);
-      newMemberDNs.add(userDN);
+      newMemberDNs.add(userDNString);
       memberDNs = newMemberDNs;
     }
   }
@@ -706,9 +730,10 @@
   {
     ensureNotNull(userDN);
 
+    ByteString userDNString = ByteString.valueOf(userDN.toNormalizedString());
     synchronized (this)
     {
-      if (! memberDNs.contains(userDN))
+      if (! memberDNs.contains(userDNString))
       {
         Message message = ERR_STATICGROUP_REMOVE_MEMBER_NO_SUCH_MEMBER.get(
             String.valueOf(userDN), String.valueOf(groupEntryDN));
@@ -741,8 +766,9 @@
       }
 
 
-      LinkedHashSet<DN> newMemberDNs = new LinkedHashSet<DN>(memberDNs);
-      newMemberDNs.remove(userDN);
+      LinkedHashSet<ByteString> newMemberDNs =
+              new LinkedHashSet<ByteString>(memberDNs);
+      newMemberDNs.remove(userDNString);
       memberDNs = newMemberDNs;
       //If it is in the nested group list remove it.
       if(nestedGroups.contains(userDN)) {

--
Gitblit v1.10.0