/** * Aspect which keeps a cache of all intercepted * invocations in a globally accessible cache. * * Though demonstrative for testing and learning purposes, this is a very * poor example of a real-world auditing mechanism. In a production environment, * the copy-on-write nature of the cache will degrade geometrically * over time, and additionally we export mutable views * (ie. {@link InvocationContext#setParameters(Object[])}) to callers * of {@link CachingAuditor#getInvocations()}. *

* @author <a href="mailto:andrew.rubinger@jboss.org">ALR</a> * @version $Revision: $ */ public class CachingAuditor { //--------------------------------------------------------------------------|| // Class Members -----------------------------------------------------------|| //--------------------------------------------------------------------------|| /** * Logger */ private static final Logger log = Logger.getLogger(CachingAuditor.class.get Name()); /** * Cached invocations; must be in a thread-safe implementation because this member * is shared by all interceptor instances, which are linked to bean instances. Though * each bean instance is guaranteed to be used by only one thread at once, many bean instances * may be executed concurrently. */ private static final List<AuditedInvocation> invocations = new CopyOnWrite ArrayList<AuditedInvocation>(); //--------------------------------------------------------------------------|| // Instance Members --------------------------------------------------------|| //--------------------------------------------------------------------------|| /** * The current EJB Context; will either be injected by the EJB Container or * manually populated by unit tests */ @Resource SessionContext beanContext; //--------------------------------------------------------------------------|| // Required Implementations ------------------------------------------------|| //--------------------------------------------------------------------------|| /** * Caches the intercepted invocation in an auditable view such that * it may later be obtained */ @AroundInvoke public Object audit(final InvocationContext invocationContext) throws Exception { // Precondition checks assert invocationContext != null : "Context was not specified"; // Obtain the caller Principal caller;