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