KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > picocontainer > alternatives > ImplementationHidingComponentAdapter


1 /*****************************************************************************
2  * Copyright (C) PicoContainer Organization. All rights reserved. *
3  * ------------------------------------------------------------------------- *
4  * The software in this package is published under the terms of the BSD *
5  * style license a copy of which has been included with this distribution in *
6  * the LICENSE.txt file. *
7  * *
8  * Original code by *
9  *****************************************************************************/

10 package org.picocontainer.alternatives;
11
12 import org.picocontainer.ComponentAdapter;
13 import org.picocontainer.PicoContainer;
14 import org.picocontainer.PicoInitializationException;
15 import org.picocontainer.PicoIntrospectionException;
16 import org.picocontainer.defaults.AssignabilityRegistrationException;
17 import org.picocontainer.defaults.DecoratingComponentAdapter;
18 import org.picocontainer.defaults.NotConcreteRegistrationException;
19
20 import java.lang.reflect.InvocationHandler JavaDoc;
21 import java.lang.reflect.InvocationTargetException JavaDoc;
22 import java.lang.reflect.Method JavaDoc;
23 import java.lang.reflect.Proxy JavaDoc;
24
25 /**
26  * This component adapter makes it possible to hide the implementation
27  * of a real subject (behind a proxy) provided the key is an interface.
28  * <p/>
29  * This class exists here, because a) it has no deps on external jars, b) dynamic proxy is quite easy.
30  * The user is prompted to look at nanocontainer-proxytoys for alternate and bigger implementations.
31  *
32  * @author Aslak Helles&oslash;y
33  * @author Paul Hammant
34  * @version $Revision: 1882 $
35  * @see org.nanocontainer.proxytoys.HotSwappingComponentAdapter for a more feature-rich version of this class.
36  * @see org.nanocontainer.proxytoys.HotSwappingComponentAdapterFactory
37  * @since 1.1
38  */

39 public class ImplementationHidingComponentAdapter extends DecoratingComponentAdapter {
40     private final boolean strict;
41
42     public ImplementationHidingComponentAdapter(ComponentAdapter delegate, boolean strict) {
43         super(delegate);
44         this.strict = strict;
45     }
46
47     public Object JavaDoc getComponentInstance(final PicoContainer container)
48             throws PicoInitializationException, PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
49
50         Object JavaDoc componentKey = getDelegate().getComponentKey();
51         Class JavaDoc[] classes = null;
52         if (componentKey instanceof Class JavaDoc && ((Class JavaDoc) getDelegate().getComponentKey()).isInterface()) {
53             classes = new Class JavaDoc[]{(Class JavaDoc) getDelegate().getComponentKey()};
54         } else if (componentKey instanceof Class JavaDoc[]) {
55             classes = (Class JavaDoc[]) componentKey;
56         } else {
57             if(strict) {
58                 throw new PicoIntrospectionException("In strict mode, " + getClass().getName() + " only allows components registered with interface keys (java.lang.Class or java.lang.Class[])");
59             }
60             return getDelegate().getComponentInstance(container);
61         }
62
63         Class JavaDoc[] interfaces = verifyInterfacesOnly(classes);
64         return createProxy(interfaces, container);
65     }
66
67     private Object JavaDoc createProxy(Class JavaDoc[] interfaces, final PicoContainer container) {
68         return Proxy.newProxyInstance(getClass().getClassLoader(),
69                 interfaces, new InvocationHandler JavaDoc() {
70                     public Object JavaDoc invoke(final Object JavaDoc proxy, final Method JavaDoc method,
71                                          final Object JavaDoc[] args)
72                             throws Throwable JavaDoc {
73                         try {
74                             Object JavaDoc componentInstance = getDelegate().getComponentInstance(container);
75                             return method.invoke(componentInstance, args);
76                         } catch (final InvocationTargetException JavaDoc ite) {
77                             throw ite.getTargetException();
78                         }
79                     }
80                 });
81     }
82
83     private Class JavaDoc[] verifyInterfacesOnly(Class JavaDoc[] classes) {
84         for (int i = 0; i < classes.length; i++) {
85             if(!classes[i].isInterface()) {
86                 throw new PicoIntrospectionException("Class keys must be interfaces. " + classes[i] + " is not an interface.");
87             }
88         }
89         return classes;
90     }
91
92     // These two methods are copied from ProxyToys' ClassHierarchyIntrospector
93
// TODO: Why? These two are currently not called in the complete Pico/Nano/Micro codebase ...
94
// they just decrease coverage significantly ...
95
/* *
96      * Get all interfaces of the given type.
97      * If the type is a class, the returned list contains any interface, that is
98      * implemented by the class. If the type is an interface, the all
99      * superinterfaces and the interface itself are included.
100      *
101      * @param clazz type to explore.
102      * @return an array with all interfaces. The array may be empty.
103      */

104     /*
105     public static Class[] getAllInterfaces(Class clazz) {
106         Set interfaces = new HashSet();
107         getInterfaces(clazz, interfaces);
108         return (Class[]) interfaces.toArray(new Class[interfaces.size()]);
109     }
110
111     private static void getInterfaces(Class clazz, Set interfaces) {
112         if (clazz.isInterface()) {
113             interfaces.add(clazz);
114         }
115         // Class.getInterfaces will return only the interfaces that are
116         // implemented by the current class. Therefore we must loop up
117         // the hierarchy for the superclasses and the superinterfaces.
118         while (clazz != null) {
119             Class[] implemented = clazz.getInterfaces();
120             for (int i = 0; i < implemented.length; i++) {
121                 if (!interfaces.contains(implemented[i])) {
122                     getInterfaces(implemented[i], interfaces);
123                 }
124             }
125             clazz = clazz.getSuperclass();
126         }
127     }
128     */

129 }
130
Popular Tags