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