1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.objectfactory.guice;
35
36 import info.magnolia.objectfactory.CandidateParameterResolver;
37 import info.magnolia.objectfactory.ComponentFactory;
38 import info.magnolia.objectfactory.ComponentProvider;
39 import info.magnolia.objectfactory.MgnlInstantiationException;
40 import info.magnolia.objectfactory.NoSuchComponentException;
41 import info.magnolia.objectfactory.ObjectManufacturer;
42 import info.magnolia.objectfactory.ParameterResolver;
43
44 import java.util.Arrays;
45 import java.util.Collections;
46 import java.util.Map;
47
48 import javax.inject.Inject;
49 import javax.inject.Provider;
50
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53
54 import com.google.inject.Injector;
55 import com.google.inject.Key;
56
57
58
59
60
61
62
63
64 public class GuiceComponentProvider implements ComponentProvider {
65
66 private static Logger logger = LoggerFactory.getLogger(GuiceComponentProvider.class);
67
68 @Inject
69 private Injector injector;
70 private ObjectManufacturer manufacturer;
71 private final Map<Key, Class> typeMappings;
72 private final GuiceComponentProvider parentComponentProvider;
73
74 public GuiceComponentProviderice/GuiceComponentProvider.html#GuiceComponentProvider">GuiceComponentProvider(Map<Key, Class> typeMappings, GuiceComponentProvider parentComponentProvider) {
75 this.parentComponentProvider = parentComponentProvider;
76 this.typeMappings = typeMappings;
77 }
78
79 @Override
80 public <T> Class<? extends T> getImplementation(Class<T> type) {
81 return getImplementation(Key.get(type));
82 }
83
84 @SuppressWarnings("unchecked")
85 public <T> Class<? extends T> getImplementation(Key<T> type) {
86 Class<?> implementation = typeMappings.get(type);
87 if (implementation == null) {
88 if (parentComponentProvider != null) {
89 return parentComponentProvider.getImplementation(type);
90 }
91 return (Class<? extends T>) type.getTypeLiteral().getRawType();
92 }
93 if (ComponentFactory.class.isAssignableFrom(implementation)) {
94 return (Class<? extends T>) type.getTypeLiteral().getRawType();
95 }
96 return (Class<? extends T>) implementation;
97 }
98
99 @Override
100 @Deprecated
101 public <T> T getSingleton(Class<T> type) {
102 return getComponent(type);
103 }
104
105 @Override
106 public <T> T getComponent(Class<T> type) throws NoSuchComponentException {
107 if (!GuiceUtils.hasExplicitBindingFor(injector, type)) {
108 throw new NoSuchComponentException("No component configuration for type [" + type.getName() + "] found. Please add a configuration to your module descriptor.");
109 }
110 return injector.getInstance(type);
111 }
112
113 @Override
114 public <T> T newInstance(Class<T> type, Object... parameters) {
115 return newInstanceWithParameterResolvers(type, new CandidateParameterResolver(parameters));
116 }
117
118 @Override
119 public <T> T newInstanceWithParameterResolvers(Class<T> type, ParameterResolver... parameterResolvers) {
120 return newInstanceWithParameterResolvers(Key.get(type), parameterResolvers);
121 }
122
123 public <T> T newInstanceWithParameterResolvers(Key<T> type, ParameterResolver... parameterResolvers) {
124 try {
125 if (this.manufacturer == null) {
126 this.manufacturer = new ObjectManufacturer();
127 }
128 Class<? extends T> implementation = getImplementation(type);
129 if (implementation == null) {
130 logger.warn("Failed to resolve implementation for {}. Perhaps it is not defined. The only types defined for this container are {}.", type, typeMappings);
131 }
132
133 parameterResolvers = concat(parameterResolvers, new GuiceParameterResolver(this));
134 T instance = (T) manufacturer.newInstance(implementation, parameterResolvers);
135 injectMembers(instance);
136 return instance;
137 } catch (Exception e) {
138 throw new MgnlInstantiationException("Failed to create instance of [" + type.getTypeLiteral().getRawType() + "]", e);
139 }
140 }
141
142 private ParameterResolver./info/magnolia/objectfactory/ParameterResolver.html#ParameterResolver">ParameterResolver./info/magnolia/objectfactory/ParameterResolver.html#ParameterResolver">ParameterResolver[] concat(ParameterResolver./info/magnolia/objectfactory/ParameterResolver.html#ParameterResolver">ParameterResolver[] array, ParameterResolver extra) {
143 ParameterResolver[] newArray = Arrays.copyOf(array, array.length + 1);
144 newArray[array.length] = extra;
145 return newArray;
146 }
147
148 public Injector getInjector() {
149 return injector;
150 }
151
152 public <T> Provider<T> getProvider(Class<T> type) {
153 if (!GuiceUtils.hasExplicitBindingFor(injector, type)) {
154 return null;
155 }
156 return injector.getProvider(type);
157 }
158
159 public void injectMembers(Object instance) {
160 injector.injectMembers(instance);
161 }
162
163 public final Map<Key, Class> getTypeMappings() {
164 return Collections.unmodifiableMap(this.typeMappings);
165 }
166
167 public void destroy() {
168
169
170
171
172
173
174
175
176
177 }
178
179 @Override
180 public GuiceComponentProvider getParent() {
181 return parentComponentProvider;
182 }
183 }