org.springmodules.cache.provider.ehcache.EhCacheFacade.java Source code

Java tutorial

Introduction

Here is the source code for org.springmodules.cache.provider.ehcache.EhCacheFacade.java

Source

/*
 * Created on Nov 10, 2004
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 *
 * Copyright @2007 the original author or authors.
 */
package org.springmodules.cache.provider.ehcache;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import net.sf.ehcache.constructs.blocking.BlockingCache;
import net.sf.ehcache.constructs.blocking.SelfPopulatingCache;
import net.sf.ehcache.constructs.blocking.UpdatingCacheEntryFactory;
import net.sf.ehcache.constructs.blocking.UpdatingSelfPopulatingCache;
import org.springframework.beans.propertyeditors.StringArrayPropertyEditor;
import org.springframework.util.ObjectUtils;
import org.springmodules.cache.CacheException;
import org.springmodules.cache.CachingModel;
import org.springmodules.cache.FatalCacheException;
import org.springmodules.cache.FlushingModel;
import org.springmodules.cache.provider.AbstractCacheProviderFacade;
import org.springmodules.cache.provider.CacheAccessException;
import org.springmodules.cache.provider.CacheModelValidator;
import org.springmodules.cache.provider.CacheNotFoundException;
import org.springmodules.cache.provider.ObjectCannotBeCachedException;
import org.springmodules.cache.provider.ReflectionCacheModelEditor;

import java.beans.PropertyEditor;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * Implementation of
 * <code>{@link org.springmodules.cache.provider.CacheProviderFacade}</code>
 * that uses EHCache as the underlying cache implementation.
 *
 * @author Omar Irbouh
 * @author Alex Ruiz
 */
public final class EhCacheFacade extends AbstractCacheProviderFacade {

    /**
     * Map referencing caches looked up from EHCache CacheManager.
     */
    private Map caches = Collections.synchronizedMap(new HashMap());

    /**
     * EHCache cache manager.
     */
    private CacheManager cacheManager;

    private CacheModelValidator cacheModelValidator;

    /**
     * Constructor.
     */
    public EhCacheFacade() {
        cacheModelValidator = new EhCacheModelValidator();
    }

    /**
     * Returns the validator of cache models. It is always an instance of
     * <code>{@link EhCacheModelValidator}</code>.
     *
     * @return the validator of cache models
     */
    public CacheModelValidator modelValidator() {
        return cacheModelValidator;
    }

    /**
     * @see org.springmodules.cache.provider.CacheProviderFacade#getCachingModelEditor()
     */
    public PropertyEditor getCachingModelEditor() {
        ReflectionCacheModelEditor editor = new ReflectionCacheModelEditor();
        editor.setCacheModelClass(EhCacheCachingModel.class);
        return editor;
    }

    /**
     * @see org.springmodules.cache.provider.CacheProviderFacade#getFlushingModelEditor()
     */
    public PropertyEditor getFlushingModelEditor() {
        Map propertyEditors = new HashMap();
        propertyEditors.put("cacheNames", new StringArrayPropertyEditor());

        ReflectionCacheModelEditor editor = new ReflectionCacheModelEditor();
        editor.setCacheModelClass(EhCacheFlushingModel.class);
        editor.setCacheModelPropertyEditors(propertyEditors);
        return editor;
    }

    /**
     * Sets the EHCache cache manager to use.
     *
     * @param newCacheManager the new cache manager
     */
    public void setCacheManager(CacheManager newCacheManager) {
        cacheManager = newCacheManager;
    }

    /**
     * Returns a EHCache cache from the cache manager.
     *
     * @param model the model containing the name of the cache to retrieve
     * @return the cache retrieved from the cache manager
     * @throws CacheNotFoundException if the cache does not exist
     * @throws CacheAccessException   wrapping any unexpected exception thrown by the cache
     */
    protected Ehcache getCache(CachingModel model) throws CacheNotFoundException, CacheAccessException {
        EhCacheCachingModel ehCacheCachingModel = (EhCacheCachingModel) model;
        String cacheName = ehCacheCachingModel.getCacheName();

        Ehcache cache = (Cache) caches.get(cacheName);
        if (cache == null) {
            cache = decorateCache(getCache(cacheName), ehCacheCachingModel);
        }
        return cache;
    }

    /**
     * Returns a EHCache cache from the cache manager.
     *
     * @param name the name of the cache
     * @return the cache retrieved from the cache manager
     * @throws CacheNotFoundException if the cache does not exist
     * @throws CacheAccessException   wrapping any unexpected exception thrown by the cache
     */
    protected Cache getCache(String name) throws CacheNotFoundException, CacheAccessException {
        Cache cache = null;

        try {
            if (cacheManager.cacheExists(name)) {
                cache = cacheManager.getCache(name);
            }
        } catch (Exception exception) {
            throw new CacheAccessException(exception);
        }

        if (cache == null) {
            throw new CacheNotFoundException(name);
        }

        return cache;
    }

    /**
     * Decorate the given Cache, if necessary.
     * <p>The default implementation simply returns the given cache object as-is.
     *
     * @param cache the raw Cache object, based on the configuration of this FactoryBean
     * @param model the model containing the name of the cache to retrieve
     * @return the (potentially decorated) cache object to be registered with the CacheManager
     */
    protected Ehcache decorateCache(Cache cache, EhCacheCachingModel model) {
        if (model.getCacheEntryFactory() != null) {
            if (model.getCacheEntryFactory() instanceof UpdatingCacheEntryFactory) {
                return new UpdatingSelfPopulatingCache(cache,
                        (UpdatingCacheEntryFactory) model.getCacheEntryFactory());
            } else {
                return new SelfPopulatingCache(cache, model.getCacheEntryFactory());
            }
        }
        if (model.isBlocking()) {
            return new BlockingCache(cache);
        }
        return cache;
    }

    /**
     * @return <code>true</code>. EHCache can only store Serializable objects
     * @see AbstractCacheProviderFacade#isSerializableCacheElementRequired()
     */
    protected boolean isSerializableCacheElementRequired() {
        return true;
    }

    /**
     * Removes all the entries in the caches specified in the given flushing
     * model. The flushing model should be an instance of
     * <code>{@link EhCacheFlushingModel}</code>.
     *
     * @param model the flushing model.
     * @throws CacheNotFoundException if the cache specified in the given model cannot be found.
     * @throws CacheAccessException   wrapping any unexpected exception thrown by the cache.
     * @see AbstractCacheProviderFacade#onFlushCache(FlushingModel)
     */
    protected void onFlushCache(FlushingModel model) throws CacheException {
        EhCacheFlushingModel flushingModel = (EhCacheFlushingModel) model;
        String[] cacheNames = flushingModel.getCacheNames();

        if (!ObjectUtils.isEmpty(cacheNames)) {
            CacheException cacheException = null;
            int nameCount = cacheNames.length;

            try {
                for (int i = 0; i < nameCount; i++) {
                    Cache cache = getCache(cacheNames[i]);
                    cache.removeAll();
                }
            } catch (CacheException exception) {
                cacheException = exception;
            } catch (Exception exception) {
                cacheException = new CacheAccessException(exception);
            }

            if (cacheException != null) {
                throw cacheException;
            }
        }
    }

    /**
     * Retrieves an object stored under the given key from the cache specified in
     * the given caching model. The caching model should be an instance of
     * <code>{@link EhCacheCachingModel}</code>.
     *
     * @param key   the key of the cache entry
     * @param model the caching model
     * @return the object retrieved from the cache. Can be <code>null</code>.
     * @throws CacheNotFoundException if the cache specified in the given model cannot be found.
     * @throws CacheAccessException   wrapping any unexpected exception thrown by the cache.
     * @see AbstractCacheProviderFacade#onGetFromCache(Serializable,CachingModel)
     */
    protected Object onGetFromCache(Serializable key, CachingModel model) throws CacheException {
        Ehcache cache = getCache(model);
        Object cachedObject = null;

        try {
            Element cacheElement = cache.get(key);
            if (cacheElement != null) {
                cachedObject = cacheElement.getValue();
            }

        } catch (Exception exception) {
            throw new CacheAccessException(exception);
        }

        return cachedObject;
    }

    /**
     * Stores the given object under the given key in the cache specified in the
     * given caching model. The caching model should be an instance of
     * <code>{@link EhCacheCachingModel}</code>.
     *
     * @param key   the key of the cache entry
     * @param model the caching model
     * @param obj   the object to store in the cache
     * @throws ObjectCannotBeCachedException if the object to store is not an implementation of
     *                                       <code>java.io.Serializable</code>.
     * @throws CacheNotFoundException      if the cache specified in the given model cannot be found.
     * @throws CacheAccessException        wrapping any unexpected exception thrown by the cache.
     * @see AbstractCacheProviderFacade#onPutInCache(Serializable,CachingModel,
     *Object)
     */
    protected void onPutInCache(Serializable key, CachingModel model, Object obj) throws CacheException {
        Ehcache cache = getCache(model);
        Element newCacheElement = new Element(key, (Serializable) obj);

        try {
            cache.put(newCacheElement);

        } catch (Exception exception) {
            throw new CacheAccessException(exception);
        }
    }

    /**
     * Removes the object stored under the given key from the cache specified in
     * the given caching model. The caching model should be an instance of
     * <code>{@link EhCacheCachingModel}</code>.
     *
     * @param key   the key of the cache entry
     * @param model the caching model
     * @throws CacheNotFoundException if the cache specified in the given model cannot be found.
     * @throws CacheAccessException   wrapping any unexpected exception thrown by the cache.
     * @see AbstractCacheProviderFacade#onRemoveFromCache(Serializable,
     *CachingModel)
     */
    protected void onRemoveFromCache(Serializable key, CachingModel model) throws CacheException {
        Ehcache cache = getCache(model);

        try {
            cache.remove(key);

        } catch (Exception exception) {
            throw new CacheAccessException(exception);
        }
    }

    /**
     * @throws FatalCacheException if the cache manager is <code>null</code>.
     * @see AbstractCacheProviderFacade#validateCacheManager()
     */
    protected void validateCacheManager() throws FatalCacheException {
        assertCacheManagerIsNotNull(cacheManager);
    }

}