001    /**
002     * Copyright (c) 2000-2013 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.CacheListener;
018    import com.liferay.portal.kernel.cache.CacheListenerScope;
019    import com.liferay.portal.kernel.cache.PortalCache;
020    import com.liferay.portal.kernel.concurrent.ConcurrentHashSet;
021    
022    import java.io.Serializable;
023    
024    import java.util.ArrayList;
025    import java.util.Collection;
026    import java.util.List;
027    import java.util.Map;
028    import java.util.Set;
029    import java.util.concurrent.ConcurrentHashMap;
030    
031    /**
032     * @author Brian Wing Shun Chan
033     * @author Edward Han
034     * @author Shuyang Zhou
035     */
036    public class MemoryPortalCache<K extends Serializable, V>
037            implements PortalCache<K, V> {
038    
039            public MemoryPortalCache(String name, int initialCapacity) {
040                    _name = name;
041                    _map = new ConcurrentHashMap<K, V>(initialCapacity);
042            }
043    
044            @Override
045            public void destroy() {
046                    removeAll();
047    
048                    _cacheListeners = null;
049                    _map = null;
050                    _name = null;
051            }
052    
053            @Override
054            public Collection<V> get(Collection<K> keys) {
055                    List<V> values = new ArrayList<V>(keys.size());
056    
057                    for (K key : keys) {
058                            values.add(get(key));
059                    }
060    
061                    return values;
062            }
063    
064            @Override
065            public V get(K key) {
066                    return _map.get(key);
067            }
068    
069            @Override
070            public List<K> getKeys() {
071                    return new ArrayList<K>(_map.keySet());
072            }
073    
074            @Override
075            public String getName() {
076                    return _name;
077            }
078    
079            @Override
080            public void put(K key, V value) {
081                    V oldValue = _map.put(key, value);
082    
083                    notifyPutEvents(key, value, oldValue != null);
084            }
085    
086            @Override
087            public void put(K key, V value, int timeToLive) {
088                    V oldValue = _map.put(key, value);
089    
090                    notifyPutEvents(key, value, oldValue != null);
091            }
092    
093            @Override
094            public void registerCacheListener(CacheListener<K, V> cacheListener) {
095                    _cacheListeners.add(cacheListener);
096            }
097    
098            @Override
099            public void registerCacheListener(
100                    CacheListener<K, V> cacheListener,
101                    CacheListenerScope cacheListenerScope) {
102    
103                    registerCacheListener(cacheListener);
104            }
105    
106            @Override
107            public void remove(K key) {
108                    V value = _map.remove(key);
109    
110                    for (CacheListener<K, V> cacheListener : _cacheListeners) {
111                            cacheListener.notifyEntryRemoved(this, key, value);
112                    }
113            }
114    
115            @Override
116            public void removeAll() {
117                    _map.clear();
118    
119                    for (CacheListener<K, V> cacheListener : _cacheListeners) {
120                            cacheListener.notifyRemoveAll(this);
121                    }
122            }
123    
124            @Override
125            public void unregisterCacheListener(CacheListener<K, V> cacheListener) {
126                    _cacheListeners.remove(cacheListener);
127            }
128    
129            @Override
130            public void unregisterCacheListeners() {
131                    _cacheListeners.clear();
132            }
133    
134            protected void notifyPutEvents(K key, V value, boolean updated) {
135                    if (updated) {
136                            for (CacheListener<K, V> cacheListener : _cacheListeners) {
137                                    cacheListener.notifyEntryUpdated(this, key, value);
138                            }
139                    }
140                    else {
141                            for (CacheListener<K, V> cacheListener : _cacheListeners) {
142                                    cacheListener.notifyEntryPut(this, key, value);
143                            }
144                    }
145            }
146    
147            private Set<CacheListener<K, V>> _cacheListeners =
148                    new ConcurrentHashSet<CacheListener<K, V>>();
149            private Map<K, V> _map;
150            private String _name;
151    
152    }