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