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

 * $Novell: PersistenceSearchCallback.java,v 1.2 2004/05/06 08:19:14 $

 * 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:         PersistenceSearchCallback.java

 * $description:  The PersistenceSearchCallback.java example shows how to

 * 				  to use a PSearchEventListener to receive notication for

 * 				  any changes to entries within the scope of the search's

 * 				  result set. <i>Note that in this code no threads or

 * 				  pooling for response is required as compared to 

 *                SearchPersist.java</i>

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

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.UnsupportedEncodingException;



import com.novell.ldap.LDAPConnection;

import com.novell.ldap.LDAPEntry;

import com.novell.ldap.LDAPException;

import com.novell.ldap.controls.LDAPPersistSearchControl;

import com.novell.ldap.events.EventConstant;

import com.novell.ldap.events.LDAPEvent;

import com.novell.ldap.events.LDAPExceptionEvent;

import com.novell.ldap.events.PSearchEventListener;

import com.novell.ldap.events.PsearchEventSource;

import com.novell.ldap.events.SearchReferralEvent;

import com.novell.ldap.events.SearchResultEvent;



public class PersistenceSearchCallback {

    static final String QUIT_PROMPT =

        "\nMonitoring changes. Enter a 'q' to quit: ";



    /**

     * This method contains the code for creating of ldap connection

     * and registering for Persistence Search event notification 

     * request.  

     * @param ldapHost  Ldap Host Address.

     * @param ldapPort  Ldap Port for the server.

     * @param loginDN   Login DN to be used for search.

     * @param password  Password for the login dn.

     * @param searchBase The search base for which persistence search events

     * 					  needs to be generated.

     */

    public void execute(

        String ldapHost,

        int ldapPort,

        String loginDN,

        String password,

        String searchBase) {

        int ldapVersion = LDAPConnection.LDAP_V3;

        PsearchEventSource source = null;

        SearchEventListener listener = null;



        LDAPConnection connection = new LDAPConnection();



        try {

            // connect to the server

            connection.connect(ldapHost, ldapPort);

            // authenticate to the server

            connection.bind(

                ldapVersion,

                loginDN,

                password.getBytes("UTF8"));



            //create an instance of Source of Persistence Search Event.

            source = new PsearchEventSource();



            String[] noAttrs = { LDAPConnection.NO_ATTRS };

            //create an instance of PSearchListener for receiving event notification.

            listener = new SearchEventListener();



            //register for search with no attributes returned

            source.registerforEvent(connection,

            //Connection to connect to server.

            searchBase, // container to search

            LDAPConnection.SCOPE_SUB, // search container's subtree

            "(objectClass=*)", // search filter, all objects

            noAttrs, // don't return attributes

            true, // return attrs and values, ignored

            null, // use default search queue

            EventConstant.LDAP_PSEARCH_ANY,

            // use default search constraints

            true, //return change only

            listener); //PsearchListener for receiving events.



        } catch (LDAPException e) {

            //catch the LDAPException and disconnect and exit.

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

            if (connection != null)

                try {

                    connection.disconnect();

                } catch (LDAPException e2) {

                }

            System.exit(1);

        } catch (UnsupportedEncodingException e) {

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

        }



        // persistent search initiated without error, monitor the results

        // looping until the user quits by entering a 'q' or 'Q'



        BufferedReader in =

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



        try { //loop until the user quits by entering 'q' or 'Q'



            String input;

            do {

                System.out.print(QUIT_PROMPT);

                input = in.readLine();

            } while (!(input.startsWith("q") || input.startsWith("Q")));



        } catch (IOException e) {

            System.out.println(e.getMessage());

        }



        //disconnect from the server before exiting

        try {

            //remove the listener

            source.removeListener(listener);



            connection.disconnect();

        } catch (LDAPException e) {

            System.out.println();

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

        }

    }

    public static void main(String[] args) {

        if (args.length != 4) {

            System.err.println(

                "Usage:   java PersistenceSearchCallback <host name> <login dn>"

                    + " <password> <search base>");

            System.err.println(

                "Example: java PersistenceSearchCallback Acme.com \"cn=admin,o=Acme\""

                    + " secret \"ou=sales,o=Acme\"");

            System.exit(0);

        }



        int ldapPort = LDAPConnection.DEFAULT_PORT;



        String ldapHost = args[0];

        String loginDN = args[1];

        String password = args[2];

        String searchBase = args[3];



        PersistenceSearchCallback callback =

            new PersistenceSearchCallback();

        callback.execute(

            ldapHost,

            ldapPort,

            loginDN,

            password,

            searchBase);

        System.exit(0);



    } // end main



    /**

     * Return a string indicating the type of change represented by the

     * changeType parameter.

     */

    private String getChangeTypeString(int changeType) {

        String changeTypeString;



        switch (changeType) {

            case LDAPPersistSearchControl.ADD :

                changeTypeString = "ADD";

                break;

            case LDAPPersistSearchControl.MODIFY :

                changeTypeString = "MODIFY";

                break;

            case LDAPPersistSearchControl.MODDN :

                changeTypeString = "MODDN";

                break;

            case LDAPPersistSearchControl.DELETE :

                changeTypeString = "DELETE";

                break;

            default :

                changeTypeString =

                    "Unknown change type: " + String.valueOf(changeType);

                break;

        }



        return changeTypeString;

    }

    /**

     * This class implements PSearchEventListener and handles the event that

     * are generated from the server.

     */

    class SearchEventListener implements PSearchEventListener {



        /* (non-Javadoc)

         * @see com.novell.ldap.events.PSearchEventListener#searchReferalEvent(com.novell.ldap.events.SearchReferralEvent)

         */

        public void searchReferalEvent(SearchReferralEvent referalevent) {

            String urls[] = referalevent.getUrls();



            System.out.println("\nSearch result references:");

            for (int i = 0; i < urls.length; i++)

                System.out.println(urls[i]);

            System.out.print(QUIT_PROMPT);

        }



        /* (non-Javadoc)

         * @see com.novell.ldap.events.PSearchEventListener#searchResultEvent(com.novell.ldap.events.SearchResultEvent)

         */

        public void searchResultEvent(SearchResultEvent event) {



            int changeType = event.getType();

            System.out.println(

                "\n\nchange type: " + getChangeTypeString(changeType));



            LDAPEntry entry = event.getEntry();

            System.out.println("entry: " + entry.getDN());

            System.out.print(QUIT_PROMPT);

        }



        /* (non-Javadoc)

         * @see com.novell.ldap.events.LDAPEventListener#ldapEventNotification(com.novell.ldap.events.LDAPEvent)

         */

        public void ldapEventNotification(LDAPEvent evt) {

            System.out.println("ldapEventNotification" + evt);



        }



        /* (non-Javadoc)

         * @see com.novell.ldap.events.LDAPEventListener#ldapEventException(com.novell.ldap.events.LDAPExceptionEvent)

         */

        public void ldapExceptionNotification(LDAPExceptionEvent ldapevt) {

            System.out.println("ldapEventException" + ldapevt);

            ldapevt.getLDAPException().printStackTrace();

        }

    }



}

