KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > picocontainer > gems > ThreadLocalComponentAdapter


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 Joerg Schaible *
9  *****************************************************************************/

10 package org.picocontainer.gems;
11
12 import com.thoughtworks.proxy.Invoker;
13 import com.thoughtworks.proxy.ProxyFactory;
14 import com.thoughtworks.proxy.factory.StandardProxyFactory;
15 import com.thoughtworks.proxy.toys.multicast.ClassHierarchyIntrospector;
16
17 import org.picocontainer.ComponentAdapter;
18 import org.picocontainer.PicoContainer;
19 import org.picocontainer.PicoInitializationException;
20 import org.picocontainer.PicoIntrospectionException;
21 import org.picocontainer.defaults.AssignabilityRegistrationException;
22 import org.picocontainer.defaults.CachingComponentAdapter;
23 import org.picocontainer.defaults.DecoratingComponentAdapter;
24 import org.picocontainer.defaults.NotConcreteRegistrationException;
25
26 import java.lang.reflect.InvocationTargetException JavaDoc;
27 import java.lang.reflect.Method JavaDoc;
28 import java.lang.reflect.Proxy JavaDoc;
29
30
31 /**
32  * A {@link ComponentAdapter}that realizes a {@link ThreadLocal}component instance.
33  * <p>
34  * The adapter creates proxy instances, that will create the necessary instances on-the-fly
35  * invoking the methods of the instance. Use this adapter, if you are instantiating your
36  * components in a single thread, but should be different when accessed from different threads.
37  * See {@link org.nanocontainer.proxytoys.ThreadLocalComponentAdapterFactory}for details.
38  * </p>
39  * <p>
40  * Note: Because this implementation uses a {@link Proxy}, you can only access the methods
41  * exposed by the implemented interfaces of your component.
42  * </p>
43  *
44  * @author J&ouml;rg Schaible
45  */

46 public class ThreadLocalComponentAdapter extends DecoratingComponentAdapter {
47
48     private transient Class JavaDoc[] interfaces;
49     private ProxyFactory proxyFactory;
50
51     /**
52      * Construct a ThreadLocalComponentAdapter.
53      *
54      * @param delegate The {@link ComponentAdapter}to delegate.
55      * @param proxyFactory The {@link ProxyFactory}to use.
56      * @throws PicoIntrospectionException Thrown if the component does not implement any
57      * interface.
58      */

59     public ThreadLocalComponentAdapter(final ComponentAdapter delegate, final ProxyFactory proxyFactory)
60             throws PicoIntrospectionException {
61         super(new CachingComponentAdapter(delegate, new ThreadLocalReference()));
62         this.proxyFactory = proxyFactory;
63         interfaces = getInterfaces();
64     }
65
66     /**
67      * Construct a ThreadLocalComponentAdapter using {@link Proxy}instances.
68      *
69      * @param delegate The {@link ComponentAdapter}to delegate.
70      * @throws PicoIntrospectionException Thrown if the component does not implement any
71      * interface.
72      */

73     public ThreadLocalComponentAdapter(final ComponentAdapter delegate) throws PicoIntrospectionException {
74         this(new CachingComponentAdapter(delegate, new ThreadLocalReference()), new StandardProxyFactory());
75     }
76
77     /**
78      * @see org.picocontainer.ComponentAdapter#getComponentInstance(PicoContainer)
79      */

80     public Object JavaDoc getComponentInstance(final PicoContainer pico)
81             throws PicoInitializationException, PicoIntrospectionException, AssignabilityRegistrationException,
82             NotConcreteRegistrationException {
83
84         if (interfaces == null) {
85             interfaces = getInterfaces();
86         }
87
88         final ComponentAdapter delegate = getDelegate();
89         final Invoker invoker = new ThreadLocalInvoker(pico, delegate);
90         return proxyFactory.createProxy(interfaces, invoker);
91     }
92
93     final private Class JavaDoc[] getInterfaces() {
94         final Object JavaDoc componentKey = getComponentKey();
95         final Class JavaDoc[] interfaces;
96         if (componentKey instanceof Class JavaDoc && ((Class JavaDoc) componentKey).isInterface()) {
97             interfaces = new Class JavaDoc[]{(Class JavaDoc) componentKey};
98         } else {
99             interfaces = ClassHierarchyIntrospector.getAllInterfaces(getComponentImplementation());
100         }
101         if (interfaces.length == 0) {
102             throw new PicoIntrospectionException("Can't proxy implementation for "
103                     + getComponentImplementation().getName()
104                     + ". It does not implement any interfaces.");
105         }
106         return interfaces;
107     }
108
109     final static private class ThreadLocalInvoker implements Invoker {
110
111         private final PicoContainer pico;
112         private final ComponentAdapter delegate;
113
114         private ThreadLocalInvoker(final PicoContainer pico, final ComponentAdapter delegate) {
115             this.pico = pico;
116             this.delegate = delegate;
117         }
118
119         /**
120          * @see com.thoughtworks.proxy.Invoker#invoke(java.lang.Object,
121          * java.lang.reflect.Method, java.lang.Object[])
122          */

123         public Object JavaDoc invoke(final Object JavaDoc proxy, final Method JavaDoc method, final Object JavaDoc[] args) throws Throwable JavaDoc {
124             final Object JavaDoc delegatedInstance = delegate.getComponentInstance(pico);
125             try {
126                 return method.invoke(delegatedInstance, args);
127             } catch (final InvocationTargetException JavaDoc e) {
128                 throw e.getTargetException();
129             }
130         }
131     }
132 }
Popular Tags