|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package com.sun.jndi.ldap; |
|
|
|
import javax.naming.*; |
|
import javax.naming.directory.*; |
|
import java.util.Vector; |
|
|
|
/** |
|
* Netscape's 3.1 servers have some schema bugs: |
|
* - It puts quotes around OIDs (such as those for SUP, SYNTAX). |
|
* - When you try to write out the MUST/MAY list (such as "MUST cn"), |
|
* it wants ("MUST (cn)") instead |
|
*/ |
|
|
|
final class LdapSchemaParser { |
|
|
|
|
|
private static final boolean debug = false; |
|
|
|
|
|
|
|
static final String OBJECTCLASSDESC_ATTR_ID = "objectClasses"; |
|
static final String ATTRIBUTEDESC_ATTR_ID = "attributeTypes"; |
|
static final String SYNTAXDESC_ATTR_ID = "ldapSyntaxes"; |
|
static final String MATCHRULEDESC_ATTR_ID = "matchingRules"; |
|
|
|
|
|
static final String OBJECTCLASS_DEFINITION_NAME = |
|
"ClassDefinition"; |
|
private static final String[] CLASS_DEF_ATTRS = { |
|
"objectclass", "ClassDefinition"}; |
|
static final String ATTRIBUTE_DEFINITION_NAME = |
|
"AttributeDefinition"; |
|
private static final String[] ATTR_DEF_ATTRS = { |
|
"objectclass", "AttributeDefinition" }; |
|
static final String SYNTAX_DEFINITION_NAME = |
|
"SyntaxDefinition"; |
|
private static final String[] SYNTAX_DEF_ATTRS = { |
|
"objectclass", "SyntaxDefinition" }; |
|
static final String MATCHRULE_DEFINITION_NAME = |
|
"MatchingRule"; |
|
private static final String[] MATCHRULE_DEF_ATTRS = { |
|
"objectclass", "MatchingRule" }; |
|
|
|
|
|
private static final char SINGLE_QUOTE = '\''; |
|
private static final char WHSP = ' '; |
|
private static final char OID_LIST_BEGIN = '('; |
|
private static final char OID_LIST_END = ')'; |
|
private static final char OID_SEPARATOR = '$'; |
|
|
|
|
|
private static final String NUMERICOID_ID = "NUMERICOID"; |
|
private static final String NAME_ID = "NAME"; |
|
private static final String DESC_ID = "DESC"; |
|
private static final String OBSOLETE_ID = "OBSOLETE"; |
|
private static final String SUP_ID = "SUP"; |
|
private static final String PRIVATE_ID = "X-"; |
|
|
|
|
|
private static final String ABSTRACT_ID = "ABSTRACT"; |
|
private static final String STRUCTURAL_ID = "STRUCTURAL"; |
|
private static final String AUXILARY_ID = "AUXILIARY"; |
|
private static final String MUST_ID = "MUST"; |
|
private static final String MAY_ID = "MAY"; |
|
|
|
|
|
private static final String EQUALITY_ID = "EQUALITY"; |
|
private static final String ORDERING_ID = "ORDERING"; |
|
private static final String SUBSTR_ID = "SUBSTR"; |
|
private static final String SYNTAX_ID = "SYNTAX"; |
|
private static final String SINGLE_VAL_ID = "SINGLE-VALUE"; |
|
private static final String COLLECTIVE_ID = "COLLECTIVE"; |
|
private static final String NO_USER_MOD_ID = "NO-USER-MODIFICATION"; |
|
private static final String USAGE_ID = "USAGE"; |
|
|
|
|
|
private static final String SCHEMA_TRUE_VALUE = "true"; |
|
|
|
|
|
private boolean netscapeBug; |
|
|
|
LdapSchemaParser(boolean netscapeBug) { |
|
this.netscapeBug = netscapeBug; |
|
} |
|
|
|
final static void LDAP2JNDISchema(Attributes schemaAttrs, |
|
LdapSchemaCtx schemaRoot) throws NamingException { |
|
Attribute objectClassesAttr = null; |
|
Attribute attributeDefAttr = null; |
|
Attribute syntaxDefAttr = null; |
|
Attribute matchRuleDefAttr = null; |
|
|
|
objectClassesAttr = schemaAttrs.get(OBJECTCLASSDESC_ATTR_ID); |
|
if(objectClassesAttr != null) { |
|
objectDescs2ClassDefs(objectClassesAttr,schemaRoot); |
|
} |
|
|
|
attributeDefAttr = schemaAttrs.get(ATTRIBUTEDESC_ATTR_ID); |
|
if(attributeDefAttr != null) { |
|
attrDescs2AttrDefs(attributeDefAttr, schemaRoot); |
|
} |
|
|
|
syntaxDefAttr = schemaAttrs.get(SYNTAXDESC_ATTR_ID); |
|
if(syntaxDefAttr != null) { |
|
syntaxDescs2SyntaxDefs(syntaxDefAttr, schemaRoot); |
|
} |
|
|
|
matchRuleDefAttr = schemaAttrs.get(MATCHRULEDESC_ATTR_ID); |
|
if(matchRuleDefAttr != null) { |
|
matchRuleDescs2MatchRuleDefs(matchRuleDefAttr, schemaRoot); |
|
} |
|
} |
|
|
|
final private static DirContext objectDescs2ClassDefs(Attribute objDescsAttr, |
|
LdapSchemaCtx schemaRoot) |
|
throws NamingException { |
|
|
|
NamingEnumeration<?> objDescs; |
|
Attributes objDef; |
|
LdapSchemaCtx classDefTree; |
|
|
|
|
|
Attributes attrs = new BasicAttributes(LdapClient.caseIgnore); |
|
attrs.put(CLASS_DEF_ATTRS[0], CLASS_DEF_ATTRS[1]); |
|
classDefTree = schemaRoot.setup(LdapSchemaCtx.OBJECTCLASS_ROOT, |
|
OBJECTCLASS_DEFINITION_NAME, attrs); |
|
|
|
objDescs = objDescsAttr.getAll(); |
|
String currentName; |
|
while(objDescs.hasMore()) { |
|
String objDesc = (String)objDescs.next(); |
|
try { |
|
Object[] def = desc2Def(objDesc); |
|
currentName = (String) def[0]; |
|
objDef = (Attributes) def[1]; |
|
classDefTree.setup(LdapSchemaCtx.OBJECTCLASS, |
|
currentName, objDef); |
|
} catch (NamingException ne) { |
|
// error occurred while parsing, ignore current entry |
|
} |
|
} |
|
|
|
return classDefTree; |
|
} |
|
|
|
final private static DirContext attrDescs2AttrDefs(Attribute attributeDescAttr, |
|
LdapSchemaCtx schemaRoot) |
|
throws NamingException { |
|
|
|
NamingEnumeration<?> attrDescs; |
|
Attributes attrDef; |
|
LdapSchemaCtx attrDefTree; |
|
|
|
|
|
Attributes attrs = new BasicAttributes(LdapClient.caseIgnore); |
|
attrs.put(ATTR_DEF_ATTRS[0], ATTR_DEF_ATTRS[1]); |
|
attrDefTree = schemaRoot.setup(LdapSchemaCtx.ATTRIBUTE_ROOT, |
|
ATTRIBUTE_DEFINITION_NAME, attrs); |
|
|
|
attrDescs = attributeDescAttr.getAll(); |
|
String currentName; |
|
while(attrDescs.hasMore()) { |
|
String attrDesc = (String)attrDescs.next(); |
|
try { |
|
Object[] def = desc2Def(attrDesc); |
|
currentName = (String) def[0]; |
|
attrDef = (Attributes) def[1]; |
|
attrDefTree.setup(LdapSchemaCtx.ATTRIBUTE, |
|
currentName, attrDef); |
|
} catch (NamingException ne) { |
|
// error occurred while parsing, ignore current entry |
|
} |
|
} |
|
|
|
return attrDefTree; |
|
} |
|
|
|
final private static DirContext syntaxDescs2SyntaxDefs( |
|
Attribute syntaxDescAttr, |
|
LdapSchemaCtx schemaRoot) |
|
throws NamingException { |
|
|
|
NamingEnumeration<?> syntaxDescs; |
|
Attributes syntaxDef; |
|
LdapSchemaCtx syntaxDefTree; |
|
|
|
|
|
Attributes attrs = new BasicAttributes(LdapClient.caseIgnore); |
|
attrs.put(SYNTAX_DEF_ATTRS[0], SYNTAX_DEF_ATTRS[1]); |
|
syntaxDefTree = schemaRoot.setup(LdapSchemaCtx.SYNTAX_ROOT, |
|
SYNTAX_DEFINITION_NAME, attrs); |
|
|
|
syntaxDescs = syntaxDescAttr.getAll(); |
|
String currentName; |
|
while(syntaxDescs.hasMore()) { |
|
String syntaxDesc = (String)syntaxDescs.next(); |
|
try { |
|
Object[] def = desc2Def(syntaxDesc); |
|
currentName = (String) def[0]; |
|
syntaxDef = (Attributes) def[1]; |
|
syntaxDefTree.setup(LdapSchemaCtx.SYNTAX, |
|
currentName, syntaxDef); |
|
} catch (NamingException ne) { |
|
// error occurred while parsing, ignore current entry |
|
} |
|
} |
|
|
|
return syntaxDefTree; |
|
} |
|
|
|
final private static DirContext matchRuleDescs2MatchRuleDefs( |
|
Attribute matchRuleDescAttr, |
|
LdapSchemaCtx schemaRoot) |
|
throws NamingException { |
|
|
|
NamingEnumeration<?> matchRuleDescs; |
|
Attributes matchRuleDef; |
|
LdapSchemaCtx matchRuleDefTree; |
|
|
|
|
|
Attributes attrs = new BasicAttributes(LdapClient.caseIgnore); |
|
attrs.put(MATCHRULE_DEF_ATTRS[0], MATCHRULE_DEF_ATTRS[1]); |
|
matchRuleDefTree = schemaRoot.setup(LdapSchemaCtx.MATCHRULE_ROOT, |
|
MATCHRULE_DEFINITION_NAME, attrs); |
|
|
|
matchRuleDescs = matchRuleDescAttr.getAll(); |
|
String currentName; |
|
while(matchRuleDescs.hasMore()) { |
|
String matchRuleDesc = (String)matchRuleDescs.next(); |
|
try { |
|
Object[] def = desc2Def(matchRuleDesc); |
|
currentName = (String) def[0]; |
|
matchRuleDef = (Attributes) def[1]; |
|
matchRuleDefTree.setup(LdapSchemaCtx.MATCHRULE, |
|
currentName, matchRuleDef); |
|
} catch (NamingException ne) { |
|
// error occurred while parsing, ignore current entry |
|
} |
|
} |
|
|
|
return matchRuleDefTree; |
|
} |
|
|
|
final private static Object[] desc2Def(String desc) |
|
throws NamingException { |
|
//System.err.println(desc); |
|
|
|
Attributes attrs = new BasicAttributes(LdapClient.caseIgnore); |
|
Attribute attr = null; |
|
int[] pos = new int[]{1}; |
|
boolean moreTags = true; |
|
|
|
|
|
attr = readNumericOID(desc, pos); |
|
String currentName = (String) attr.get(0); |
|
attrs.put(attr); |
|
|
|
skipWhitespace(desc, pos); |
|
|
|
while (moreTags) { |
|
attr = readNextTag(desc, pos); |
|
attrs.put(attr); |
|
|
|
if (attr.getID().equals(NAME_ID)) { |
|
currentName = (String) attr.get(0); |
|
} |
|
|
|
skipWhitespace(desc, pos); |
|
|
|
if( pos[0] >= desc.length() -1 ) { |
|
moreTags = false; |
|
} |
|
} |
|
|
|
return new Object[] {currentName, attrs}; |
|
} |
|
|
|
// returns the index of the first whitespace char of a linear whitspace |
|
|
|
final private static int findTrailingWhitespace(String string, int pos) { |
|
for(int i = pos; i > 0; i--) { |
|
if(string.charAt(i) != WHSP) { |
|
return i + 1; |
|
} |
|
} |
|
return 0; |
|
} |
|
|
|
final private static void skipWhitespace(String string, int[] pos) { |
|
for(int i=pos[0]; i < string.length(); i++) { |
|
if(string.charAt(i) != WHSP) { |
|
pos[0] = i; |
|
if (debug) { |
|
System.err.println("skipWhitespace: skipping to "+i); |
|
} |
|
return; |
|
} |
|
} |
|
} |
|
|
|
final private static Attribute readNumericOID(String string, int[] pos) |
|
throws NamingException { |
|
|
|
if (debug) { |
|
System.err.println("readNumericoid: pos="+pos[0]); |
|
} |
|
|
|
int begin, end; |
|
String value = null; |
|
|
|
skipWhitespace(string, pos); |
|
|
|
begin = pos[0]; |
|
end = string.indexOf(WHSP, begin); |
|
|
|
if (end == -1 || end - begin < 1) { |
|
throw new InvalidAttributeValueException("no numericoid found: " |
|
+ string); |
|
} |
|
|
|
value = string.substring(begin, end); |
|
|
|
pos[0] += value.length(); |
|
|
|
return new BasicAttribute(NUMERICOID_ID, value); |
|
} |
|
|
|
final private static Attribute readNextTag(String string, int[] pos) |
|
throws NamingException { |
|
|
|
Attribute attr = null; |
|
String tagName = null; |
|
String[] values = null; |
|
|
|
skipWhitespace(string, pos); |
|
|
|
if (debug) { |
|
System.err.println("readNextTag: pos="+pos[0]); |
|
} |
|
|
|
|
|
int trailingSpace = string.indexOf( WHSP, pos[0] ); |
|
|
|
|
|
if (trailingSpace < 0) { |
|
tagName = string.substring( pos[0], string.length() - 1); |
|
} else { |
|
tagName = string.substring( pos[0], trailingSpace ); |
|
} |
|
|
|
values = readTag(tagName, string, pos); |
|
|
|
|
|
if(values.length < 0) { |
|
throw new InvalidAttributeValueException("no values for " + |
|
"attribute \"" + |
|
tagName + "\""); |
|
} |
|
|
|
|
|
attr = new BasicAttribute(tagName, values[0]); |
|
|
|
|
|
for(int i = 1; i < values.length; i++) { |
|
attr.add(values[i]); |
|
} |
|
|
|
return attr; |
|
} |
|
|
|
final private static String[] readTag(String tag, String string, int[] pos) |
|
throws NamingException { |
|
|
|
if (debug) { |
|
System.err.println("ReadTag: " + tag + " pos="+pos[0]); |
|
} |
|
|
|
|
|
pos[0] += tag.length(); |
|
skipWhitespace(string, pos); |
|
|
|
if (tag.equals(NAME_ID)) { |
|
return readQDescrs(string, pos); |
|
} |
|
|
|
if(tag.equals(DESC_ID)) { |
|
return readQDString(string, pos); |
|
} |
|
|
|
if ( |
|
tag.equals(EQUALITY_ID) || |
|
tag.equals(ORDERING_ID) || |
|
tag.equals(SUBSTR_ID) || |
|
tag.equals(SYNTAX_ID)) { |
|
return readWOID(string, pos); |
|
} |
|
|
|
if (tag.equals(OBSOLETE_ID) || |
|
tag.equals(ABSTRACT_ID) || |
|
tag.equals(STRUCTURAL_ID) || |
|
tag.equals(AUXILARY_ID) || |
|
tag.equals(SINGLE_VAL_ID) || |
|
tag.equals(COLLECTIVE_ID) || |
|
tag.equals(NO_USER_MOD_ID)) { |
|
return new String[] {SCHEMA_TRUE_VALUE}; |
|
} |
|
|
|
if (tag.equals(SUP_ID) || |
|
tag.equals(MUST_ID) || |
|
tag.equals(MAY_ID) || |
|
tag.equals(USAGE_ID)) { |
|
return readOIDs(string, pos); |
|
} |
|
|
|
|
|
return readQDStrings(string, pos); |
|
} |
|
|
|
final private static String[] readQDString(String string, int[] pos) |
|
throws NamingException { |
|
|
|
int begin, end; |
|
|
|
begin = string.indexOf(SINGLE_QUOTE, pos[0]) + 1; |
|
end = string.indexOf(SINGLE_QUOTE, begin); |
|
|
|
if (debug) { |
|
System.err.println("ReadQDString: pos=" + pos[0] + |
|
" begin=" + begin + " end=" + end); |
|
} |
|
|
|
if(begin == -1 || end == -1 || begin == end) { |
|
throw new InvalidAttributeIdentifierException("malformed " + |
|
"QDString: " + |
|
string); |
|
} |
|
|
|
|
|
if (string.charAt(begin - 1) != SINGLE_QUOTE) { |
|
throw new InvalidAttributeIdentifierException("qdstring has " + |
|
"no end mark: " + |
|
string); |
|
} |
|
|
|
pos[0] = end+1; |
|
return new String[] {string.substring(begin, end)}; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private final static String[] readQDStrings(String string, int[] pos) |
|
throws NamingException { |
|
|
|
return readQDescrs(string, pos); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
final private static String[] readQDescrs(String string, int[] pos) |
|
throws NamingException { |
|
|
|
if (debug) { |
|
System.err.println("readQDescrs: pos="+pos[0]); |
|
} |
|
|
|
skipWhitespace(string, pos); |
|
|
|
switch( string.charAt(pos[0]) ) { |
|
case OID_LIST_BEGIN: |
|
return readQDescrList(string, pos); |
|
case SINGLE_QUOTE: |
|
return readQDString(string, pos); |
|
default: |
|
throw new InvalidAttributeValueException("unexpected oids " + |
|
"string: " + string); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
final private static String[] readQDescrList(String string, int[] pos) |
|
throws NamingException { |
|
|
|
int begin, end; |
|
Vector<String> values = new Vector<>(5); |
|
|
|
if (debug) { |
|
System.err.println("ReadQDescrList: pos="+pos[0]); |
|
} |
|
|
|
pos[0]++; |
|
skipWhitespace(string, pos); |
|
begin = pos[0]; |
|
end = string.indexOf(OID_LIST_END, begin); |
|
|
|
if(end == -1) { |
|
throw new InvalidAttributeValueException ("oidlist has no end "+ |
|
"mark: " + string); |
|
} |
|
|
|
while(begin < end) { |
|
String[] one = readQDString(string, pos); |
|
|
|
if (debug) { |
|
System.err.println("ReadQDescrList: found '" + one[0] + |
|
"' at begin=" + begin + " end =" + end); |
|
} |
|
|
|
values.addElement(one[0]); |
|
skipWhitespace(string, pos); |
|
begin = pos[0]; |
|
} |
|
|
|
pos[0] = end+1; |
|
|
|
String[] answer = new String[values.size()]; |
|
for (int i = 0; i < answer.length; i++) { |
|
answer[i] = values.elementAt(i); |
|
} |
|
return answer; |
|
} |
|
|
|
final private static String[] readWOID(String string, int[] pos) |
|
throws NamingException { |
|
|
|
if (debug) { |
|
System.err.println("readWOIDs: pos="+pos[0]); |
|
} |
|
|
|
skipWhitespace(string, pos); |
|
|
|
if (string.charAt(pos[0]) == SINGLE_QUOTE) { |
|
|
|
return readQDString(string, pos); |
|
} |
|
|
|
int begin, end; |
|
|
|
begin = pos[0]; |
|
end = string.indexOf(WHSP, begin); |
|
|
|
if (debug) { |
|
System.err.println("ReadWOID: pos=" + pos[0] + |
|
" begin=" + begin + " end=" + end); |
|
} |
|
|
|
if(end == -1 || begin == end) { |
|
throw new InvalidAttributeIdentifierException("malformed " + |
|
"OID: " + |
|
string); |
|
} |
|
pos[0] = end+1; |
|
|
|
return new String[] {string.substring(begin, end)}; |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
final private static String[] readOIDs(String string, int[] pos) |
|
throws NamingException { |
|
|
|
if (debug) { |
|
System.err.println("readOIDs: pos="+pos[0]); |
|
} |
|
|
|
skipWhitespace(string, pos); |
|
|
|
|
|
if (string.charAt(pos[0]) != OID_LIST_BEGIN) { |
|
return readWOID(string, pos); |
|
} |
|
|
|
// Multiple OIDs |
|
|
|
int begin, cur, end; |
|
String oidName = null; |
|
Vector<String> values = new Vector<>(5); |
|
|
|
if (debug) { |
|
System.err.println("ReadOIDList: pos="+pos[0]); |
|
} |
|
|
|
pos[0]++; |
|
skipWhitespace(string, pos); |
|
begin = pos[0]; |
|
end = string.indexOf(OID_LIST_END, begin); |
|
cur = string.indexOf(OID_SEPARATOR, begin); |
|
|
|
if(end == -1) { |
|
throw new InvalidAttributeValueException ("oidlist has no end "+ |
|
"mark: " + string); |
|
} |
|
|
|
if(cur == -1 || end < cur) { |
|
cur = end; |
|
} |
|
|
|
while(cur < end && cur > 0) { |
|
int wsBegin = findTrailingWhitespace(string, cur - 1); |
|
oidName = string.substring(begin, wsBegin); |
|
if (debug) { |
|
System.err.println("ReadOIDList: found '" + oidName + |
|
"' at begin=" + begin + " end =" + end); |
|
} |
|
values.addElement(oidName); |
|
pos[0] = cur + 1; |
|
skipWhitespace(string, pos); |
|
begin = pos[0]; |
|
cur = string.indexOf(OID_SEPARATOR, begin); |
|
if(debug) {System.err.println("ReadOIDList: begin = " + begin);} |
|
} |
|
|
|
if (debug) { |
|
System.err.println("ReadOIDList: found '" + oidName + |
|
"' at begin=" + begin + " end =" + end); |
|
} |
|
|
|
int wsBegin = findTrailingWhitespace(string, end - 1); |
|
oidName = string.substring(begin, wsBegin); |
|
values.addElement(oidName); |
|
|
|
pos[0] = end+1; |
|
|
|
String[] answer = new String[values.size()]; |
|
for (int i = 0; i < answer.length; i++) { |
|
answer[i] = values.elementAt(i); |
|
} |
|
return answer; |
|
} |
|
|
|
// ----------------- "unparser" methods |
|
// Methods that are used for translating a node in the schema tree |
|
// into RFC2252 format for storage back into the LDAP directory |
|
/* |
|
static Attributes JNDI2LDAPSchema(DirContext schemaRoot) |
|
throws NamingException { |
|
|
|
Attribute objDescAttr = new BasicAttribute(OBJECTCLASSDESC_ATTR_ID); |
|
Attribute attrDescAttr = new BasicAttribute(ATTRIBUTEDESC_ATTR_ID); |
|
Attribute syntaxDescAttr = new BasicAttribute(SYNTAXDESC_ATTR_ID); |
|
Attributes attrs = new BasicAttributes(LdapClient.caseIgnore); |
|
DirContext classDefs, attributeDefs, syntaxDefs; |
|
Attributes classDefsAttrs, attributeDefsAttrs, syntaxDefsAttrs; |
|
NamingEnumeration defs; |
|
Object obj; |
|
int i = 0; |
|
|
|
try { |
|
obj = schemaRoot.lookup(OBJECTCLASS_DEFINITION_NAME); |
|
if(obj != null && obj instanceof DirContext) { |
|
classDefs = (DirContext)obj; |
|
defs = classDefs.listBindings(""); |
|
while(defs.hasMoreElements()) { |
|
i++; |
|
DirContext classDef = (DirContext) |
|
((Binding)(defs.next())).getObject(); |
|
classDefAttrs = classDef.getAttributes(""); |
|
objDescAttr.add(classDef2ObjectDesc(classDefAttrs)); |
|
} |
|
if (debug) |
|
System.err.println(i + " total object classes"); |
|
attrs.put(objDescAttr); |
|
} else { |
|
throw new NamingException( |
|
"Problem with Schema tree: the object named " + |
|
OBJECTCLASS_DEFINITION_NAME + " is not a " + |
|
"DirContext"); |
|
} |
|
} catch (NameNotFoundException e) {} // ignore |
|
|
|
i=0; |
|
try { |
|
obj = schemaRoot.lookup(ATTRIBUTE_DEFINITION_NAME); |
|
if(obj instanceof DirContext) { |
|
attributeDefs = (DirContext)obj; |
|
defs = attributeDefs.listBindings(""); |
|
while(defs.hasMoreElements()) { |
|
i++; |
|
DirContext attrDef = (DirContext) |
|
((Binding)defs.next()).getObject(); |
|
attrDefAttrs = attrDef.getAttributes(""); |
|
attrDescAttr.add(attrDef2AttrDesc(attrDefAttrs)); |
|
} |
|
if (debug) |
|
System.err.println(i + " attribute definitions"); |
|
attrs.put(attrDescAttr); |
|
} else { |
|
throw new NamingException( |
|
"Problem with schema tree: the object named " + |
|
ATTRIBUTE_DEFINITION_NAME + " is not a " + |
|
"DirContext"); |
|
} |
|
} catch (NameNotFoundException e) {} // ignore |
|
|
|
i=0; |
|
try { |
|
obj = schemaRoot.lookup(SYNTAX_DEFINITION_NAME); |
|
if(obj instanceof DirContext) { |
|
syntaxDefs = (DirContext)obj; |
|
defs =syntaxDefs.listBindings(""); |
|
while(defs.hasMoreElements()) { |
|
i++; |
|
DirContext syntaxDef = (DirContext) |
|
((Binding)defs.next()).getObject(); |
|
syntaxDefAttrs = syntaxDef.getAttributes(""); |
|
syntaxDescAttr.add(syntaxDef2SyntaxDesc(syntaxDefAttrs)); |
|
} |
|
if (debug) |
|
System.err.println(i + " total syntax definitions"); |
|
attrs.put(syntaxDescAttr); |
|
} else { |
|
throw new NamingException( |
|
"Problem with schema tree: the object named " + |
|
SYNTAX_DEFINITION_NAME + " is not a " + |
|
"DirContext"); |
|
} |
|
} catch (NameNotFoundException e) {} // ignore |
|
|
|
return attrs; |
|
} |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
*/ |
|
final private String classDef2ObjectDesc(Attributes attrs) |
|
throws NamingException { |
|
|
|
StringBuffer objectDesc = new StringBuffer("( "); |
|
|
|
Attribute attr = null; |
|
int count = 0; |
|
|
|
// extract attributes by ID to guarantee ordering |
|
|
|
attr = attrs.get(NUMERICOID_ID); |
|
if (attr != null) { |
|
objectDesc.append(writeNumericOID(attr)); |
|
count++; |
|
} else { |
|
throw new ConfigurationException("Class definition doesn't" + |
|
"have a numeric OID"); |
|
} |
|
|
|
attr = attrs.get(NAME_ID); |
|
if (attr != null) { |
|
objectDesc.append(writeQDescrs(attr)); |
|
count++; |
|
} |
|
|
|
attr = attrs.get(DESC_ID); |
|
if (attr != null) { |
|
objectDesc.append(writeQDString(attr)); |
|
count++; |
|
} |
|
|
|
attr = attrs.get(OBSOLETE_ID); |
|
if (attr != null) { |
|
objectDesc.append(writeBoolean(attr)); |
|
count++; |
|
} |
|
|
|
attr = attrs.get(SUP_ID); |
|
if (attr != null) { |
|
objectDesc.append(writeOIDs(attr)); |
|
count++; |
|
} |
|
|
|
attr = attrs.get(ABSTRACT_ID); |
|
if (attr != null) { |
|
objectDesc.append(writeBoolean(attr)); |
|
count++; |
|
} |
|
|
|
attr = attrs.get(STRUCTURAL_ID); |
|
if (attr != null) { |
|
objectDesc.append(writeBoolean(attr)); |
|
count++; |
|
} |
|
|
|
attr = attrs.get(AUXILARY_ID); |
|
if (attr != null) { |
|
objectDesc.append(writeBoolean(attr)); |
|
count++; |
|
} |
|
|
|
attr = attrs.get(MUST_ID); |
|
if (attr != null) { |
|
objectDesc.append(writeOIDs(attr)); |
|
count++; |
|
} |
|
|
|
attr = attrs.get(MAY_ID); |
|
if (attr != null) { |
|
objectDesc.append(writeOIDs(attr)); |
|
count++; |
|
} |
|
|
|
|
|
if (count < attrs.size()) { |
|
String attrId = null; |
|
|
|
|
|
for (NamingEnumeration<? extends Attribute> ae = attrs.getAll(); |
|
ae.hasMoreElements(); ) { |
|
|
|
attr = ae.next(); |
|
attrId = attr.getID(); |
|
|
|
|
|
if (attrId.equals(NUMERICOID_ID) || |
|
attrId.equals(NAME_ID) || |
|
attrId.equals(SUP_ID) || |
|
attrId.equals(MAY_ID) || |
|
attrId.equals(MUST_ID) || |
|
attrId.equals(STRUCTURAL_ID) || |
|
attrId.equals(DESC_ID) || |
|
attrId.equals(AUXILARY_ID) || |
|
attrId.equals(ABSTRACT_ID) || |
|
attrId.equals(OBSOLETE_ID)) { |
|
continue; |
|
|
|
} else { |
|
objectDesc.append(writeQDStrings(attr)); |
|
} |
|
} |
|
} |
|
|
|
objectDesc.append(")"); |
|
|
|
return objectDesc.toString(); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
final private String attrDef2AttrDesc(Attributes attrs) |
|
throws NamingException { |
|
|
|
StringBuffer attrDesc = new StringBuffer("( "); |
|
|
|
Attribute attr = null; |
|
int count = 0; |
|
|
|
// extract attributes by ID to guarantee ordering |
|
|
|
attr = attrs.get(NUMERICOID_ID); |
|
if (attr != null) { |
|
attrDesc.append(writeNumericOID(attr)); |
|
count++; |
|
} else { |
|
throw new ConfigurationException("Attribute type doesn't" + |
|
"have a numeric OID"); |
|
} |
|
|
|
attr = attrs.get(NAME_ID); |
|
if (attr != null) { |
|
attrDesc.append(writeQDescrs(attr)); |
|
count++; |
|
} |
|
|
|
attr = attrs.get(DESC_ID); |
|
if (attr != null) { |
|
attrDesc.append(writeQDString(attr)); |
|
count++; |
|
} |
|
|
|
attr = attrs.get(OBSOLETE_ID); |
|
if (attr != null) { |
|
attrDesc.append(writeBoolean(attr)); |
|
count++; |
|
} |
|
|
|
attr = attrs.get(SUP_ID); |
|
if (attr != null) { |
|
attrDesc.append(writeWOID(attr)); |
|
count++; |
|
} |
|
|
|
attr = attrs.get(EQUALITY_ID); |
|
if (attr != null) { |
|
attrDesc.append(writeWOID(attr)); |
|
count++; |
|
} |
|
|
|
attr = attrs.get(ORDERING_ID); |
|
if (attr != null) { |
|
attrDesc.append(writeWOID(attr)); |
|
count++; |
|
} |
|
|
|
attr = attrs.get(SUBSTR_ID); |
|
if (attr != null) { |
|
attrDesc.append(writeWOID(attr)); |
|
count++; |
|
} |
|
|
|
attr = attrs.get(SYNTAX_ID); |
|
if (attr != null) { |
|
attrDesc.append(writeWOID(attr)); |
|
count++; |
|
} |
|
|
|
attr = attrs.get(SINGLE_VAL_ID); |
|
if (attr != null) { |
|
attrDesc.append(writeBoolean(attr)); |
|
count++; |
|
} |
|
|
|
attr = attrs.get(COLLECTIVE_ID); |
|
if (attr != null) { |
|
attrDesc.append(writeBoolean(attr)); |
|
count++; |
|
} |
|
|
|
attr = attrs.get(NO_USER_MOD_ID); |
|
if (attr != null) { |
|
attrDesc.append(writeBoolean(attr)); |
|
count++; |
|
} |
|
|
|
attr = attrs.get(USAGE_ID); |
|
if (attr != null) { |
|
attrDesc.append(writeQDString(attr)); |
|
count++; |
|
} |
|
|
|
|
|
if (count < attrs.size()) { |
|
String attrId = null; |
|
|
|
|
|
for (NamingEnumeration<? extends Attribute> ae = attrs.getAll(); |
|
ae.hasMoreElements(); ) { |
|
|
|
attr = ae.next(); |
|
attrId = attr.getID(); |
|
|
|
|
|
if (attrId.equals(NUMERICOID_ID) || |
|
attrId.equals(NAME_ID) || |
|
attrId.equals(SYNTAX_ID) || |
|
attrId.equals(DESC_ID) || |
|
attrId.equals(SINGLE_VAL_ID) || |
|
attrId.equals(EQUALITY_ID) || |
|
attrId.equals(ORDERING_ID) || |
|
attrId.equals(SUBSTR_ID) || |
|
attrId.equals(NO_USER_MOD_ID) || |
|
attrId.equals(USAGE_ID) || |
|
attrId.equals(SUP_ID) || |
|
attrId.equals(COLLECTIVE_ID) || |
|
attrId.equals(OBSOLETE_ID)) { |
|
continue; |
|
|
|
} else { |
|
attrDesc.append(writeQDStrings(attr)); |
|
} |
|
} |
|
} |
|
|
|
attrDesc.append(")"); |
|
|
|
return attrDesc.toString(); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
final private String syntaxDef2SyntaxDesc(Attributes attrs) |
|
throws NamingException { |
|
|
|
StringBuffer syntaxDesc = new StringBuffer("( "); |
|
|
|
Attribute attr = null; |
|
int count = 0; |
|
|
|
// extract attributes by ID to guarantee ordering |
|
|
|
attr = attrs.get(NUMERICOID_ID); |
|
if (attr != null) { |
|
syntaxDesc.append(writeNumericOID(attr)); |
|
count++; |
|
} else { |
|
throw new ConfigurationException("Attribute type doesn't" + |
|
"have a numeric OID"); |
|
} |
|
|
|
attr = attrs.get(DESC_ID); |
|
if (attr != null) { |
|
syntaxDesc.append(writeQDString(attr)); |
|
count++; |
|
} |
|
|
|
|
|
if (count < attrs.size()) { |
|
String attrId = null; |
|
|
|
|
|
for (NamingEnumeration<? extends Attribute> ae = attrs.getAll(); |
|
ae.hasMoreElements(); ) { |
|
|
|
attr = ae.next(); |
|
attrId = attr.getID(); |
|
|
|
|
|
if (attrId.equals(NUMERICOID_ID) || |
|
attrId.equals(DESC_ID)) { |
|
continue; |
|
|
|
} else { |
|
syntaxDesc.append(writeQDStrings(attr)); |
|
} |
|
} |
|
} |
|
|
|
syntaxDesc.append(")"); |
|
|
|
return syntaxDesc.toString(); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
final private String matchRuleDef2MatchRuleDesc(Attributes attrs) |
|
throws NamingException { |
|
|
|
StringBuffer matchRuleDesc = new StringBuffer("( "); |
|
|
|
Attribute attr = null; |
|
int count = 0; |
|
|
|
// extract attributes by ID to guarantee ordering |
|
|
|
attr = attrs.get(NUMERICOID_ID); |
|
if (attr != null) { |
|
matchRuleDesc.append(writeNumericOID(attr)); |
|
count++; |
|
} else { |
|
throw new ConfigurationException("Attribute type doesn't" + |
|
"have a numeric OID"); |
|
} |
|
|
|
attr = attrs.get(NAME_ID); |
|
if (attr != null) { |
|
matchRuleDesc.append(writeQDescrs(attr)); |
|
count++; |
|
} |
|
|
|
attr = attrs.get(DESC_ID); |
|
if (attr != null) { |
|
matchRuleDesc.append(writeQDString(attr)); |
|
count++; |
|
} |
|
|
|
attr = attrs.get(OBSOLETE_ID); |
|
if (attr != null) { |
|
matchRuleDesc.append(writeBoolean(attr)); |
|
count++; |
|
} |
|
|
|
attr = attrs.get(SYNTAX_ID); |
|
if (attr != null) { |
|
matchRuleDesc.append(writeWOID(attr)); |
|
count++; |
|
} else { |
|
throw new ConfigurationException("Attribute type doesn't" + |
|
"have a syntax OID"); |
|
} |
|
|
|
|
|
if (count < attrs.size()) { |
|
String attrId = null; |
|
|
|
|
|
for (NamingEnumeration<? extends Attribute> ae = attrs.getAll(); |
|
ae.hasMoreElements(); ) { |
|
|
|
attr = ae.next(); |
|
attrId = attr.getID(); |
|
|
|
|
|
if (attrId.equals(NUMERICOID_ID) || |
|
attrId.equals(NAME_ID) || |
|
attrId.equals(SYNTAX_ID) || |
|
attrId.equals(DESC_ID) || |
|
attrId.equals(OBSOLETE_ID)) { |
|
continue; |
|
|
|
} else { |
|
matchRuleDesc.append(writeQDStrings(attr)); |
|
} |
|
} |
|
} |
|
|
|
matchRuleDesc.append(")"); |
|
|
|
return matchRuleDesc.toString(); |
|
} |
|
|
|
final private String writeNumericOID(Attribute nOIDAttr) |
|
throws NamingException { |
|
if(nOIDAttr.size() != 1) { |
|
throw new InvalidAttributeValueException( |
|
"A class definition must have exactly one numeric OID"); |
|
} |
|
return (String)(nOIDAttr.get()) + WHSP; |
|
} |
|
|
|
final private String writeWOID(Attribute attr) throws NamingException { |
|
if (netscapeBug) |
|
return writeQDString(attr); |
|
else |
|
return attr.getID() + WHSP + attr.get() + WHSP; |
|
} |
|
|
|
|
|
final private String writeQDString(Attribute qdStringAttr) |
|
throws NamingException { |
|
if(qdStringAttr.size() != 1) { |
|
throw new InvalidAttributeValueException( |
|
qdStringAttr.getID() + " must have exactly one value"); |
|
} |
|
|
|
return qdStringAttr.getID() + WHSP + |
|
SINGLE_QUOTE + qdStringAttr.get() + SINGLE_QUOTE + WHSP; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private final String writeQDStrings(Attribute attr) throws NamingException { |
|
return writeQDescrs(attr); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private final String writeQDescrs(Attribute attr) throws NamingException { |
|
switch(attr.size()) { |
|
case 0: |
|
throw new InvalidAttributeValueException( |
|
attr.getID() + "has no values"); |
|
case 1: |
|
return writeQDString(attr); |
|
} |
|
|
|
// write QDList |
|
|
|
StringBuffer qdList = new StringBuffer(attr.getID()); |
|
qdList.append(WHSP); |
|
qdList.append(OID_LIST_BEGIN); |
|
|
|
NamingEnumeration<?> values = attr.getAll(); |
|
|
|
while(values.hasMore()) { |
|
qdList.append(WHSP); |
|
qdList.append(SINGLE_QUOTE); |
|
qdList.append((String)values.next()); |
|
qdList.append(SINGLE_QUOTE); |
|
qdList.append(WHSP); |
|
} |
|
|
|
qdList.append(OID_LIST_END); |
|
qdList.append(WHSP); |
|
|
|
return qdList.toString(); |
|
} |
|
|
|
final private String writeOIDs(Attribute oidsAttr) |
|
throws NamingException { |
|
|
|
switch(oidsAttr.size()) { |
|
case 0: |
|
throw new InvalidAttributeValueException( |
|
oidsAttr.getID() + "has no values"); |
|
|
|
case 1: |
|
if (netscapeBug) { |
|
break; |
|
} |
|
return writeWOID(oidsAttr); |
|
} |
|
|
|
// write OID List |
|
|
|
StringBuffer oidList = new StringBuffer(oidsAttr.getID()); |
|
oidList.append(WHSP); |
|
oidList.append(OID_LIST_BEGIN); |
|
|
|
NamingEnumeration<?> values = oidsAttr.getAll(); |
|
oidList.append(WHSP); |
|
oidList.append(values.next()); |
|
|
|
while(values.hasMore()) { |
|
oidList.append(WHSP); |
|
oidList.append(OID_SEPARATOR); |
|
oidList.append(WHSP); |
|
oidList.append((String)values.next()); |
|
} |
|
|
|
oidList.append(WHSP); |
|
oidList.append(OID_LIST_END); |
|
oidList.append(WHSP); |
|
|
|
return oidList.toString(); |
|
} |
|
|
|
private final String writeBoolean(Attribute booleanAttr) |
|
throws NamingException { |
|
return booleanAttr.getID() + WHSP; |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
final Attribute stringifyObjDesc(Attributes classDefAttrs) |
|
throws NamingException { |
|
Attribute objDescAttr = new BasicAttribute(OBJECTCLASSDESC_ATTR_ID); |
|
objDescAttr.add(classDef2ObjectDesc(classDefAttrs)); |
|
return objDescAttr; |
|
} |
|
|
|
|
|
|
|
*/ |
|
final Attribute stringifyAttrDesc(Attributes attrDefAttrs) |
|
throws NamingException { |
|
Attribute attrDescAttr = new BasicAttribute(ATTRIBUTEDESC_ATTR_ID); |
|
attrDescAttr.add(attrDef2AttrDesc(attrDefAttrs)); |
|
return attrDescAttr; |
|
} |
|
|
|
|
|
|
|
*/ |
|
final Attribute stringifySyntaxDesc(Attributes syntaxDefAttrs) |
|
throws NamingException { |
|
Attribute syntaxDescAttr = new BasicAttribute(SYNTAXDESC_ATTR_ID); |
|
syntaxDescAttr.add(syntaxDef2SyntaxDesc(syntaxDefAttrs)); |
|
return syntaxDescAttr; |
|
} |
|
|
|
|
|
|
|
*/ |
|
final Attribute stringifyMatchRuleDesc(Attributes matchRuleDefAttrs) |
|
throws NamingException { |
|
Attribute matchRuleDescAttr = new BasicAttribute(MATCHRULEDESC_ATTR_ID); |
|
matchRuleDescAttr.add(matchRuleDef2MatchRuleDesc(matchRuleDefAttrs)); |
|
return matchRuleDescAttr; |
|
} |
|
} |