10910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber/**
20910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * Copyright (C) 2015 Google Inc.
30910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *
40910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * Licensed under the Apache License, Version 2.0 (the "License");
50910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * you may not use this file except in compliance with the License.
60910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * You may obtain a copy of the License at
70910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *
80910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * http://www.apache.org/licenses/LICENSE-2.0
90910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *
100910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * Unless required by applicable law or agreed to in writing, software
110910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * distributed under the License is distributed on an "AS IS" BASIS,
120910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * See the License for the specific language governing permissions and
140910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * limitations under the License.
150910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber */
160910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruberpackage com.google.inject.daggeradapter;
170910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber
180910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruberimport com.google.common.collect.ImmutableSet;
190910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruberimport com.google.inject.Binder;
200910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruberimport com.google.inject.Key;
210910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruberimport com.google.inject.internal.UniqueAnnotations;
220910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruberimport com.google.inject.multibindings.Multibinder;
230910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruberimport com.google.inject.spi.InjectionPoint;
240910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruberimport com.google.inject.spi.ModuleAnnotatedMethodScanner;
250910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber
260910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruberimport dagger.Provides;
270910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruberimport dagger.Provides.Type;
280910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber
290910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruberimport java.lang.annotation.Annotation;
300910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruberimport java.lang.reflect.Method;
310910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruberimport java.util.Set;
320910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber
330910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber/**
340910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * A scanner to process provider methods on Dagger modules.
350910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *
360910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * @author cgruber@google.com (Christian Gruber)
370910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber */
380910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruberfinal class DaggerMethodScanner extends ModuleAnnotatedMethodScanner {
390910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber  static DaggerMethodScanner INSTANCE = new DaggerMethodScanner();
400910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber
410910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber  @Override public Set<? extends Class<? extends Annotation>> annotationClasses() {
420910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber    return ImmutableSet.of(dagger.Provides.class);
430910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber  }
440910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber
450910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber  @Override public <T> Key<T> prepareMethod(
460910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber      Binder binder, Annotation rawAnnotation, Key<T> key, InjectionPoint injectionPoint) {
470910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber    Method providesMethod = (Method) injectionPoint.getMember();
480910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber    Provides annotation = (Provides) rawAnnotation;
490910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber    switch (annotation.type()) {
500910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber      case UNIQUE:
510910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber        return key;
520910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber      case MAP:
530910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber        /* TODO(cgruber) implement map bindings */
540910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber        binder.addError("Map bindings are not yet supported.");
550910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber      case SET:
560910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber        return processSetBinding(binder, key);
570910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber      case SET_VALUES:
580910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber        binder.addError(Type.SET_VALUES.name() + " contributions are not supported by Guice.",
590910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber            providesMethod);
600910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber        return key;
610910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber      default:
620910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber        binder.addError("Unknown @Provides type " + annotation.type() + ".", providesMethod);
630910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber        return key;
640910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber    }
650910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber  }
660910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber
670910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber  private static <T> Key<T> processSetBinding(Binder binder, Key<T> key) {
680910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber    Multibinder<T> setBinder = Multibinder.newSetBinder(binder, key.getTypeLiteral());
690910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber    Key<T> newKey = Key.get(key.getTypeLiteral(), UniqueAnnotations.create());
700910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber    setBinder.addBinding().to(newKey);
710910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber    return newKey;
720910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber  }
730910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber
740910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber  private DaggerMethodScanner() {}
750910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber}