📄 dxattributes.java
字号:
* 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 <b>replaces</b> the values...
* @param attr the attribute to add
* @return the previous attribute (if any) with this key.
*/
public Attribute put(Attribute attr)
{
if (attr == null) return null; // sanity check - can't add a null attribute...
Attribute old = get(attr.getID().toLowerCase());
schemaChecked = false;
if (old!=null)
{
atts.remove(old.getID().toLowerCase()); // code for *replacing* existing attribute values
}
String ID = attr.getID().toLowerCase();
if (attr instanceof DXAttribute)
atts.put(ID, attr);
else
atts.put(ID, new DXAttribute(attr));
return old;
}
/**
* 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
* <b>adds</b> the new object value...
*
* @param attrID the String ID of the newly added attribute
* @param val the value to associate with the ID for the newly
* created attribute
* @return the previous attribute (if any) with this key.
*/
public Attribute put(java.lang.String attrID, java.lang.Object val)
{
schemaChecked = false;
return put(new DXAttribute(attrID.toLowerCase(), val));
}
/**
* Adds an Enumeration of Attribute(s) to a DXAttribute
*
* @param attributeList the list of attributes to add.
*/
public void put(Enumeration attributeList)
{
while (attributeList.hasMoreElements())
{
Attribute a = (Attribute)attributeList.nextElement();
if (a instanceof DXAttribute)
put(a);
else
put(new DXAttribute(a));
}
}
/**
* removes the attribute containing this key (if any).
* @param attrID the ID of the attribute to remove
* @return the removed attribute (if any)
*/
public Attribute remove(java.lang.String attrID)
{
schemaChecked = false;
return (Attribute) atts.remove(attrID.toLowerCase());
}
/**
* returns the number of Attribute objects held.
*
* @return number of attribute objects
*/
public int size()
{
return atts.size();
}
/**
* 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.
*/
/*
public void checkSchema()
{
if ((schema == null)|| (schemaChecked==true)) return; // nothing to do
try
{
// update the hashtable with complete list
// of attributes as read from schema
expandAllAttributes(getAllObjectClasses());
//print();
}
catch (NamingException e)
{
log.warning("Naming Exception in Schema Read of DXAttribute\n " + e);
}
schemaChecked = true;
}
*/
/*
public String getBaseObjectClass()
{
if (baseObjectClass == null)
{
setAllObjectClasses();
if (baseObjectClass == null) // Still? Must be an error somewhere...
return "top";
}
return baseObjectClass;
}
*/
public void setAllObjectClasses()
{
allObjectClasses = getAllObjectClasses();
}
/**
* Return a list of object classes as a vector from deepest (at pos 0) to 'top' (at pos (size()-1) ).
*/
public Vector getOrderedOCs()
{
Vector ret = null;
try
{
Attribute oc = getAllObjectClasses();
if (oc == null)
return null;
ret = new Vector(oc.size());
NamingEnumeration vals = oc.getAll();
while (vals.hasMore())
{
ret.add(vals.next());
}
return ret;
}
catch (NamingException e)
{
log.log(Level.WARNING, "Yet another rare naming exception - DXAttributes:getOrderedOCs ", e);
return new Vector(0);
}
}
public Attribute getAllObjectClasses()
{
Attribute att = get("objectclass");
if (att != null) //TE: check that the attribute is set.
{
if (att instanceof DXAttribute)
return getAllObjectClasses((DXAttribute)att);
else
return getAllObjectClasses(new DXAttribute(att));
}
return null; //TE: return null if att is null.
}
/**
* 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.
*
* @return an Attribute containing the names of all the object classes...
*/
// XXX objecClass should no longer be case sensitive. When happy this works,
// XXX delete code below.
public static DXAttribute getAllObjectClasses(DXAttribute oc)
{
if (oc==null) return null; // no object classes (may be virtual entry such as DSA prefix)
if (knownSubSets.containsKey(oc))
return(DXAttribute) knownSubSets.get(oc);
try
{
DXAttribute orig = new DXAttribute(oc);
Enumeration vals = oc.getAll();
while (vals.hasMoreElements())
{
Attribute parents = getParentObjectClasses((String)vals.nextElement());
if (parents != null)
{
Enumeration parentVals = parents.getAll();
while (parentVals.hasMoreElements())
{
String parent = (String) parentVals.nextElement();
if (oc.contains(parent) == false)
{
oc.add(parent);
}
}
}
}
DXAttribute fullOC = sortOCByDepth(oc);
knownSubSets.put(orig, fullOC);
return fullOC;
}
catch (NamingException e)
{
log.log(Level.WARNING, "NamingException in getAllObjectClasses ", e);
return 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() ).
*/
protected static DXAttribute sortOCByDepth(Attribute oc)
{
DXAttribute ret = new DXAttribute("objectClass");
ret.setOrdered(true);
try
{
Enumeration vals = oc.getAll();
while (vals.hasMoreElements())
{
String val = (String) vals.nextElement();
Integer myInt = (Integer)objectClassDepths.get(val);
if (myInt == null) // shouldn't happen (if schema is correct), but in case we missed one...
{
getParentObjectClasses(val); // try again to set the objectClassDepths hash for this value. (probably won't work).
myInt = (Integer)objectClassDepths.get(val); // and try to reget the value.
if (myInt == null) // if still null, give up and set to zero.
myInt = new Integer(0);
}
int depth = myInt.intValue();
int i;
for (i=ret.size()-1; i>=0; i--)
{
int existing = ( (Integer)objectClassDepths.get(ret.get(i)) ).intValue();
if ( existing >= depth)
{
ret.add(i+1, val);
break;
}
}
if (i == -1)
ret.add(0, val);
}
return ret;
}
catch (NamingException e)
{
log.log(Level.WARNING, "Naming Exception in DXAttributes sortOCByDepth()", e);
return new DXAttribute(oc);
}
}
/**
* recursively builds up a complete ordered list of all the parents of a particular
* object class (including the child object class) from schema.
*
* @param childOC the child Object Class to search for parents of
* @return an attribute containing the child class and all parents
*/
public static DXAttribute getParentObjectClasses(String childOC)
throws NamingException
{
if (schema == null) // in the absence of a schema, everything is at level '1', just below 'top'
{
objectClassDepths.put(childOC, new Integer(1));
return null;
}
if ("schema attributedefinition classdefinition syntaxdefinition matchingrule".indexOf(childOC.toLowerCase()) != -1) return null; // don't bother looking up synthetic object classes.
if (knownParents.containsKey(childOC))
{
return (DXAttribute) knownParents.get(childOC);
}
DXAttribute parents = new DXAttribute("objectClass"); // this is the attribute returned
String schemaParent = null;
try
{
//schemaParents = schema.getAttributes("ClassDefinition/" + childOC, new String[] {"SUP"});
Attributes schemaDef = schema.getAttributes("ClassDefinition/" + childOC);
if (schemaDef!=null)
{
Attribute sup = schemaDef.get("SUP");
if (sup!=null)
schemaParent = (String)sup.get();
}
}
catch (NamingException e) // easily throws a name-not-found exception
{
log.warning("Possible Schema Error: class definition for " + childOC + " could not be found");
objectClassDepths.put(childOC, new Integer(1)); // BAD SCHEMA! NO BISCUIT! Set to one 'cause we don't know true depth (and top is always zero).
return null; // do nothing
}
// TODO: this is silly; why don't we just reuse the DXAttribute object returned?
// XXX - no time to fix now; maybe later...
if (schemaParent != null) // may not: e.g. 'top' has no parent
{
DXAttribute oc = getParentObjectClasses(schemaParent); // recurse -> this should also set the depth in objectClassDepths
if (oc != null)
{
Enumeration vals = oc.getAll();
while (vals.hasMoreElements()) // load up the return attribute
{
parents.add(vals.nextElement()); // (o.k. to add the same value twice...)
}
}
int depth = ((Integer)objectClassDepths.get(schemaParent)).intValue();
if (objectClassDepths.containsKey(childOC) == false)
{
objectClassDepths.put(childOC, new Integer(depth+1));
}
else
{
int oldDepth = ((Integer)objectClassDepths.get(childOC)).intValue();
if (oldDepth <= depth)
objectClassDepths.put(childOC, new Integer(depth+1));
}
}
else // no schemaParents
{
objectClassDepths.put(childOC, new Integer(1)); // BAD SCHEMA! NO BISCUIT! Set to one 'cause we don't know true depth (and top is always zero).
//schemaParents = null; // so store a blank place holder
}
parents.add(childOC); // *** Note Cunning Recursive Magic - this is where base stuff actually gets added to parents... ***
knownParents.put(childOC, parents);
return parents;
}
/**
* Get structural object classes, in deepest oc first order.
* @return vector of structural OCs (may be null if can't be resolved)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -