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

 * $Novell: EdirEventsCallback.java,v 1.2 2004/05/14 17:32:24 $

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

 * $description:  The EdirEventsCallback.java example shows how to use a

 * 				  LDAPListener to receive notication for edirectory events.

 * 				  It is used as an example for listening to any value addition

 * 				  changes.<i>Note that in this code no threads or pooling for

 * 				  response is required.Also important point is the difference

 *                in the way we handle MonitorEventResponse as compared to

 * 				  EdirEventSample.</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.LDAPException;

import com.novell.ldap.LDAPMessage;

import com.novell.ldap.events.LDAPEvent;

import com.novell.ldap.events.LDAPEventListener;

import com.novell.ldap.events.LDAPExceptionEvent;

import com.novell.ldap.events.edir.EdirEventConstant;

import com.novell.ldap.events.edir.EdirEventIntermediateResponse;

import com.novell.ldap.events.edir.EdirEventSource;

import com.novell.ldap.events.edir.EdirEventSpecifier;

import com.novell.ldap.events.edir.EventResponseData;

import com.novell.ldap.events.edir.MonitorEventResponse;

import com.novell.ldap.events.edir.eventdata.ValueEventData;



public class EdirEventsCallback {

    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 Edirectory event notification.   

    * @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.

    */

    public void execute(

        String ldapHost,

        int ldapPort,

        String loginDN,

        String password) {

        int ldapVersion = LDAPConnection.LDAP_V3;

        EdirEventSource source = null;

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



            source = new EdirEventSource(); //create an instance



            EdirEventSpecifier specifier[] = new EdirEventSpecifier[2];

            //array of EdirEventSpecifier to specify the event types



            listener = new EdirLDAPEventListener();

            //An implementation of LDAPEventListener



            specifier[0] =

                new EdirEventSpecifier(EdirEventConstant.EVT_ADD_VALUE,

                //For getting exception, set first parameter(classification) to -1.

    EdirEventConstant.EVT_STATUS_ALL);

            // All Add Values events.

            specifier[1] =

                new EdirEventSpecifier(

                    EdirEventConstant.EVT_ADD_ENTRY,

                    EdirEventConstant.EVT_STATUS_ALL);

            //All Add Entry events.



            source.registerforEvent(specifier, connection, listener);

            //register for events



        } catch (LDAPException e) {

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

            try {

                connection.disconnect();

            } catch (LDAPException e2) {

            }

            System.exit(1);

        } catch (UnsupportedEncodingException e) {

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

        }



        // Edir Eventing 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 {

            //Process the events in the listener



            //In the end,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 != 3) {

            System.err.println(

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

                    + " <password> ");

            System.err.println(

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

                    + " secret ");

            System.exit(0);

        }



        int ldapPort = LDAPConnection.DEFAULT_PORT;



        String ldapHost = args[0];

        String loginDN = args[1];

        String password = args[2];



        EdirEventsCallback callback = new EdirEventsCallback();

        callback.execute(ldapHost, ldapPort, loginDN, password);

        System.exit(0);



    } // end main



    class EdirLDAPEventListener implements LDAPEventListener {



        /* (non-Javadoc)

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

         */

        public void ldapEventNotification(LDAPEvent evt) {

            System.out.println("Edir Event Occured");

            LDAPMessage message = evt.getContainedEventInformation();



            // is the response a event response ?

            if (message instanceof EdirEventIntermediateResponse) {

                System.out.println("Edir Event Occured");

                EdirEventIntermediateResponse eventresponse =

                    (EdirEventIntermediateResponse) message;



                System.out.println(

                    "Event Type=" + eventresponse.getEventtype());

                System.out.println(

                    "Event Result=" + eventresponse.getEventResult());

                //process the eventresponse Data, depending on the

                // type of response 

                processEventData(

                    eventresponse.getResponsedata(),

                    eventresponse.getEventtype());



                System.out.print(QUIT_PROMPT);

            }

            // the message is a Unknown response

            else {

                System.out.println("UnKnown Message =" + message);

            }

        }



        /* (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();



            // Handle the MonitorEventResponse. (Optional).

            LDAPMessage message = ldapevt.getContainedEventInformation();

            if (message instanceof MonitorEventResponse) {

                MonitorEventResponse eventerrorresponse =

                    (MonitorEventResponse) message;



                System.out.println(

                    "\nError in Registration ResultCode="

                        + eventerrorresponse.getResultCode());

                EdirEventSpecifier specifiers[] =

                    eventerrorresponse.getSpecifierList();

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

                    System.out.println(

                        "Specifier: EventClassification="

                            + specifiers[i].getEventclassification()

                            + "EventType="

                            + specifiers[i].getEventtype());

                }

                System.exit(-1);



            }

        }

    }

    /**

     * Processes the Event Data depending on the Type.

     * @param data EventResponseData.

     * @param type Type of Data.

     */

    static private void processEventData(

        EventResponseData data,

        int type) {

        switch (type) {

            case EdirEventConstant.EVT_ADD_VALUE :

                // Value event.

                //Output the relevant Data.

                ValueEventData valueevent = (ValueEventData) data;

                System.out.println("Entry =" + valueevent.getEntry());

                System.out.println(

                    "attribute =" + valueevent.getAttribute());

                System.out.println("Class id =" + valueevent.getClassid());

                System.out.println("Data=" + valueevent.getData());

                System.out.println(

                    "prepetratorDN=" + valueevent.getPrepetratorDN());

                System.out.println("Syntax=" + valueevent.getSyntax());

                System.out.println(

                    "timeStamp=" + valueevent.getTimeStamp());



                break;

            default :

                //Unknow Event.

                break;

        }



    }



}

