| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
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;  | 
 | 
    }  | 
 | 
}  |