/*
* 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();
}