KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > google > inject > ConstructionContext


1 /**
2  * Copyright (C) 2006 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package com.google.inject;
18
19 import java.lang.reflect.InvocationHandler JavaDoc;
20 import java.lang.reflect.InvocationTargetException JavaDoc;
21 import java.lang.reflect.Method JavaDoc;
22 import java.lang.reflect.Proxy JavaDoc;
23 import java.util.ArrayList JavaDoc;
24 import java.util.List JavaDoc;
25
26 /**
27  * Context of a dependency construction. Used to manage circular references.
28  *
29  * @author crazybob@google.com (Bob Lee)
30  */

31 class ConstructionContext<T> {
32
33   T currentReference;
34   boolean constructing;
35
36   List JavaDoc<DelegatingInvocationHandler<T>> invocationHandlers;
37
38   T getCurrentReference() {
39     return currentReference;
40   }
41
42   void removeCurrentReference() {
43     this.currentReference = null;
44   }
45
46   void setCurrentReference(T currentReference) {
47     this.currentReference = currentReference;
48   }
49
50   boolean isConstructing() {
51     return constructing;
52   }
53
54   void startConstruction() {
55     this.constructing = true;
56   }
57
58   void finishConstruction() {
59     this.constructing = false;
60     invocationHandlers = null;
61   }
62
63   Object JavaDoc createProxy(Class JavaDoc<?> expectedType) {
64     // TODO: if I create a proxy which implements all the interfaces of
65
// the implementation type, I'll be able to get away with one proxy
66
// instance (as opposed to one per caller).
67

68     if (!expectedType.isInterface()) {
69       // TODO: Report better error.
70
throw new ConfigurationException("Tried proxying "
71           + expectedType.getName() + " to support a circular dependency, but"
72           + " it is not an interface.");
73     }
74
75     if (invocationHandlers == null) {
76       invocationHandlers = new ArrayList JavaDoc<DelegatingInvocationHandler<T>>();
77     }
78
79     DelegatingInvocationHandler<T> invocationHandler
80         = new DelegatingInvocationHandler<T>();
81     invocationHandlers.add(invocationHandler);
82
83     Object JavaDoc object = Proxy.newProxyInstance(expectedType.getClassLoader(),
84         new Class JavaDoc[] { expectedType }, invocationHandler);
85     return expectedType.cast(object);
86   }
87
88   void setProxyDelegates(T delegate) {
89     if (invocationHandlers != null) {
90       for (DelegatingInvocationHandler<T> handler : invocationHandlers) {
91         handler.setDelegate(delegate);
92       }
93     }
94   }
95
96   static class DelegatingInvocationHandler<T> implements InvocationHandler JavaDoc {
97
98     T delegate;
99
100     public Object JavaDoc invoke(Object JavaDoc proxy, Method JavaDoc method, Object JavaDoc[] args)
101         throws Throwable JavaDoc {
102       if (delegate == null) {
103         throw new IllegalStateException JavaDoc("This is a proxy used to support"
104             + " circular references involving constructors. The object we're"
105             + " proxying is not constructed yet. Please wait until after"
106             + " injection has completed to use this object.");
107       }
108
109       try {
110         // This appears to be not test-covered
111
return method.invoke(delegate, args);
112       }
113       catch (IllegalAccessException JavaDoc e) {
114         throw new RuntimeException JavaDoc(e);
115       }
116       catch (IllegalArgumentException JavaDoc e) {
117         throw new RuntimeException JavaDoc(e);
118       }
119       catch (InvocationTargetException JavaDoc e) {
120         throw e.getTargetException();
121       }
122     }
123
124     void setDelegate(T delegate) {
125       this.delegate = delegate;
126     }
127   }
128 }
129
Popular Tags