001: /**
002: * Copyright (C) 2006 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */package com.google.inject;
016:
017: import com.google.inject.binder.ConstantBindingBuilder;
018: import com.google.inject.binder.AnnotatedBindingBuilder;
019: import com.google.inject.binder.LinkedBindingBuilder;
020: import com.google.inject.binder.AnnotatedConstantBindingBuilder;
021: import com.google.inject.matcher.Matcher;
022: import com.google.inject.spi.SourceProviders;
023: import com.google.inject.util.Objects;
024: import java.lang.annotation.Annotation;
025: import java.lang.reflect.Method;
026: import org.aopalliance.intercept.MethodInterceptor;
027:
028: /**
029: * A support class for {@link Module}s which reduces repetition and results in
030: * a more readable configuration. Simply extend this class, implement {@link
031: * #configure()}, and call the inherited methods which mirror those found in
032: * {@link Binder}. For example:
033: *
034: * <pre>
035: * import static com.google.inject.Names.named;
036: *
037: * public class MyModule extends AbstractModule {
038: * protected void configure() {
039: * bind(Foo.class).to(FooImpl.class).in(Scopes.SINGLETON);
040: * bind(BarImpl.class);
041: * link(Bar.class).to(BarImpl.class);
042: * bindConstant(named("port")).to(8080);
043: * }
044: * }
045: * </pre>
046: *
047: * @author crazybob@google.com (Bob Lee)
048: */
049: public abstract class AbstractModule implements Module {
050:
051: static {
052: SourceProviders.skip(AbstractModule.class);
053: }
054:
055: Binder builder;
056:
057: public final synchronized void configure(Binder builder) {
058: try {
059: if (this .builder != null) {
060: throw new IllegalStateException(
061: "Re-entry is not allowed.");
062: }
063: this .builder = Objects.nonNull(builder, "builder");
064:
065: configure();
066:
067: } finally {
068: this .builder = null;
069: }
070: }
071:
072: /**
073: * Configures a {@link Binder} via the exposed methods.
074: */
075: protected abstract void configure();
076:
077: /**
078: * Gets direct access to the underlying {@code Binder}.
079: */
080: protected Binder binder() {
081: return builder;
082: }
083:
084: /**
085: * @see Binder#bindScope(Class, Scope)
086: */
087: protected void bindScope(
088: Class<? extends Annotation> scopeAnnotation, Scope scope) {
089: builder.bindScope(scopeAnnotation, scope);
090: }
091:
092: /**
093: * @see Binder#bind(Key)
094: */
095: protected <T> LinkedBindingBuilder<T> bind(Key<T> key) {
096: return builder.bind(key);
097: }
098:
099: /**
100: * @see Binder#bind(TypeLiteral)
101: */
102: protected <T> AnnotatedBindingBuilder<T> bind(
103: TypeLiteral<T> typeLiteral) {
104: return builder.bind(typeLiteral);
105: }
106:
107: /**
108: * @see Binder#bind(Class)
109: */
110: protected <T> AnnotatedBindingBuilder<T> bind(Class<T> clazz) {
111: return builder.bind(clazz);
112: }
113:
114: /**
115: * @see Binder#bindConstant()
116: */
117: protected AnnotatedConstantBindingBuilder bindConstant() {
118: return builder.bindConstant();
119: }
120:
121: /**
122: * @see Binder#install(Module)
123: */
124: protected void install(Module module) {
125: builder.install(module);
126: }
127:
128: /**
129: * @see Binder#addError(String, Object[])
130: */
131: protected void addError(String message, Object... arguments) {
132: builder.addError(message, arguments);
133: }
134:
135: /**
136: * @see Binder#addError(Throwable)
137: */
138: protected void addError(Throwable t) {
139: builder.addError(t);
140: }
141:
142: /**
143: * @see Binder#requestStaticInjection(Class[])
144: */
145: protected void requestStaticInjection(Class<?>... types) {
146: builder.requestStaticInjection(types);
147: }
148:
149: /**
150: * @see Binder#bindInterceptor(com.google.inject.matcher.Matcher,
151: * com.google.inject.matcher.Matcher,
152: * org.aopalliance.intercept.MethodInterceptor[])
153: */
154: protected void bindInterceptor(
155: Matcher<? super Class<?>> classMatcher,
156: Matcher<? super Method> methodMatcher,
157: MethodInterceptor... interceptors) {
158: builder.bindInterceptor(classMatcher, methodMatcher,
159: interceptors);
160: }
161: }
|