Coverage Report - org.seasar.cubby.plugins.guice.CubbyModule
 
Classes in this File Line Coverage Branch Coverage Complexity
CubbyModule
88%
62/70
100%
6/6
0
CubbyModule$1
100%
3/3
N/A
0
CubbyModule$2
100%
4/4
N/A
0
CubbyModule$3
100%
3/3
N/A
0
CubbyModule$4
100%
4/4
N/A
0
CubbyModule$5
100%
3/3
N/A
0
CubbyModule$6
100%
4/4
N/A
0
 
 1  
 /*
 2  
  * Copyright 2004-2010 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  
 
 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  
  * Cubby の設定を行う {@link Module} です。
 88  
  * 
 89  
  * @author baba
 90  
  */
 91  40
 public class CubbyModule extends AbstractModule {
 92  
 
 93  
         /** コンテナに登録されたアクションクラスのセット。 */
 94  1
         private final Set<Class<?>> actionClasses = new LinkedHashSet<Class<?>>();
 95  
 
 96  
         /** コンテナからコンバータを取得するための {@link Key} のセット。 */
 97  1
         private final Set<Key<? extends Converter>> converterKeys = new LinkedHashSet<Key<? extends Converter>>();
 98  
 
 99  
         /** コンテナから要求解析器を取得するための {@link Key} のセット。 */
 100  1
         private final Set<Key<? extends RequestParser>> requestParserKeys = new LinkedHashSet<Key<? extends RequestParser>>();
 101  
 
 102  
         /**
 103  
          * Cubby を構成します。
 104  
          */
 105  
         @Override
 106  
         public void configure() {
 107  1
                 configureTypeListeners();
 108  1
                 configureProviders();
 109  1
                 configureComponents();
 110  1
                 configureDefaultRequestParsers();
 111  1
                 configureDefaultConverters();
 112  1
         }
 113  
 
 114  
         /**
 115  
          * {@link TypeListener} をバインドします。
 116  
          */
 117  
         private void configureTypeListeners() {
 118  
                 // action class listener
 119  1
                 bindListener(new AbstractMatcher<TypeLiteral<?>>() {
 120  
 
 121  
                         public boolean matches(final TypeLiteral<?> typeLiteral) {
 122  39
                                 final boolean matches = ActionUtils.isActionClass(typeLiteral
 123  
                                                 .getRawType());
 124  39
                                 return matches;
 125  
                         }
 126  
 
 127  1
                 }, new TypeListener() {
 128  
 
 129  
                         public <I> void hear(final TypeLiteral<I> typeLiteral,
 130  
                                         final TypeEncounter<I> typeEncounter) {
 131  1
                                 final Class<?> actionClass = typeLiteral.getRawType();
 132  1
                                 actionClasses.add(actionClass);
 133  1
                         }
 134  
 
 135  
                 });
 136  
 
 137  
                 // converter listener
 138  1
                 bindListener(new AbstractMatcher<TypeLiteral<?>>() {
 139  
 
 140  
                         public boolean matches(final TypeLiteral<?> typeLiteral) {
 141  39
                                 final boolean matches = Converter.class
 142  
                                                 .isAssignableFrom(typeLiteral.getRawType());
 143  39
                                 return matches;
 144  
                         }
 145  
 
 146  1
                 }, new TypeListener() {
 147  
 
 148  
                         public <I> void hear(final TypeLiteral<I> typeLiteral,
 149  
                                         final TypeEncounter<I> typeEncounter) {
 150  17
                                 final Key<? extends Converter> key = key(typeLiteral);
 151  17
                                 converterKeys.add(key);
 152  17
                         }
 153  
 
 154  
                 });
 155  
 
 156  
                 // request parser listener
 157  1
                 bindListener(new AbstractMatcher<TypeLiteral<?>>() {
 158  
 
 159  
                         public boolean matches(final TypeLiteral<?> typeLiteral) {
 160  39
                                 final boolean matches = RequestParser.class
 161  
                                                 .isAssignableFrom(typeLiteral.getRawType());
 162  39
                                 return matches;
 163  
                         }
 164  
 
 165  1
                 }, new TypeListener() {
 166  
 
 167  
                         public <I> void hear(final TypeLiteral<I> typeLiteral,
 168  
                                         final TypeEncounter<I> typeEncounter) {
 169  2
                                 final Key<? extends RequestParser> key = key(typeLiteral);
 170  2
                                 requestParserKeys.add(key);
 171  2
                         }
 172  
 
 173  
                 });
 174  1
         }
 175  
 
 176  
         /**
 177  
          * 以下のクラスをバインドします。
 178  
          * <ul>
 179  
          * <li>{@link ContainerProvider}</li>
 180  
          * <li>{@link BeanDescProvider}</li>
 181  
          * <li>{@link RequestParserProvider}</li>
 182  
          * <li>{@link ConverterProvider}</li>
 183  
          * <li>{@link PathResolverProvider}</li>
 184  
          * </ul>
 185  
          */
 186  
         private void configureProviders() {
 187  1
                 bind(ContainerProvider.class).to(GuiceContainerProvider.class)
 188  
                                 .asEagerSingleton();
 189  1
                 bind(BeanDescProvider.class).to(DefaultBeanDescProvider.class)
 190  
                                 .asEagerSingleton();
 191  1
                 bind(RequestParserProvider.class).to(GuiceRequestParserProvider.class)
 192  
                                 .asEagerSingleton();
 193  1
                 bind(ConverterProvider.class).to(GuiceConverterProvider.class)
 194  
                                 .asEagerSingleton();
 195  1
                 bind(PathResolverProvider.class).to(GuicePathResolverProvider.class)
 196  
                                 .asEagerSingleton();
 197  1
         }
 198  
 
 199  
         /**
 200  
          * 以下のクラスをバインドします。
 201  
          * <ul>
 202  
          * <li>{@link MessagesBehaviour}</li>
 203  
          * <li>{@link FormatPattern}</li>
 204  
          * </ul>
 205  
          */
 206  
         private void configureComponents() {
 207  1
                 bind(MessagesBehaviour.class).to(DefaultMessagesBehaviour.class)
 208  
                                 .asEagerSingleton();
 209  1
                 bind(FormatPattern.class).to(DefaultFormatPattern.class)
 210  
                                 .asEagerSingleton();
 211  1
         }
 212  
 
 213  
         /**
 214  
          * 標準の要求解析器をコンテナに登録します。
 215  
          * <p>
 216  
          * 以下の要求解析器を登録します。
 217  
          * <ol>
 218  
          * <li>{@link MultipartRequestParser}</li>
 219  
          * <li>{@link DefaultRequestParser}</li>
 220  
          * </ol>
 221  
          * </p>
 222  
          * <p>
 223  
          * 要求を解析する場合は、コンテナに登録された順序で
 224  
          * {@link RequestParser#isParsable(javax.servlet.http.HttpServletRequest)}
 225  
          * が評価されて、最初に <code>true</code> を返したインスタンスを解析に使用します。
 226  
          * {@link DefaultRequestParser#isParsable(javax.servlet.http.HttpServletRequest)}
 227  
          * は、常に <code>true</code> を返すので、 このメソッドをオーバーライドする場合は
 228  
          * {@link DefaultRequestParser} のインスタンスを最後に登録するようにしてください。
 229  
          * </p>
 230  
          */
 231  
         protected void configureDefaultRequestParsers() {
 232  1
                 bind(MultipartRequestParser.class).asEagerSingleton();
 233  1
                 bind(DefaultRequestParser.class).asEagerSingleton();
 234  1
         }
 235  
 
 236  
         /**
 237  
          * 標準のコンバータをコンテナに登録します。
 238  
          * <p>
 239  
          * 以下のコンバータが登録されます。
 240  
          * <ul>
 241  
          * <li>{@link BigDecimalConverter}</li>
 242  
          * <li>{@link BigIntegerConverter}</li>
 243  
          * <li>{@link BooleanConverter}</li>
 244  
          * <li>{@link ByteArrayFileItemConverter}</li>
 245  
          * <li>{@link ByteConverter}</li>
 246  
          * <li>{@link CharacterConverter}</li>
 247  
          * <li>{@link DateConverter}</li>
 248  
          * <li>{@link DoubleConverter}</li>
 249  
          * <li>{@link EnumConverter}</li>
 250  
          * <li>{@link FloatConverter}</li>
 251  
          * <li>{@link InputStreamFileItemConverter}</li>
 252  
          * <li>{@link IntegerConverter}</li>
 253  
          * <li>{@link LongConverter}</li>
 254  
          * <li>{@link ShortConverter}</li>
 255  
          * <li>{@link SqlDateConverter}</li>
 256  
          * <li>{@link SqlTimeConverter}</li>
 257  
          * <li>{@link SqlTimestampConverter}</li>
 258  
          * </ul>
 259  
          * </p>
 260  
          */
 261  
         protected void configureDefaultConverters() {
 262  1
                 bind(BigDecimalConverter.class).asEagerSingleton();
 263  1
                 bind(BigIntegerConverter.class).asEagerSingleton();
 264  1
                 bind(BooleanConverter.class).asEagerSingleton();
 265  1
                 bind(ByteArrayFileItemConverter.class).asEagerSingleton();
 266  1
                 bind(ByteConverter.class).asEagerSingleton();
 267  1
                 bind(CharacterConverter.class).asEagerSingleton();
 268  1
                 bind(DateConverter.class).asEagerSingleton();
 269  1
                 bind(DoubleConverter.class).asEagerSingleton();
 270  1
                 bind(EnumConverter.class).asEagerSingleton();
 271  1
                 bind(FloatConverter.class).asEagerSingleton();
 272  1
                 bind(InputStreamFileItemConverter.class).asEagerSingleton();
 273  1
                 bind(IntegerConverter.class).asEagerSingleton();
 274  1
                 bind(LongConverter.class).asEagerSingleton();
 275  1
                 bind(ShortConverter.class).asEagerSingleton();
 276  1
                 bind(SqlDateConverter.class).asEagerSingleton();
 277  1
                 bind(SqlTimeConverter.class).asEagerSingleton();
 278  1
                 bind(SqlTimestampConverter.class).asEagerSingleton();
 279  1
         }
 280  
 
 281  
         // Provider methods ------------------------------------------------
 282  
 
 283  
         @Provides
 284  
         @Singleton
 285  
         Collection<RequestParser> provideRequestParsers(final Injector injector) {
 286  1
                 final Set<RequestParser> requestParsers = new LinkedHashSet<RequestParser>();
 287  1
                 for (final Key<? extends RequestParser> key : requestParserKeys) {
 288  2
                         final RequestParser requestParser = injector.getInstance(key);
 289  2
                         requestParsers.add(requestParser);
 290  2
                 }
 291  1
                 return Collections.unmodifiableCollection(requestParsers);
 292  
         }
 293  
 
 294  
         @Provides
 295  
         @Singleton
 296  
         Collection<Converter> provideConverters(final Injector injector) {
 297  1
                 final Set<Converter> converters = new HashSet<Converter>();
 298  1
                 for (final Key<? extends Converter> key : converterKeys) {
 299  17
                         final Converter converter = injector.getInstance(key);
 300  17
                         converters.add(converter);
 301  17
                 }
 302  1
                 return Collections.unmodifiableCollection(converters);
 303  
         }
 304  
 
 305  
         @Provides
 306  
         @Singleton
 307  
         PathTemplateParser providePathTemplateParser() {
 308  0
                 final PathTemplateParser pathTemplateParser = new PathTemplateParserImpl();
 309  0
                 return pathTemplateParser;
 310  
         }
 311  
 
 312  
         @Provides
 313  
         @Singleton
 314  
         PathResolver providePathResolver(final PathTemplateParser pathTemplateParser) {
 315  1
                 final PathResolver pathResolver = new PathResolverImpl(
 316  
                                 pathTemplateParser);
 317  1
                 for (final Class<?> actionClass : actionClasses) {
 318  1
                         pathResolver.add(actionClass);
 319  
                 }
 320  1
                 return pathResolver;
 321  
         }
 322  
 
 323  
         @Provides
 324  
         @RequestScoped
 325  
         ActionErrors provideActionErrors(final HttpServletRequest request) {
 326  0
                 final ActionErrors actionErrors = new ActionErrorsProxy(request);
 327  0
                 return actionErrors;
 328  
         }
 329  
 
 330  
         @Provides
 331  
         @RequestScoped
 332  
         FlashMap provideFlashMap(final HttpServletRequest request) {
 333  0
                 final FlashMap flashMap = new FlashMapProxy(request);
 334  0
                 return flashMap;
 335  
         }
 336  
 
 337  
         @Provides
 338  
         @RequestScoped
 339  
         ActionContext provideActionContext(final HttpServletRequest request) {
 340  0
                 final ActionContext actionContext = new ActionContextProxy(request);
 341  0
                 return actionContext;
 342  
         }
 343  
 
 344  
         private static <T> Key<T> key(final TypeLiteral<?> typeLiteral) {
 345  
                 @SuppressWarnings("unchecked")
 346  19
                 final Key<T> key = (Key<T>) Key.get(typeLiteral);
 347  19
                 return key;
 348  
         }
 349  
 
 350  
 }