/* * Copyright (C) 2014 Google, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package dagger.internal.codegen; import com.google.common.base.Function; import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableSet; import dagger.MembersInjector; import dagger.producers.Producer; import javax.inject.Provider; import static com.google.common.collect.Iterables.getOnlyElement; /** * A mapper for associating a {@link DependencyRequest} to a framework class, dependent on * the type of code to be generated (e.g., for {@link Provider} or {@link Producer}). * * @author Jesse Beder * @since 2.0 */ abstract class DependencyRequestMapper { abstract Class<?> getFrameworkClass(DependencyRequest request); /** * Returns the framework class to use for a collection of requests of the same {@link BindingKey}. * This allows factories to only take a single argument for multiple requests of the same key. */ Class<?> getFrameworkClass(Iterable<DependencyRequest> requests) { ImmutableSet<Class<?>> classes = FluentIterable.from(requests) .transform(new Function<DependencyRequest, Class<?>>() { @Override public Class<?> apply(DependencyRequest request) { return getFrameworkClass(request); } }) .toSet(); if (classes.size() == 1) { return getOnlyElement(classes); } else if (classes.equals(ImmutableSet.of(Producer.class, Provider.class))) { return Provider.class; } else { throw new IllegalStateException("Bad set of framework classes: " + classes); } } private static final class MapperForProvider extends DependencyRequestMapper { @Override public Class<?> getFrameworkClass(DependencyRequest request) { switch (request.kind()) { case INSTANCE: case PROVIDER: case LAZY: return Provider.class; case MEMBERS_INJECTOR: return MembersInjector.class; case PRODUCED: case PRODUCER: throw new IllegalArgumentException(); default: throw new AssertionError(); } } } static final DependencyRequestMapper FOR_PROVIDER = new MapperForProvider(); private static final class MapperForProducer extends DependencyRequestMapper { @Override public Class<?> getFrameworkClass(DependencyRequest request) { switch (request.kind()) { case INSTANCE: case PRODUCED: case PRODUCER: return Producer.class; case PROVIDER: case LAZY: return Provider.class; case MEMBERS_INJECTOR: return MembersInjector.class; default: throw new AssertionError(); } } } static final DependencyRequestMapper FOR_PRODUCER = new MapperForProducer(); }