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