View Javadoc

1   /*
2    * Copyright 2004-2009 the Seasar Foundation and the Others.
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,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.seasar.cubby.plugins.guice;
17  
18  import java.util.ArrayList;
19  import java.util.Collection;
20  import java.util.Collections;
21  import java.util.HashSet;
22  import java.util.List;
23  import java.util.Set;
24  
25  import org.seasar.cubby.controller.FormatPattern;
26  import org.seasar.cubby.controller.MessagesBehaviour;
27  import org.seasar.cubby.controller.RequestParser;
28  import org.seasar.cubby.controller.impl.DefaultFormatPattern;
29  import org.seasar.cubby.controller.impl.DefaultMessagesBehaviour;
30  import org.seasar.cubby.controller.impl.DefaultRequestParser;
31  import org.seasar.cubby.controller.impl.MultipartRequestParser;
32  import org.seasar.cubby.converter.Converter;
33  import org.seasar.cubby.converter.impl.BigDecimalConverter;
34  import org.seasar.cubby.converter.impl.BigIntegerConverter;
35  import org.seasar.cubby.converter.impl.BooleanConverter;
36  import org.seasar.cubby.converter.impl.ByteArrayFileItemConverter;
37  import org.seasar.cubby.converter.impl.ByteConverter;
38  import org.seasar.cubby.converter.impl.CharacterConverter;
39  import org.seasar.cubby.converter.impl.DateConverter;
40  import org.seasar.cubby.converter.impl.DoubleConverter;
41  import org.seasar.cubby.converter.impl.EnumConverter;
42  import org.seasar.cubby.converter.impl.FloatConverter;
43  import org.seasar.cubby.converter.impl.InputStreamFileItemConverter;
44  import org.seasar.cubby.converter.impl.IntegerConverter;
45  import org.seasar.cubby.converter.impl.LongConverter;
46  import org.seasar.cubby.converter.impl.ShortConverter;
47  import org.seasar.cubby.converter.impl.SqlDateConverter;
48  import org.seasar.cubby.converter.impl.SqlTimeConverter;
49  import org.seasar.cubby.converter.impl.SqlTimestampConverter;
50  import org.seasar.cubby.plugins.guice.spi.GuiceContainerProvider;
51  import org.seasar.cubby.plugins.guice.spi.GuiceConverterProvider;
52  import org.seasar.cubby.plugins.guice.spi.GuicePathResolverProvider;
53  import org.seasar.cubby.plugins.guice.spi.GuiceRequestParserProvider;
54  import org.seasar.cubby.routing.PathResolver;
55  import org.seasar.cubby.spi.BeanDescProvider;
56  import org.seasar.cubby.spi.ContainerProvider;
57  import org.seasar.cubby.spi.ConverterProvider;
58  import org.seasar.cubby.spi.PathResolverProvider;
59  import org.seasar.cubby.spi.RequestParserProvider;
60  import org.seasar.cubby.spi.beans.impl.DefaultBeanDescProvider;
61  
62  import com.google.inject.AbstractModule;
63  import com.google.inject.Inject;
64  import com.google.inject.Injector;
65  import com.google.inject.Module;
66  import com.google.inject.Provider;
67  import com.google.inject.Singleton;
68  import com.google.inject.TypeLiteral;
69  
70  /**
71   * Cubby の設定を行う {@link Module} の抽象クラスです。
72   * 
73   * @author baba
74   */
75  public abstract class AbstractCubbyModule extends AbstractModule {
76  
77  	/**
78  	 * Cubby を構成します。
79  	 */
80  	@Override
81  	public void configure() {
82  		// ContainerProvider
83  		bind(ContainerProvider.class).to(GuiceContainerProvider.class).in(
84  				Singleton.class);
85  
86  		// BeanDescProvider
87  		bind(BeanDescProvider.class).to(DefaultBeanDescProvider.class).in(
88  				Singleton.class);
89  
90  		// RequestParserProvider
91  		bind(new TypeLiteral<Collection<RequestParser>>() {
92  		}).toProvider(new Provider<Collection<RequestParser>>() {
93  
94  			@Inject
95  			public Injector injector;
96  
97  			public Collection<RequestParser> get() {
98  				return createRequestParsers(injector);
99  			}
100 
101 		}).in(Singleton.class);
102 		bind(RequestParserProvider.class).to(GuiceRequestParserProvider.class)
103 				.in(Singleton.class);
104 
105 		// ConverterProvider
106 		bind(new TypeLiteral<Collection<Converter>>() {
107 		}).toProvider(new Provider<Collection<Converter>>() {
108 
109 			@Inject
110 			public Injector injector;
111 
112 			public Collection<Converter> get() {
113 				return createConverters(injector);
114 			}
115 
116 		}).in(Singleton.class);
117 		bind(ConverterProvider.class).to(GuiceConverterProvider.class).in(
118 				Singleton.class);
119 
120 		// PathResolverProvider
121 		bind(PathResolver.class).toInstance(getPathResolver());
122 		bind(PathResolverProvider.class).to(GuicePathResolverProvider.class)
123 				.in(Singleton.class);
124 
125 		configureMessagesBehaviour();
126 		configureFormatPattern();
127 	}
128 
129 	/**
130 	 * リクエスト解析器のコレクションを取得します。
131 	 * <p>
132 	 * 戻り値のコレクションには以下の順序でリクエスト解析器のインスタンスが格納されます。
133 	 * <ol>
134 	 * <li>{@link MultipartRequestParser}</li>
135 	 * <li>{@link DefaultRequestParser}</li>
136 	 * </ol>
137 	 * </p>
138 	 * <p>
139 	 * 要求を解析する場合は、このメソッドの戻り値のコレクションの順序で
140 	 * {@link RequestParser#isParsable(javax.servlet.http.HttpServletRequest)}
141 	 * が評価されて、最初に <code>true</code> を返したインスタンスを解析に使用します。
142 	 * {@link DefaultRequestParser#isParsable(javax.servlet.http.HttpServletRequest)}
143 	 * は、常に <code>true</code> を返すので、 このメソッドをオーバーライドする場合は
144 	 * {@link DefaultRequestParser} のインスタンスがコレクションの最後になるようにしてください。
145 	 * </p>
146 	 * 
147 	 * @param injector
148 	 *            インジェクタ
149 	 * @return リクエスト解析器のコレクション
150 	 */
151 	protected Collection<RequestParser> createRequestParsers(
152 			final Injector injector) {
153 		final List<RequestParser> requestParsers = new ArrayList<RequestParser>();
154 		requestParsers.add(injector.getInstance(MultipartRequestParser.class));
155 		requestParsers.add(injector.getInstance(DefaultRequestParser.class));
156 		return Collections.unmodifiableCollection(requestParsers);
157 	}
158 
159 	/**
160 	 * コンバーターのコレクションを取得します。
161 	 * <p>
162 	 * 戻り値のコレクションには以下のコンバータが含まれます。
163 	 * <ul>
164 	 * <li>{@link BigDecimalConverter}</li>
165 	 * <li>{@link BigIntegerConverter}</li>
166 	 * <li>{@link BooleanConverter}</li>
167 	 * <li>{@link ByteArrayFileItemConverter}</li>
168 	 * <li>{@link ByteConverter}</li>
169 	 * <li>{@link CharacterConverter}</li>
170 	 * <li>{@link DateConverter}</li>
171 	 * <li>{@link DoubleConverter}</li>
172 	 * <li>{@link EnumConverter}</li>
173 	 * <li>{@link FloatConverter}</li>
174 	 * <li>{@link InputStreamFileItemConverter}</li>
175 	 * <li>{@link IntegerConverter}</li>
176 	 * <li>{@link LongConverter}</li>
177 	 * <li>{@link ShortConverter}</li>
178 	 * <li>{@link SqlDateConverter}</li>
179 	 * <li>{@link SqlTimeConverter}</li>
180 	 * <li>{@link SqlTimestampConverter}</li>
181 	 * </ul>
182 	 * </p>
183 	 * 
184 	 * @param injector
185 	 *            インジェクタ
186 	 * @return コンバーターのコレクション
187 	 */
188 	protected Collection<Converter> createConverters(final Injector injector) {
189 		final Set<Converter> converters = new HashSet<Converter>();
190 		converters.add(injector.getInstance(BigDecimalConverter.class));
191 		converters.add(injector.getInstance(BigIntegerConverter.class));
192 		converters.add(injector.getInstance(BooleanConverter.class));
193 		converters.add(injector.getInstance(ByteArrayFileItemConverter.class));
194 		converters.add(injector.getInstance(ByteConverter.class));
195 		converters.add(injector.getInstance(CharacterConverter.class));
196 		converters.add(injector.getInstance(DateConverter.class));
197 		converters.add(injector.getInstance(DoubleConverter.class));
198 		converters.add(injector.getInstance(EnumConverter.class));
199 		converters.add(injector.getInstance(FloatConverter.class));
200 		converters
201 				.add(injector.getInstance(InputStreamFileItemConverter.class));
202 		converters.add(injector.getInstance(IntegerConverter.class));
203 		converters.add(injector.getInstance(LongConverter.class));
204 		converters.add(injector.getInstance(ShortConverter.class));
205 		converters.add(injector.getInstance(SqlDateConverter.class));
206 		converters.add(injector.getInstance(SqlTimeConverter.class));
207 		converters.add(injector.getInstance(SqlTimestampConverter.class));
208 		return Collections.unmodifiableCollection(converters);
209 	}
210 
211 	/**
212 	 * {@link PathResolver} を取得します。
213 	 * <p>
214 	 * サブクラスではアクションを登録済みの {@link PathResolver} を返してください。
215 	 * </p>
216 	 * 
217 	 * @return {@link PathResolver}
218 	 */
219 	protected abstract PathResolver getPathResolver();
220 
221 	/**
222 	 * {@link MessagesBehaviour} を構成します。
223 	 * <p>
224 	 * {@link MessagesBehaviour} を {@link DefaultMessagesBehaviour} にバインドします。
225 	 * </p>
226 	 */
227 	protected void configureMessagesBehaviour() {
228 		bind(MessagesBehaviour.class).to(DefaultMessagesBehaviour.class).in(
229 				Singleton.class);
230 	}
231 
232 	/**
233 	 * {@link FormatPattern} を構成します。
234 	 * <p>
235 	 * {@link FormatPattern} を {@link DefaultFormatPattern} にバインドします。
236 	 * </p>
237 	 */
238 	protected void configureFormatPattern() {
239 		bind(FormatPattern.class).to(DefaultFormatPattern.class).in(
240 				Singleton.class);
241 	}
242 
243 }