com.ca.commons.naming
Class DXAttributes

java.lang.Object
  |
  +--com.ca.commons.naming.DXAttributes
All Implemented Interfaces:
javax.naming.directory.Attributes, java.lang.Cloneable, java.io.Serializable
Direct Known Subclasses:
DXEntry

public class DXAttributes
extends java.lang.Object
implements javax.naming.directory.Attributes

This class is a container for a collection of Attribute objects. It is schema aware, and will search schema to find a complete set of attributes for its component objectClass(s).

The class is built around a hashtable of id/attribute pairs.

See Also:
Serialized Form

Constructor Summary
DXAttributes()
          Initialises an empty set of attributes with no schema
DXAttributes(javax.naming.directory.Attribute a)
          Initialises a set of attributes with a single attribute
DXAttributes(javax.naming.directory.Attributes a)
          Copies an existing Attributes object into a DXAttributes object.
DXAttributes(java.util.Hashtable newAtts)
          Initialises a set of DXattributes using a Hashtable of existing id/attribute pairs...
DXAttributes(javax.naming.NamingEnumeration newAtts)
          Initialises a set of DXattributes using a NamingEnumeration of existing attribute(s).
 
Method Summary
static boolean attributesEqual(javax.naming.directory.Attributes a, javax.naming.directory.Attributes b)
          Checks whether two 'Attributes' objects are equivalent (including naming attributes, if any).
 java.lang.Object clone()
          creates a new DXAttributes, copying each Attribute object.
static boolean emptyAtt(javax.naming.directory.Attribute att)
          Utility ftn: checks that an attribute is not null and has at least one non-null value.
 boolean equals(javax.naming.directory.Attributes atts)
           
 boolean equals(java.lang.Object o)
           
 void expandAllAttributes()
          Sets the internal list of all attribute IDs needed for a given set of object classes, as well as noting which are mandatory and which optional.
 javax.naming.directory.Attribute get(java.lang.String attrID)
          gets an Attribute specified by its ID
static DXAttributes getAdditionSet(RDN newRDN, javax.naming.directory.Attributes oldSet, javax.naming.directory.Attributes newSet)
          Returns the set of attributes that are in the newSet, but not in the old set, excluding the rdnclass).
 javax.naming.NamingEnumeration getAll()
          returns all the Attribute(s) in this DXAttributes object
 javax.naming.NamingEnumeration getAllNonNull()
          returns all the Attribute(s) that have non-null values in this DXAttributes object
 javax.naming.directory.Attribute getAllObjectClasses()
           
static DXAttribute getAllObjectClasses(DXAttribute oc)
          Some directories don't include all of an entry's object classes, but only the lowest level ones.
 javax.naming.directory.Attributes getAsNonNullAttributes()
          For convenience and display, DXAttributes objects have a complete list of all attribute(s) that the objectclass(s) represented might possibly contain.
static DXAttributes getDeletionSet(RDN newRDN, javax.naming.directory.Attributes oldSet, javax.naming.directory.Attributes newSet)
          Returns the set of attributes that are in the oldSet, but not in the new set, and thus must be deleted.
 int getID()
           
 javax.naming.NamingEnumeration getIDs()
          returns all the attribute IDs held in this DXAttributes object.
 java.lang.String getldapName(java.lang.String attOID)
          This method does it's darndnest to return a string ldap name.
 javax.naming.NamingEnumeration getMandatory()
          returns all the mandatory 'MUST' have Attribute(s) in this DXAttributes object
 java.lang.String getObjectClassName()
           
 javax.naming.NamingEnumeration getOptional()
          returns all the optional 'MAY' Attribute(s) in this DXAttributes object
 java.util.Vector getOrderedOCs()
          Return a list of object classes as a vector from deepest (at pos 0) to 'top' (at pos (size()-1) ).
static DXAttribute getParentObjectClasses(java.lang.String childOC)
          recursively builds up a complete ordered list of all the parents of a particular object class (including the child object class) from schema.
static DXAttributes getReplacementSet(RDN newRDN, javax.naming.directory.Attributes oldSet, javax.naming.directory.Attributes newSet)
          Returns all single valued attributes whose values have changed - that is, exist in both the new set and the old set, but have different values.
 javax.naming.directory.DirContext getSchema()
           
 boolean hasOIDs()
          A quick test - do we have any numeric OIDs
 boolean isCaseIgnored()
          returns whether attribute IDs are stored in a case sensitive manner; i.e. whether 'person' is different from 'Person'.
 void print()
           
 void print(java.lang.String msg)
           
static void printAttributeList(javax.naming.NamingEnumeration enum)
           
static void printAttributes(javax.naming.directory.Attributes a)
           
 javax.naming.directory.Attribute put(javax.naming.directory.Attribute attr)
          adds an attribute to the DXAttributes collection, using the attribute.getID() method to find a key.
 void put(java.util.Enumeration attributeList)
          Adds an Enumeration of Attribute(s) to a DXAttribute
 javax.naming.directory.Attribute put(java.lang.String attrID, java.lang.Object val)
          creates an attribute with the specified values and adds it to the DXAttributes collection, using the attrID string as a key.
 boolean registerOID(java.lang.String oid, java.lang.String ldapName)
          Adds an OID / ldapName combination to the hashtable of all oid / ldapNames.
 javax.naming.directory.Attribute remove(java.lang.String attrID)
          removes the attribute containing this key (if any).
 void removeEmptyAttributes()
          This method trims all empty attributes (attributes without values) from the DXAttributes object.
 void setAllObjectClasses()
          searches the schema for all the possible attributes that the objectClasses present *could* have, and adds new attributes that are not already present to the list of current Attribute objects as empty attributes.
static void setDefaultSchema(javax.naming.directory.DirContext defaultSchema)
          This sets the standard schema to use while this connection is open.
 int size()
          returns the number of Attribute objects held.
protected static DXAttribute sortOCByDepth(javax.naming.directory.Attribute oc)
          Takes a list of *all* object class values, and returns them sorted by depth.
 java.lang.String[] toIDStringArray()
           
 java.lang.String toString()
           
 
Methods inherited from class java.lang.Object
finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

DXAttributes

public DXAttributes()
Initialises an empty set of attributes with no schema


DXAttributes

public DXAttributes(javax.naming.directory.Attribute a)
Initialises a set of attributes with a single attribute


DXAttributes

public DXAttributes(javax.naming.directory.Attributes a)
Copies an existing Attributes object into a DXAttributes object.


DXAttributes

public DXAttributes(java.util.Hashtable newAtts)
Initialises a set of DXattributes using a Hashtable of existing id/attribute pairs...


DXAttributes

public DXAttributes(javax.naming.NamingEnumeration newAtts)
Initialises a set of DXattributes using a NamingEnumeration of existing attribute(s).

Method Detail

setDefaultSchema

public static void setDefaultSchema(javax.naming.directory.DirContext defaultSchema)
This sets the standard schema to use while this connection is open. (It may be possible in future releases to set schema on a per-Attribute basis - it is not clear yet whether this would be useful.)


getID

public int getID()

clone

public java.lang.Object clone()
creates a new DXAttributes, copying each Attribute object.

Specified by:
clone in interface javax.naming.directory.Attributes
Overrides:
clone in class java.lang.Object
Returns:
a new DXAttributes object

get

public javax.naming.directory.Attribute get(java.lang.String attrID)
gets an Attribute specified by its ID

Specified by:
get in interface javax.naming.directory.Attributes
Returns:
the specified attribute (actually a DXAttribute) - null if it can't be found.

getAll

public javax.naming.NamingEnumeration getAll()
returns all the Attribute(s) in this DXAttributes object. - the NamingEnumeration is (evily) pre-sorted alphabetically...

Specified by:
getAll in interface javax.naming.directory.Attributes
Returns:
enumeration of all stored Attribute objects

getAsNonNullAttributes

public javax.naming.directory.Attributes getAsNonNullAttributes()
For convenience and display, DXAttributes objects have a complete list of all attribute(s) that the objectclass(s) represented might possibly contain. However sometimes we need an Attributes object that has no null-valued attributes (i.e. when adding it to the directory).

Returns:
an Attributes object containing no null valued attribute(s).

getAllNonNull

public javax.naming.NamingEnumeration getAllNonNull()
returns all the Attribute(s) that have non-null values in this DXAttributes object. - the NamingEnumeration is (evily) pre-sorted alphabetically...

Warning: whether an attribute is added is undefined if the attribute is multi-valued and contains one or more null values in addition to other non-null values.

Returns:
enumeration of all stored Attribute objects with non-null values

getMandatory

public javax.naming.NamingEnumeration getMandatory()
returns all the mandatory 'MUST' have Attribute(s) in this DXAttributes object. - the NamingEnumeration is (evily) pre-sorted alphabetically...

Returns:
enumeration of all stored Attribute objects

getOptional

public javax.naming.NamingEnumeration getOptional()
returns all the optional 'MAY' Attribute(s) in this DXAttributes object. - the NamingEnumeration is (evily) pre-sorted alphabetically...

Returns:
enumeration of all stored Attribute objects

getIDs

public javax.naming.NamingEnumeration getIDs()
returns all the attribute IDs held in this DXAttributes object.

Specified by:
getIDs in interface javax.naming.directory.Attributes
Returns:
all attribute IDs

isCaseIgnored

public boolean isCaseIgnored()
returns whether attribute IDs are stored in a case sensitive manner; i.e. whether 'person' is different from 'Person'. The default is false, implying case sensitivity.

Specified by:
isCaseIgnored in interface javax.naming.directory.Attributes
Returns:
whether case is ignored for attribute IDs

put

public javax.naming.directory.Attribute put(javax.naming.directory.Attribute attr)
adds an attribute to the DXAttributes collection, using the attribute.getID() method to find a key. NB: doco seems unclear on whether this adds to, or replaces, any existing attribute with the same ID. At the moment this replaces the values...

Specified by:
put in interface javax.naming.directory.Attributes
Parameters:
attr - the attribute to add
Returns:
the previous attribute (if any) with this key.

put

public javax.naming.directory.Attribute put(java.lang.String attrID,
                                            java.lang.Object val)
creates an attribute with the specified values and adds it to the DXAttributes collection, using the attrID string as a key. NB: doco seems unclear on whether this adds to, or replaces, an existing attribute with the same ID. This implementation adds the new object value...

Specified by:
put in interface javax.naming.directory.Attributes
Parameters:
attrID - the String ID of the newly added attribute
val - the value to associate with the ID for the newly created attribute
Returns:
the previous attribute (if any) with this key.

put

public void put(java.util.Enumeration attributeList)
Adds an Enumeration of Attribute(s) to a DXAttribute


remove

public javax.naming.directory.Attribute remove(java.lang.String attrID)
removes the attribute containing this key (if any).

Specified by:
remove in interface javax.naming.directory.Attributes
Parameters:
attrID - the ID of the attribute to remove
Returns:
the removed attribute (if any)

size

public int size()
returns the number of Attribute objects held.

Specified by:
size in interface javax.naming.directory.Attributes
Returns:
number of attribute objects

setAllObjectClasses

public void setAllObjectClasses()
searches the schema for all the possible attributes that the objectClasses present *could* have, and adds new attributes that are not already present to the list of current Attribute objects as empty attributes.


getObjectClassName

public java.lang.String getObjectClassName()

getOrderedOCs

public java.util.Vector getOrderedOCs()
Return a list of object classes as a vector from deepest (at pos 0) to 'top' (at pos (size()-1) ).


getAllObjectClasses

public javax.naming.directory.Attribute getAllObjectClasses()

getAllObjectClasses

public static DXAttribute getAllObjectClasses(DXAttribute oc)
Some directories don't include all of an entry's object classes, but only the lowest level ones. This looks up all the parents the low level object classes are inherited from and, forms a complete ordered list of all object classes for this Attributes object.

Returns:
an Attribute containing the names of all the object classes...

sortOCByDepth

protected static DXAttribute sortOCByDepth(javax.naming.directory.Attribute oc)
Takes a list of *all* object class values, and returns them sorted by depth. This requires the objectClassDepths hashtable to be set (which is done by getParentObjectClasses() ).


getParentObjectClasses

public static DXAttribute getParentObjectClasses(java.lang.String childOC)
                                          throws javax.naming.NamingException
recursively builds up a complete ordered list of all the parents of a particular object class (including the child object class) from schema.

Parameters:
childOC - the child Object Class to search for parents of
Returns:
an attribute containing the child class and all parents
javax.naming.NamingException

registerOID

public boolean registerOID(java.lang.String oid,
                           java.lang.String ldapName)
Adds an OID / ldapName combination to the hashtable of all oid / ldapNames.

If the oid is actually an ldap String (different servers return different things...) it doesn't bother registering the string...

Parameters:
oid - the numeric oid to register
ldapName - the name of the corresponding ldap descr
Returns:
true if new oid was registered, false if it was already known

removeEmptyAttributes

public void removeEmptyAttributes()
This method trims all empty attributes (attributes without values) from the DXAttributes object.


expandAllAttributes

public void expandAllAttributes()
Sets the internal list of all attribute IDs needed for a given set of object classes, as well as noting which are mandatory and which optional.

As an added wrinkle, this must be able to cope with attribute ID's expressed either as ldap strings, or as numeric OIDs. It does this by automatically detecting OIDs, and translating them to strings using schema lookups.

This method uses the schema to create empty valued attributes for attributes which don't currently exist, but which are allowed.


getldapName

public java.lang.String getldapName(java.lang.String attOID)
This method does it's darndnest to return a string ldap name.

First, it checks whether the string is already an ldap name; if it is, it returns it unchanged.

Secondly, it tries to find the ldap text name for an oid (i.e. converts 2.5.4.0 to 'objectClass').

Finally, if it can't find the name it returns the oid instead... (This shouldn't really happen, but means that the system may still work, although the raw OIDs aren't very user friendly)


toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object

print

public void print()

print

public void print(java.lang.String msg)

printAttributes

public static void printAttributes(javax.naming.directory.Attributes a)

printAttributeList

public static void printAttributeList(javax.naming.NamingEnumeration enum)

getAdditionSet

public static DXAttributes getAdditionSet(RDN newRDN,
                                          javax.naming.directory.Attributes oldSet,
                                          javax.naming.directory.Attributes newSet)
                                   throws javax.naming.NamingException

Returns the set of attributes that are in the newSet, but not in the old set, excluding the rdnclass).

It also returns partial attributes that contain values that are in the newSet but not in the oldSet, when either a) either attribute has a size larger than one, or b) the attribute has a distinguished value.

The logic for case a) is that we can use adds and deletes on individual attributes to simulate a 'replace' operation, but we need to avoid doing this for single valued attributes (for which we *always* use replace). So if Attribute A has values {1,2,3}, and is changed to A' {1,3,5,6}, this method returns an 'add' {5,6}.

The logic for case b) is that we cannot use 'replace' on an attribute with a naming value in it, so we *must* use adds and deletes - and we'll have to take our chances that it is not single valued. (Possibly later on we can check this from schema). This method cannot change the distinguished value, but produces an 'add' for any other changed. So if, for entry cn=fred, Attribute cn has values {fred,erik} and cn' has values {fred, nigel], this method produces an 'add' {nigel}.

Parameters:
newRDN - the new RDN of the entry that is being created (usually this is the same as the RDN of the original entry) May be null if it is not to be checked.
oldSet - the set of already existing attributes
newSet - the set of new attributes to test
Returns:
attributes that must be added to the object.
javax.naming.NamingException

getReplacementSet

public static DXAttributes getReplacementSet(RDN newRDN,
                                             javax.naming.directory.Attributes oldSet,
                                             javax.naming.directory.Attributes newSet)
                                      throws javax.naming.NamingException

Returns all single valued attributes whose values have changed - that is, exist in both the new set and the old set, but have different values. Note that this function ignores the naming attribute.

We need this function to cope with mandatory single valued attributes (otherwise we could just use add and delete).

All other attribute combinations are handled by attribute value adds and deletes. (This is slightly more efficient, and is required to modify non-distinguished values of the naming attribute anyway).

Parameters:
newRDN - the RDN of the newer entry. (usually this is the same as the RDN of the original entry) May be null if it is not to be checked.
oldSet - the set of already existing attributes
newSet - the set of new attributes to test
Returns:
attributes that require updating
javax.naming.NamingException

getDeletionSet

public static DXAttributes getDeletionSet(RDN newRDN,
                                          javax.naming.directory.Attributes oldSet,
                                          javax.naming.directory.Attributes newSet)
                                   throws javax.naming.NamingException

Returns the set of attributes that are in the oldSet, but not in the new set, and thus must be deleted.

It also returns the set of attribute *values* that are in the old set, but not in the new set. E.g. if attribute A has values {1,2,3,4}, and the new attribute A' has {1,4,6,7}, this returns {2,3} for deletion.

This method will ignore naming values, but will correctly handle other values of the naming attribute.

Parameters:
newRDN - the RDN of the newer entry. (usually this is the same as the RDN of the original entry). May be null if it is not to be checked.
oldSet - the set of already existing attributes
newSet - the set of new attributes to test
javax.naming.NamingException

attributesEqual

public static boolean attributesEqual(javax.naming.directory.Attributes a,
                                      javax.naming.directory.Attributes b)
                               throws javax.naming.NamingException
Checks whether two 'Attributes' objects are equivalent (including naming attributes, if any).

javax.naming.NamingException

equals

public boolean equals(java.lang.Object o)
Overrides:
equals in class java.lang.Object

equals

public boolean equals(javax.naming.directory.Attributes atts)
               throws javax.naming.NamingException
javax.naming.NamingException

getSchema

public javax.naming.directory.DirContext getSchema()

toIDStringArray

public java.lang.String[] toIDStringArray()

hasOIDs

public boolean hasOIDs()
A quick test - do we have any numeric OIDs


emptyAtt

public static boolean emptyAtt(javax.naming.directory.Attribute att)
Utility ftn: checks that an attribute is not null and has at least one non-null value.