All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.novell.ldap.events.LDAPEventSource Maven / Gradle / Ivy

There is a newer version: 2009-10-07
Show newest version
/* **************************************************************************
 * $OpenLDAP: pkg/jldap/com/novell/ldap/events/LDAPEventSource.java,v 1.2 2005/01/17 15:49:49 sunilk Exp $
 *
 * Copyright (C) 1999-2002 Novell, Inc. All Rights Reserved.
 *
 * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND
 * TREATIES. USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT
 * TO VERSION 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS
 * AVAILABLE AT HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE"
 * IN THE TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION
 * OF THIS WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP
 * PUBLIC LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT
 * THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
 ******************************************************************************/
package com.novell.ldap.events;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import com.novell.ldap.LDAPConnection;
import com.novell.ldap.LDAPException;
import com.novell.ldap.LDAPMessage;
import com.novell.ldap.LDAPMessageQueue;
import com.novell.ldap.LDAPResponse;
import com.novell.ldap.client.Debug;

/**
 * The base Class which is used by all Ldap Event Generator. This class is
 * defined abstract so that it cannot be used directly. But it needs to
 * be subclassed to define a EventSource which can also classify
 * events.Since Event Classification is not handled completely in this
 * class.
 */
public abstract class LDAPEventSource {
    /**
     * Local Constant for time to sleep between two calls to checking the
     * queue.
     */
    private long sleepTime = 1000L;

    /**
     * Local Map to Store LDAPEventListener and associated generation
     * thread.
     */
    private Map listenermap = new TreeMap(new HashComparator());

    /**
     * Stops and removes the polling Thread for this listener from
     * receiving LDAP events fired by this class. The listener can only
     * register once once with this LDAPEventSource. After this method is
     * invoked, the listener will no longer receive events with this
     * LDAPEventSource instance as the event source (except for those
     * events already in the process of being dispatched). If the
     * listener was not, or is no longer, registered with this instance,
     * this method does not do anything.
     *
     * @param alistener Removes the listener from receiving the events
     *        fired by this LDAPEventSource.
     *
     * @throws LDAPException If problem is encountered while removing the
     *         listener.
     */
    protected void stopeventpolling(final LDAPEventListener alistener)
        throws LDAPException {
        if (alistener == null) {
            throw new IllegalArgumentException("No parameter can be Null.");
        }

        if (!listenermap.containsKey(alistener)) {
            if (Debug.LDAP_DEBUG) {
                Debug.trace(
                    Debug.EventsCalls,
                    "Unknown Listener send for removal");
            }
            throw new LDAPException(
                null,
                LDAPException.OTHER,
                "This in not a registered Listener");

        }

        Iterator eventthreaditerator =
            ((List) listenermap.get(alistener)).iterator();

        listenermap.remove(alistener);

        while (eventthreaditerator.hasNext()) {
            EventsGenerator generator =
                ((EventsGenerator) eventthreaditerator.next());

            generator.stopEventGeneration();

        }

    }

    /**
     * This method is to register for LDAPEvents generated from a specific
     * LDAPMessageQueue.
     *
     * @param queue LDAPMessageQueue for checking the events.
     * @param conn LDAPConnection used to create this MessageQueue ,
     *        required to abandon the message.
     * @param alistener The listener which would get the event.
     * @param msgid The message id for the Message send.
     * @param source The object which would be used as for LDAPEvents
     *        Generated.
     */
    protected void pollforevents(
        final LDAPMessageQueue queue,
        final LDAPConnection conn,
        final LDAPEventListener alistener,
        final int msgid,
        final LDAPEventSource source) {
        //check for not null, for each event.
        if ((queue == null)
            || (conn == null)
            || (alistener == null)
            || (source == null)) {
            throw new IllegalArgumentException("No parameter can be Null.");
        }

        EventsGenerator eventsthread =
            createListeningThread(queue, conn, alistener, msgid, source);

        eventsthread.start();

        List eventdecoratorlist = null;

        if (listenermap.containsKey(alistener)) {
            eventdecoratorlist = (List) listenermap.get(alistener);
        } else {
            eventdecoratorlist = new ArrayList();
            listenermap.put(alistener, eventdecoratorlist);
        }

        //Add Thread to List of Thread generating events for this Listener.
        eventdecoratorlist.add(eventsthread);

    }

    /**
     * This method creates the instance of EventsGenerator Thread, which
     * transforms the ldapresponse received into events.
     *
     * @param queue LDAPMessageQueue for checking the events.
     * @param conn LDAPConnection used to create this MessageQueue ,
     *        required to abandon the message.
     * @param alistener The listener which would get the event.
     * @param msgid The message id for the Message send.
     * @param source The object which would be used as for LDAPEvents
     *        Generated.
     *
     * @return instance of EventsGenerator
     */
    protected EventsGenerator createListeningThread(
        final LDAPMessageQueue queue,
        final LDAPConnection conn,
        final LDAPEventListener alistener,
        final int msgid,
        final LDAPEventSource source) {
        return new EventsGenerator(source, queue, alistener, conn, msgid);
    }

    /**
     * This method returns the time to sleep (or wait) between two calls
     * to check the ldap message queue for response.
     *
     * @return time in milliseconds
     */
    public long getSleepTime() {
        return sleepTime;
    }

    /**
     * This method is used to set the time(in milliseconds) to sleep
     * between two calls to check the ldap messsage queue for response.
     * The value of sleep time cannot be zero or negative.
     * Note: If the time is set to very high value, the events
     * would not be received. Recommended value is 1 second
     * (Default).
     *
     * @param l Sleep Time in MilliSeconds.
     */
    public void setSleepTime(final long l) {
        if (l <= 0) {
            throw new IllegalArgumentException("Sleep Time must be a non-zero positive number");
        }
        sleepTime = l;
    }

    /**
     * This inner Thread is used to notify the Registered Listener when an
     * LDAPResponse occurs.
     */
    protected class EventsGenerator extends Thread {
        /**
         * Local Variable, which is a reference to  SearchQueue containing
         * the response.
         */
        private final LDAPMessageQueue searchqueue;

        /**
         * Local Varible,which is used for storing the reference to the
         * source of the events generated from this Thread. This
         * reference is send to all the LDAPEvents.
         */
        private final LDAPEventSource eventsource;

        /** Message id for the Search Request Message. */
        private final int messageid;

        /** LDAPConnection for used to abandon the Message Queue.. */
        private final LDAPConnection ldapconnection;

        /**
         * Local reference to the listener to which the event notification
         * is to be sent.
         */
        private final LDAPEventListener eventlistener;

        /** Local variable to control the state of the system. */
        private volatile boolean isrunning = true;

        /**
         * Default Constructor for EventGenerator.
         *
         * @param aeventsource The Source Object which is required for
         *        LDAPEvents generation.
         * @param queue LDAPSearchqueue which contains the LDAPResponse
         *        objects.
         * @param listener LDAPEventListener which needs to be notified of
         *        the events.
         * @param aconnection LDAPConnection used to create this
         *        searchqueue.
         * @param amessageid LDAPMessage Id for the message send. events.
         */
        public EventsGenerator(
            final LDAPEventSource aeventsource,
            final LDAPMessageQueue queue,
            final LDAPEventListener listener,
            final LDAPConnection aconnection,
            final int amessageid) {
            super();
            eventsource = aeventsource;
            searchqueue = queue;
            eventlistener = listener;
            ldapconnection = aconnection;
            messageid = amessageid;
        }

        /**
         * Waits for the Messages on the Queue and notifies the Listener
         * of the same.
         *
         * @see java.lang.Runnable#run()
         */
        public final void run() {
            while (isrunning) {
                try {
                    LDAPMessage response = null;

                    while ((isrunning)
                        && (!searchqueue.isResponseReceived(messageid))) {
                        try {
                            sleep(sleepTime);
                        } catch (InterruptedException e) {
                            ///CLOVER:OFF
                            // ignore exception, just log it
                            if (Debug.LDAP_DEBUG) {
                                Debug.trace(
                                    Debug.EventsCalls,
                                    "Interrupt Exception"
                                        + e.getMessage());
                            }
                            ///CLOVER:ON
                        }
                    }

                    if (isrunning) {
                        response = searchqueue.getResponse(messageid);
                    }

                    if (response != null) {
                        processmessage(response);
                    }
                } catch (LDAPException e) {
                    ///CLOVER:OFF
                    LDAPExceptionEvent exceptionevent =
                        new LDAPExceptionEvent(eventsource, e, null);
                    eventlistener.ldapExceptionNotification(
                        exceptionevent);
                    ///CLOVER:ON
                }
            }
        }

        /**Processes the Message Receive on the queue.
         * This method actually sends the notification to the 
         * LDAPEventListener.
         * @param response
         */
        protected void processmessage(final LDAPMessage response) {
            //Received a response object , use it to create a Event.
            if (response instanceof LDAPResponse) {
                //Throws a LDAPException , which is sent to client.
                try {
                    ((LDAPResponse) response).chkResultCode();

                    //or simple send a ldapevent
                    eventlistener.ldapEventNotification(
                        new LDAPEvent(
                            eventsource,
                            response,
                            EventConstant.CLASSIFICATION_UNKNOWN,
                            EventConstant.TYPE_UNKNOWN));
                } catch (LDAPException e) {
                    LDAPExceptionEvent exceptionevent =
                        new LDAPExceptionEvent(eventsource, e, response);
                    eventlistener.ldapExceptionNotification(
                        exceptionevent);
                }
            } else {
                eventlistener.ldapEventNotification(
                    new LDAPEvent(
                        eventsource,
                        response,
                        EventConstant.CLASSIFICATION_UNKNOWN,
                        EventConstant.TYPE_UNKNOWN));
            }
        }

        /**
         * Stop the Persistence Search Events Generation by abandoning the
         * Search Request.
         *
         * @throws LDAPException When Cancelling of LDAPConnection Fails.
         */
        public final void stopEventGeneration() throws LDAPException {
            if (Debug.LDAP_DEBUG) {
                Debug.trace(Debug.EventsCalls, "Closing EventGeneration");
            }

            isrunning = false;
            ldapconnection.abandon(searchqueue);
        }
    }

    /* end of class EventsGenerator */

    /**
     * This  Comparator defines Equality based on hashcode value and not
     * actual equality of instance. Used primarly to make User defined
     * LDAPListener and internal contained LDAPListener (as in
     * PSearchSource) equal for a TreeMap.
     */
    private class HashComparator implements Comparator {
        /**
         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
         */
        public int compare(final Object o1, final Object o2) {
            int hash1 = o1.hashCode();
            int hash2 = o2.hashCode();

            if (hash1 > hash2) {
                return 1;
            }

            if (hash1 < hash2) {
                return -1;
            }

            return 0;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy