All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nanocontainer.aop.dynaop.DynaopAspectsManager Maven / Gradle / Ivy

/*****************************************************************************
 * Copyright (c) PicoContainer Organization. All rights reserved.            *
 * ------------------------------------------------------------------------- *
 * 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.                                                     *
 *                                                                           *
 * Idea by Rachel Davies, Original code by various                           *
 *****************************************************************************/
package org.nanocontainer.aop.dynaop;

import dynaop.Aspects;
import dynaop.Interceptor;
import dynaop.InterceptorFactory;
import dynaop.ProxyFactory;
import dynaop.util.Classes;
import org.aopalliance.intercept.MethodInterceptor;
import org.nanocontainer.aop.AspectsManager;
import org.nanocontainer.aop.ClassPointcut;
import org.nanocontainer.aop.ComponentPointcut;
import org.nanocontainer.aop.MethodPointcut;
import org.nanocontainer.aop.PointcutsFactory;
import org.picocontainer.PicoContainer;

import java.lang.reflect.Method;

/**
 * An AspectsManager implemented using dynaop.
 *
 * @author Stephen Molitor
 * @version $Revision: 3144 $
 */
public class DynaopAspectsManager implements AspectsManager {

    private final Aspects containerAspects;
    private final PointcutsFactory pointcutsFactory;
    private final ContainerLoader containerLoader = new ContainerLoader();
    private final PicoContainer container = PicoContainerProxy.create(containerLoader);
    private final ComponentAspectsCollection componentAspects = new ComponentAspectsCollection();

    /**
     * Creates a new DynaopAspectsManager that will used the
     * given dynaop.Aspects object and pointcuts factory. This
     * constructor might be useful if the containerAspects object
     * contains aspects already configured via dynaop's API, perhaps using
     * dynaop's BeanShell configuration mechanism.
     *
     * @param containerAspects the dyanop.Aspects object used to
     *                         contain the aspects.
     * @param pointcutsFactory the pointcuts factory.
     */
    public DynaopAspectsManager(Aspects containerAspects, PointcutsFactory pointcutsFactory) {
        this.containerAspects = containerAspects;
        this.pointcutsFactory = pointcutsFactory;
    }

    /**
     * Creates a new DynaopAspectsManager that will used the
     * given dynaop.Aspects object. This constructor might be
     * useful if the containerAspects object contains aspects
     * already configured via dynaop's API, perhaps using dynaop's BeanShell
     * configuration mechanism.
     *
     * @param containerAspects the dyanop.Aspects object used to
     *                         contain the aspects.
     */
    public DynaopAspectsManager(Aspects containerAspects) {
        this(containerAspects, new DynaopPointcutsFactory());
    }

    /**
     * Creates a new DynaopAspectsManager that will use the given
     * pointcuts factory.
     *
     * @param pointcutsFactory the pointcuts factory.
     */
    public DynaopAspectsManager(PointcutsFactory pointcutsFactory) {
        this(new Aspects(), pointcutsFactory);
    }

    /**
     * Creates a new DynaopAspectsManager.
     */
    public DynaopAspectsManager() {
        this(new Aspects());
    }

    public void registerInterceptor(ClassPointcut classPointcut, MethodPointcut methodPointcut,
                                    Object interceptorComponentKey) {
        containerAspects.interceptor(getClassPointcut(classPointcut), getMethodPointcut(methodPointcut),
                createInterceptorFactory(interceptorComponentKey));
    }

    public void registerInterceptor(ClassPointcut classPointcut, MethodPointcut methodPointcut,
                                    MethodInterceptor interceptor) {
        containerAspects.interceptor(getClassPointcut(classPointcut), getMethodPointcut(methodPointcut),
                createInterceptor(interceptor));
    }

    public void registerInterceptor(ComponentPointcut componentPointcut, MethodPointcut methodPointcut,
                                    Object interceptorComponentKey) {
        componentAspects.add(new InterceptorComponentAspect(componentPointcut, getMethodPointcut(methodPointcut),
                createInterceptorFactory(interceptorComponentKey)));
    }

    public void registerInterceptor(ComponentPointcut componentPointcut, MethodPointcut methodPointcut,
                                    MethodInterceptor interceptor) {
        componentAspects.add(new InterceptorComponentAspect(componentPointcut, getMethodPointcut(methodPointcut),
                createInterceptor(interceptor)));
    }

    public void registerMixin(ClassPointcut classPointcut, Class mixinClass) {
        registerMixin(classPointcut, Classes.getAllInterfaces(mixinClass), mixinClass);
    }

    public void registerMixin(ClassPointcut classPointcut, Class[] interfaces, Class mixinClass) {
        containerAspects.mixin(getClassPointcut(classPointcut), interfaces, new ContainerSuppliedMixinFactory(container, mixinClass));
    }

    public void registerMixin(ComponentPointcut componentPointcut, Class mixinClass) {
        registerMixin(componentPointcut, Classes.getAllInterfaces(mixinClass), mixinClass);
    }

    public void registerMixin(ComponentPointcut componentPointcut, Class[] interfaces, Class mixinClass) {
        componentAspects.add(new MixinComponentAspect(componentPointcut, interfaces, new ContainerSuppliedMixinFactory(container, mixinClass)));
    }

    public void registerInterfaces(ClassPointcut classPointcut, Class[] interfaces) {
        containerAspects.interfaces(getClassPointcut(classPointcut), interfaces);
    }

    public void registerInterfaces(ComponentPointcut componentPointcut, Class[] interfaces) {
        componentAspects.add(new InterfacesComponentAspect(componentPointcut, interfaces));
    }

    public PointcutsFactory getPointcutsFactory() {
        return pointcutsFactory;
    }

    public Object applyAspects(Object componentKey, Object component, PicoContainer container) {
        containerLoader.setContainer(container);
        Aspects aspects = componentAspects.registerAspects(componentKey, containerAspects);
        return ProxyFactory.getInstance(aspects).wrap(component);
    }

    private dynaop.ClassPointcut getClassPointcut(final ClassPointcut classPointcut) {
        if (classPointcut instanceof dynaop.ClassPointcut) {
            return (dynaop.ClassPointcut) classPointcut;
        }
        return new dynaop.ClassPointcut() {
            public boolean picks(Class clazz) {
                return classPointcut.picks(clazz);
            }
        };
    }

    private dynaop.MethodPointcut getMethodPointcut(final MethodPointcut methodPointcut) {
        if (methodPointcut instanceof dynaop.MethodPointcut) {
            return (dynaop.MethodPointcut) methodPointcut;
        }
        return new dynaop.MethodPointcut() {
            public boolean picks(Method method) {
                return methodPointcut.picks(method);
            }
        };
    }

    private Interceptor createInterceptor(MethodInterceptor methodInterceptor) {
        return new MethodInterceptorAdapter(methodInterceptor);
    }

    private InterceptorFactory createInterceptorFactory(Object interceptorComponent) {
        return new ContainerSuppliedInterceptorFactory(container, interceptorComponent);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy