org.seasar.caching.interceptor.CallCacheInterceptor.java Source code

Java tutorial

Introduction

Here is the source code for org.seasar.caching.interceptor.CallCacheInterceptor.java

Source

/*
 * Copyright 2004-2010 the Seasar Foundation and the Others.
 *
 * 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.
 */
package org.seasar.caching.interceptor;

import java.io.Serializable;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheException;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.lang.SerializationUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.seasar.framework.aop.interceptors.AbstractInterceptor;

/**
 * ?????Interceptor.
 * 
 * Dao???????????.
 * <ul>
 *  <li>getfind????? CallCacheInterceptor?
 *  <li>update,insert,delete,set???? CallCachePurgeInterceptor?
 *  <li>Interceptor???????? ?????
 *  <li>???????CacheManager????????????
 * </ul>
 *
 * ????????
 * <ul>
 *  <li><b>?????singleton?????????.</b>
 *  ?????????????????
 *  ?????????.
 *   <li>???Serializable????????.
 *   <li>??Serializable????????.
 *   <li>????????.
 * </ul> 
 *  
 * @author TANIGUCHI Hikaru
 */
public class CallCacheInterceptor extends AbstractInterceptor {
    private static final Log logger = LogFactory.getLog(CallCacheInterceptor.class);

    private final Cache cache;
    private final CacheManager cacheManager;
    private final String cacheName;

    /**
     * constructor
     * 
     * @param cacheManager ehCache??
     * @param cacheName ??(???)
     * @throws CacheException
     */
    public CallCacheInterceptor(CacheManager cacheManager, String cacheName) throws CacheException {
        this.cacheManager = cacheManager;
        this.cacheName = cacheName;
        if (!cacheManager.cacheExists(cacheName)) {
            cacheManager.addCache(cacheName);
        }
        this.cache = cacheManager.getCache(cacheName);
    }

    public Object invoke(MethodInvocation invocation) throws Throwable {
        // ???Serializable???????????????
        if (!isAllArgumentsSerializable(invocation) || !isReturnTypeSerializable(invocation)) {
            return invocation.proceed();
        }

        // ??Serializable??? CallDescription????????
        CallDescription description = new CallDescription(invocation);
        Element element = cache.get(description);
        if (element != null) {
            Serializable originalResult = element.getValue();

            return SerializationUtils.clone(originalResult);
        } else {
            Object result = invocation.proceed(); // ????????????

            Element insertElement = new Element(description, (Serializable) result);
            cache.put(insertElement);

            return SerializationUtils.clone((Serializable) result);
        }
    }

    protected boolean isReturnTypeSerializable(MethodInvocation invocation) {
        Class returnType = invocation.getMethod().getReturnType();
        return (returnType.isPrimitive() || Serializable.class.isAssignableFrom(returnType));
    }

    protected boolean isAllArgumentsSerializable(MethodInvocation invocation) {
        Object[] arguments = invocation.getArguments();
        for (int i = 0; i < arguments.length; i++) {
            if (!(arguments[i] instanceof Serializable)) {
                return false;
            }
        }
        return true;
    }
}