/*******************************************************************************

 * $Novell: MakeContainer.java,v 1.6 2002/07/29 21:17:43 $

 * Copyright (c) 2001 Novell, Inc. All Rights Reserved.

 *

 * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND

 * TREATIES. USE AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO THE LICENSE

 * AGREEMENT ACCOMPANYING THE SOFTWARE DEVELOPMENT KIT (SDK) THAT CONTAINS

 * THIS WORK. PURSUANT TO THE SDK LICENSE AGREEMENT, NOVELL HEREBY GRANTS TO

 * DEVELOPER A ROYALTY-FREE, NON-EXCLUSIVE LICENSE TO INCLUDE NOVELL'S SAMPLE

 * CODE IN ITS PRODUCT. NOVELL GRANTS DEVELOPER WORLDWIDE DISTRIBUTION RIGHTS

 * TO MARKET, DISTRIBUTE, OR SELL NOVELL'S SAMPLE CODE AS A COMPONENT OF

 * DEVELOPER'S PRODUCTS. NOVELL SHALL HAVE NO OBLIGATIONS TO DEVELOPER OR

 * DEVELOPER'S CUSTOMERS WITH RESPECT TO THIS CODE.

 *

 * $name:         MakeContainer.java

 * $description:  MakeContainer.java shows how to modify the 'inetOrgPerson'

 *                object class definition. By default, in Novell eDirectory

 *                schema, 'inetOrgPerson' is a leaf object class with the

 *                containment flag of "X-NDS_NOT_CONTAINER '1'". Running this

 *                sample removes this flag from the 'inetOrgPerson' object class

 *                schema definition, and thus changes all user objects of

 *                'inetOrgPerson' object class from leaf objects to container

 *                objects.

 *

 *                WARNING: THIS MODIFICATION IS NOT REVERSIBLE!

 *

 *                Just because you can do something, does not always mean you

 *                should. Keep in mind when making this change that there

 *                could be unforeseen issues caused by this action. You should

 *                not make this change in an mixed-tree environment that has

 *                NDS versions prior to NDS8. Also, running the option in

 *                DSRepair (to restore the operational schema) once this change

 *                is made, could cause problems. Once you make this change, it

 *                is NOT reversible.

 *

 *                Please look at TID 102504 on http://developer.novell.com

 *                before attempting to use this sample code.

 ******************************************************************************/

import java.util.Enumeration;

import java.io.BufferedReader;

import java.io.InputStreamReader;

import java.io.IOException;

import com.novell.ldap.LDAPConnection;

import com.novell.ldap.LDAPException;

import com.novell.ldap.LDAPObjectClassSchema;

import com.novell.ldap.LDAPSchema;

import com.novell.ldap.LDAPModification;



public class MakeContainer {



    public static void main(String[] args)

    {

        if (args.length != 4) {

            usage();

            System.exit(0);

        }



        String ldapHost =  args[0];

        int    ldapPort =  Integer.parseInt(args[1]);

        String loginDN  =  args[2];

        String password =  args[3];

        int    index, len;

        String inetOrgPersonString = null, new_inetString = null;

        String flag = "X-NDS_NOT_CONTAINER '1'";

        LDAPConnection conn = new LDAPConnection();

        BufferedReader inputBuffer =

                          new BufferedReader(new InputStreamReader(System.in));



        try {

            System.out.println("WARNING: THIS MODIFICATION IS NOT REVERSIBLE!"

                              + "\nDo you want to continue?(N/Y)\n");

            String input = inputBuffer.readLine();

            if ( (!input.startsWith("y")) && (!input.startsWith("Y")) )

                System.exit(0);



            // connect to the server

            conn.connect( ldapHost, ldapPort );

            // bind to the server

            conn.bind( LDAPConnection.LDAP_V3, loginDN,

                     password.getBytes("UTF8"));



            LDAPSchema schema = conn.fetchSchema( conn.getSchemaDN() );

            LDAPObjectClassSchema inetOrgPerson =

                    schema.getObjectClassSchema("inetOrgPerson");

            inetOrgPersonString = inetOrgPerson.toString();



            if (inetOrgPersonString == null) {

                System.out.println("Could not find 'inetOrgPerson' object clsss"

                                                     + " definition to modify");

                conn.disconnect();

                System.exit(0);

            }

            else if ((index = inetOrgPersonString.indexOf(flag)) == -1) {

                System.out.println("X_NDS_NOT_CONTAINER flag not persent."

                             + "\n'inetOrgPerson' is already a container");

                conn.disconnect();

                System.exit(0);

            }

            else {

                // remove container flag from 'inetOrgPerson'

                // object class definition

                String tail = inetOrgPersonString.substring(index + flag.length());

                String newDefinition = inetOrgPersonString.substring(0, index);

                newDefinition += tail;



                // Create an object class schema object with new definition

                LDAPObjectClassSchema new_inetOrgPerson =

                                 new LDAPObjectClassSchema(newDefinition);



                //A modification of an existing schema definition consists of

                //a DELETE and an ADD in the same modify operation

                LDAPModification modify[] = new LDAPModification[2];

                modify[0] = new LDAPModification(LDAPModification.DELETE,

                        inetOrgPerson);

                modify[1] = new LDAPModification(LDAPModification.ADD,

                        new_inetOrgPerson);



                // modify 'inetOrgPerson' object class schema

                conn.modify( conn.getSchemaDN(), modify );



                System.out.println("'inetOrgPerson' object class was modified"

                                        + " to be a container object class.");

            }



            conn.disconnect();

        }

        catch(IOException ie) {

            System.out.println("IO Error: " + ie.toString());

            System.exit(1);

        }

        catch(LDAPException le) {

            System.out.println( "LDAP Error: " + le.toString() );

            System.exit(1);

        }

        catch( Exception e ) {

            System.out.println( "Error: " + e.toString() );

            System.exit(1);

        }



        System.exit(0);

    }



    public static void usage()

    {

        System.out.println("Usage:   java MakeContainer <host name>"

                               + " <port number> <login dn> <password>");

        System.out.println("Example: java MakeContainer Acme.com 389 "

                                          + "cn=admin,o=Acme secret");

    }

}

