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

 * $Novell: ClientSideSort.java,v 1.3 2002/07/29 21:28:12 $

 * Copyright (C) 1999, 2000, 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:         ClientSideSort.java

 * $description:  The ClientSideSort.java example demonstrates the sorting

 *                capabilities for search results, i.e., LDAPEntries, and

 *                LDAPAttributes.  The example sorts and prints entries in the

 *                specified container (search base).

 *

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

import com.novell.ldap.*;

import java.io.UnsupportedEncodingException;

import java.util.Arrays;

import java.util.Enumeration;

import java.util.Iterator;

import java.util.Set;

import java.util.TreeSet;



public class ClientSideSort

{

    public static void main( String[] args )

    {

        if (args.length != 5) {

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

                              "<login dn> <password> <search base>\n"

                              + "         <search filter>");

           System.out.println("Example: java ClientSideSort Acme.com"

                                    + " \"cn=admin,o=Acme\""

                                    + " secret \"ou=sales,o=Acme\"\n"

                                    + "         \"(objectclass=*)\"");

           System.exit(0);

        }



        int ldapPort = LDAPConnection.DEFAULT_PORT;

        int searchScope = LDAPConnection.SCOPE_ONE;

        int ldapVersion  = LDAPConnection.LDAP_V3;

        String ldapHost = args[0];

        String loginDN  = args[1];

        String password = args[2];

        String searchBase = args[3];

        String searchFilter = args[4];

        LDAPConnection conn = new LDAPConnection();



        try {

            // connect to the server

            conn.connect( ldapHost, ldapPort );

            // bind to the server

            conn.bind( ldapVersion, loginDN, password.getBytes("UTF8"));



            LDAPSearchResults searchResults =

                conn.search(  searchBase,

                            searchScope,

                            searchFilter,

                            new String[] {"cn", "uid", "sn"}, //attributes

                            false);        // return attrs and values



            /* sortedResults will sort the entries according to the natural

             * ordering of LDAPEntry (by distiguished name).

             */

            TreeSet sortedResults = new TreeSet();

            while ( searchResults.hasMore()) {

                try {

                    sortedResults.add( searchResults.next() );

                }

                catch(LDAPException e) {

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

                    // Exception is thrown, go for next entry

                    continue;

                }

            }



            // print the sorted results

            System.out.println( "\n"+

                    "****************************\n"+

                    "Search results sorted by DN:\n"+

                    "****************************");

            Iterator i = sortedResults.iterator();

            while (i.hasNext()){

                printEntry( (LDAPEntry) i.next() );

            }



            /* resort the results an an array using a specific comparator */

            String namesToSortBy[]  = { "sn", "uid", "cn"  };

            boolean sortAscending[] = { true, false, true };

            LDAPCompareAttrNames myComparator = new LDAPCompareAttrNames(

                    namesToSortBy, sortAscending);



            Object sortedSpecial[] = sortedResults.toArray();

            Arrays.sort(sortedSpecial, myComparator);



            // print the re-sorted results

            System.out.println( "\n" +

                    "*****************************************************\n" +

                    "Search results sorted by sn, uid(Descending), and cn:\n" +

                    "*****************************************************");

            for(int j=0; j< sortedSpecial.length; j++){

                printEntry( (LDAPEntry) sortedSpecial[j] );

            }

            // disconnect with the server

            conn.disconnect();

        }

        catch( LDAPException e ) {

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

        }

        catch( UnsupportedEncodingException e ) {

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

        }

        System.exit(0);

    }



    /**

     * Prints the DN and attributes in an LDAPEntry to System.out.

     * This method used TreeSet to sort the attributes by name.

     */

    public static void printEntry(LDAPEntry entry){

        /* To print an entry,

         *   -- Loop through all the attributes

         *   -- Loop through all the attribute values

         */



        System.out.println(entry.getDN());

        System.out.println("\tAttributes: ");



        LDAPAttributeSet attributeSet = entry.getAttributeSet();

        Set sortedAttributes = new TreeSet( attributeSet );

        Iterator allAttributes = sortedAttributes.iterator();



        while(allAttributes.hasNext()) {

            LDAPAttribute attribute =

                    (LDAPAttribute)allAttributes.next();

            String attributeName = attribute.getName();



            System.out.println("\t\t" + attributeName);



            Enumeration allValues = attribute.getStringValues();



            if( allValues != null) {

                while(allValues.hasMoreElements()) {

                    String Value = (String) allValues.nextElement();

                    System.out.println("\t\t\t" + Value);

                }

            }

        }

        return;

    }

}



