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