com.sun.jndi.ldap.obj
Class GroupOfURLs

java.lang.Object
  extended by com.sun.jndi.ldap.obj.GroupOfURLs
All Implemented Interfaces:
java.security.acl.Group, java.security.Principal

public class GroupOfURLs
extends java.lang.Object
implements java.security.acl.Group

A representation of the LDAP groupOfURLs object class. This is a dynamic group: its membership is determined by evaluating the group's LDAP URLs.

Note that when a GroupOfURLs object is created by the application program then most of its methods throw IllegalStateException until the program binds the object in the directory. However, when a GroupOfURLs object is returned to the application program then the object is already bound in the directory and its methods function normally.

A GroupOfURLs instance is not synchronized against concurrent multithreaded access. Multiple threads trying to access and modify a GroupOfURLs should lock the object.

In order to bind a GroupOfURLs object in the directory, the following LDAP object class definition must be supported in the directory schema:

     ( 2.16.840.1.113730.3.2.33 NAME 'groupOfURLs' 
        SUP top 
        STRUCTURAL 
        MUST cn 
        MAY ( memberURL $ 
              businessCategory $ 
              description $ 
              o $ 
              ou $ 
              owner $ 
              seeAlso ) )
 
See DirContext.bind for details on binding an object in the directory.

The following code sample shows how the class may be used:


     // set the java.naming.factory.object property
     env.put(Context.OBJECT_FACTORIES,
         "com.sun.jndi.ldap.obj.LdapGroupFactory");

     // set the java.naming.factory.state property
     env.put(Context.STATE_FACTORIES,
         "com.sun.jndi.ldap.obj.LdapGroupFactory");

     // create an initial context using the supplied environment properties
     DirContext ctx = new InitialDirContext(env);

     // create a set of member URLs
     Set members = new HashSet();
     members.add(
         "ldap:///" + ctx.getNameInNamespace() + "??sub?(title=Manager)");
     Group managers = new GroupOfURLs(members);

     // bind the group in the directory
     ctx.bind("cn=managers,ou=groups", managers);

     // list all of the group's members 
     listMembers(managers);
     ...


     // list the members of a group (subgroups are expanded, by default)
     void listMembers(Group group) {
         for (Enumeration members = group.members();
                 members.hasMoreElements(); ) {
             Object object = members.nextElement();
             if (object instanceof Group) {
                 System.out.println("+" + ((Group) object).getName());
             } else if (object instanceof Principal) {
                 System.out.println(" " + ((Principal) object).getName());
             }
          }
      }
 
 

Author:
Vincent Ryan

Nested Class Summary
(package private)  class GroupOfURLs.Members
          The members of a dynamic group.
 
Field Summary
private  javax.naming.directory.Attributes attributes
           
private  javax.naming.directory.DirContext bindCtx
           
private  java.lang.String bindDN
           
private  javax.naming.Name bindName
           
private  javax.naming.directory.DirContext ctx
           
private static boolean debug
           
private  java.util.Hashtable env
           
private static java.lang.String EXPAND_GROUP
           
private  boolean expandGroup
           
private  java.lang.String groupDN
           
private static java.lang.String GROUPS_ONLY
           
private static java.lang.String MEMBER_ATTR_ID
           
private  javax.naming.directory.Attribute memberAttr
           
private  javax.naming.directory.ModificationItem[] modification
           
private  javax.naming.Name name
           
private static java.lang.String OBJECT_CLASS
           
private static javax.naming.directory.Attribute OBJECT_CLASS_ATTR
           
private  boolean objectIsBound
           
private  javax.naming.directory.SearchControls objectSearch
           
private  javax.naming.directory.DirContext rootCtx
           
private  javax.naming.directory.SearchControls searchNoAttrs
           
 
Constructor Summary
  GroupOfURLs()
          Create an empty group object.
  GroupOfURLs(java.util.Set memberURLs)
          Create a group object with an initial set of member URLs.
private GroupOfURLs(java.lang.String groupDN, javax.naming.directory.DirContext ctx, javax.naming.Name name, java.util.Hashtable env, javax.naming.directory.Attributes attributes)
           
 
Method Summary
 boolean addMember(java.security.Principal member)
          A member cannot be added to the group directly.
 void addMembers(java.lang.String members)
          Adds members to the group.
private static java.lang.Object appendFilterComponent(java.lang.StringBuffer filterBuffer, int filterIndex, java.lang.String rdn, boolean leastSignificantRdn)
           
 void close()
          Releases the naming context created by this group.
(package private)  javax.naming.directory.Attributes getAttributes()
          Retrieves the group's attributes.
 java.lang.String getName()
          Retrieves the distinguished name of the group.
(package private) static java.lang.Object getObjectInstance(java.lang.String groupDN, javax.naming.directory.DirContext ctx, javax.naming.Name name, java.util.Hashtable env, javax.naming.directory.Attributes attributes)
          Create a group object from its entry in the directory.
private  void initializeBoundState(java.lang.String groupDN, javax.naming.directory.DirContext ctx, javax.naming.Name name, java.util.Hashtable env, javax.naming.directory.Attributes attributes)
           
private  boolean isBound()
           
 boolean isMember(java.security.Principal member)
          Checks if the supplied name is a member of the group.
 boolean isMember(java.lang.String dn)
          Checks if the supplied name is a member of the group.
private  boolean isSubgroupMember(java.lang.String dn)
           
(package private) static boolean matches(javax.naming.directory.Attribute objectClass)
          Determines whether the supplied LDAP objectClass attribute matches that of the group.
 java.util.Enumeration members()
          Returns the members of the group.
 java.util.Enumeration members(java.lang.String filter)
          Returns the members of the group that satisfy the search filter.
private  void modifyMembers(java.lang.String members, int mod_op)
           
 boolean removeMember(java.security.Principal member)
          A member cannot be removed from the group directly.
 void removeMembers(java.lang.String members)
          Removes members from the group.
private static java.util.ArrayList restrictFilter(java.lang.String filter, java.lang.String dn)
           
private  javax.naming.NamingEnumeration searchUsingLdapUrl(java.lang.String memberUrl, javax.naming.directory.SearchControls searchControls, java.lang.String memberDn)
           
private  javax.naming.NamingEnumeration searchUsingLdapUrl(java.lang.String memberUrl, java.lang.String filter, javax.naming.directory.SearchControls searchControls)
           
private  javax.naming.NamingEnumeration searchUsingLdapUrl(java.lang.String memberDn, java.lang.String memberUrl, java.lang.String andFilter, javax.naming.directory.SearchControls searchControls)
           
(package private)  void setName(java.lang.String groupDN, javax.naming.directory.DirContext ctx, javax.naming.Name name)
          Sets the distinguished name of the group.
 java.lang.String toString()
          Creates a string representation of the group.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface java.security.Principal
equals, hashCode
 

Field Detail

debug

private static final boolean debug
See Also:
Constant Field Values

OBJECT_CLASS

private static final java.lang.String OBJECT_CLASS
See Also:
Constant Field Values

MEMBER_ATTR_ID

private static final java.lang.String MEMBER_ATTR_ID
See Also:
Constant Field Values

EXPAND_GROUP

private static final java.lang.String EXPAND_GROUP
See Also:
Constant Field Values

GROUPS_ONLY

private static final java.lang.String GROUPS_ONLY
See Also:
Constant Field Values

OBJECT_CLASS_ATTR

private static final javax.naming.directory.Attribute OBJECT_CLASS_ATTR

objectIsBound

private boolean objectIsBound

expandGroup

private boolean expandGroup

attributes

private javax.naming.directory.Attributes attributes

memberAttr

private javax.naming.directory.Attribute memberAttr

searchNoAttrs

private javax.naming.directory.SearchControls searchNoAttrs

objectSearch

private javax.naming.directory.SearchControls objectSearch

modification

private javax.naming.directory.ModificationItem[] modification

groupDN

private java.lang.String groupDN

bindDN

private java.lang.String bindDN

rootCtx

private javax.naming.directory.DirContext rootCtx

ctx

private javax.naming.directory.DirContext ctx

bindCtx

private javax.naming.directory.DirContext bindCtx

name

private javax.naming.Name name

bindName

private javax.naming.Name bindName

env

private java.util.Hashtable env
Constructor Detail

GroupOfURLs

public GroupOfURLs()
Create an empty group object.

Note that the newly constructed object does not represent a group in the directory until it is bound by using DirContext.bind.


GroupOfURLs

public GroupOfURLs(java.util.Set memberURLs)
Create a group object with an initial set of member URLs.

Note that the newly constructed object does not represent a group in the directory until it is bound by using DirContext.bind.

Parameters:
memberURLs - The set of initial member URLs. It may be null. Each element is a string LDAP URL (RFC 2255).

GroupOfURLs

private GroupOfURLs(java.lang.String groupDN,
                    javax.naming.directory.DirContext ctx,
                    javax.naming.Name name,
                    java.util.Hashtable env,
                    javax.naming.directory.Attributes attributes)
Method Detail

getObjectInstance

static java.lang.Object getObjectInstance(java.lang.String groupDN,
                                          javax.naming.directory.DirContext ctx,
                                          javax.naming.Name name,
                                          java.util.Hashtable env,
                                          javax.naming.directory.Attributes attributes)
Create a group object from its entry in the directory. This method is called by LdapGroupFactory.

Parameters:
groupDN - The group's distinguished name.
ctx - An LDAP context.
name - The group's name relative to the context.
env - The context's environment properties.
attributes - The group's LDAP attributes.
Returns:
Object The new object instance.

addMember

public boolean addMember(java.security.Principal member)
A member cannot be added to the group directly. Instead, members are added by adding a group LDAP URL. See addMembers(String)

Specified by:
addMember in interface java.security.acl.Group
Parameters:
member - The name of the member to be added.
Returns:
The exception is always thrown.
Throws:
java.lang.UnsupportedOperationException - A member cannot be added directly.

addMembers

public void addMembers(java.lang.String members)
                throws javax.naming.NamingException
Adds members to the group. Performs an LDAP modify to add the LDAP URL.

Parameters:
members - The string LDAP URL describing the members to be added.
Throws:
javax.naming.NamingException - The exception is thrown if an error occurs while performing LDAP modify.
java.lang.IllegalStateException - The exception is thrown if the group does not represent a group in the directory.

isMember

public boolean isMember(java.security.Principal member)
Checks if the supplied name is a member of the group. Performs an LDAP search to determine membership.

By default, subgroups are also checked. As subgroup expansion is potentially an expensive activity the feature may be disabled by setting the environment property "com.sun.jndi.ldap.obj.expandGroup" to the string value "false.

Specified by:
isMember in interface java.security.acl.Group
Parameters:
member - The name of the member to be checked.
Returns:
boolean true if membership is confirmed; false otherwise.
Throws:
java.lang.IllegalStateException - The exception is thrown if the group does not represent a group in the directory.

isMember

public boolean isMember(java.lang.String dn)
                 throws javax.naming.NamingException
Checks if the supplied name is a member of the group. Performs an LDAP search to determine membership.

By default, subgroups are also checked. As subgroup expansion is potentially an expensive activity the feature may be disabled by setting the environment property "com.sun.jndi.ldap.obj.expandGroup" to the string value "false.

Parameters:
dn - The distinguished name (RFC 2253) of the member to be checked.
Returns:
boolean true if membership is confirmed; false otherwise.
Throws:
javax.naming.NamingException - The exception is thrown if an error occurs while performing LDAP search.
java.lang.IllegalStateException - The exception is thrown if the group does not represent a group in the directory.

members

public java.util.Enumeration members()
Returns the members of the group. Performs LDAP searches to retrieve the members.

By default, subgroups and their members are also included. As subgroup expansion is potentially an expensive activity the feature may be disabled by setting the environment property "com.sun.jndi.ldap.obj.expandGroup" to the string value "false. When the feature is disabled only the group's direct members are returned.

Specified by:
members in interface java.security.acl.Group
Returns:
Enumeration The list of members of the group. When only the LdapGroupFactory object factory is active then each element in the enumeration is of class Group or Principal However, when additional object factories are active then the enumeration may contain elements of a different class.
Throws:
java.lang.IllegalStateException - The exception is thrown if the group does not represent a group in the directory.

members

public java.util.Enumeration members(java.lang.String filter)
                              throws javax.naming.NamingException
Returns the members of the group that satisfy the search filter. Performs LDAP searches to retrieve the members.

By default, subgroups and their members are also included. As subgroup expansion is potentially an expensive activity the feature may be disabled by setting the environment property "com.sun.jndi.ldap.obj.expandGroup" to the string value "false. When the feature is disabled only the group's direct members are returned.

Parameters:
filter - The string filter to apply to the members of the group. If the argument is null then no filtering is performed.
Returns:
Enumeration The list of members that satisfy the filter. When only the LdapGroupFactory object factory is active then each element in the enumeration is of class Group or Principal However, when additional object factories are active then the enumeration may contain elements of a different class.
Throws:
javax.naming.NamingException - The exception is thrown if an error occurs while performing LDAP search.
java.lang.IllegalStateException - The exception is thrown if the group does not represent a group in the directory.

removeMember

public boolean removeMember(java.security.Principal member)
A member cannot be removed from the group directly. Instead, members are removed by removing a group LDAP URL. See removeMembers(String)

Specified by:
removeMember in interface java.security.acl.Group
Parameters:
member - The name of the member to be removed.
Returns:
The exception is always thrown.
Throws:
java.lang.UnsupportedOperationException - A member cannot be removed directly.

removeMembers

public void removeMembers(java.lang.String members)
                   throws javax.naming.NamingException
Removes members from the group. Performs an LDAP modify to remove the LDAP URL.

Parameters:
members - The LDAP URL describing the members to be removed.
Throws:
javax.naming.NamingException - The exception is thrown if an error occurs while performing LDAP modify.
java.lang.IllegalStateException - The exception is thrown if the group does not represent a group in the directory.

getName

public java.lang.String getName()
Retrieves the distinguished name of the group.

Specified by:
getName in interface java.security.Principal
Returns:
String The distinguished name of the group.
Throws:
java.lang.IllegalStateException - The exception is thrown if the group does not represent a group in the directory.

setName

void setName(java.lang.String groupDN,
             javax.naming.directory.DirContext ctx,
             javax.naming.Name name)
Sets the distinguished name of the group. This method is called by LdapGroupFactory

Parameters:
groupDN - The group's distinguished name.
ctx - An LDAP context.
name - The group's name relative to the context.

toString

public java.lang.String toString()
Creates a string representation of the group.

Specified by:
toString in interface java.security.Principal
Overrides:
toString in class java.lang.Object
Returns:
String A string listing the distinguished name of the group and the contents of the group's attribute set. See BasicAttributes.toString() for details. The name is omitted if the group is not bound in the directory and null is returned if no attributes are available.

getAttributes

javax.naming.directory.Attributes getAttributes()
Retrieves the group's attributes. This method is called by LdapGroupFactory.

Returns:
Attribute The group's attributes.

matches

static boolean matches(javax.naming.directory.Attribute objectClass)
Determines whether the supplied LDAP objectClass attribute matches that of the group. A match occurs if the argument contains the value "GroupOfURLs".

Parameters:
objectClass - The non-null objectClass attribute to check against.
Returns:
true if the objectClass attributes match; false otherwise.

isBound

private boolean isBound()

close

public void close()
           throws javax.naming.NamingException
Releases the naming context created by this group. Closes the root naming context if one had been created.

Throws:
javax.naming.NamingException - If a naming exception is encountered while closing the root context.

initializeBoundState

private void initializeBoundState(java.lang.String groupDN,
                                  javax.naming.directory.DirContext ctx,
                                  javax.naming.Name name,
                                  java.util.Hashtable env,
                                  javax.naming.directory.Attributes attributes)

modifyMembers

private void modifyMembers(java.lang.String members,
                           int mod_op)
                    throws javax.naming.NamingException
Throws:
javax.naming.NamingException

isSubgroupMember

private boolean isSubgroupMember(java.lang.String dn)
                          throws javax.naming.NamingException
Throws:
javax.naming.NamingException

searchUsingLdapUrl

private javax.naming.NamingEnumeration searchUsingLdapUrl(java.lang.String memberUrl,
                                                          javax.naming.directory.SearchControls searchControls,
                                                          java.lang.String memberDn)
                                                   throws javax.naming.NamingException
Throws:
javax.naming.NamingException

searchUsingLdapUrl

private javax.naming.NamingEnumeration searchUsingLdapUrl(java.lang.String memberUrl,
                                                          java.lang.String filter,
                                                          javax.naming.directory.SearchControls searchControls)
                                                   throws javax.naming.NamingException
Throws:
javax.naming.NamingException

searchUsingLdapUrl

private javax.naming.NamingEnumeration searchUsingLdapUrl(java.lang.String memberDn,
                                                          java.lang.String memberUrl,
                                                          java.lang.String andFilter,
                                                          javax.naming.directory.SearchControls searchControls)
                                                   throws javax.naming.NamingException
Throws:
javax.naming.NamingException

restrictFilter

private static java.util.ArrayList restrictFilter(java.lang.String filter,
                                                  java.lang.String dn)
                                           throws javax.naming.InvalidNameException
Throws:
javax.naming.InvalidNameException

appendFilterComponent

private static java.lang.Object appendFilterComponent(java.lang.StringBuffer filterBuffer,
                                                      int filterIndex,
                                                      java.lang.String rdn,
                                                      boolean leastSignificantRdn)