001    package org.apache.commons.ognl.internal;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information       
007     * regarding copyright ownership.  The ASF licenses this file  
008     * to you under the Apache License, Version 2.0 (the           
009     * "License"); you may not use this file except in compliance  
010     * with the License.  You may obtain a copy of the License at  
011     *                                                             
012     *   http://www.apache.org/licenses/LICENSE-2.0                
013     *                                                             
014     * Unless required by applicable law or agreed to in writing,  
015     * software distributed under the License is distributed on an 
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY      
017     * KIND, either express or implied.  See the License for the   
018     * specific language governing permissions and limitations     
019     * under the License.
020     */
021    
022    /*
023     * $Id: ConcurrentHashMapCache.java 1194950 2011-10-29 17:52:20Z mcucchiara $
024     */
025    import org.apache.commons.ognl.internal.entry.CacheEntryFactory;
026    
027    import java.util.concurrent.ConcurrentHashMap;
028    
029    public class ConcurrentHashMapCache<K, V>
030        implements Cache<K, V>
031    {
032        private ConcurrentHashMap<K, V> cache = new ConcurrentHashMap<K, V>();
033    
034        private CacheEntryFactory<K, V> cacheEntryFactory;
035    
036        public ConcurrentHashMapCache()
037        {
038        }
039    
040        public ConcurrentHashMapCache( CacheEntryFactory<K, V> cacheEntryFactory )
041        {
042            this.cacheEntryFactory = cacheEntryFactory;
043        }
044    
045        public void clear()
046        {
047            cache.clear();
048        }
049    
050        public int getSize()
051        {
052            return cache.size();
053        }
054    
055        public V get( K key )
056            throws CacheException
057        {
058            V v = cache.get( key );
059            if ( shouldCreate( cacheEntryFactory, v ) )
060            {
061                return put( key, cacheEntryFactory.create( key ) );
062            }
063            return v;
064        }
065    
066        protected boolean shouldCreate( CacheEntryFactory<K, V> cacheEntryFactory, V v )
067            throws CacheException
068        {
069            if ( cacheEntryFactory != null )
070            {
071                if ( v == null )
072                {
073                    return true;
074                }
075            }
076            return false;
077        }
078    
079        public V put( K key, V value )
080        {
081            V collision = cache.putIfAbsent( key, value );
082            if ( collision != null )
083            {
084                return collision;
085            }
086            return value;
087        }
088    
089        public boolean contains( K key )
090        {
091            return this.cache.contains( key );
092        }
093    }