/*
 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

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 {

    // do debugging
    private static final boolean debug = false;


    // names of attribute IDs in the LDAP schema entry
    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";

    // information for creating internal nodes in JNDI schema tree
    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" };

    // special tokens used in LDAP schema descriptions
    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 = '$';

    // common IDs
    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-";

    // Object Class specific IDs
    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";

    // Attribute Type specific IDs
    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";

    // The string value we give to boolean variables
    private static final String SCHEMA_TRUE_VALUE = "true";

    // To get around writing schemas that crash Netscape server
    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;

        // create the class def subtree
        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;

        // create the AttributeDef subtree
        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;

        // create the SyntaxDef subtree
        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;

        // create the MatchRuleDef subtree
        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}; // tolerate missing leading space
        boolean         moreTags = true;

        // Always begins with <whsp numericoid whsp>
        attr = readNumericOID(desc, pos);
        String currentName = (String) attr.get(0);  // name is OID by default
        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);  // use NAME attribute as name
            }

            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
    // sequince ending at the given position.
    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]);
        }

        // get the name and values of the attribute to return
        int trailingSpace = string.indexOf( WHSP, pos[0] );

        // tolerate a schema that omits the trailing space
        if (trailingSpace < 0) {
            tagName = string.substring( pos[0], string.length() - 1);
        } else {
            tagName = string.substring( pos[0], trailingSpace );
        }

        values = readTag(tagName, string, pos);

        // make sure at least one value was returned
        if(values.length < 0) {
            throw new InvalidAttributeValueException("no values for " +
                                                     "attribute \"" +
                                                     tagName + "\"");
        }

        // create the attribute, using the first value
        attr = new BasicAttribute(tagName, values[0]);

        // add other values if there are any
        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]);
        }

        // move parser past tag name
        pos[0] += tag.length();
        skipWhitespace(string, pos);

        if (tag.equals(NAME_ID)) {
            return readQDescrs(string, pos);  // names[0] is NAME
        }

        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) ||   // oid list for object class; WOID for attribute
            tag.equals(MUST_ID) ||
            tag.equals(MAY_ID) ||
            tag.equals(USAGE_ID)) {
            return readOIDs(string, pos);
        }

        // otherwise it's a schema element with a quoted string value
        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);
        }

        // make sure the qdstring end symbol is there
        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)};
    }

   /**
    * dstring         = 1*utf8
    * qdstring        = whsp "'" dstring "'" whsp
    * qdstringlist    = [ qdstring *( qdstring ) ]
    * qdstrings       = qdstring / ( whsp "(" qdstringlist ")" whsp )
    */
    private final static String[] readQDStrings(String string, int[] pos)
        throws NamingException {

        return readQDescrs(string, pos);
    }

    /**
     * ; object descriptors used as schema element names
     * qdescrs         = qdescr / ( whsp "(" qdescrlist ")" whsp )
     * qdescrlist      = [ qdescr *( qdescr ) ]
     * qdescr          = whsp "'" descr "'" whsp
     * descr           = keystring
     */
    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);
        }
    }

    /**
     * qdescrlist      = [ qdescr *( qdescr ) ]
     * qdescr          = whsp "'" descr "'" whsp
     * descr           = keystring
     */
    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]++; // skip '('
        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; // skip ')'

        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) {
            // %%% workaround for Netscape schema bug
            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)};
    }

    /*
     * oids            = woid / ( "(" oidlist ")" )
     * oidlist         = woid *( "$" woid )
     */
    final private static String[] readOIDs(String string, int[] pos)
        throws NamingException {

        if (debug) {
            System.err.println("readOIDs: pos="+pos[0]);
        }

        skipWhitespace(string, pos);

        // Single OID
        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;
    }

*/

    /**
      * Translate attributes that describe an object class into the
      * string description as defined in RFC 2252.
      */
    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++;
        }

        // process any remaining attributes
        if (count < attrs.size()) {
            String attrId = null;

            // use enumeration because attribute ID is not known
            for (NamingEnumeration<? extends Attribute> ae = attrs.getAll();
                ae.hasMoreElements(); ) {

                attr = ae.next();
                attrId = attr.getID();

                // skip those already processed
                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();
    }

    /**
      * Translate attributes that describe an attribute definition into the
      * string description as defined in RFC 2252.
      */
    final private String attrDef2AttrDesc(Attributes attrs)
        throws NamingException {

        StringBuffer attrDesc = new StringBuffer("( "); // opening parens

        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++;
        }

        // process any remaining attributes
        if (count < attrs.size()) {
            String attrId = null;

            // use enumeration because attribute ID is not known
            for (NamingEnumeration<? extends Attribute> ae = attrs.getAll();
                ae.hasMoreElements(); ) {

                attr = ae.next();
                attrId = attr.getID();

                // skip those already processed
                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(")");  // add closing parens

        return attrDesc.toString();
    }

    /**
      * Translate attributes that describe an attribute syntax definition into the
      * string description as defined in RFC 2252.
      */
    final private String syntaxDef2SyntaxDesc(Attributes attrs)
        throws NamingException {

        StringBuffer syntaxDesc = new StringBuffer("( "); // opening parens

        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++;
        }

        // process any remaining attributes
        if (count < attrs.size()) {
            String attrId = null;

            // use enumeration because attribute ID is not known
            for (NamingEnumeration<? extends Attribute> ae = attrs.getAll();
                ae.hasMoreElements(); ) {

                attr = ae.next();
                attrId = attr.getID();

                // skip those already processed
                if (attrId.equals(NUMERICOID_ID) ||
                    attrId.equals(DESC_ID)) {
                    continue;

                } else {
                    syntaxDesc.append(writeQDStrings(attr));
                }
            }
        }

        syntaxDesc.append(")");

        return syntaxDesc.toString();
    }

    /**
      * Translate attributes that describe an attribute matching rule
      * definition into the string description as defined in RFC 2252.
      */
    final private String matchRuleDef2MatchRuleDesc(Attributes attrs)
        throws NamingException {

        StringBuffer matchRuleDesc = new StringBuffer("( "); // opening parens

        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");
        }

        // process any remaining attributes
        if (count < attrs.size()) {
            String attrId = null;

            // use enumeration because attribute ID is not known
            for (NamingEnumeration<? extends Attribute> ae = attrs.getAll();
                ae.hasMoreElements(); ) {

                attr = ae.next();
                attrId = attr.getID();

                // skip those already processed
                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;
    }

    /*  qdescr          = whsp "'" descr "'" 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;
    }

   /**
    * dstring         = 1*utf8
    * qdstring        = whsp "'" dstring "'" whsp
    * qdstringlist    = [ qdstring *( qdstring ) ]
    * qdstrings       = qdstring / ( whsp "(" qdstringlist ")" whsp )
    */
    private final String writeQDStrings(Attribute attr) throws NamingException {
        return writeQDescrs(attr);
    }

    /**
     * qdescrs         = qdescr / ( whsp "(" qdescrlist ")" whsp )
     * qdescrlist      = [ qdescr *( qdescr ) ]
     * qdescr          = whsp "'" descr "'" whsp
     * descr           = keystring
     */
    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; // %%% write out as list to avoid crashing server
            }
            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;
    }

    /**
     * Returns an attribute for updating the Object Class Definition schema
     * attribute
     */
    final Attribute stringifyObjDesc(Attributes classDefAttrs)
        throws NamingException {
        Attribute objDescAttr = new BasicAttribute(OBJECTCLASSDESC_ATTR_ID);
        objDescAttr.add(classDef2ObjectDesc(classDefAttrs));
        return objDescAttr;
    }

    /**
     * Returns an attribute for updating the Attribute Definition schema attribute
     */
    final Attribute stringifyAttrDesc(Attributes attrDefAttrs)
        throws NamingException {
        Attribute attrDescAttr = new BasicAttribute(ATTRIBUTEDESC_ATTR_ID);
        attrDescAttr.add(attrDef2AttrDesc(attrDefAttrs));
        return attrDescAttr;
    }

    /**
     * Returns an attribute for updating the Syntax schema attribute
     */
    final Attribute stringifySyntaxDesc(Attributes syntaxDefAttrs)
    throws NamingException {
        Attribute syntaxDescAttr = new BasicAttribute(SYNTAXDESC_ATTR_ID);
        syntaxDescAttr.add(syntaxDef2SyntaxDesc(syntaxDefAttrs));
        return syntaxDescAttr;
    }

    /**
     * Returns an attribute for updating the Matching Rule schema attribute
     */
    final Attribute stringifyMatchRuleDesc(Attributes matchRuleDefAttrs)
    throws NamingException {
        Attribute matchRuleDescAttr = new BasicAttribute(MATCHRULEDESC_ATTR_ID);
        matchRuleDescAttr.add(matchRuleDef2MatchRuleDesc(matchRuleDefAttrs));
        return matchRuleDescAttr;
    }
}
