📄 schemaops.java
字号:
{
System.out.println("error printing raw schema:" + e);
}
}
/**
* <p>This returns the raw schema straight from the
* directory. Only use this if you <i>really</i>
* know what you're doing - see getAttributes() for
* an explanation.</p>
*/
// ...Your schema caching code here...
public Attributes getRawSchema()
throws NamingException
{
String rawSchemaRoot = getSchemaRoot();
log.finest("reading raw schema from " + rawSchemaRoot);
// need to explicitly list operational attributes... (although eTrust Directory doesn't need this, others do)
Attributes rawSchema = null;
if (ctx != null)
rawSchema = ctx.getAttributes(rawSchemaRoot, new String[]{"attributeTypes", "objectClasses", "matchingRules", "ldapSyntaxes", "*"});
if (rawSchema == null)
{
log.warning("null schema read - returning empty schema list.");
rawSchema = new BasicAttributes(); // return empty atts rather than null, to cut down on 'check for null' code...
}
else
{
if (rawSchema.size() == 0) // may be a type of directory that requires explicit listing of schema objects...
{
log.warning("Unable to read schema details from directory.");
rawSchema = new BasicAttributes(); // give up - set to empty :-(
return rawSchema;
}
log.finest("some schema read...");
rawSchema.remove("objectClass"); // Paranoid. Yes.
rawSchema.remove("oc"); // But very thorough.
rawSchema.remove("objectclass");
String nameAttribute = rawSchemaRoot.substring(0, rawSchemaRoot.indexOf('='));
rawSchema.remove(nameAttribute);
}
return rawSchema;
}
private void setSchemaRoot(String schema)
{
schemaRoot = schema;
}
/**
* returns the root DN of the schema subentry as a string.
*
* @return the schema subentry (i.e. something like 'cn=schema')
*/
public String getSchemaRoot()
{
if (schemaRoot != null)
return schemaRoot;
if (ctx != null)
{
try
{
log.finest("start get schema root call");
Attributes SSSE;
SSSE = ctx.getAttributes("", new String[]{subschemaAttributeName});
if (SSSE != null && SSSE.get(subschemaAttributeName) != null)
schemaRoot = (String) SSSE.get(subschemaAttributeName).get();
log.finest("schema root read as being: '" + String.valueOf(schemaRoot) + "'");
}
catch (NamingException e)
{
// revert to using good old 'cn=schema' ...
}
}
if (schemaRoot == null)
{
log.finest("forcing value of schema root to 'cn=schema', since can't read subschema attribute name");
schemaRoot = "cn=schema"; // default: this is what it usually is anyway... :-)
}
return schemaRoot;
}
/**
* <p>HERE BE DRAGONS</p>
* <p/>
* <p>Similarly to jndi, we impose a structure on the raw schema entry. In the
* directory, there is a single schema entry, with a number of multi-valued attributes, e.g.
* one attribute for 'objectClasses', one for 'ldapSyntaxes'. Each attribute value has
* a wretched format, e.g. an objectClasses value might be:
* " ( 0.9.2342.19200300.100.4.4 NAME 'newPilotPerson' SUP ( person )
* STRUCTURAL MAY ( uid $ mail $ drink $ roomNumber $ userClass $ homePhone $ homePostalAddress
* $ secretary $ personalTitle $ preferredDeliveryMethod $ businessCategory $ janetMailbox
* $ otherMailbox $ mobile $ pager $ organizationalStatus $ mailPreferenceOption $ personalSignature ) ) "</p>
* <p/>
* <p>We break this up by adding an extra layer of virtual attributes, turning the above attribute
* value into an attributes object (with a 'MAY' attribute, a 'NAME' attribute etc. ...
* (If you need the real deal, use getRawSchema()... but be sure
* you know what you're doing :-). </p>
*
* @param entryName the name of an entry, e.g. schema=cn,schema=attributeTypes
*/
public Attributes getAttributes(String entryName)
throws NamingException
{
entryName = mangleEntryName(entryName);
BasicAttributes schemaAttributes = new BasicAttributes(); // add fake object class to keep some DXattributes routines happy...
schemaAttributes.put(schemaObjectClassAttribute);
if (entryName == null || entryName.length() == 0) // return synthetic entry for syntax root
{
schemaAttributes.put(subschemaAttributeName, schemaRoot);
}
else if (entryName.indexOf(',') == -1 && entryName.indexOf('/') == -1) // return synthetic entry for syntax type headings
{
String schemaType = entryName.substring(entryName.indexOf('=') + 1);
schemaAttributes.put("schemaType", schemaType);
}
else
{
schemaAttributes = getAttributesFromSchemaName(entryName);
}
return schemaAttributes;
}
/**
* <p>This method does three things; firstly, it trims the schema root from
* the name if present (e.g. trims ",cn=schema" in most cases).
* Secondly, it trims any ';binary' from the end of the string.
* Finally, it translates the pseudo-schema names jndi imposes on top of the
* standard ldap/X500 syntax names from rfc 2252/2256:</p>
* <ul>
* <li>AttributeDefinition => attributeTypes
* <li>ClassDefinition => objectClasses
* <li>SyntaxDefinition => ldapSyntaxes
* </ul>
*
* @param entryName : schema=ClassDefinition,cn=schema or schema=cn,schema=attributeTypes
* @return
*/
protected String mangleEntryName(String entryName)
{
if (entryName.indexOf("ClassDefinition") > -1)
entryName = entryName.replaceAll("(ClassDefinition)", "objectClasses");
if (entryName.indexOf("SyntaxDefinition") > -1)
entryName = entryName.replaceAll("(SyntaxDefinition)", "ldapSyntaxes");
if (entryName.indexOf("AttributeDefinition") > -1)
entryName = entryName.replaceAll("(AttributeDefinition)", "attributeTypes");
// if it is an ldap name, restructure it to the schema=..., schema=... used in JX.
if (entryName.indexOf('/') > 0)
{
// trim ;binary for prettiness...
// TODO: Is this such a good idea?; it may mess up some directories such as slapd...
int pos = entryName.indexOf(";binary");
if (pos > -1)
entryName = entryName.substring(0, pos);
int slashpos = entryName.indexOf('/');
String topLevelName = entryName.substring(0, slashpos);
String specificName = entryName.substring(++slashpos);
return "schema=" + specificName + ",schema=" + topLevelName;
}
// otherwise it is already a JX style name, so we clean it up a bit to get it in a standard form
// trim the schema root off the end, since we're only interested in the next level (objectclasses etc.)
int pos = entryName.indexOf(schemaRoot);
if (pos > 0) // not '-1' due to need to trim preceeding comma
entryName = entryName.substring(0, pos - 1);
// a little naughtily, we often use 'cn=schema' as shorthand for the schema root... get rid of that instead if it is different from the schema root (usually it isn't)
pos = entryName.indexOf("cn=schema");
if (pos > 0) // not '-1' due to need to trim preceeding comma
entryName = entryName.substring(0, pos - 1);
return entryName;
}
/**
* returns the specific schema entry name - eg 'cn' in 'schema=cn,schema=attributeTypes'
*
* @param entryName the schema entry DN in JX format - 'schema=cn,schema=attributeTypes'
* @return the specific schema name - e.g. 'cn'
* @throws NamingException
*/
protected String getSpecificName(String entryName)
throws NamingException
{
int equalpos = entryName.indexOf('=') + 1;
int commapos = entryName.indexOf(',');
if (equalpos <= 0 || commapos == -1 || equalpos > commapos)
throw new NamingException("error parsing schema dn '" + entryName + "' ");
return entryName.substring(equalpos, commapos);
}
/**
* returns the specific schema entry name - eg 'cn' in 'schema=cn,schema=attributeTypes'
*
* @param entryName the schema entry DN in JX format - 'schema=cn,schema=attributeTypes'
* @return the specific schema name - e.g. 'cn'
* @throws NamingException
*/
protected String getTypeName(String entryName)
throws NamingException
{
if (entryName.endsWith(",cn=schema"))
entryName = entryName.substring(0, entryName.length() - 10);
int equalpos = entryName.lastIndexOf('=') + 1;
return entryName.substring(equalpos);
}
/**
* This looks up the raw 'Attribute' corresponding to the full entryName. It then takes the value
* of that attribute, and creates a new Attributes object by parsing that value.
*
* @param entryName
* @throws NamingException
*/
// package visibility for testing
protected BasicAttributes getAttributesFromSchemaName(String entryName) throws NamingException
{
if (rawSchemaAttributes == null)
return null;
entryName = mangleEntryName(entryName);
// do all this the slow way for now...
String schemaTypeName = getTypeName(entryName);
String specificName = getSpecificName(entryName);
Attribute schemaGroup = rawSchemaAttributes.get(schemaTypeName);
if (schemaGroup == null)
{
// some wierdo directories manage to get their cases muddled. This is a last-gasp attempt
// to read them by using an all-lower case version of the name.
schemaGroup = rawSchemaAttributes.get(schemaTypeName.toLowerCase());
throw new NamingException("Unable to find schema entry for schema type '" + schemaTypeName + "'");
}
NamingEnumeration schemaValues = schemaGroup.getAll();
String schemaValue;
while (schemaValues.hasMore())
{
schemaValue = (String) schemaValues.next();
String[] names = getNames(schemaValue);
for (int i = 0; i < names.length; i++)
{
// use case-insensitive match to cope with weirdo directories that muddle case
if (specificName.equalsIgnoreCase(names[i]))
{
return getAttributesFromSchemaValue(schemaValue);
}
}
}
return null;
}
/**
* <p>This Parses the schema values from the syntaxValue. The parser is very simple,
* and this might cause trouble in future years. The assumptions are:</p>
* <ul>
* <li> syntax keywords are all in upper case (e.g. NAME, DESC etc.).
* <li> keywords are all followed by a list of values in mixed case.
* <li> all values are more than one character long.
* <li>
* </ul>
*/
// package visibility for testing
/**
* A quicky parse routine to spin through a list ( 'fred' 0.2.3.4 'nigel' 'horse heads' ) fnord fnord fnord ( 'more fnords' )
* adding elements to the passed attribute until it hits the first ')'
*
* @param schemaAttribute attribute to add the bracketed strings to.
* @param st a string tokeniser to read values from.
*/
private void addBracketedValues(Attribute schemaAttribute, StringTokenizer st)
{
while (st.hasMoreTokens())
{
String token = st.nextToken();
if (token.endsWith(")")) // that's all for this list...
{
if (token.length() > 1)
schemaAttribute.add(getQuotedTokens(token.substring(0, token.length() - 1), st));
return;
}
schemaAttribute.add(getQuotedTokens(token, st));
}
}
/**
* If the token has an opening ' character, this will read either it or a sequence until
* it gets to the closing ' - otherwise it just returns the token.
*
* @param token
* @return
*/
private String getQuotedTokens(String token, StringTokenizer st)
{
if (token.charAt(0) != '\'')
return token;
if (token.length() < 2) // ??? Wierd - this should never happen.
return token;
if (token.charAt(0) == '\'' && token.charAt(token.length() - 1) == '\'')
return token.substring(1, token.length() - 1);
// string of quoted text... this would be so much easier in perl. sigh.
StringBuffer returnText = new StringBuffer(token.substring(1));
while (st.hasMoreTokens())
{
token = st.nextToken();
if (token.endsWith("'"))
return (returnText.append(" ").append(token.substring(0, token.length() - 1)).toString());
else
returnText.append(" ").append(token);
}
return returnText.toString(); // someone forgot the closing quote I guess...
}
/**
* This parses an attribute schema string such as: "( 2.5.6.2 NAME 'country' SUP ( top ) STRUCTURAL MUST ( c ) MAY ( description $ searchGuide ) )"
* and breaks it up into a pseudo attribute with elements such as 'NAME'->'country' and 'MAY' -> 'description', 'searchGuide'
*
* @param syntaxValue the string of syntax details as per rfc 2252
* @return the pseudo attribute, suitable for display.
*/
protected BasicAttributes getAttributesFromSchemaValue(String syntaxValue)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -