01: /**************************************************************************************
02: * Copyright (c) Jonas BonŽr, Alexandre Vasseur. All rights reserved. *
03: * http://aspectwerkz.codehaus.org *
04: * ---------------------------------------------------------------------------------- *
05: * The software in this package is published under the terms of the LGPL license *
06: * a copy of which has been included with this distribution in the license.txt file. *
07: **************************************************************************************/package examples.caching;
08:
09: import java.util.HashMap;
10: import java.util.Map;
11:
12: import org.codehaus.aspectwerkz.joinpoint.JoinPoint;
13: import org.codehaus.aspectwerkz.joinpoint.MethodSignature;
14: import org.codehaus.aspectwerkz.joinpoint.MethodRtti;
15: import org.codehaus.aspectwerkz.joinpoint.Rtti;
16: import org.codehaus.aspectwerkz.AspectContext;
17: import org.codehaus.aspectwerkz.AspectContext;
18: import org.codehaus.aspectwerkz.AspectContext;
19:
20: /**
21: * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
22: * @Aspect perInstance name=NAME
23: */
24: public class CachingAspect {
25:
26: /**
27: * The cross-cutting info.
28: */
29: private final AspectContext m_info;
30:
31: /**
32: * The cache.
33: */
34: private final Map m_cache = new HashMap();
35:
36: /**
37: * We are interested in cross-cutting info, therefore we have added a constructor that takes a
38: * cross-cutting infor instance as its only parameter.
39: *
40: * @param info the cross-cutting info
41: */
42: public CachingAspect(final AspectContext info) {
43: m_info = info;
44: }
45:
46: /**
47: * @Before call(int examples.caching.Pi.getPiDecimal(int)) && withincode(int
48: * examples.caching.main(String[]))
49: */
50: public void invocationCounter(final JoinPoint joinPoint)
51: throws Throwable {
52: MethodSignature signature = (MethodSignature) joinPoint
53: .getSignature();
54: CacheStatistics.addMethodInvocation(signature.getName(),
55: signature.getParameterTypes());
56: }
57:
58: /**
59: * @Around execution(int examples.caching.Pi.getPiDecimal(int))
60: */
61: public Object cache(final JoinPoint joinPoint) throws Throwable {
62: MethodRtti mrtti = (MethodRtti) joinPoint.getRtti();
63: final Long hash = new Long(calculateHash(mrtti));
64: final Object cachedResult = m_cache.get(hash);
65: if (cachedResult != null) {
66: System.out.println("using cache");
67: CacheStatistics.addCacheInvocation(mrtti.getName(), mrtti
68: .getParameterTypes());
69: System.out.println("parameter: timeout = "
70: + m_info.getParameter("timeout"));
71: return cachedResult;
72: }
73: final Object result = joinPoint.proceed();
74: m_cache.put(hash, result);
75: return result;
76: }
77:
78: // ============ Utility methods ============
79:
80: private long calculateHash(final MethodRtti rtti) {
81: int result = 17;
82: result = 37 * result + rtti.getName().hashCode();
83: Object[] parameters = rtti.getParameterValues();
84: for (int i = 0, j = parameters.length; i < j; i++) {
85: result = 37 * result + parameters[i].hashCode();
86: }
87: return result;
88: }
89: }
|