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 AggregatedPortalCacheListener<K extends Serializable, V>
030 implements PortalCacheListener<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 addPortalCacheListener(
041 PortalCacheListener<K, V> portalCacheListener) {
042
043 addPortalCacheListener(
044 portalCacheListener, PortalCacheListenerScope.ALL);
045 }
046
047 public void addPortalCacheListener(
048 PortalCacheListener<K, V> portalCacheListener,
049 PortalCacheListenerScope portalCacheListenerScope) {
050
051 _portalCacheListeners.putIfAbsent(
052 portalCacheListener, portalCacheListenerScope);
053 }
054
055 public void clearAll() {
056 dispose();
057
058 _portalCacheListeners.clear();
059 }
060
061 @Override
062 public void dispose() {
063 for (PortalCacheListener<K, V> portalCacheListener :
064 _portalCacheListeners.keySet()) {
065
066 portalCacheListener.dispose();
067 }
068 }
069
070 public Map<PortalCacheListener<K, V>, PortalCacheListenerScope>
071 getPortalCacheListeners() {
072
073 return Collections.unmodifiableMap(_portalCacheListeners);
074 }
075
076 public boolean isEmpty() {
077 return _portalCacheListeners.isEmpty();
078 }
079
080 @Override
081 public void notifyEntryEvicted(
082 PortalCache<K, V> portalCache, K key, V value, int timeToLive)
083 throws PortalCacheException {
084
085 for (Map.Entry<PortalCacheListener<K, V>, PortalCacheListenerScope>
086 entry : _portalCacheListeners.entrySet()) {
087
088 PortalCacheListener<K, V> portalCacheListener = entry.getKey();
089
090 if (_shouldDeliver(portalCacheListener, entry.getValue())) {
091 portalCacheListener.notifyEntryEvicted(
092 portalCache, key, value, timeToLive);
093 }
094 }
095 }
096
097 @Override
098 public void notifyEntryExpired(
099 PortalCache<K, V> portalCache, K key, V value, int timeToLive)
100 throws PortalCacheException {
101
102 for (Map.Entry<PortalCacheListener<K, V>, PortalCacheListenerScope>
103 entry : _portalCacheListeners.entrySet()) {
104
105 PortalCacheListener<K, V> portalCacheListener = entry.getKey();
106
107 if (_shouldDeliver(portalCacheListener, entry.getValue())) {
108 portalCacheListener.notifyEntryExpired(
109 portalCache, key, value, timeToLive);
110 }
111 }
112 }
113
114 @Override
115 public void notifyEntryPut(
116 PortalCache<K, V> portalCache, K key, V value, int timeToLive)
117 throws PortalCacheException {
118
119 for (Map.Entry<PortalCacheListener<K, V>, PortalCacheListenerScope>
120 entry : _portalCacheListeners.entrySet()) {
121
122 PortalCacheListener<K, V> portalCacheListener = entry.getKey();
123
124 if (_shouldDeliver(portalCacheListener, entry.getValue())) {
125 portalCacheListener.notifyEntryPut(
126 portalCache, key, value, timeToLive);
127 }
128 }
129 }
130
131 @Override
132 public void notifyEntryRemoved(
133 PortalCache<K, V> portalCache, K key, V value, int timeToLive)
134 throws PortalCacheException {
135
136 for (Map.Entry<PortalCacheListener<K, V>, PortalCacheListenerScope>
137 entry : _portalCacheListeners.entrySet()) {
138
139 PortalCacheListener<K, V> portalCacheListener = entry.getKey();
140
141 if (_shouldDeliver(portalCacheListener, entry.getValue())) {
142 portalCacheListener.notifyEntryRemoved(
143 portalCache, key, value, timeToLive);
144 }
145 }
146 }
147
148 @Override
149 public void notifyEntryUpdated(
150 PortalCache<K, V> portalCache, K key, V value, int timeToLive)
151 throws PortalCacheException {
152
153 for (Map.Entry<PortalCacheListener<K, V>, PortalCacheListenerScope>
154 entry : _portalCacheListeners.entrySet()) {
155
156 PortalCacheListener<K, V> portalCacheListener = entry.getKey();
157
158 if (_shouldDeliver(portalCacheListener, entry.getValue())) {
159 portalCacheListener.notifyEntryUpdated(
160 portalCache, key, value, timeToLive);
161 }
162 }
163 }
164
165 @Override
166 public void notifyRemoveAll(PortalCache<K, V> portalCache)
167 throws PortalCacheException {
168
169 for (Map.Entry<PortalCacheListener<K, V>, PortalCacheListenerScope>
170 entry : _portalCacheListeners.entrySet()) {
171
172 PortalCacheListener<K, V> portalCacheListener = entry.getKey();
173
174 if (_shouldDeliver(portalCacheListener, entry.getValue())) {
175 portalCacheListener.notifyRemoveAll(portalCache);
176 }
177 }
178 }
179
180 public void removePortalCacheListener(
181 PortalCacheListener<K, V> portalCacheListener) {
182
183 portalCacheListener.dispose();
184
185 _portalCacheListeners.remove(portalCacheListener);
186 }
187
188 private boolean _shouldDeliver(
189 PortalCacheListener<K, V> portalCacheListener,
190 PortalCacheListenerScope portalCacheListenerScope) {
191
192 if (_remoteInvokeThreadLocal.get()) {
193 if (portalCacheListener instanceof PortalCacheReplicator) {
194 return false;
195 }
196
197 if (portalCacheListenerScope.equals(PortalCacheListenerScope.ALL) ||
198 portalCacheListenerScope.equals(
199 PortalCacheListenerScope.REMOTE)) {
200
201 return true;
202 }
203
204 return false;
205 }
206
207 if (portalCacheListenerScope.equals(PortalCacheListenerScope.ALL) ||
208 portalCacheListenerScope.equals(PortalCacheListenerScope.LOCAL)) {
209
210 return true;
211 }
212
213 return false;
214 }
215
216 private static final ThreadLocal<Boolean> _remoteInvokeThreadLocal =
217 new InitialThreadLocal<>(
218 AggregatedPortalCacheListener.class + "._remoteInvokeThreadLocal",
219 false);
220
221 private final ConcurrentMap
222 <PortalCacheListener<K, V>, PortalCacheListenerScope>
223 _portalCacheListeners = new ConcurrentHashMap<>();
224
225 }