1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.seasar.cubby.plugins.guice;
18
19 import java.util.Collection;
20 import java.util.Collections;
21 import java.util.HashSet;
22 import java.util.LinkedHashSet;
23 import java.util.Set;
24
25 import javax.servlet.http.HttpServletRequest;
26
27 import org.seasar.cubby.action.ActionContext;
28 import org.seasar.cubby.action.ActionContextProxy;
29 import org.seasar.cubby.action.ActionErrors;
30 import org.seasar.cubby.action.ActionErrorsProxy;
31 import org.seasar.cubby.action.FlashMap;
32 import org.seasar.cubby.action.FlashMapProxy;
33 import org.seasar.cubby.controller.FormatPattern;
34 import org.seasar.cubby.controller.MessagesBehaviour;
35 import org.seasar.cubby.controller.RequestParser;
36 import org.seasar.cubby.controller.impl.DefaultFormatPattern;
37 import org.seasar.cubby.controller.impl.DefaultMessagesBehaviour;
38 import org.seasar.cubby.controller.impl.DefaultRequestParser;
39 import org.seasar.cubby.controller.impl.MultipartRequestParser;
40 import org.seasar.cubby.converter.Converter;
41 import org.seasar.cubby.converter.impl.BigDecimalConverter;
42 import org.seasar.cubby.converter.impl.BigIntegerConverter;
43 import org.seasar.cubby.converter.impl.BooleanConverter;
44 import org.seasar.cubby.converter.impl.ByteArrayFileItemConverter;
45 import org.seasar.cubby.converter.impl.ByteConverter;
46 import org.seasar.cubby.converter.impl.CharacterConverter;
47 import org.seasar.cubby.converter.impl.DateConverter;
48 import org.seasar.cubby.converter.impl.DoubleConverter;
49 import org.seasar.cubby.converter.impl.EnumConverter;
50 import org.seasar.cubby.converter.impl.FloatConverter;
51 import org.seasar.cubby.converter.impl.InputStreamFileItemConverter;
52 import org.seasar.cubby.converter.impl.IntegerConverter;
53 import org.seasar.cubby.converter.impl.LongConverter;
54 import org.seasar.cubby.converter.impl.ShortConverter;
55 import org.seasar.cubby.converter.impl.SqlDateConverter;
56 import org.seasar.cubby.converter.impl.SqlTimeConverter;
57 import org.seasar.cubby.converter.impl.SqlTimestampConverter;
58 import org.seasar.cubby.plugins.guice.spi.GuiceContainerProvider;
59 import org.seasar.cubby.plugins.guice.spi.GuiceConverterProvider;
60 import org.seasar.cubby.plugins.guice.spi.GuicePathResolverProvider;
61 import org.seasar.cubby.plugins.guice.spi.GuiceRequestParserProvider;
62 import org.seasar.cubby.routing.PathResolver;
63 import org.seasar.cubby.routing.PathTemplateParser;
64 import org.seasar.cubby.routing.impl.PathResolverImpl;
65 import org.seasar.cubby.routing.impl.PathTemplateParserImpl;
66 import org.seasar.cubby.spi.BeanDescProvider;
67 import org.seasar.cubby.spi.ContainerProvider;
68 import org.seasar.cubby.spi.ConverterProvider;
69 import org.seasar.cubby.spi.PathResolverProvider;
70 import org.seasar.cubby.spi.RequestParserProvider;
71 import org.seasar.cubby.spi.beans.impl.DefaultBeanDescProvider;
72 import org.seasar.cubby.util.ActionUtils;
73
74 import com.google.inject.AbstractModule;
75 import com.google.inject.Injector;
76 import com.google.inject.Key;
77 import com.google.inject.Module;
78 import com.google.inject.Provides;
79 import com.google.inject.Singleton;
80 import com.google.inject.TypeLiteral;
81 import com.google.inject.matcher.AbstractMatcher;
82 import com.google.inject.servlet.RequestScoped;
83 import com.google.inject.spi.TypeEncounter;
84 import com.google.inject.spi.TypeListener;
85
86
87
88
89
90
91 public class CubbyModule extends AbstractModule {
92
93
94 private final Set<Class<?>> actionClasses = new LinkedHashSet<Class<?>>();
95
96
97 private final Set<Key<? extends Converter>> converterKeys = new LinkedHashSet<Key<? extends Converter>>();
98
99
100 private final Set<Key<? extends RequestParser>> requestParserKeys = new LinkedHashSet<Key<? extends RequestParser>>();
101
102
103
104
105 @Override
106 public void configure() {
107 configureTypeListeners();
108 configureProviders();
109 configureComponents();
110 configureDefaultRequestParsers();
111 configureDefaultConverters();
112 }
113
114
115
116
117 private void configureTypeListeners() {
118
119 bindListener(new AbstractMatcher<TypeLiteral<?>>() {
120
121 public boolean matches(final TypeLiteral<?> typeLiteral) {
122 final boolean matches = ActionUtils.isActionClass(typeLiteral
123 .getRawType());
124 return matches;
125 }
126
127 }, new TypeListener() {
128
129 public <I> void hear(final TypeLiteral<I> typeLiteral,
130 final TypeEncounter<I> typeEncounter) {
131 final Class<?> actionClass = typeLiteral.getRawType();
132 actionClasses.add(actionClass);
133 }
134
135 });
136
137
138 bindListener(new AbstractMatcher<TypeLiteral<?>>() {
139
140 public boolean matches(final TypeLiteral<?> typeLiteral) {
141 final boolean matches = Converter.class
142 .isAssignableFrom(typeLiteral.getRawType());
143 return matches;
144 }
145
146 }, new TypeListener() {
147
148 public <I> void hear(final TypeLiteral<I> typeLiteral,
149 final TypeEncounter<I> typeEncounter) {
150 final Key<? extends Converter> key = key(typeLiteral);
151 converterKeys.add(key);
152 }
153
154 });
155
156
157 bindListener(new AbstractMatcher<TypeLiteral<?>>() {
158
159 public boolean matches(final TypeLiteral<?> typeLiteral) {
160 final boolean matches = RequestParser.class
161 .isAssignableFrom(typeLiteral.getRawType());
162 return matches;
163 }
164
165 }, new TypeListener() {
166
167 public <I> void hear(final TypeLiteral<I> typeLiteral,
168 final TypeEncounter<I> typeEncounter) {
169 final Key<? extends RequestParser> key = key(typeLiteral);
170 requestParserKeys.add(key);
171 }
172
173 });
174 }
175
176
177
178
179
180
181
182
183
184
185
186 private void configureProviders() {
187 bind(ContainerProvider.class).to(GuiceContainerProvider.class)
188 .asEagerSingleton();
189 bind(BeanDescProvider.class).to(DefaultBeanDescProvider.class)
190 .asEagerSingleton();
191 bind(RequestParserProvider.class).to(GuiceRequestParserProvider.class)
192 .asEagerSingleton();
193 bind(ConverterProvider.class).to(GuiceConverterProvider.class)
194 .asEagerSingleton();
195 bind(PathResolverProvider.class).to(GuicePathResolverProvider.class)
196 .asEagerSingleton();
197 }
198
199
200
201
202
203
204
205
206 private void configureComponents() {
207 bind(MessagesBehaviour.class).to(DefaultMessagesBehaviour.class)
208 .asEagerSingleton();
209 bind(FormatPattern.class).to(DefaultFormatPattern.class)
210 .asEagerSingleton();
211 }
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231 protected void configureDefaultRequestParsers() {
232 bind(MultipartRequestParser.class).asEagerSingleton();
233 bind(DefaultRequestParser.class).asEagerSingleton();
234 }
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261 protected void configureDefaultConverters() {
262 bind(BigDecimalConverter.class).asEagerSingleton();
263 bind(BigIntegerConverter.class).asEagerSingleton();
264 bind(BooleanConverter.class).asEagerSingleton();
265 bind(ByteArrayFileItemConverter.class).asEagerSingleton();
266 bind(ByteConverter.class).asEagerSingleton();
267 bind(CharacterConverter.class).asEagerSingleton();
268 bind(DateConverter.class).asEagerSingleton();
269 bind(DoubleConverter.class).asEagerSingleton();
270 bind(EnumConverter.class).asEagerSingleton();
271 bind(FloatConverter.class).asEagerSingleton();
272 bind(InputStreamFileItemConverter.class).asEagerSingleton();
273 bind(IntegerConverter.class).asEagerSingleton();
274 bind(LongConverter.class).asEagerSingleton();
275 bind(ShortConverter.class).asEagerSingleton();
276 bind(SqlDateConverter.class).asEagerSingleton();
277 bind(SqlTimeConverter.class).asEagerSingleton();
278 bind(SqlTimestampConverter.class).asEagerSingleton();
279 }
280
281
282
283 @Provides
284 @Singleton
285 Collection<RequestParser> provideRequestParsers(final Injector injector) {
286 final Set<RequestParser> requestParsers = new LinkedHashSet<RequestParser>();
287 for (final Key<? extends RequestParser> key : requestParserKeys) {
288 final RequestParser requestParser = injector.getInstance(key);
289 requestParsers.add(requestParser);
290 }
291 return Collections.unmodifiableCollection(requestParsers);
292 }
293
294 @Provides
295 @Singleton
296 Collection<Converter> provideConverters(final Injector injector) {
297 final Set<Converter> converters = new HashSet<Converter>();
298 for (final Key<? extends Converter> key : converterKeys) {
299 final Converter converter = injector.getInstance(key);
300 converters.add(converter);
301 }
302 return Collections.unmodifiableCollection(converters);
303 }
304
305 @Provides
306 @Singleton
307 PathTemplateParser providePathTemplateParser() {
308 final PathTemplateParser pathTemplateParser = new PathTemplateParserImpl();
309 return pathTemplateParser;
310 }
311
312 @Provides
313 @Singleton
314 PathResolver providePathResolver(final PathTemplateParser pathTemplateParser) {
315 final PathResolver pathResolver = new PathResolverImpl(
316 pathTemplateParser);
317 for (final Class<?> actionClass : actionClasses) {
318 pathResolver.add(actionClass);
319 }
320 return pathResolver;
321 }
322
323 @Provides
324 @RequestScoped
325 ActionErrors provideActionErrors(final HttpServletRequest request) {
326 final ActionErrors actionErrors = new ActionErrorsProxy(request);
327 return actionErrors;
328 }
329
330 @Provides
331 @RequestScoped
332 FlashMap provideFlashMap(final HttpServletRequest request) {
333 final FlashMap flashMap = new FlashMapProxy(request);
334 return flashMap;
335 }
336
337 @Provides
338 @RequestScoped
339 ActionContext provideActionContext(final HttpServletRequest request) {
340 final ActionContext actionContext = new ActionContextProxy(request);
341 return actionContext;
342 }
343
344 private static <T> Key<T> key(final TypeLiteral<?> typeLiteral) {
345 @SuppressWarnings("unchecked")
346 final Key<T> key = (Key<T>) Key.get(typeLiteral);
347 return key;
348 }
349
350 }