//Warning: This code has been marked up for HTML

/**************************************************************************
*  Novell Software Developer Kit
*
*  Copyright (C) 2002-2003 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 DEVELOPER 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:         SearchControl.java
* $description:  SearchControl.java covers most of the APIs of the classe
*                SearchControl. Most of the API calls are not necessary,
*                they only show the possible use of those APIs
******************************************************************************/
import java.util.Enumeration;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.LdapContext;
import javax.naming.ldap.InitialLdapContext;


public class SearchControl {
    public static void main(String[] args) {

        if (args.length != 4) {
           usage();
        }

        String hostURL       = args[0];
        String loginDN       = args[1];
        String password      = args[2];
        String searchBase    = args[3];

        /* Initialize search constraint parameters and pass them to
         * searchControl constructor:
         *    1. search scpoe to OBJECT_SCOPE (0), ONELEVEL_SCOPE (1), or
         *       SUBTREE_SCOPE (2).
         *    2. Number of ms to wait before return, 0-> infinite.
         *    3. Maximum nubber to return, 0 -> no limit.
         *    4. Attributes to return, null -> all; "" -> nothing
         *    5. Return object, true -> returnthe object bound to the name,
         *       false ->not return object
         *    6. Deference, true -> deference the link during search
         */
        int      scope       =  2;
        int      timeLimit   =  1000;
        long     countLimit  =  1000;
        String   returnedAttributes[]=  {"cn", "sn", "mail", "telephoneNumber"};
        boolean  returnObject=  false;
        boolean  deference   =  false;

        System.out.println(
            "\nCall SearchControl constructor to set search constraints...");
        SearchControls constraints = new SearchControls( scope,
                                                         countLimit,
                                                         timeLimit,
                                                         returnedAttributes,
                                                         returnObject,
                                                         deference   );

        System.out.println(
            "Call SearchControl APIs to set search constraints again...");
        constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
        constraints.setTimeLimit( 2000 );
        constraints.setDerefLinkFlag( false );
        constraints.setReturningObjFlag( false );
        constraints.setCountLimit( 1001 );
        constraints.setReturningAttributes( returnedAttributes );

        System.out.println( "Call SearchControl APIs to display search"
                            +"contraints");
        System.out.println( "Search scope: " + constraints.getSearchScope());
        System.out.println( "Time limit  : " + constraints.getTimeLimit());
        System.out.println( "Deference link flag: "
                                            + constraints.getDerefLinkFlag());
        System.out.println( "Returing object flag: "
                                         + constraints.getReturningObjFlag());
        System.out.println( "Count limit: " + constraints.getCountLimit());
        String returnedAttrs[]  =  constraints.getReturningAttributes();
        for( int i=0;i < returnedAttrs.length; ++i )
           System.out.println( returnedAttrs[i] );


        try {
            /* Setup enviro*/
            Hashtable env = new Hashtable(5, 0.75f);
            env.put(Context.INITIAL_CONTEXT_FACTORY,
                           "com.sun.jndi.ldap.LdapCtxFactory" );
            env.put(Context.PROVIDER_URL, hostURL );
            env.put(Context.SECURITY_AUTHENTICATION, "simple" );
            env.put(Context.SECURITY_PRINCIPAL, loginDN );
            env.put(Context.SECURITY_CREDENTIALS, password);

            /* Construct a LdapContext object */
            LdapContext ctx = new InitialLdapContext( env, null );

            /* Search the directory */
            NamingEnumeration results = ctx.search(searchBase,
                                                   "objectclass=*",
                                                   constraints);

            /* Print each entry, it's attributes and attribute values */
            while (results != null && results.hasMore()) {

                SearchResult nextEntry = ( SearchResult )results.next();
                System.out.println("name: " + nextEntry.getName());
                Attributes attributeSet = nextEntry.getAttributes();

                if (attributeSet == null) {
                    System.out.println("No attributes returned");
                }
                else {
                    System.out.println( attributeSet );

                    for (NamingEnumeration allAttributes = attributeSet.getAll();
                             allAttributes.hasMoreElements(); ) {

                        Attribute attribute = (Attribute)allAttributes.next();
                        String attributeId = attribute.getID();

                        for ( Enumeration values = attribute.getAll();
                                  values.hasMoreElements();
                                      System.out.println(attributeId + ": "
                                          + values.nextElement()));
                    }
                }
                System.out.println();
            }
        }
        catch (NamingException e) {
            System.err.println("SearchControl example failed.");
            e.printStackTrace();
        }
        finally {
            System.exit(0);
        }
    }

    public static void usage() {
        System.err.println("\n Usage:   java SearchControl <host URL> "
                            + "<login dn> <password> <entry dn>"
                            +"\n          <trustee dn>");
        System.err.println("\n Example: java SearchControl ldap://Acme.com:389"
                           + " \"cn=Admin,o=Acme\" secret \n          "
                         +"\"ou=Sales,o=Acme\" ");
        System.exit(1);
    }
}