001
014
015 package com.liferay.portal.kernel.cache;
016
017 import com.liferay.portal.kernel.util.InitialThreadLocal;
018
019 import java.io.Serializable;
020
021 import java.util.Collections;
022 import java.util.Map;
023 import java.util.concurrent.ConcurrentHashMap;
024 import java.util.concurrent.ConcurrentMap;
025
026
029 public class AggregatedCacheListener<K extends Serializable, V>
030 implements CacheListener<K, V> {
031
032 public static boolean isRemoteInvoke() {
033 return _remoteInvokeThreadLocal.get();
034 }
035
036 public static void setRemoteInvoke(boolean remoteInvoke) {
037 _remoteInvokeThreadLocal.set(remoteInvoke);
038 }
039
040 public void addCacheListener(CacheListener<K, V> cacheListener) {
041 addCacheListener(cacheListener, CacheListenerScope.ALL);
042 }
043
044 public void addCacheListener(
045 CacheListener<K, V> cacheListener,
046 CacheListenerScope cacheListenerScope) {
047
048 _cacheListeners.putIfAbsent(cacheListener, cacheListenerScope);
049 }
050
051 public void clearAll() {
052 dispose();
053
054 _cacheListeners.clear();
055 }
056
057 @Override
058 public void dispose() {
059 for (CacheListener<K, V> cacheListener : _cacheListeners.keySet()) {
060 cacheListener.dispose();
061 }
062 }
063
064 public Map<CacheListener<K, V>, CacheListenerScope> getCacheListeners() {
065 return Collections.unmodifiableMap(_cacheListeners);
066 }
067
068 public boolean isEmpty() {
069 return _cacheListeners.isEmpty();
070 }
071
072 @Override
073 public void notifyEntryEvicted(
074 PortalCache<K, V> portalCache, K key, V value, int timeToLive)
075 throws PortalCacheException {
076
077 for (Map.Entry<CacheListener<K, V>, CacheListenerScope> entry :
078 _cacheListeners.entrySet()) {
079
080 CacheListener<K, V> cacheListener = entry.getKey();
081
082 if (_shouldDeliver(cacheListener, entry.getValue())) {
083 cacheListener.notifyEntryEvicted(
084 portalCache, key, value, timeToLive);
085 }
086 }
087 }
088
089 @Override
090 public void notifyEntryExpired(
091 PortalCache<K, V> portalCache, K key, V value, int timeToLive)
092 throws PortalCacheException {
093
094 for (Map.Entry<CacheListener<K, V>, CacheListenerScope> entry :
095 _cacheListeners.entrySet()) {
096
097 CacheListener<K, V> cacheListener = entry.getKey();
098
099 if (_shouldDeliver(cacheListener, entry.getValue())) {
100 cacheListener.notifyEntryExpired(
101 portalCache, key, value, timeToLive);
102 }
103 }
104 }
105
106 @Override
107 public void notifyEntryPut(
108 PortalCache<K, V> portalCache, K key, V value, int timeToLive)
109 throws PortalCacheException {
110
111 for (Map.Entry<CacheListener<K, V>, CacheListenerScope> entry :
112 _cacheListeners.entrySet()) {
113
114 CacheListener<K, V> cacheListener = entry.getKey();
115
116 if (_shouldDeliver(cacheListener, entry.getValue())) {
117 cacheListener.notifyEntryPut(
118 portalCache, key, value, timeToLive);
119 }
120 }
121 }
122
123 @Override
124 public void notifyEntryRemoved(
125 PortalCache<K, V> portalCache, K key, V value, int timeToLive)
126 throws PortalCacheException {
127
128 for (Map.Entry<CacheListener<K, V>, CacheListenerScope> entry :
129 _cacheListeners.entrySet()) {
130
131 CacheListener<K, V> cacheListener = entry.getKey();
132
133 if (_shouldDeliver(cacheListener, entry.getValue())) {
134 cacheListener.notifyEntryRemoved(
135 portalCache, key, value, timeToLive);
136 }
137 }
138 }
139
140 @Override
141 public void notifyEntryUpdated(
142 PortalCache<K, V> portalCache, K key, V value, int timeToLive)
143 throws PortalCacheException {
144
145 for (Map.Entry<CacheListener<K, V>, CacheListenerScope> entry :
146 _cacheListeners.entrySet()) {
147
148 CacheListener<K, V> cacheListener = entry.getKey();
149
150 if (_shouldDeliver(cacheListener, entry.getValue())) {
151 cacheListener.notifyEntryUpdated(
152 portalCache, key, value, timeToLive);
153 }
154 }
155 }
156
157 @Override
158 public void notifyRemoveAll(PortalCache<K, V> portalCache)
159 throws PortalCacheException {
160
161 for (Map.Entry<CacheListener<K, V>, CacheListenerScope> entry :
162 _cacheListeners.entrySet()) {
163
164 CacheListener<K, V> cacheListener = entry.getKey();
165
166 if (_shouldDeliver(cacheListener, entry.getValue())) {
167 cacheListener.notifyRemoveAll(portalCache);
168 }
169 }
170 }
171
172 public void removeCacheListener(CacheListener<K, V> cacheListener) {
173 cacheListener.dispose();
174
175 _cacheListeners.remove(cacheListener);
176 }
177
178 private boolean _shouldDeliver(
179 CacheListener<K, V> cacheListener,
180 CacheListenerScope cacheListenerScope) {
181
182 if (_remoteInvokeThreadLocal.get()) {
183 if (cacheListener instanceof CacheReplicator) {
184 return false;
185 }
186
187 if (cacheListenerScope.equals(CacheListenerScope.ALL) ||
188 cacheListenerScope.equals(CacheListenerScope.REMOTE)) {
189
190 return true;
191 }
192
193 return false;
194 }
195
196 if (cacheListenerScope.equals(CacheListenerScope.ALL) ||
197 cacheListenerScope.equals(CacheListenerScope.LOCAL)) {
198
199 return true;
200 }
201
202 return false;
203 }
204
205 private static final ThreadLocal<Boolean> _remoteInvokeThreadLocal =
206 new InitialThreadLocal<>(
207 AggregatedCacheListener.class + "._remoteInvokeThreadLocal", false);
208
209 private final ConcurrentMap<CacheListener<K, V>, CacheListenerScope>
210 _cacheListeners = new ConcurrentHashMap<>();
211
212 }