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.cache.memory;
016    
017    import com.liferay.portal.kernel.cache.AbstractPortalCacheManager;
018    import com.liferay.portal.kernel.cache.CacheListenerScope;
019    import com.liferay.portal.kernel.cache.PortalCache;
020    import com.liferay.portal.kernel.cache.PortalCacheManager;
021    import com.liferay.portal.kernel.cache.PortalCacheManagerTypes;
022    import com.liferay.portal.kernel.cache.cluster.ClusterLinkCallbackFactory;
023    import com.liferay.portal.kernel.cache.configuration.CallbackConfiguration;
024    import com.liferay.portal.kernel.cache.configuration.PortalCacheConfiguration;
025    import com.liferay.portal.kernel.cache.configuration.PortalCacheManagerConfiguration;
026    import com.liferay.portal.util.PropsValues;
027    import com.liferay.registry.Registry;
028    import com.liferay.registry.RegistryUtil;
029    import com.liferay.registry.ServiceRegistrar;
030    
031    import java.io.Serializable;
032    
033    import java.net.URL;
034    
035    import java.util.HashMap;
036    import java.util.Map;
037    import java.util.Properties;
038    import java.util.concurrent.ConcurrentHashMap;
039    import java.util.concurrent.ConcurrentMap;
040    
041    /**
042     * @author Brian Wing Shun Chan
043     * @author Tina Tian
044     */
045    public class MemoryPortalCacheManager<K extends Serializable, V>
046            extends AbstractPortalCacheManager<K, V> {
047    
048            public static <K extends Serializable, V> MemoryPortalCacheManager<K, V>
049                    createMemoryPortalCacheManager(String portalCacheManagerName) {
050    
051                    MemoryPortalCacheManager<K, V> memoryPortalCacheManager =
052                            new MemoryPortalCacheManager<>();
053    
054                    memoryPortalCacheManager.setName(portalCacheManagerName);
055    
056                    memoryPortalCacheManager.initialize();
057    
058                    return memoryPortalCacheManager;
059            }
060    
061            @Override
062            public void destroy() {
063                    if (_serviceRegistrar != null) {
064                            _serviceRegistrar.destroy();
065                    }
066    
067                    super.destroy();
068            }
069    
070            @Override
071            public void reconfigureCaches(URL configurationURL) {
072                    throw new UnsupportedOperationException();
073            }
074    
075            public void setCacheInitialCapacity(int cacheInitialCapacity) {
076                    _cacheInitialCapacity = cacheInitialCapacity;
077            }
078    
079            public void setCacheManagerInitialCapacity(
080                    int cacheManagerInitialCapacity) {
081    
082                    _cacheManagerInitialCapacity = cacheManagerInitialCapacity;
083            }
084    
085            @Override
086            protected PortalCache<K, V> createPortalCache(
087                    PortalCacheConfiguration portalCacheConfiguration) {
088    
089                    String portalCacheName = portalCacheConfiguration.getPortalCacheName();
090    
091                    MemoryPortalCache<K, V> portalCache = _memoryPortalCaches.get(
092                            portalCacheName);
093    
094                    if (portalCache != null) {
095                            return portalCache;
096                    }
097    
098                    portalCache = new MemoryPortalCache<>(
099                            this, portalCacheName, _cacheInitialCapacity);
100    
101                    MemoryPortalCache<K, V> previousPortalCache =
102                            _memoryPortalCaches.putIfAbsent(portalCacheName, portalCache);
103    
104                    if (previousPortalCache == null) {
105                            aggregatedCacheManagerListener.notifyCacheAdded(portalCacheName);
106                    }
107                    else {
108                            portalCache = previousPortalCache;
109                    }
110    
111                    return portalCache;
112            }
113    
114            @Override
115            protected void doClearAll() {
116                    for (MemoryPortalCache<K, V> memoryPortalCache :
117                                    _memoryPortalCaches.values()) {
118    
119                            memoryPortalCache.removeAll();
120                    }
121            }
122    
123            @Override
124            protected void doDestroy() {
125                    for (MemoryPortalCache<K, V> memoryPortalCache :
126                                    _memoryPortalCaches.values()) {
127    
128                            memoryPortalCache.destroy();
129                    }
130    
131                    aggregatedCacheManagerListener.dispose();
132            }
133    
134            @Override
135            protected void doRemoveCache(String portalCacheName) {
136                    MemoryPortalCache<K, V> memoryPortalCache = _memoryPortalCaches.remove(
137                            portalCacheName);
138    
139                    memoryPortalCache.destroy();
140    
141                    aggregatedCacheManagerListener.notifyCacheRemoved(portalCacheName);
142            }
143    
144            @Override
145            protected PortalCacheManagerConfiguration
146                    getPortalCacheManagerConfiguration() {
147    
148                    Map<CallbackConfiguration, CacheListenerScope>
149                            cacheListenerConfigurations = null;
150                    CallbackConfiguration bootstrapLoaderConfiguration = null;
151    
152                    if (isClusterAware() && PropsValues.CLUSTER_LINK_ENABLED) {
153                            CallbackConfiguration cacheListenerConfiguration =
154                                    new CallbackConfiguration(
155                                            ClusterLinkCallbackFactory.INSTANCE, new Properties());
156    
157                            cacheListenerConfigurations = new HashMap<>();
158    
159                            cacheListenerConfigurations.put(
160                                    cacheListenerConfiguration, CacheListenerScope.ALL);
161    
162                            bootstrapLoaderConfiguration = new CallbackConfiguration(
163                                    ClusterLinkCallbackFactory.INSTANCE, new Properties());
164                    }
165    
166                    return new PortalCacheManagerConfiguration(
167                            null,
168                            new PortalCacheConfiguration(
169                                    PortalCacheConfiguration.DEFAULT_PORTAL_CACHE_NAME,
170                                    cacheListenerConfigurations, bootstrapLoaderConfiguration),
171                            null);
172            }
173    
174            @Override
175            protected String getType() {
176                    return PortalCacheManagerTypes.MEMORY;
177            }
178    
179            @Override
180            protected void initialize() {
181                    super.initialize();
182    
183                    Registry registry = RegistryUtil.getRegistry();
184    
185                    _serviceRegistrar = registry.getServiceRegistrar(
186                            (Class<PortalCacheManager<K, V>>)(Class<?>)
187                                    PortalCacheManager.class);
188    
189                    Map<String, Object> properties = new HashMap<>();
190    
191                    properties.put("portal.cache.manager.name", getName());
192                    properties.put("portal.cache.manager.type", getType());
193    
194                    _serviceRegistrar.registerService(
195                            (Class<PortalCacheManager<K, V>>) (Class<?>)
196                                    PortalCacheManager.class, this, properties);
197            }
198    
199            @Override
200            protected void initPortalCacheManager() {
201                    _memoryPortalCaches = new ConcurrentHashMap<>(
202                            _cacheManagerInitialCapacity);
203    
204                    aggregatedCacheManagerListener.init();
205            }
206    
207            private int _cacheInitialCapacity = 10000;
208            private int _cacheManagerInitialCapacity = 10000;
209            private ConcurrentMap<String, MemoryPortalCache<K, V>> _memoryPortalCaches;
210            private ServiceRegistrar<PortalCacheManager<K, V>> _serviceRegistrar;
211    
212    }