📄 schemaops.java
字号:
{
BasicAttributes schemaValues = new BasicAttributes(); // add fake object class to keep some DXattributes routines happy...
schemaValues.put(schemaObjectClassAttribute);
StringTokenizer st = new StringTokenizer(syntaxValue, " \t\n\r\f$");
// Special Handling for first OID case
if (st.hasMoreTokens())
{
String oid = st.nextToken();
if (oid.startsWith("(")) // can be a stray opening '('.
{
if (oid.length() == 1)
oid = st.nextToken();
else
oid = oid.substring(1); // handle case where there is no space between ( and Oid.
}
schemaValues.put(new BasicAttribute("OID", oid));
}
while (st.hasMoreTokens())
{
String attributeID = st.nextToken();
if (attributeID.endsWith(")") == false) // stray closing ')' is possible (see above)
{
addAttribute(schemaValues, attributeID, st);
}
else
{
if (attributeID.length() > 1)
addAttribute(schemaValues, attributeID.substring(1), st);
}
}
try
{
Attribute syntaxOID;
if ((syntaxOID = schemaValues.get("SYNTAX")) != null)
{
String syntaxOIDString = (String)syntaxOID.get();
String syntaxDescription = translateOID(syntaxOIDString);
schemaValues.put(new BasicAttribute("SYNTAX Description", syntaxDescription));
}
}
catch (Exception e)
{
log.log(Level.INFO, "unable to translate syntax oid ", e);
}
return schemaValues;
}
/**
* Parses the current attribute from the schema string. NB - this method will recurse if two
* attribute keyword tokens are discovered next to each other.
*
* @param schemaValues - the Attributes object to add the schema Attribut<b>e</b> objects to.
* @param attributeName - the name of the new Attribut<b>e</b> object to construct
* @param st the token list to read the attribute data from
*/
private void addAttribute(Attributes schemaValues, String attributeName, StringTokenizer st)
{
BasicAttribute schemaAttribute = new BasicAttribute(attributeName);
schemaValues.put(schemaAttribute);
if (st.hasMoreTokens())
{
String token = st.nextToken();
if (token.startsWith("("))
{
if (token.length() > 1)
{
if (token.endsWith(")") == true) // pathalogical case: "(VALUE)"
{
token = token.substring(0, token.length() - 1);
schemaAttribute.add(token.substring(1));
}
else
{
schemaAttribute.add(token.substring(1));
addBracketedValues(schemaAttribute, st);
}
}
else
addBracketedValues(schemaAttribute, st);
}
else if (token.endsWith(")"))
{ // do nothing - this should be the very end of the string tokenizer list, and this the left over bit at the end.
// (note this is *not* the match to the "{" case above...!)
}
else if (isSyntaxKeyword(token) == true)
{
addAttribute(schemaValues, token, st);
}
else
{
token = getQuotedTokens(token, st);
schemaAttribute.add(token);
}
}
}
/**
* Read the next block of text in a single quoted block, e.g. DESC 'some stuff here',
* (assuming that the first quoted string has already been read before the string
* tokenizer has been passed in, e.g. this should get "stuff here'", and return
* "stuff here".
*
* @param st a string tokenizer with a series of tokens one of which ends in a single quote
* @return the concatenated string of all tokens up to and including the one suffixed with a single quote.
*/
private static String readQuoteBlock(StringTokenizer st)
{
StringBuffer returnBuffer = new StringBuffer();
while (st.hasMoreTokens())
{
String token = st.nextToken();
returnBuffer.append(" ");
returnBuffer.append(token);
if (token.endsWith("'"))
{
returnBuffer.deleteCharAt(returnBuffer.length() - 1); // remove final quote
return returnBuffer.toString();
}
}
log.finest("unexpected end of schema text in single quoted block");
return returnBuffer.toString();
}
/**
* This <i>should</i> probably have a list of keywords extracted from rfc 2252... but I can't be
* bothered, so I'll simply test that the token is entirely uppercase, alphabetic characters...
*
* @param token the token to test for being an rfc 2252 syntax keyword.
* @return
*/
private static boolean isSyntaxKeyword(String token)
{
String[] reservedKeywords = {
"ABSTRACT",
"APPLIES",
"AUXILIARY",
"COLLECTIVE",
"DESC",
"EQUALITY",
"MAY",
"MUST",
"NAME",
"NO-USER-MODIFICATION",
"OBSOLETE",
"ORDERING",
"SINGLE-VALUE",
"STRUCTURAL",
"SUBSTR",
"SUP",
"SYNTAX",
"USAGE"};
int size = reservedKeywords.length;
for (int i = 0; i < size; i++)
if (reservedKeywords[i].equals(token))
return true;
if (token.startsWith("X-"))
return true;
return false; // probably isn't - but they might change the standard I suppose. Oh well...
}
/* simply returning true for capitalised is too simplistic...
int i, len = token.length();
char c;
for (i=0; i<len; i++)
{
c = token.charAt(i);
if (c<'A' || c>'Z')
return false;
}
return true;
*/
/**
* <p>Returns the next level in our virtual view of the schema.
* The virtual view may either be in the jndi form (e.g. "objectClass/person")
* of a 'dn like form' (e.g. "schema=objectClass, schema=person"). If it is
* the latter, the 'fake attribute type' is ignored, e.g. "fnordle=objectClass,
* snork=person" would resolve the same as "schema=objectClass, schema=person").</p>
*
* @param entryName the full schema name to get the next level of: e.g. "schema=objectClass"
* @return the undecorated names of the next level (e.g. {'person', 'top', 'organisation'}
*/
public ArrayList listEntryNames(String entryName)
throws NamingException
{
if (rawSchemaAttributes == null)
return new ArrayList();
entryName = mangleEntryName(entryName);
ArrayList schemaNames;
if (entryName == null || entryName.length() == 0 || entryName.equals("cn=schema") || entryName.equals(schemaRoot)) // The 'root node', i.e. the top of the schema tree - returns things like
{ // 'objectClasses', 'ldapSyntaxes', 'attributeTypes'
schemaNames = new ArrayList(10);
Enumeration schemaTopLevelNames = rawSchemaAttributes.getIDs();
while (schemaTopLevelNames.hasMoreElements())
{
String name = (String) schemaTopLevelNames.nextElement();
if (!schemaNames.contains(name)) //TE: don't add duplicates
schemaNames.add(name);
}
}
else if (entryName.indexOf(',') == -1 && entryName.indexOf('/') == -1) // the first layer - returns things like
{ // 'person', 'orgunit', 'newPilotPerson' etc...
schemaNames = new ArrayList(1000);
if (entryName.indexOf('=') > 0)
entryName = entryName.substring(entryName.indexOf('=') + 1);
Attribute rawSyntaxAttribute = rawSchemaAttributes.get(entryName); // entryName might be 'attributeTypes'
if (rawSyntaxAttribute == null)
throw new NamingException("unable to list syntaxes of type '" + entryName + "'");
Enumeration values = rawSyntaxAttribute.getAll();
String[] names;
while (values.hasMoreElements())
{
names = getNames((String) values.nextElement());
for (int i = 0; i < names.length; i++)
{
if (!schemaNames.contains(names[i])) //TE: don't add duplicates
schemaNames.add(names[i]);
}
}
}
else // double element, e.g. objectClass/person -> never has children.
{
schemaNames = new ArrayList(0);
}
return schemaNames;
}
// note kind-a-sad attempt to make this method fastish.
private int name_pos, bracket_pos, quote_pos, last_pos, pos; // pointers for string parsing.
/**
* This strips the OID from a schema attribute description string. The OID
* is assumed to be the first element after an optional '(' character.
*
* @param ldapSchemaDescription
* @return the OID string ('1.2.3.4' etc.) - or '0' if ldapSchemaDescription is null or unknown
*/
// package visibility for testing
public final String getOID(String ldapSchemaDescription)
{
if (ldapSchemaDescription == null)
return "0"; // error.
int start = 0;
if (ldapSchemaDescription.charAt(0) == '(')
start++;
while (ldapSchemaDescription.charAt(start) == ' ') // technically could be any whitespace, but practically it is only spaces... (I hope)
start++;
try
{
int endpos = ldapSchemaDescription.indexOf(' ', start);
if (endpos == -1)
endpos = ldapSchemaDescription.indexOf(')', start);
if (endpos == -1)
endpos = ldapSchemaDescription.length();
String ret = ldapSchemaDescription.substring(start, endpos);
return ret;
}
catch (Exception e)
{
log.log(Level.WARNING, "can't parse '" + ldapSchemaDescription + "'");
e.printStackTrace();
return "0";
}
}
/**
* parse strings that may be of the form either:
* ????????????????/ NAME 'myname' ???????????
* ????????????????/ NAME ('firstname', 'secondname', 'thirdname') ???????????
*
* @return the single name, or the first of the array of names, as a string.
*/
// IMP note - for speed, this is implemented separately from getNames()
public final String getFirstName(String ldapSchemaDescription)
{
name_pos = ldapSchemaDescription.indexOf("NAME");
if (name_pos == -1)
name_pos = ldapSchemaDescription.indexOf("DESC"); // for ldapSyntaxes entries
if (name_pos == -1) // fall back - should never happen; try to return OID
{
if (ldapSchemaDescription.startsWith("{"))
ldapSchemaDescription = ldapSchemaDescription.substring(1).trim();
pos = ldapSchemaDescription.indexOf(' ');
if (pos == -1)
{
log.log(Level.WARNING, "unable to get name from " + ldapSchemaDescription);
return "syntax_error";
}
return ldapSchemaDescription.substring(0, pos).trim();
}
quote_pos = ldapSchemaDescription.indexOf('\'', name_pos);
quote_pos++;
last_pos = ldapSchemaDescription.indexOf('\'', quote_pos);
if (quote_pos != 0 && last_pos != -1)
return ldapSchemaDescription.substring(quote_pos, last_pos);
else
{
log.log(Level.WARNING, "unable to parse " + ldapSchemaDescription);
return "syntax_error";
}
}
/**
* parse strings that may be of the form either:
* ????????????????/ NAME 'myname' ???????????
* ????????????????/ NAME ('firstname', 'secondname', 'thirdname') ???????????
*
* @return the Name or array of names, as an array of strings 1 or more elements long.
*/
// package visibility for testing
public final String[] getNames(String ldapSyntaxDescription)
{
try
{
name_pos = ldapSyntaxDescription.indexOf("NAME");
if (name_pos == -1)
name_pos = ldapSyntaxDescription.indexOf("DESC"); // for ldapSyntaxes entries
if (name_pos == -1) // fall back - should never happen; try to return OID
{
if (ldapSyntaxDescription.startsWith("{"))
ldapSyntaxDescription = ldapSyntaxDescription.substring(1).trim();
return new String[]{ldapSyntaxDescription.substring(0, ldapSyntaxDescription.indexOf(' ')).trim()};
}
bracket_pos = ldapSyntaxDescription.indexOf('(', name_pos);
quote_pos = ldapSyntaxDescription.indexOf('\'', name_pos);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -