Package org.nanocontainer.aop.dynaop

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

/*****************************************************************************
* 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 org.picocontainer.PicoInitializationException;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;

/**
* Represents the collection of component scoped aspects for a Pico container.
* Manages a collection of <code>ComponentAspect</code> objects, and knows how
* to register their aspects.
*
* @author Stephen Molitor
* @version $Revision: 1631 $
*/
class ComponentAspectsCollection {

    private final Collection componentsAspects = new ArrayList();

    /**
     * Adds a component aspect to this collection.
     *
     * @param componentAspect the component aspect to add.
     */
    void add(ComponentAspect componentAspect) {
        componentsAspects.add(componentAspect);
    }

    /**
     * Registers all aspects whose component pointcut matches
     * <code>componentKey</code>. Creates and returns a new
     * <code>dynaop.Aspects</code> object that is the union of the component
     * and container scoped aspects. By copying the container scoped aspects to
     * a new <code>dynaop.Aspects</code> and adding the component aspects to
     * this new object, we avoid having to create proxies on top of proxies.
     *
     * @param componentKey     the component key.
     * @param containerAspects the container scoped aspects.
     * @return a new <code>dynaop.Aspects</code> object that contains
     *         everything in <code>containerAspects</code> plus the component
     *         aspects that match <code>componentKey</code>.
     */
    Aspects registerAspects(Object componentKey, Aspects containerAspects) {
        Aspects aspects = copyAspects(containerAspects);
        Iterator iterator = componentsAspects.iterator();
        while (iterator.hasNext()) {
            ComponentAspect componentAspect = (ComponentAspect) iterator.next();
            componentAspect.registerAspect(componentKey, aspects);
        }
        return aspects;
    }

    private static Aspects copyAspects(Aspects aspects) {
        // TODO: Lobby Bob Lee to make the Aspects copy constructor public.
        try {
            Constructor constructor = getAspectsCopyConstructor();
            constructor.setAccessible(true);
            return (Aspects) constructor.newInstance(new Object[]{aspects});
        } catch (SecurityException e) {
            throw new PicoInitializationException("security exception copying dynaop.Aspects", e);
        } catch (IllegalArgumentException e) {
            throw new PicoInitializationException("illegal argument passed to dynaop.Aspects copy constructor", e);
        } catch (InstantiationException e) {
            throw new PicoInitializationException("error instantiating dynaop.Aspects copy constructor object", e);
        } catch (IllegalAccessException e) {
            throw new PicoInitializationException("illegal access exception while trying to make dynaop.Aspects copy constructor accessible", e);
        } catch (InvocationTargetException e) {
            throw new PicoInitializationException("dynaop.Aspects copy constructor threw an exception", e);
        }
    }

    private static Constructor getAspectsCopyConstructor() {
        final Class[] params = new Class[]{Aspects.class};
        Constructor[] constructors = Aspects.class.getDeclaredConstructors();
        for (int i = 0; i < constructors.length; ++i) {
            Constructor constructor = constructors[i];
            if (Arrays.equals(params, constructor.getParameterTypes())) {
                return constructor;
            }
        }
        throw new PicoInitializationException("dynaop.Aspects copy constructor not found");
    }

}
TOP

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

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.