• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (C) 2006 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  */
16 
17 package com.google.inject;
18 
19 import static com.google.common.base.Preconditions.checkNotNull;
20 import static com.google.common.base.Preconditions.checkState;
21 
22 import com.google.inject.binder.AnnotatedBindingBuilder;
23 import com.google.inject.binder.AnnotatedConstantBindingBuilder;
24 import com.google.inject.binder.LinkedBindingBuilder;
25 import com.google.inject.matcher.Matcher;
26 import com.google.inject.spi.Message;
27 import com.google.inject.spi.ProvisionListener;
28 import com.google.inject.spi.TypeConverter;
29 import com.google.inject.spi.TypeListener;
30 
31 import java.lang.annotation.Annotation;
32 import java.lang.reflect.Method;
33 
34 /**
35  * A support class for {@link Module}s which reduces repetition and results in
36  * a more readable configuration. Simply extend this class, implement {@link
37  * #configure()}, and call the inherited methods which mirror those found in
38  * {@link Binder}. For example:
39  *
40  * <pre>
41  * public class MyModule extends AbstractModule {
42  *   protected void configure() {
43  *     bind(Service.class).to(ServiceImpl.class).in(Singleton.class);
44  *     bind(CreditCardPaymentService.class);
45  *     bind(PaymentService.class).to(CreditCardPaymentService.class);
46  *     bindConstant().annotatedWith(Names.named("port")).to(8080);
47  *   }
48  * }
49  * </pre>
50  *
51  * @author crazybob@google.com (Bob Lee)
52  */
53 public abstract class AbstractModule implements Module {
54 
55   Binder binder;
56 
configure(Binder builder)57   public final synchronized void configure(Binder builder) {
58     checkState(this.binder == null, "Re-entry is not allowed.");
59 
60     this.binder = checkNotNull(builder, "builder");
61     try {
62       configure();
63     }
64     finally {
65       this.binder = null;
66     }
67   }
68 
69   /**
70    * Configures a {@link Binder} via the exposed methods.
71    */
configure()72   protected abstract void configure();
73 
74   /**
75    * Gets direct access to the underlying {@code Binder}.
76    */
binder()77   protected Binder binder() {
78     checkState(binder != null, "The binder can only be used inside configure()");
79     return binder;
80   }
81 
82   /**
83    * @see Binder#bindScope(Class, Scope)
84    */
bindScope(Class<? extends Annotation> scopeAnnotation, Scope scope)85   protected void bindScope(Class<? extends Annotation> scopeAnnotation,
86       Scope scope) {
87     binder().bindScope(scopeAnnotation, scope);
88   }
89 
90   /**
91    * @see Binder#bind(Key)
92    */
bind(Key<T> key)93   protected <T> LinkedBindingBuilder<T> bind(Key<T> key) {
94     return binder().bind(key);
95   }
96 
97   /**
98    * @see Binder#bind(TypeLiteral)
99    */
bind(TypeLiteral<T> typeLiteral)100   protected <T> AnnotatedBindingBuilder<T> bind(TypeLiteral<T> typeLiteral) {
101     return binder().bind(typeLiteral);
102   }
103 
104   /**
105    * @see Binder#bind(Class)
106    */
bind(Class<T> clazz)107   protected <T> AnnotatedBindingBuilder<T> bind(Class<T> clazz) {
108     return binder().bind(clazz);
109   }
110 
111   /**
112    * @see Binder#bindConstant()
113    */
bindConstant()114   protected AnnotatedConstantBindingBuilder bindConstant() {
115     return binder().bindConstant();
116   }
117 
118   /**
119    * @see Binder#install(Module)
120    */
install(Module module)121   protected void install(Module module) {
122     binder().install(module);
123   }
124 
125   /**
126    * @see Binder#addError(String, Object[])
127    */
addError(String message, Object... arguments)128   protected void addError(String message, Object... arguments) {
129     binder().addError(message, arguments);
130   }
131 
132   /**
133    * @see Binder#addError(Throwable)
134    */
addError(Throwable t)135   protected void addError(Throwable t) {
136     binder().addError(t);
137   }
138 
139   /**
140    * @see Binder#addError(Message)
141    * @since 2.0
142    */
addError(Message message)143   protected void addError(Message message) {
144     binder().addError(message);
145   }
146 
147   /**
148    * @see Binder#requestInjection(Object)
149    * @since 2.0
150    */
requestInjection(Object instance)151   protected void requestInjection(Object instance) {
152     binder().requestInjection(instance);
153   }
154 
155   /**
156    * @see Binder#requestStaticInjection(Class[])
157    */
requestStaticInjection(Class<?>.... types)158   protected void requestStaticInjection(Class<?>... types) {
159     binder().requestStaticInjection(types);
160   }
161 
162   /*if[AOP]*/
163   /**
164    * @see Binder#bindInterceptor(com.google.inject.matcher.Matcher,
165    *  com.google.inject.matcher.Matcher,
166    *  org.aopalliance.intercept.MethodInterceptor[])
167    */
bindInterceptor(Matcher<? super Class<?>> classMatcher, Matcher<? super Method> methodMatcher, org.aopalliance.intercept.MethodInterceptor... interceptors)168   protected void bindInterceptor(Matcher<? super Class<?>> classMatcher,
169       Matcher<? super Method> methodMatcher,
170       org.aopalliance.intercept.MethodInterceptor... interceptors) {
171     binder().bindInterceptor(classMatcher, methodMatcher, interceptors);
172   }
173   /*end[AOP]*/
174 
175   /**
176    * Adds a dependency from this module to {@code key}. When the injector is
177    * created, Guice will report an error if {@code key} cannot be injected.
178    * Note that this requirement may be satisfied by implicit binding, such as
179    * a public no-arguments constructor.
180    *
181    * @since 2.0
182    */
requireBinding(Key<?> key)183   protected void requireBinding(Key<?> key) {
184     binder().getProvider(key);
185   }
186 
187   /**
188    * Adds a dependency from this module to {@code type}. When the injector is
189    * created, Guice will report an error if {@code type} cannot be injected.
190    * Note that this requirement may be satisfied by implicit binding, such as
191    * a public no-arguments constructor.
192    *
193    * @since 2.0
194    */
requireBinding(Class<?> type)195   protected void requireBinding(Class<?> type) {
196     binder().getProvider(type);
197   }
198 
199   /**
200    * @see Binder#getProvider(Key)
201    * @since 2.0
202    */
getProvider(Key<T> key)203   protected <T> Provider<T> getProvider(Key<T> key) {
204     return binder().getProvider(key);
205   }
206 
207   /**
208    * @see Binder#getProvider(Class)
209    * @since 2.0
210    */
getProvider(Class<T> type)211   protected <T> Provider<T> getProvider(Class<T> type) {
212     return binder().getProvider(type);
213   }
214 
215   /**
216    * @see Binder#convertToTypes
217    * @since 2.0
218    */
convertToTypes(Matcher<? super TypeLiteral<?>> typeMatcher, TypeConverter converter)219   protected void convertToTypes(Matcher<? super TypeLiteral<?>> typeMatcher,
220       TypeConverter converter) {
221     binder().convertToTypes(typeMatcher, converter);
222   }
223 
224   /**
225    * @see Binder#currentStage()
226    * @since 2.0
227    */
currentStage()228   protected Stage currentStage() {
229     return binder().currentStage();
230   }
231 
232   /**
233    * @see Binder#getMembersInjector(Class)
234    * @since 2.0
235    */
getMembersInjector(Class<T> type)236   protected <T> MembersInjector<T> getMembersInjector(Class<T> type) {
237     return binder().getMembersInjector(type);
238   }
239 
240   /**
241    * @see Binder#getMembersInjector(TypeLiteral)
242    * @since 2.0
243    */
getMembersInjector(TypeLiteral<T> type)244   protected <T> MembersInjector<T> getMembersInjector(TypeLiteral<T> type) {
245     return binder().getMembersInjector(type);
246   }
247 
248   /**
249    * @see Binder#bindListener(com.google.inject.matcher.Matcher,
250    *  com.google.inject.spi.TypeListener)
251    * @since 2.0
252    */
bindListener(Matcher<? super TypeLiteral<?>> typeMatcher, TypeListener listener)253   protected void bindListener(Matcher<? super TypeLiteral<?>> typeMatcher,
254       TypeListener listener) {
255     binder().bindListener(typeMatcher, listener);
256   }
257 
258   /**
259    * @see Binder#bindListener(Matcher, ProvisionListener...)
260    * @since 4.0
261    */
bindListener(Matcher<? super Binding<?>> bindingMatcher, ProvisionListener... listener)262   protected void bindListener(Matcher<? super Binding<?>> bindingMatcher,
263       ProvisionListener... listener) {
264     binder().bindListener(bindingMatcher, listener);
265   }
266 }
267