coherence/util/MapListenerSupport.hpp

00001 /*
00002 * MapListenerSupport.hpp
00003 *
00004 * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
00005 *
00006 * Oracle is a registered trademarks of Oracle Corporation and/or its
00007 * affiliates.
00008 *
00009 * This software is the confidential and proprietary information of Oracle
00010 * Corporation. You shall not disclose such confidential and proprietary
00011 * information and shall use it only in accordance with the terms of the
00012 * license agreement you entered into with Oracle.
00013 *
00014 * This notice may not be removed or altered.
00015 */
00016 #ifndef COH_MAP_LISTENER_SUPPORT_HPP
00017 #define COH_MAP_LISTENER_SUPPORT_HPP
00018 
00019 #include "coherence/lang.ns"
00020 
00021 #include "coherence/net/cache/CacheEvent.hpp"
00022 #include "coherence/util/Converter.hpp"
00023 #include "coherence/util/Filter.hpp"
00024 #include "coherence/util/Listeners.hpp"
00025 #include "coherence/util/MapEvent.hpp"
00026 #include "coherence/util/MapListener.hpp"
00027 #include "coherence/util/Set.hpp"
00028 
00029 COH_OPEN_NAMESPACE2(coherence,util)
00030 
00031 using coherence::net::cache::CacheEvent;
00032 
00033 
00034 /**
00035 * This class provides support for advanced MapListener functionality.
00036 *
00037 * @author js  2008.06.10
00038 */
00039 class COH_EXPORT MapListenerSupport
00040     : public class_spec<MapListenerSupport>
00041     {
00042     friend class factory<MapListenerSupport>;
00043 
00044     // ----- constructors ---------------------------------------------------
00045 
00046     protected:
00047         /**
00048         * Create a new MapListenerSupport.
00049         */
00050         MapListenerSupport();
00051 
00052 
00053     // ----- MapListenerSupport interface -----------------------------------
00054 
00055     public:
00056         /**
00057         * Add a map listener that receives events based on a filter
00058         * evaluation.
00059         *
00060         * @param hListener  the listener to add
00061         * @param vFilter    a filter that will be passed MapEvent objects to
00062         *                   select from; a MapEvent will be delivered to the
00063         *                   listener only if the filter evaluates to true for
00064         *                   that MapEvent; NULL is equivalent to a filter
00065         *                   that alway returns true
00066         * @param fLite      true to indicate that the MapEvent objects do not
00067         *                   have to include the OldValue and NewValue
00068         *                   property values in order to allow optimizations
00069         */
00070         virtual void addListener(MapListener::Handle hListener,
00071                 Filter::View vFilter, bool fLite);
00072 
00073         /**
00074         * Add a map listener for a specific key.
00075         *
00076         * @param hListener  the listener to add
00077         * @param vKey       the key that identifies the entry for which to
00078         *                   raise events
00079         * @param fLite      true to indicate that the MapEvent objects do not
00080         *                   have to include the OldValue and NewValue
00081         *                   property values in order to allow optimizations
00082         *
00083         */
00084         virtual void addListener(MapListener::Handle hListener,
00085                 Object::View vKey, bool fLite);
00086 
00087         /**
00088         * Remove a map listener that previously signed up for events based on
00089         * a filter evaluation.
00090         *
00091         * @param vListener  the listener to remove
00092         * @param vFilter    a filter used to evaluate events
00093         */
00094         virtual void removeListener(MapListener::View vListener,
00095                 Filter::View vFilter);
00096 
00097         /**
00098         * Remove a map listener that previously signed up for events about a
00099         * specific key.
00100         *
00101         * @param vListener  the listener to remove
00102         * @param vKey       the key that identifies the entry for which to
00103         *                   raise events
00104         */
00105         virtual void removeListener(MapListener::View vListener,
00106                 Object::View vKey);
00107 
00108         /**
00109         * Remove all signed up listeners.
00110         */
00111         virtual void clear();
00112 
00113         /**
00114         * Checks whether or not this MapListenerSupport object contains
00115         * any listeners.
00116         *
00117         * @return true iff there are no listeners encapsulated by this
00118         *         MapListenerSupport object
00119         */
00120         virtual bool isEmpty() const;
00121 
00122         /**
00123         * Checks whether or not this MapListenerSupport object contains
00124         * any listeners for a given filter.
00125         *
00126         * @param vFilter  the filter
00127         *
00128         * @return true iff there are no listeners for the specified filter
00129         *              encapsulated by this MapListenerSupport object
00130         */
00131         virtual bool isEmpty(Filter::View vFilter) const;
00132 
00133         /**
00134         * Checks whether or not this MapListenerSupport object contains
00135         * any listeners for a given key.
00136         *
00137         * @param vKey  the key
00138         *
00139         * @return true iff there are no listeners for the specified filter
00140         *              encapsulated by this MapListenerSupport object
00141         */
00142         virtual bool isEmpty(Object::View vKey) const;
00143 
00144         /**
00145         * Checks whether or not this MapListenerSupport object contains
00146         * any standard (not lite) listeners for a given filter.
00147         *
00148         * @param vFilter  the filter
00149         *
00150         * @return true iff there are no standard listeners for the specified
00151         *              filter encapsulated by this MapListenerSupport object
00152         */
00153         virtual bool containsStandardListeners(
00154                 Filter::View vFilter) const;
00155 
00156         /**
00157         * Checks whether or not this MapListenerSupport object contains
00158         * any standard (not lite) listeners for a given key.
00159         *
00160         * @param vKey  the key
00161         *
00162         * @return true iff there are no standard listeners for the specified
00163         *              filter encapsulated by this MapListenerSupport object
00164         */
00165         virtual bool containsStandardListeners(Object::View vKey) const;
00166 
00167         /**
00168         * Obtain a set of all filters that have assosiated global listeners.
00169         * <p>
00170         * <b>Note</b>: The returned value must be treated as an immutable.
00171         *
00172         * @return a set of all filters that have assosiated global listeners
00173         */
00174         virtual Set::View getFilterSet() const;
00175 
00176         /**
00177         * Obtain a set of all keys that have assosiated key listeners.
00178         * <p>
00179         * <b>Note</b>: The returned value must be treated as an immutable.
00180         *
00181         * @return a set of all keys that have assosiated key listeners
00182         */
00183         virtual Set::View getKeySet() const;
00184 
00185         /**
00186         * Obtain the Listeners object for a given filter.
00187         *
00188         * @param vFilter  the filter
00189         *
00190         * @return the Listeners object for the filter; NULL if none exists
00191         */
00192         virtual Listeners::View getListeners(Filter::View vFilter) const;
00193 
00194         /**
00195         * Obtain the Listeners object for a given key.
00196         *
00197         * @param vKey  the key
00198         *
00199         * @return the Listeners object for the key; NULL if none exists
00200         */
00201         virtual Listeners::View getListeners(Object::View vKey) const;
00202 
00203         /**
00204         * Collect all Listeners that should be notified for a given event.
00205         * <p>
00206         * <b>Note</b>: The returned value must be treated as an immutable.
00207         *
00208         * @param vEvent the MapEvent object
00209         *
00210         * @return the Listeners object containing the relevant listeners
00211         */
00212         virtual Listeners::View collectListeners(MapEvent::View vEvent);
00213 
00214         /**
00215         * Fire the specified map event.
00216         *
00217         * @param hEvent    the map event
00218         * @param fStrict   if true then any RuntimeException thrown by event
00219         *                  handlers stops all further event processing and
00220         *                  the exception is re-thrown; if false then all
00221         *                  exceptions are logged and the process continues
00222         */
00223         virtual void fireEvent(MapEvent::Handle hEvent, bool fStrict);
00224 
00225         /**
00226         * Convert the specified map event into another MapEvent that ensures
00227         * the lazy event data conversion using the specified converters.
00228         *
00229         * @param vEvent    the map event
00230         * @param hmapConv  the source for the converted event
00231         * @param vConvKey  (optional) the key Converter
00232         * @param vConvVal  (optional) the value converter
00233         *
00234         * @return the converted MapEvent object
00235         */
00236         static MapEvent::Handle convertEvent(MapEvent::View vEvent,
00237                 ObservableMap::Handle hmapConv,
00238                 Converter::View vConvKey = NULL,
00239                 Converter::View vConvVal = NULL);
00240 
00241 
00242     // ----- helper methods -------------------------------------------------
00243 
00244     protected:
00245         /**
00246         * Ensure that the specified map has a Listeners object assosiated
00247         * with the specified key and add the specified listener to it.
00248         *
00249         * @param hmapListeners  map of listeners
00250         * @param vKey           key of the listener
00251         * @param hListener      the listener to add
00252         */
00253         static void addSafeListener(Map::Handle hmapListeners,
00254                 Object::View vKey, MapListener::Handle hListener);
00255 
00256         /**
00257         * Remove the specified listener from the Listeners object assosiated
00258         * with the specified key.
00259         *
00260         * @param hmapListeners  map of listeners
00261         * @param vKey           key of the listener
00262         * @param vListener      the listener to remove
00263         */
00264         static void removeSafeListener(Map::Handle hmapListeners,
00265                 Object::View vKey, MapListener::View vListener);
00266 
00267         /**
00268         * Add a state information (lite or standard) associated with
00269         * specified key and listener.
00270         *
00271         * @param hmapStandardListeners  map of standard listeners
00272         * @param vKey                   key of the listener
00273         * @param hListener              the listener to add
00274         * @param fLite                  true to indicate that the MapEvent
00275         *                               objects do not have to include the
00276         *                               OldValue and NewValue property values
00277         */
00278         static void addListenerState(Map::Handle hmapStandardListeners,
00279                 Object::View vKey, MapListener::Handle hListener,
00280                 bool fLite);
00281 
00282         /**
00283         * Remove a state information (lite or standard) assosiated with
00284         * specified key and listener.
00285         *
00286         * @param hmapStandardListeners  map of standard listeners
00287         * @param vKey                   key of the listener
00288         * @param vListener              the listener to remove
00289         */
00290         static void removeListenerState(Map::Handle hmapStandardListeners,
00291                 Object::View vKey, MapListener::View vListener);
00292 
00293 
00294     // ----- Object interface -----------------------------------------------
00295 
00296     public:
00297         /**
00298         * {@inheritDoc}
00299         */
00300         virtual void toStream(std::ostream& out) const;
00301 
00302 
00303     // ----- inner class: FilterEvent ---------------------------------------
00304 
00305     public:
00306         /**
00307         * An extension of the CacheEvent which may carry no values (old or
00308         * new), but instead holds an array of Filter objects being the
00309         * "cause" of the event.
00310         */
00311         class COH_EXPORT FilterEvent
00312             : public class_spec<FilterEvent,
00313                 extends<CacheEvent> >
00314             {
00315             friend class factory<FilterEvent>;
00316 
00317             // ----- constructors ---------------------------------------
00318 
00319             protected:
00320                 /**
00321                 * Create a new FilterEvent with no old and new values.
00322                 *
00323                 * @param hMap        the map on which the Event initially
00324                 *                    occurred
00325                 * @param nId         the events id (ENTRY_INSERTED |
00326                 *                    ENTRY_UPDATED | ENTRY_DELETED)
00327                 * @param vKey        the key into the map
00328                 * @param fSynthetic  true iff the event is caused by internal
00329                 *                    cache processing such as eviction or
00330                 *                    loading
00331                 * @param haFilters   an array of Filters
00332                 */
00333                 FilterEvent(ObservableMap::Handle hMap, int32_t nId,
00334                         Object::View vKey, Object::View vValueOld,
00335                         Object::View vValueNew, bool fSynthetic,
00336                         ObjectArray::Handle haFilters);
00337 
00338             // ----- FilterEvent interface ------------------------------
00339 
00340             public:
00341                 /**
00342                 * Return an array of filters that are the cause of this
00343                 * event.
00344                 *
00345                 * @return an array of filters
00346                 */
00347                 virtual ObjectArray::View getFilter() const;
00348 
00349 
00350             // ----- Describable interface ------------------------------
00351 
00352             public:
00353                 /**
00354                 * {@inheritDoc}
00355                 */
00356                 virtual void outputDescription(std::ostream& out) const;
00357 
00358             // ----- helper methods -------------------------------------
00359 
00360             public:
00361                 /**
00362                 * Determine if this filter event contains a specified filter.
00363                 *
00364                 * @param vFilter  the filter to search for
00365                 *
00366                 * @return true if the event contained the specified filter,
00367                 *         false otherwise
00368                 */
00369                 virtual bool containsFilter(Filter::View vFilter) const;
00370 
00371             // ----- data members ---------------------------------------
00372 
00373             protected:
00374                 /**
00375                 * Filters which caused the event.
00376                 */
00377                 MemberHandle<ObjectArray> m_haFilters;
00378             };
00379 
00380 
00381     // ----- inner class: SynchronousListener -------------------------------
00382 
00383     public:
00384         /**
00385         * A tag interface indicating that tagged MapListener implementation
00386         * has to receive the MapEvent notifications in a synchronous manner.
00387         * <p>
00388         * Consider a MapListener that subscribes to receive notifications for
00389         * distributed (partitioned) cache. All events notifications are
00390         * received by the service thread and immediately queued to be
00391         * processed by the dedicated event dispatcher thread. This makes it
00392         * impossible to differentiate between the event caused by the updates
00393         * made by this thread and any other thread (possibly in a different
00394         * VM). Forcing the events to be processed on the service thread
00395         * guarantees that by the time "put" or "remove" requests return to
00396         * the caller all relevant MapEvent notification have been processed
00397         * (due to the "in order delivery" rule enforced by the TCMP).
00398         * <p>
00399         * This interface should be considered as a very advanced feature, so
00400         * a MapListener implementation that is tagged as a
00401         * SynchronousListener must exercise extreme caution during event
00402         * processing since any delay with return or unhandled exception will
00403         * cause a delay or complete shutdown of the corresponding cache
00404         * service.
00405         * <p>
00406         * <b>Note:</b> The contract by the event producer in respect to the
00407         * SynchronousListener is somewhat weaker then the general one.
00408         * First, the SynchronousListener implementaion should make no
00409         * assumptions about the event source obtained by {MapEvent#getMap()}.
00410         * Second, in the event of [automatic] service restart, the listener
00411         * has to be re-registered manually (for example, in response to the
00412         * {com::tangosol::net::MemberEvent#MEMBER_JOINED MEMBER_JOINED}
00413         * event). Third, and the most important, no calls against the
00414         * NamedCache are allowed during the synchronous event processing (the
00415         * only exception being a call to remove the listener itself).
00416         */
00417         class COH_EXPORT SynchronousListener
00418             : public interface_spec<SynchronousListener,
00419                 implements<MapListener> >
00420             {
00421             };
00422 
00423 
00424     // ----- inner class: WrapperSynchronousListener ------------------------
00425 
00426     public:
00427         /**
00428         * A wrapper class that turns the specified MapListener into
00429         * a synchronous listener.
00430         */
00431         class COH_EXPORT WrapperSynchronousListener
00432             : public class_spec<WrapperSynchronousListener,
00433                 extends<Object>,
00434                 implements<SynchronousListener> >
00435             {
00436             friend class factory<WrapperSynchronousListener>;
00437 
00438             // ----- constructors ---------------------------------------
00439 
00440             protected:
00441                 /**
00442                 * Create a new WrapperSynchronousListener.
00443                 *
00444                 * @param hListener  the listener to be wrapped
00445                 *
00446                 * @return the new WrapperSynchronousListener instance
00447                 */
00448                 WrapperSynchronousListener(MapListener::Handle hListener);
00449 
00450             // ----- MapListener interface ------------------------------
00451 
00452             public:
00453                 /**
00454                 * {@inheritDoc}
00455                 */
00456                 virtual void entryInserted(MapEvent::View vEvent);
00457 
00458                 /**
00459                 * {@inheritDoc}
00460                 */
00461                 virtual void entryUpdated(MapEvent::View vEvent);
00462 
00463                 /**
00464                 * {@inheritDoc}
00465                 */
00466                 virtual void entryDeleted(MapEvent::View vEvent);
00467 
00468             // ----- Object interface -----------------------------------
00469 
00470             public:
00471                 /**
00472                 * {@inheritDoc}
00473                 */
00474                 virtual size32_t hashCode() const;
00475 
00476                 /**
00477                 * {@inheritDoc}
00478                 */
00479                 virtual bool equals(Object::View v) const;
00480 
00481             // ----- data members ---------------------------------------
00482 
00483             protected:
00484                 /**
00485                 * Wrapped MapListener.
00486                 */
00487                 MemberHandle<MapListener> m_hListener;
00488             };
00489 
00490 
00491     // ----- enums ----------------------------------------------------------
00492 
00493     protected:
00494         /**
00495         * Optimization Plan enum.
00496         */
00497         enum Plan
00498             {
00499             NONE,          // A plan has not yet been formed
00500             NO_LISTENERS,  // There are no listeners
00501             ALL_LISTENER,  // There is one all-keys non-filtered listener
00502             KEY_LISTENER,  // One key listener (even if for multiple keys)
00503             NO_OPTIMIZE    // No optimized plan, use the default approach
00504             };
00505 
00506 
00507     // ----- data members ---------------------------------------------------
00508 
00509     protected:
00510          /**
00511         * The collections of MapListener objects that have signed up for
00512         * notifications from an ObservableMap implementation keyed by the
00513         * corresponding Filter objects.
00514         */
00515         MemberHandle<Map> m_hmapListeners;
00516 
00517         /**
00518         * The collections of MapListener objects that have signed up for key
00519         * based notifications from an ObservableMap implementation keyed by
00520         * the corresponding key objects.
00521         */
00522         MemberHandle<Map> m_hmapKeyListeners;
00523 
00524         // consider adding listener tag support to Listeners class, which
00525         // would allow getting rid of the following data structures ...
00526         /**
00527         * The subset of standard (not lite) global listeners. The keys are
00528         * the Filter objects, the values are sets of corresponding standard
00529         * listeners.
00530         */
00531         MemberHandle<Map> m_hmapStandardListeners;
00532 
00533         /**
00534         * The subset of standard (not lite) key listeners. The keys are the
00535         * key objects, the values are sets of corresponding standard
00536         * listeners.
00537         */
00538         MemberHandle<Map> m_hmapStandardKeyListeners;
00539 
00540         /**
00541         * The optimization plan which indicates the fastest way to put
00542         * together a set of listeners.
00543         */
00544         Plan m_optimizationPlan;
00545 
00546         /**
00547         * A cached set of Listeners.
00548         */
00549         MemberView<Listeners> m_vListenersCached;
00550     };
00551 
00552 COH_CLOSE_NAMESPACE2
00553 
00554 #endif // COH_MAP_LISTENER_SUPPORT_HPP
00555 
Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.