FiltersModuleBuilder.java revision b4b7f7209570bd75352eb322825ae79392f03978
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.AbstractModule;
19import com.google.inject.Key;
20import com.google.inject.internal.util.Lists;
21import com.google.inject.internal.UniqueAnnotations;
22import java.util.HashMap;
23import java.util.List;
24import java.util.Map;
25import javax.servlet.Filter;
26
27/**
28 * Builds the guice module that binds configured filters, with their
29 * wrapper FilterDefinitions. Is part of the binding EDSL. All Filters
30 * and Servlets are always bound as singletons.
31 *
32 * @author dhanji@gmail.com (Dhanji R. Prasanna)
33 */
34class FiltersModuleBuilder extends AbstractModule {
35  private final List<FilterDefinition> filterDefinitions = Lists.newArrayList();
36  private final List<FilterInstanceBindingEntry> filterInstanceEntries = Lists.newArrayList();
37
38  //invoked on injector config
39  @Override
40  protected void configure() {
41    // Create bindings for filter instances
42    for (FilterInstanceBindingEntry entry : filterInstanceEntries) {
43      bind(entry.key).toInstance(entry.filter);
44    }
45
46    // Bind these filter definitions to a unique random key. Doesn't matter what it is,
47    // coz it's never used.
48    for(FilterDefinition fd : filterDefinitions) {
49      bind(FilterDefinition.class).annotatedWith(UniqueAnnotations.create()).toProvider(fd);
50    }
51  }
52
53  public ServletModule.FilterKeyBindingBuilder filter(List<String> patterns) {
54    return new FilterKeyBindingBuilderImpl(patterns, UriPatternType.SERVLET);
55  }
56
57  public ServletModule.FilterKeyBindingBuilder filterRegex(List<String> regexes) {
58    return new FilterKeyBindingBuilderImpl(regexes, UriPatternType.REGEX);
59  }
60
61  private static class FilterInstanceBindingEntry {
62    final Key<Filter> key;
63    final Filter filter;
64
65    FilterInstanceBindingEntry(Key<Filter> key, Filter filter) {
66      this.key = key;
67      this.filter = filter;
68    }
69  }
70
71  //non-static inner class so it can access state of enclosing module class
72  class FilterKeyBindingBuilderImpl implements ServletModule.FilterKeyBindingBuilder {
73    private final List<String> uriPatterns;
74    private final UriPatternType uriPatternType;
75
76    private FilterKeyBindingBuilderImpl(List<String> uriPatterns, UriPatternType uriPatternType) {
77      this.uriPatterns = uriPatterns;
78      this.uriPatternType = uriPatternType;
79    }
80
81    public void through(Class<? extends Filter> filterKey) {
82      through(Key.get(filterKey));
83    }
84
85    public void through(Key<? extends Filter> filterKey) {
86      through(filterKey, new HashMap<String, String>());
87    }
88
89    public void through(Filter filter) {
90      through(filter, new HashMap<String, String>());
91    }
92
93    public void through(Class<? extends Filter> filterKey,
94        Map<String, String> contextParams) {
95
96      // Careful you don't accidentally make this method recursive, thank you IntelliJ IDEA!
97      through(Key.get(filterKey), contextParams);
98    }
99
100    public void through(Key<? extends Filter> filterKey,
101        Map<String, String> contextParams) {
102      through(filterKey, contextParams, null);
103    }
104
105    private void through(Key<? extends Filter> filterKey,
106        Map<String, String> contextParams,
107        Filter filterInstance) {
108      for (String pattern : uriPatterns) {
109        filterDefinitions.add(
110            new FilterDefinition(pattern, filterKey, UriPatternType.get(uriPatternType, pattern),
111                contextParams, filterInstance));
112      }
113    }
114
115    public void through(Filter filter,
116        Map<String, String> contextParams) {
117      Key<Filter> filterKey = Key.get(Filter.class, UniqueAnnotations.create());
118      filterInstanceEntries.add(new FilterInstanceBindingEntry(filterKey, filter));
119      through(filterKey, contextParams, filter);
120    }
121  }
122}
123