001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing,
013     * software distributed under the License is distributed on an
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     * KIND, either express or implied.  See the License for the
016     * specific language governing permissions and limitations
017     * under the License.
018     */
019    package org.apache.shiro.cache;
020    
021    import org.apache.shiro.util.CollectionUtils;
022    
023    import java.util.Collection;
024    import java.util.Collections;
025    import java.util.Map;
026    import java.util.Set;
027    
028    /**
029     * A <code>MapCache</code> is a {@link Cache Cache} implementation that uses a backing {@link Map} instance to store
030     * and retrieve cached data.
031     *
032     * @author Les Hazlewood
033     * @since 1.0
034     */
035    public class MapCache<K, V> implements Cache<K, V> {
036    
037        /**
038         * Backing instance.
039         */
040        private final Map<K, V> map;
041    
042        /**
043         * The name of this cache.
044         */
045        private final String name;
046    
047        public MapCache(String name, Map<K, V> backingMap) {
048            if (name == null) {
049                throw new IllegalArgumentException("Cache name cannot be null.");
050            }
051            if (backingMap == null) {
052                throw new IllegalArgumentException("Backing map cannot be null.");
053            }
054            this.name = name;
055            this.map = backingMap;
056        }
057    
058        public V get(K key) throws CacheException {
059            return map.get(key);
060        }
061    
062        public V put(K key, V value) throws CacheException {
063            return map.put(key, value);
064        }
065    
066        public V remove(K key) throws CacheException {
067            return map.remove(key);
068        }
069    
070        public void clear() throws CacheException {
071            map.clear();
072        }
073    
074        public int size() {
075            return map.size();
076        }
077    
078        public Set<K> keys() {
079            Set<K> keys = map.keySet();
080            if (!keys.isEmpty()) {
081                return Collections.unmodifiableSet(keys);
082            }
083            return Collections.emptySet();
084        }
085    
086        public Collection<V> values() {
087            Collection<V> values = map.values();
088            if (!CollectionUtils.isEmpty(values)) {
089                return Collections.unmodifiableCollection(values);
090            }
091            return Collections.emptySet();
092        }
093    
094        public String toString() {
095            return new StringBuilder("MapCache '")
096                    .append(name).append("' (")
097                    .append(map.size())
098                    .append(" entries)")
099                    .toString();
100        }
101    }