1/**
2 * Copyright (C) 2008 Google Inc.
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, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.google.inject.servlet;
17
18import com.google.inject.Binder;
19import com.google.inject.Key;
20import com.google.inject.internal.UniqueAnnotations;
21
22import java.util.HashMap;
23import java.util.List;
24import java.util.Map;
25
26import javax.servlet.Filter;
27
28/**
29 * Builds the guice module that binds configured filters, with their
30 * wrapper FilterDefinitions. Is part of the binding EDSL. All Filters
31 * and Servlets are always bound as singletons.
32 *
33 * @author dhanji@gmail.com (Dhanji R. Prasanna)
34 */
35class FiltersModuleBuilder {
36
37  private final Binder binder;
38
39  public FiltersModuleBuilder(Binder binder) {
40    this.binder = binder;
41  }
42
43  public ServletModule.FilterKeyBindingBuilder filter(List<String> patterns) {
44    return new FilterKeyBindingBuilderImpl(patterns, UriPatternType.SERVLET);
45  }
46
47  public ServletModule.FilterKeyBindingBuilder filterRegex(List<String> regexes) {
48    return new FilterKeyBindingBuilderImpl(regexes, UriPatternType.REGEX);
49  }
50
51  //non-static inner class so it can access state of enclosing module class
52  class FilterKeyBindingBuilderImpl implements ServletModule.FilterKeyBindingBuilder {
53    private final List<String> uriPatterns;
54    private final UriPatternType uriPatternType;
55
56    private FilterKeyBindingBuilderImpl(List<String> uriPatterns, UriPatternType uriPatternType) {
57      this.uriPatterns = uriPatterns;
58      this.uriPatternType = uriPatternType;
59    }
60
61    public void through(Class<? extends Filter> filterKey) {
62      through(Key.get(filterKey));
63    }
64
65    public void through(Key<? extends Filter> filterKey) {
66      through(filterKey, new HashMap<String, String>());
67    }
68
69    public void through(Filter filter) {
70      through(filter, new HashMap<String, String>());
71    }
72
73    public void through(Class<? extends Filter> filterKey,
74        Map<String, String> initParams) {
75
76      // Careful you don't accidentally make this method recursive, thank you IntelliJ IDEA!
77      through(Key.get(filterKey), initParams);
78    }
79
80    public void through(Key<? extends Filter> filterKey,
81        Map<String, String> initParams) {
82      through(filterKey, initParams, null);
83    }
84
85    private void through(Key<? extends Filter> filterKey,
86        Map<String, String> initParams,
87        Filter filterInstance) {
88      for (String pattern : uriPatterns) {
89        binder.bind(FilterDefinition.class).annotatedWith(UniqueAnnotations.create()).toProvider(
90            new FilterDefinition(pattern, filterKey, UriPatternType.get(uriPatternType, pattern),
91                initParams, filterInstance));
92      }
93    }
94
95    public void through(Filter filter,
96        Map<String, String> initParams) {
97      Key<Filter> filterKey = Key.get(Filter.class, UniqueAnnotations.create());
98      binder.bind(filterKey).toInstance(filter);
99      through(filterKey, initParams, filter);
100    }
101  }
102}
103