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 }