001 /*****************************************************************************
002 * Copyright (c) PicoContainer Organization. All rights reserved. *
003 * ------------------------------------------------------------------------- *
004 * The software in this package is published under the terms of the BSD *
005 * style license a copy of which has been included with this distribution in *
006 * the LICENSE.txt file. *
007 * *
008 * Idea by Rachel Davies, Original code by various *
009 *****************************************************************************/
010 package org.nanocontainer.aop.dynaop;
011
012 import dynaop.Aspects;
013 import dynaop.Pointcuts;
014 import dynaop.ProxyFactory;
015 import org.nanocontainer.aop.AspectablePicoContainer;
016 import org.nanocontainer.aop.AspectablePicoContainerFactory;
017 import org.nanocontainer.aop.AspectsContainer;
018 import org.nanocontainer.aop.AspectsManager;
019 import org.nanocontainer.aop.defaults.AspectsComponentAdapterFactory;
020 import org.picocontainer.MutablePicoContainer;
021 import org.picocontainer.PicoContainer;
022 import org.picocontainer.defaults.ComponentAdapterFactory;
023 import org.picocontainer.defaults.DefaultComponentAdapterFactory;
024 import org.picocontainer.defaults.DefaultPicoContainer;
025
026 /**
027 * Uses dynaop to create <code>AspectablePicoContainer</code> objects.
028 *
029 * @author Stephen Molitor
030 * @author Mauro Talevi
031 * @version $Revision: 3144 $
032 */
033 public class DynaopAspectablePicoContainerFactory implements AspectablePicoContainerFactory {
034
035 public AspectablePicoContainer createContainer(Class containerClass, AspectsManager aspectsManager,
036 ComponentAdapterFactory componentAdapterFactory, PicoContainer parent) {
037
038 ComponentAdapterFactory aspectsComponentAdapterFactory = new AspectsComponentAdapterFactory(aspectsManager,
039 componentAdapterFactory);
040 MutablePicoContainer pico = createMutablePicoContainer(containerClass, aspectsComponentAdapterFactory, parent);
041 return mixinAspectablePicoContainer(aspectsManager, pico);
042 }
043
044 public AspectablePicoContainer createContainer(Class containerClass,
045 ComponentAdapterFactory componentAdapterFactory, PicoContainer parent) {
046 return createContainer(containerClass, new DynaopAspectsManager(), componentAdapterFactory, parent);
047 }
048
049 public AspectablePicoContainer createContainer(ComponentAdapterFactory componentAdapterFactory, PicoContainer parent) {
050 return createContainer(DefaultPicoContainer.class, componentAdapterFactory, parent);
051 }
052
053 public AspectablePicoContainer createContainer(ComponentAdapterFactory componentAdapterFactory) {
054 return createContainer(componentAdapterFactory, null);
055 }
056
057 public AspectablePicoContainer createContainer(PicoContainer parent) {
058 return createContainer(new DefaultComponentAdapterFactory(), parent);
059 }
060
061 public AspectablePicoContainer createContainer() {
062 return createContainer(new DefaultComponentAdapterFactory());
063 }
064
065 public AspectablePicoContainer makeChildContainer(AspectsManager aspectsManager, AspectablePicoContainer parent) {
066 return mixinAspectablePicoContainer(aspectsManager, parent.makeChildContainer());
067 }
068
069 public AspectablePicoContainer makeChildContainer(AspectablePicoContainer parent) {
070 return makeChildContainer(new DynaopAspectsManager(), parent);
071 }
072
073 private MutablePicoContainer createMutablePicoContainer(Class containerClass, ComponentAdapterFactory caFactory,
074 PicoContainer parent) {
075 MutablePicoContainer temp = new DefaultPicoContainer();
076 temp.registerComponentImplementation(containerClass);
077 temp.registerComponentInstance(ComponentAdapterFactory.class, caFactory);
078 if (parent != null) {
079 temp.registerComponentInstance(PicoContainer.class, parent);
080 }
081 return (MutablePicoContainer) temp.getComponentInstance(containerClass);
082 }
083
084 private AspectablePicoContainer mixinAspectablePicoContainer(AspectsManager aspectsManager,
085 MutablePicoContainer pico) {
086 Aspects aspects = new Aspects();
087 aspects.mixin(Pointcuts.ALL_CLASSES, new Class[]{AspectsContainer.class}, new InstanceMixinFactory(aspectsManager));
088 aspects.interfaces(Pointcuts.ALL_CLASSES, new Class[]{AspectablePicoContainer.class});
089 return (AspectablePicoContainer) ProxyFactory.getInstance(aspects).wrap(pico);
090 }
091
092 }