KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > nanocontainer > nanning > NanningComponentAdapterFactory


1 package org.nanocontainer.nanning;
2
3 import org.codehaus.nanning.config.AspectSystem;
4 import org.codehaus.nanning.config.Aspect;
5 import org.codehaus.nanning.AspectInstance;
6 import org.codehaus.nanning.Mixin;
7 import org.picocontainer.extras.DecoratingComponentAdapterFactory;
8 import org.picocontainer.extras.DecoratingComponentAdapter;
9 import org.picocontainer.defaults.*;
10 import org.picocontainer.*;
11
12 import java.io.Serializable JavaDoc;
13 import java.util.Arrays JavaDoc;
14 import java.util.List JavaDoc;
15 import java.util.Collections JavaDoc;
16 import java.util.ArrayList JavaDoc;
17
18 /**
19  * @author Jon Tirsen
20  * @version $Revision: 1.2 $
21  */

22 public class NanningComponentAdapterFactory extends DecoratingComponentAdapterFactory implements Serializable JavaDoc {
23     private AspectSystem aspectSystem;
24
25     public NanningComponentAdapterFactory(AspectSystem aspectSystem,
26                                           ComponentAdapterFactory delegate) {
27         super(delegate);
28         this.aspectSystem = aspectSystem;
29     }
30
31     public NanningComponentAdapterFactory() {
32         this(new AspectSystem(), new DefaultComponentAdapterFactory());
33     }
34
35     public ComponentAdapter createComponentAdapter(Object JavaDoc componentKey,
36                                                    Class JavaDoc componentImplementation,
37                                                    Parameter[] parameters)
38             throws PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
39         ComponentAdapter componentAdapter = super.createComponentAdapter(componentKey, componentImplementation, parameters);
40
41         if (Aspect.class.isAssignableFrom(componentImplementation)) {
42             componentAdapter = new AspectAdapter(componentAdapter, aspectSystem);
43
44         } else if (canBeWeaved(componentImplementation)) {
45             Class JavaDoc componentInterface = getComponentInterface(componentImplementation);
46             componentAdapter = new WeavingAdapter(componentAdapter, aspectSystem, componentInterface);
47         }
48
49         return componentAdapter;
50     }
51
52     private Class JavaDoc getComponentInterface(Class JavaDoc componentImplementation) {
53         return (Class JavaDoc) getAllInterfaces(componentImplementation).get(0);
54     }
55
56     List JavaDoc getAllInterfaces(Class JavaDoc componentImplementation) {
57         if (componentImplementation == null) {
58             return Collections.EMPTY_LIST;
59         }
60         List JavaDoc result = new ArrayList JavaDoc(Arrays.asList(componentImplementation.getInterfaces()));
61         result.addAll(getAllInterfaces(componentImplementation.getSuperclass()));
62         return result;
63     }
64
65     private boolean canBeWeaved(Class JavaDoc componentImplementation) {
66         return getAllInterfaces(componentImplementation).size() == 1;
67     }
68
69     public static class WeavingAdapter extends DecoratingComponentAdapter {
70
71         private final AspectSystem aspectSystem;
72         private Class JavaDoc componentInterface;
73
74         public WeavingAdapter(ComponentAdapter delegate, AspectSystem aspectSystem, Class JavaDoc componentInterface) {
75             super(delegate);
76             this.aspectSystem = aspectSystem;
77             this.componentInterface = componentInterface;
78         }
79
80         public Object JavaDoc getComponentInstance(MutablePicoContainer picoContainer) throws PicoInitializationException, PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
81             Object JavaDoc component = super.getComponentInstance(picoContainer);
82             // TODO Nanning will at the moment only aspectify stuff when it has one and only one interface
83

84             // the trick: set up first mixin manually with the component as target
85
AspectInstance aspectInstance = new AspectInstance(componentInterface);
86             Mixin mixin = new Mixin(componentInterface, component);
87             aspectInstance.addMixin(mixin);
88
89             // let the aspects do its work
90
getAspectSystem().initialize(aspectInstance);
91             component = aspectInstance.getProxy();
92
93             return component;
94         }
95
96         private AspectSystem getAspectSystem() {
97             return aspectSystem;
98         }
99     }
100
101     public static class AspectAdapter extends DecoratingComponentAdapter {
102         private AspectSystem aspectSystem;
103
104         public AspectAdapter(ComponentAdapter delegate, AspectSystem aspectSystem) {
105             super(delegate);
106             this.aspectSystem = aspectSystem;
107         }
108
109         public Object JavaDoc getComponentInstance(MutablePicoContainer picoContainer)
110                 throws PicoInitializationException, PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
111             Aspect aspect = (Aspect) super.getComponentInstance(picoContainer);
112             getAspectSystem().addAspect(aspect);
113             return aspect;
114         }
115
116         private AspectSystem getAspectSystem() {
117             return aspectSystem;
118         }
119     }
120 }
121
Popular Tags