1 /* 2 * Copyright (C) 2014 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 package dagger.internal.codegen; 17 18 import com.google.common.base.Function; 19 import com.google.common.collect.FluentIterable; 20 import com.google.common.collect.ImmutableSet; 21 import dagger.MembersInjector; 22 import dagger.producers.Producer; 23 import javax.inject.Provider; 24 25 import static com.google.common.collect.Iterables.getOnlyElement; 26 27 /** 28 * A mapper for associating a {@link DependencyRequest} to a framework class, dependent on 29 * the type of code to be generated (e.g., for {@link Provider} or {@link Producer}). 30 * 31 * @author Jesse Beder 32 * @since 2.0 33 */ 34 abstract class DependencyRequestMapper { getFrameworkClass(DependencyRequest request)35 abstract Class<?> getFrameworkClass(DependencyRequest request); 36 37 /** 38 * Returns the framework class to use for a collection of requests of the same {@link BindingKey}. 39 * This allows factories to only take a single argument for multiple requests of the same key. 40 */ getFrameworkClass(Iterable<DependencyRequest> requests)41 Class<?> getFrameworkClass(Iterable<DependencyRequest> requests) { 42 ImmutableSet<Class<?>> classes = FluentIterable.from(requests) 43 .transform(new Function<DependencyRequest, Class<?>>() { 44 @Override public Class<?> apply(DependencyRequest request) { 45 return getFrameworkClass(request); 46 } 47 }) 48 .toSet(); 49 if (classes.size() == 1) { 50 return getOnlyElement(classes); 51 } else if (classes.equals(ImmutableSet.of(Producer.class, Provider.class))) { 52 return Provider.class; 53 } else { 54 throw new IllegalStateException("Bad set of framework classes: " + classes); 55 } 56 } 57 58 private static final class MapperForProvider extends DependencyRequestMapper { getFrameworkClass(DependencyRequest request)59 @Override public Class<?> getFrameworkClass(DependencyRequest request) { 60 switch (request.kind()) { 61 case INSTANCE: 62 case PROVIDER: 63 case LAZY: 64 return Provider.class; 65 case MEMBERS_INJECTOR: 66 return MembersInjector.class; 67 case PRODUCED: 68 case PRODUCER: 69 throw new IllegalArgumentException(); 70 default: 71 throw new AssertionError(); 72 } 73 } 74 } 75 76 static final DependencyRequestMapper FOR_PROVIDER = new MapperForProvider(); 77 78 private static final class MapperForProducer extends DependencyRequestMapper { getFrameworkClass(DependencyRequest request)79 @Override public Class<?> getFrameworkClass(DependencyRequest request) { 80 switch (request.kind()) { 81 case INSTANCE: 82 case PRODUCED: 83 case PRODUCER: 84 return Producer.class; 85 case PROVIDER: 86 case LAZY: 87 return Provider.class; 88 case MEMBERS_INJECTOR: 89 return MembersInjector.class; 90 default: 91 throw new AssertionError(); 92 } 93 } 94 } 95 96 static final DependencyRequestMapper FOR_PRODUCER = new MapperForProducer(); 97 } 98