/************************************************************************************** * Copyright (c) Jonas Bon�r, Alexandre Vasseur. All rights reserved. * * http://aspectwerkz.codehaus.org * * ---------------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD-style license * * a copy of which has been included with this distribution in the license.txt file. * **************************************************************************************/ package examples.caching; import java.util.HashMap; import java.util.Map; import org.codehaus.aspectwerkz.joinpoint.JoinPoint; import org.codehaus.aspectwerkz.joinpoint.MethodRtti; import org.codehaus.aspectwerkz.joinpoint.Rtti; /** * Sample that calculates fibonacci number naively, uses an inner aspect to cache redundant * calculations. * * @author <a href="mailto:jboner@codehaus.org">Jonas Bon�r </a> */ public class Fibonacci { // naive implementation of fibonacci, resulting in a lot // of redundant calculations of the same values. public static int fib(int n) { if (n < 2) { System.err.println(n + "."); return 1; } else { System.err.print(n + ","); return fib(n - 1) + fib(n - 2); } } public static void main(String[] args) { System.err.println("fib(10) = " + fib(10)); } /** * Caches redundant fibonacci calculations. */ public static class FibonacciCacheAspect { private Map m_cache = new HashMap(); /** * @Around execution(int *..Fibonacci.fib(int)) */ public Object cache(final JoinPoint joinPoint) throws Throwable { MethodRtti mrtti = (MethodRtti) joinPoint.getRtti(); Integer parameter = (Integer) mrtti.getParameterValues()[0]; Integer cachedValue = (Integer) m_cache.get(parameter); if (cachedValue == null) { Object newValue = joinPoint.proceed(); // not found => calculate m_cache.put(parameter, newValue); return newValue; } else { System.out.println("using cache: " + cachedValue); return cachedValue; // return cached value } } } }