📄 jndibroker.java
字号:
public boolean isActive() { return (ctx != null); }
/**
* whether the data source is currently on-line.
* @return on-line status
*/
public boolean hasConnectionError() { return ((ctx==null)||(connectionError)); }
/**
* Reads an entry with all its attributes from the directory.
* @param entryDN the DN of the entry.
* @param returnAttributes a list of string names of attributes to return in the search.
* (null means 'return all entries', a zero length array means 'return no attributes'.)
* @return the entry.
*/
public DXEntry unthreadedReadEntry(DN entryDN, String[] returnAttributes)
throws NamingException
{
DXAttributes atts = new DXAttributes(dirOps.read(entryDN, returnAttributes));
return new DXEntry(atts, entryDN);
}
/**
* Add the new entry to the directory.
* @param newEntry the new entry containing the replacement set of attributes.
*/
public void addEntry(DXEntry newEntry)
throws NamingException
{
// sanity check
if (newEntry.getDN() == null)
throw new NamingException("Internal Error: Entry with null DN passed to JNDIBroker addEntry(). Modify Request Cancelled.");
dirOps.addEntry(newEntry.getDN(), newEntry);
}
/**
* Utility ftn for updateNode - takes a list of attributes to modify, and
* the type of modification, and adds them to an array of modifications (starting
* at a particular index).
*
* @param mods the array of modification items
* @param atts an enumeration of attributes to add to the mod array
* @param TYPE the type of modification (DELETE,REPLACE,ADD)
* @param index the position in the modification array to start filling entries in
* @return the final index position reached.
*/
protected int loadMods(ModificationItem[] mods, NamingEnumeration atts, int TYPE, int index)
throws NamingException
{
while (atts.hasMore())
{
Attribute temp = (Attribute)atts.next();
mods[index++] = new ModificationItem(TYPE,temp);
}
return index;
}
/**
* Update an entry with the designated DN.
* @param oldEntry the old entry containing teh old set of attributes.
* @param newEntry the new entry containing the replacement set of attributes.
*/
public void unthreadedModify(DXEntry oldEntry, DXEntry newEntry)
throws NamingException
{
if (useSpecialWriteAllAttsMode()) // do magic for Mitch
doSpecialWriteAllAttsHandling(oldEntry, newEntry);
else
dirOps.modifyEntry(oldEntry, newEntry);
}
private void doSpecialWriteAllAttsHandling(DXEntry oldEntry, DXEntry newEntry)
throws NamingException
{
// check for cases where handling is the same as normal
if ( (newEntry == null) || (oldEntry == null && newEntry.getStatus() == DXEntry.NEW) )
{
dirOps.modifyEntry(oldEntry, newEntry);
}
// do any rename required
if (oldEntry.getDN().toString().equals(newEntry.getDN().toString()) == false)
{
moveTree(oldEntry.getDN(), newEntry.getDN());
}
if (DXAttributes.attributesEqual(oldEntry,newEntry))
{
return; // nothing to do.
}
DN nodeDN = newEntry.getDN();
RDN newRDN = nodeDN.getLowestRDN();
DXAttributes adds = null; // use modify-add for new attribute values (inc entirely new attribute)
DXAttributes reps = null; // use modify-replace for changed attribute values
DXAttributes dels = null; // use modify-delete for deleted attribute values (inc deleting entire attribute)
try
{
if (hasVerboseObjectClass(newEntry)) // ?? XXX is this right? Shouldn't oldSet be null or something?
reps = Special.getReplacementSet(newRDN, oldEntry, newEntry);
else
reps = new DXAttributes();
dels = Special.getDeletionSet(newRDN, oldEntry, newEntry);
adds = Special.getAdditionSet(newRDN, oldEntry, newEntry);
log.fine("updateNode: " + nodeDN);
ModificationItem[] mods;
mods = new ModificationItem[dels.size() + reps.size() + adds.size()];
int modIndex = 0;
modIndex = loadMods(mods, dels.getAll(), DirContext.REMOVE_ATTRIBUTE, modIndex);
modIndex = loadMods(mods, adds.getAll(), DirContext.ADD_ATTRIBUTE, modIndex);
modIndex = loadMods(mods, reps.getAll(), DirContext.REPLACE_ATTRIBUTE, modIndex);
dirOps.modifyAttributes(nodeDN, mods);
}
catch (Exception e)
{
NamingException os390 = new NamingException("SPECIAL OS390 MODE ERROR: Unexpected Error updating node " + oldEntry.getDN() + "! " + e.toString());
os390.initCause(e);
throw os390;
}
}
/*
* Optional debug code. Very useful. NEVER REMOVE!!!
* @param oldSet old entry.
* @param newSet new entry.
* @param adds list of attributes to add.
* @param reps list of attributes to replace.
* @param dels list of attributes to delete.
*/
/*
private void printDebug(DXEntry oldSet, DXEntry newSet, DXAttributes adds, DXAttributes reps, DXAttributes dels)
{
System.out.println("\n*** entries are ***\n\nold:\n" + oldSet.toString() + "\n\nnew:\n" + newSet.toString());
System.out.println("\n-----------------\nreps:\n" + reps.toString());
System.out.println("\n-----------------\ndels:\n" + dels.toString());
System.out.println("\n-----------------\nadds:\n" + adds.toString());
//Thread.currentThread().dumpStack();
}
*/
protected boolean useSpecialWriteAllAttsMode()
{
// XXX Warning - the 'special code for Mitch' works very differently
// XXX from the normal DXAttributes.get... code in the normal operation
// XXX section - be careful about changing it.
return (specialObjectClasses != null); // test for special hack for Mitch
}
/**
* Checks if any of the objectClasses of this object are on the list
* of special objects that require all attributes to be sent in a
* 'replace' list, whether or not they have been modified by the user.
* (by request of Mitch Rozonkiewiecz and the OS390 security people...)
* @param atts the list of attributes.
* @return true if on the list, false other wise.
*/
protected boolean hasVerboseObjectClass(Attributes atts)
{
if (specialObjectClasses == null) return false; // there are none.
try
{
Attribute oc;
if (atts instanceof DXAttributes == false)
oc = atts.get("objectClass"); // even odds: this may screw up due to capitalization.
else // (but this *should* always be a DXAttributes object...)
oc = ((DXAttributes)atts).getAllObjectClasses();
NamingEnumeration ocs = oc.getAll();
while (ocs.hasMore())
{
Object test = ocs.next();
if (specialObjectClasses.contains(test))
{
return true;
}
}
return false;
}
catch (NamingException e)
{
log.warning("error getting object classes in jndibroker " + e);
return false;
}
}
/**
* Checks whether the current data source is modifiable. (Nb.,
* a directory may have different access controls defined on
* different parts of the directory: if this is the case, the
* directory may return true to isModifiable(), however a
* particular modify attempt may still fail.
*
* @return whether the directory is modifiable
*/
public boolean isModifiable()
{
return true;
}
/*** DataSource-Like methods querying schemaOps. These are used
by 'SchemaBroker' to support querying of schemaOps info. ***/
/**
* returns the root DN of the schemaOps subentry as a string.
* @return the schemaOps subentry (i.e. something like 'cn=schemaOps')
*/
public String getSchemaRoot()
{
if (ctx==null)
return "";
String fnord = "";
//System.out.println("long shot...");
try
{
fnord = ctx.getSchema("").toString();
return fnord;
}
catch (NamingException e)
{ log.warning("error reading schemaOps\n" + e);}
return "cn=schemaOps"; // default: often what is anyway... :-)
}
/**
* Gets a list of the object classes most likely
* to be used for the next Level of the DN...
* @param dn the dn of the parent to determine likely
* child object classes for
* @return list of recommended object classes...
*/
public ArrayList unthreadedGetRecOCs(DN dn)
{
return schemaOps.getRecommendedObjectClasses(dn.toString());
}
/**
* Modifies the attributes associated with a named object using an an ordered list of modifications.
* @param dn distinguished name of object to modify
* @param mods an ordered sequence of modifications to be performed; may not be null
*/
public void modifyAttributes(DN dn, ModificationItem[] mods)
throws AttributeModificationException, NamingException
{
if (ctx == null)
throw new NamingException("no directory context to work with");
ctx.modifyAttributes(dn, mods);
}
/**
* Usually shells to CBUtility.error, but will log instead if quiet mode
* is set.
* @param msg the error message to display.
* @param e the exception caused.
*/
public void error(String msg, Exception e)
{
if (quietMode == false)
{
CBUtility.error(msg, e);
}
else
{
errorWhileQuietFlag = true;
log.warning(msg + "\n (details) " + e.toString());
}
}
/**
* @return the directory operations object.
*/
public CBGraphicsOps getDirOp() { return dirOps; }
/**
* @return the directory operations context.
*/
public DirContext getDirContext() { return (dirOps==null)?null:dirOps.getContext(); }
/**
* If the rootDN doesn't exist, we try to read the
* the root DN from the server. Not all servers
* support this functionality, but some include a
* <i>namingcontexts</i> attribute for their empty
* entry...
* @return the rootDN, or null if none was found.
*/
public DN[] readFallbackRoot()
{
log.finer("reading fallback root DN...");
try
{
Attributes a = unthreadedReadEntry(new DN(""), new String[] {"namingContexts"});
if (a==null) return null; // can't do anything, bail.
log.finer("...Got root DSE data...");
//XXX namingContexts may need to be explicitly asked for, since it is an op att.
Attribute rootDNC;
rootDNC = a.get("namingcontexts");
if (rootDNC == null)
rootDNC = a.get("namingContexts"); // some servers do 'ave em...
if (rootDNC == null || rootDNC.size()==0) return new DN[] {new DN()}; // can't do anything; bail with an empty DN.
if (rootDNC.size() == 1)
{
String rootDNString = rootDNC.get().toString();
log.info("read fallback root DN as: " + rootDNString);
return new DN[] {new DN(rootDNString)};
}
// Multiple Naming Contexts!!
DN contexts[] = new DN[rootDNC.size()];
int index=0;
Enumeration roots = rootDNC.getAll();
while (roots.hasMoreElements())
{
String dn = roots.nextElement().toString();
contexts[index++] = new DN(dn);
}
return contexts;
}
catch (NamingException e)
{
log.log(Level.WARNING, "Error reading fallback root: ",e);
return null;
}
}
/**
* This sets the context to use either jndi 'searching' or 'never' alias
* resolution, depending on the value of the jxplorer property
* option.ldap.searchAliasBehaviour.
*/
public void SetContextToSearchingAliases()
{
try
{
if (ctx != null) ctx.addToEnvironment("java.naming.ldap.derefAliases", JXplorer.getProperty("option.ldap.searchAliasBehaviour"));
}
catch( Exception e)
{
log.warning("Unexpected exception setting search alias handling behaviour in context to " + JXplorer.getProperty("option.ldap.searchAliasBehaviour") + "\n " + e);
}
}
/**
* This sets the context to use either jndi 'browsing' or 'never' alias
* resolution, depending on the value of the jxplorer property
* option.ldap.browseAliasBehaviour.
*/
public void SetContextToBrowsingAliases()
{
try
{
if (ctx != null) ctx.addToEnvironment("java.naming.ldap.derefAliases", JXplorer.getProperty("option.ldap.browseAliasBehaviour"));
}
catch( Exception e)
{
log.warning("Unexpected exception setting browse alias handling behaviour in context to " + JXplorer.getProperty("option.ldap.browseAliasBehaviour") + "\n " + e);
}
}
/**
* Returns a schemaOps ops object capable of answering questions about schemaOps and syntax.
* @return a schemaOps aware schemaOps object linked to the same directory context as the broker.
*/
public SchemaOps getSchemaOps()
{
return schemaOps;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -