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