001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.cache;
016    
017    import com.liferay.portal.kernel.cache.configuration.PortalCacheConfiguration;
018    import com.liferay.portal.kernel.cache.configuration.PortalCacheManagerConfiguration;
019    import com.liferay.portal.kernel.cache.transactional.TransactionalPortalCache;
020    import com.liferay.portal.kernel.resiliency.spi.SPIUtil;
021    import com.liferay.portal.kernel.util.CharPool;
022    import com.liferay.portal.kernel.util.StringPool;
023    import com.liferay.portal.kernel.util.StringUtil;
024    import com.liferay.portal.kernel.util.Validator;
025    
026    import java.io.Serializable;
027    
028    import java.util.Properties;
029    import java.util.Set;
030    import java.util.concurrent.ConcurrentHashMap;
031    import java.util.concurrent.ConcurrentMap;
032    
033    /**
034     * @author Tina Tian
035     */
036    public abstract class AbstractPortalCacheManager<K extends Serializable, V>
037            implements PortalCacheManager<K, V> {
038    
039            @Override
040            public void clearAll() throws PortalCacheException {
041                    doClearAll();
042            }
043    
044            @Override
045            public void destroy() {
046                    portalCaches.clear();
047    
048                    doDestroy();
049            }
050    
051            @Override
052            public PortalCache<K, V> getPortalCache(String portalCacheName)
053                    throws PortalCacheException {
054    
055                    return getPortalCache(portalCacheName, false);
056            }
057    
058            @Override
059            public PortalCache<K, V> getPortalCache(
060                            String portalCacheName, boolean blocking)
061                    throws PortalCacheException {
062    
063                    PortalCache<K, V> portalCache = portalCaches.get(portalCacheName);
064    
065                    if (portalCache != null) {
066                            return portalCache;
067                    }
068    
069                    PortalCacheConfiguration portalCacheConfiguration =
070                            _portalCacheManagerConfiguration.getPortalCacheConfiguration(
071                                    portalCacheName);
072    
073                    if (portalCacheConfiguration == null) {
074                            portalCacheConfiguration =
075                                    _defaultPortalCacheConfiguration.newPortalCacheConfiguration(
076                                            portalCacheName);
077    
078                            _portalCacheManagerConfiguration.putPortalCacheConfiguration(
079                                    portalCacheName, portalCacheConfiguration);
080                    }
081    
082                    portalCache = createPortalCache(portalCacheConfiguration);
083    
084                    _initPortalCacheListeners(portalCache, portalCacheConfiguration);
085    
086                    if (isTransactionalPortalCacheEnabled() &&
087                            isTransactionalPortalCache(portalCacheName)) {
088    
089                            portalCache = new TransactionalPortalCache<>(portalCache);
090                    }
091    
092                    if (isBlockingPortalCacheAllowed() && blocking) {
093                            portalCache = new BlockingPortalCache<>(portalCache);
094                    }
095    
096                    PortalCache<K, V> previousPortalCache = portalCaches.putIfAbsent(
097                            portalCacheName, portalCache);
098    
099                    if (previousPortalCache != null) {
100                            portalCache = previousPortalCache;
101                    }
102                    else if (isPortalCacheBootstrapLoaderEnabled() &&
103                                     (portalCacheConfiguration != null)) {
104    
105                            Properties portalCacheBootstrapLoaderProperties =
106                                    portalCacheConfiguration.
107                                            getPortalCacheBootstrapLoaderProperties();
108    
109                            if (portalCacheBootstrapLoaderProperties != null) {
110                                    PortalCacheBootstrapLoader portalCacheBootstrapLoader =
111                                            portalCacheBootstrapLoaderFactory.create(
112                                                    portalCacheBootstrapLoaderProperties);
113    
114                                    if (portalCacheBootstrapLoader != null) {
115                                            portalCacheBootstrapLoader.loadPortalCache(
116                                                    getPortalCacheManagerName(), portalCacheName);
117                                    }
118                            }
119                    }
120    
121                    return portalCache;
122            }
123    
124            @Override
125            public Set<PortalCacheManagerListener> getPortalCacheManagerListeners() {
126                    return aggregatedPortalCacheManagerListener.
127                            getPortalCacheManagerListeners();
128            }
129    
130            @Override
131            public String getPortalCacheManagerName() {
132                    return _portalCacheManagerName;
133            }
134    
135            public String[] getTransactionalPortalCacheNames() {
136                    return _transactionalPortalCacheNames;
137            }
138    
139            public boolean isBlockingPortalCacheAllowed() {
140                    return _blockingPortalCacheAllowed;
141            }
142    
143            @Override
144            public boolean isClusterAware() {
145                    return _clusterAware;
146            }
147    
148            public boolean isPortalCacheBootstrapLoaderEnabled() {
149                    return _portalCacheBootstrapLoaderEnabled;
150            }
151    
152            public boolean isTransactionalPortalCacheEnabled() {
153                    return _transactionalPortalCacheEnabled;
154            }
155    
156            @Override
157            public boolean registerPortalCacheManagerListener(
158                    PortalCacheManagerListener portalCacheManagerListener) {
159    
160                    return aggregatedPortalCacheManagerListener.addPortalCacheListener(
161                            portalCacheManagerListener);
162            }
163    
164            @Override
165            public void removePortalCache(String portalCacheName) {
166                    portalCaches.remove(portalCacheName);
167    
168                    doRemovePortalCache(portalCacheName);
169            }
170    
171            public void setBlockingPortalCacheAllowed(
172                    boolean blockingPortalCacheAllowed) {
173    
174                    _blockingPortalCacheAllowed = blockingPortalCacheAllowed;
175            }
176    
177            public void setClusterAware(boolean clusterAware) {
178                    this._clusterAware = clusterAware;
179            }
180    
181            public void setMpiOnly(boolean mpiOnly) {
182                    _mpiOnly = mpiOnly;
183            }
184    
185            public void setPortalCacheBootstrapLoaderEnabled(
186                    boolean portalCacheBootstrapLoaderEnabled) {
187    
188                    _portalCacheBootstrapLoaderEnabled = portalCacheBootstrapLoaderEnabled;
189            }
190    
191            public void setPortalCacheManagerName(String portalCacheManagerName) {
192                    _portalCacheManagerName = portalCacheManagerName;
193            }
194    
195            public void setTransactionalPortalCacheEnabled(
196                    boolean transactionalPortalCacheEnabled) {
197    
198                    _transactionalPortalCacheEnabled = transactionalPortalCacheEnabled;
199            }
200    
201            public void setTransactionalPortalCacheNames(
202                    String[] transactionalPortalCacheNames) {
203    
204                    _transactionalPortalCacheNames = transactionalPortalCacheNames;
205            }
206    
207            @Override
208            public boolean unregisterPortalCacheManagerListener(
209                    PortalCacheManagerListener portalCacheManagerListener) {
210    
211                    return aggregatedPortalCacheManagerListener.removePortalCacheListener(
212                            portalCacheManagerListener);
213            }
214    
215            @Override
216            public void unregisterPortalCacheManagerListeners() {
217                    aggregatedPortalCacheManagerListener.clearAll();
218            }
219    
220            protected abstract PortalCache<K, V> createPortalCache(
221                    PortalCacheConfiguration portalCacheConfiguration);
222    
223            protected abstract void doClearAll();
224    
225            protected abstract void doDestroy();
226    
227            protected abstract void doRemovePortalCache(String portalCacheName);
228    
229            protected abstract PortalCacheManagerConfiguration
230                    getPortalCacheManagerConfiguration();
231    
232            protected void initialize() {
233                    if ((_portalCacheManagerConfiguration != null) ||
234                            (_mpiOnly && SPIUtil.isSPI())) {
235    
236                            return;
237                    }
238    
239                    if (Validator.isNull(_portalCacheManagerName)) {
240                            throw new IllegalArgumentException(
241                                    "Portal cache manager name is not specified");
242                    }
243    
244                    initPortalCacheManager();
245    
246                    _portalCacheManagerConfiguration = getPortalCacheManagerConfiguration();
247    
248                    _defaultPortalCacheConfiguration =
249                            _portalCacheManagerConfiguration.
250                                    getDefaultPortalCacheConfiguration();
251    
252                    for (Properties properties :
253                                    _portalCacheManagerConfiguration.
254                                            getPortalCacheManagerListenerPropertiesSet()) {
255    
256                            PortalCacheManagerListener portalCacheManagerListener =
257                                    portalCacheManagerListenerFactory.create(this, properties);
258    
259                            if (portalCacheManagerListener != null) {
260                                    registerPortalCacheManagerListener(portalCacheManagerListener);
261                            }
262                    }
263            }
264    
265            protected abstract void initPortalCacheManager();
266    
267            protected boolean isTransactionalPortalCache(String portalCacheName) {
268                    for (String namePattern : getTransactionalPortalCacheNames()) {
269                            if (StringUtil.wildcardMatches(
270                                            portalCacheName, namePattern, CharPool.QUESTION,
271                                            CharPool.STAR, CharPool.PERCENT, true)) {
272    
273                                    return true;
274                            }
275                    }
276    
277                    return false;
278            }
279    
280            protected void reconfigPortalCache(
281                    PortalCacheManagerConfiguration portalCacheManagerConfiguration) {
282    
283                    for (String portalCacheName :
284                                    portalCacheManagerConfiguration.getPortalCacheNames()) {
285    
286                            PortalCacheConfiguration portalCacheConfiguration =
287                                    portalCacheManagerConfiguration.getPortalCacheConfiguration(
288                                            portalCacheName);
289    
290                            _portalCacheManagerConfiguration.putPortalCacheConfiguration(
291                                    portalCacheName, portalCacheConfiguration);
292    
293                            PortalCache<K, V> portalCache = portalCaches.get(portalCacheName);
294    
295                            if (portalCache == null) {
296                                    continue;
297                            }
298    
299                            portalCache.unregisterPortalCacheListeners();
300    
301                            _initPortalCacheListeners(portalCache, portalCacheConfiguration);
302                    }
303            }
304    
305            protected final AggregatedPortalCacheManagerListener
306                    aggregatedPortalCacheManagerListener =
307                            new AggregatedPortalCacheManagerListener();
308            protected PortalCacheBootstrapLoaderFactory
309                    portalCacheBootstrapLoaderFactory;
310            protected PortalCacheListenerFactory portalCacheListenerFactory;
311            protected PortalCacheManagerListenerFactory<PortalCacheManager<K, V>>
312                    portalCacheManagerListenerFactory;
313            protected final ConcurrentMap<String, PortalCache<K, V>> portalCaches =
314                    new ConcurrentHashMap<>();
315    
316            private void _initPortalCacheListeners(
317                    PortalCache<K, V> portalCache,
318                    PortalCacheConfiguration portalCacheConfiguration) {
319    
320                    if (portalCacheConfiguration == null) {
321                            return;
322                    }
323    
324                    for (Properties properties :
325                                    portalCacheConfiguration.
326                                            getPortalCacheListenerPropertiesSet()) {
327    
328                            PortalCacheListenerScope portalCacheListenerScope =
329                                    (PortalCacheListenerScope)properties.remove(
330                                            PortalCacheConfiguration.PORTAL_CACHE_LISTENER_SCOPE);
331    
332                            if (portalCacheListenerScope == null) {
333                                    portalCacheListenerScope = PortalCacheListenerScope.ALL;
334                            }
335    
336                            PortalCacheListener<K, V> portalCacheListener =
337                                    portalCacheListenerFactory.create(properties);
338    
339                            portalCache.registerPortalCacheListener(
340                                    portalCacheListener, portalCacheListenerScope);
341                    }
342            }
343    
344            private boolean _blockingPortalCacheAllowed;
345            private boolean _clusterAware;
346            private PortalCacheConfiguration _defaultPortalCacheConfiguration;
347            private boolean _mpiOnly;
348            private boolean _portalCacheBootstrapLoaderEnabled;
349            private PortalCacheManagerConfiguration _portalCacheManagerConfiguration;
350            private String _portalCacheManagerName;
351            private boolean _transactionalPortalCacheEnabled;
352            private String[] _transactionalPortalCacheNames = StringPool.EMPTY_ARRAY;
353    
354    }