Package org.nanocontainer.aop.dynaop

Source Code of org.nanocontainer.aop.dynaop.DynaopAspectsManager

/*****************************************************************************
* 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 <code>AspectsManager</code> implemented using dynaop.
*
* @author Stephen Molitor
* @version $Revision: 1631 $
*/
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 <code>DynaopAspectsManager</code> that will used the
     * given <code>dynaop.Aspects</code> object and pointcuts factory. This
     * constructor might be useful if the <code>containerAspects</code> object
     * contains aspects already configured via dynaop's API, perhaps using
     * dynaop's BeanShell configuration mechanism.
     *
     * @param containerAspects the <code>dyanop.Aspects</code> 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 <code>DynaopAspectsManager</code> that will used the
     * given <code>dynaop.Aspects</code> object. This constructor might be
     * useful if the <code>containerAspects</code> object contains aspects
     * already configured via dynaop's API, perhaps using dynaop's BeanShell
     * configuration mechanism.
     *
     * @param containerAspects the <code>dyanop.Aspects</code> object used to
     *                         contain the aspects.
     */
    public DynaopAspectsManager(Aspects containerAspects) {
        this(containerAspects, new DynaopPointcutsFactory());
    }

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

    /**
     * Creates a new <code>DynaopAspectsManager</code>.
     */
    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);
    }

}
TOP

Related Classes of org.nanocontainer.aop.dynaop.DynaopAspectsManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.