org.esco.grouperui.tools.cache.MethodCacheInterceptor.java Source code

Java tutorial

Introduction

Here is the source code for org.esco.grouperui.tools.cache.MethodCacheInterceptor.java

Source

/**
 * Copyright (C) 2009 GIP RECIA http://www.recia.fr
 * @Author (C) 2009 GIP RECIA <contact@recia.fr>
 * @Contributor (C) 2009 SOPRA http://www.sopragroup.com/
 * @Contributor (C) 2011 Pierre Legay <pierre.legay@recia.fr>
 *
 * 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.esco.grouperui.tools.cache;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;

/**
 * @author sopragroup
 */
@Aspect
public class MethodCacheInterceptor {
    /**
     * Le logger de la classe.
     */
    private static final Log LOGGER = LogFactory.getLog(MethodCacheInterceptor.class);

    private ICache<ICacheKey<String>, Object> cache;
    private ICacheKey<String> key;

    /**
     * sets cache name to be used.
     * 
     * @param theCache
     *            the cache to set
     */
    public void setCache(final ICache<ICacheKey<String>, Object> theCache) {
        this.cache = theCache;
    }

    /**
     * @param key
     *            the key to set
     */
    public void setKey(final ICacheKey<String> key) {
        this.key = key;
    }

    /**
     * Times repository method invocations and outputs performance results to a
     * Log4J logger.
     * 
     * @param theMethod
     *            The join point representing the intercepted repository method
     * @return The object returned by the target method
     * @throws Throwable
     *             if thrown by the target method
     */
    public Object cache(final ProceedingJoinPoint theMethod) throws Throwable {
        Object result;

        MethodCacheInterceptor.LOGGER.debug("looking for method result in cache");
        ICacheKey<String> cacheKey = this.getCacheKey(theMethod);

        Object element = this.cache.get(cacheKey);
        if (element == null) {
            // call target/sub-interceptor
            MethodCacheInterceptor.LOGGER.debug("calling intercepted method");
            result = theMethod.proceed();

            element = result;
            // cache method result
            MethodCacheInterceptor.LOGGER.debug("caching result");

            this.cache.put(cacheKey, result);
        }
        return element;
    }

    /**
     * creates cache key: targetName.methodName.argument0.argument1...
     * 
     * @param theMethod
     *            les informations sur la mthode dont on cre la cle du cache
     * @return la cle
     */
    private ICacheKey<String> getCacheKey(final ProceedingJoinPoint theMethod) {
        ICacheKey<String> cacheKey = null;
        try {
            cacheKey = this.key.clone();

            Object[] arguments = theMethod.getArgs();
            // Extraction du package + la classes + la mthode separ par
            // des
            // points
            String signature = this.createJoinPointTraceName(theMethod);

            StringBuffer stringbuffer = new StringBuffer();
            stringbuffer.append(signature).append("(");
            if (arguments != null && arguments.length != 0) {
                for (int i = 0; i < arguments.length; i++) {
                    if (arguments[i] == null) {
                        stringbuffer.append("null null");
                    } else {
                        stringbuffer.append(arguments[i].getClass().getName()).append(" ").append(arguments[i]);
                    }
                    if (i < arguments.length - 1) {
                        stringbuffer.append(", ");
                    }
                }
            }

            cacheKey.setKey(stringbuffer.append(")").toString());
        } catch (CloneNotSupportedException e) {
        }

        return cacheKey;
    }

    /**
     * Recupere le nom de la methode sous forme de {@link String}.
     * 
     * @param theJoinPoint
     *            la methode
     * @return le nom sous forme de {@link String}
     */
    private String createJoinPointTraceName(final JoinPoint theJoinPoint) {
        Signature signature = theJoinPoint.getSignature();
        StringBuilder stringb = new StringBuilder();
        stringb.append(signature.getDeclaringType().getName());
        stringb.append('.').append(signature.getName());
        return stringb.toString();
    }
}