
dagger.internal.SetFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dapper Show documentation
Show all versions of dapper Show documentation
dapper annotations and utils
/*
* Copyright (C) 2014 The Dagger Authors.
*
* 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;
import static dagger.internal.DaggerCollections.hasDuplicates;
import static dagger.internal.DaggerCollections.newHashSetWithExpectedSize;
import static dagger.internal.DaggerCollections.presizedList;
import static dagger.internal.Preconditions.checkNotNull;
import static java.util.Collections.emptySet;
import static java.util.Collections.unmodifiableSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import jakarta.inject.Provider;
/**
* A {@link Factory} implementation used to implement {@link Set} bindings. This factory always
* returns a new {@link Set} instance for each call to {@link #get} (as required by {@link Factory})
* whose elements are populated by subsequent calls to their {@link Provider#get} methods.
*/
public final class SetFactory implements Factory> {
private static final Factory> EMPTY_FACTORY = InstanceFactory.create(emptySet());
@SuppressWarnings({"unchecked", "rawtypes"}) // safe covariant cast
public static Factory> empty() {
return (Factory) EMPTY_FACTORY;
}
/**
* Constructs a new {@link Builder} for a {@link SetFactory} with {@code individualProviderSize}
* individual {@code Provider} and {@code collectionProviderSize} {@code
* Provider>} instances.
*/
public static Builder builder(int individualProviderSize, int collectionProviderSize) {
return new Builder(individualProviderSize, collectionProviderSize);
}
/**
* A builder to accumulate {@code Provider} and {@code Provider>} instances.
* These are only intended to be single-use and from within generated code. Do NOT add
* providers after calling {@link #build()}.
*/
public static final class Builder {
private final List> individualProviders;
private final List>> collectionProviders;
private Builder(int individualProviderSize, int collectionProviderSize) {
individualProviders = presizedList(individualProviderSize);
collectionProviders = presizedList(collectionProviderSize);
}
@SuppressWarnings("unchecked")
public Builder addProvider(Provider extends T> individualProvider) {
assert individualProvider != null : "Codegen error? Null provider";
// TODO(ronshapiro): Store a List extends Provider> and avoid the cast to Provider
individualProviders.add((Provider) individualProvider);
return this;
}
@SuppressWarnings("unchecked")
public Builder addCollectionProvider(
Provider extends Collection extends T>> collectionProvider) {
assert collectionProvider != null : "Codegen error? Null provider";
collectionProviders.add((Provider>) collectionProvider);
return this;
}
public SetFactory build() {
assert !hasDuplicates(individualProviders)
: "Codegen error? Duplicates in the provider list";
assert !hasDuplicates(collectionProviders)
: "Codegen error? Duplicates in the provider list";
return new SetFactory(individualProviders, collectionProviders);
}
}
private final List> individualProviders;
private final List>> collectionProviders;
private SetFactory(
List> individualProviders, List>> collectionProviders) {
this.individualProviders = individualProviders;
this.collectionProviders = collectionProviders;
}
/**
* Returns a {@link Set} that contains the elements given by each of the providers.
*
* @throws NullPointerException if any of the delegate {@link Set} instances or elements therein
* are {@code null}
*/
@Override
public Set get() {
int size = individualProviders.size();
// Profiling revealed that this method was a CPU-consuming hotspot in some applications, so
// these loops were changed to use c-style for. Versus enhanced for-each loops, C-style for is
// faster for ArrayLists, at least through Java 8.
List> providedCollections =
new ArrayList>(collectionProviders.size());
for (int i = 0, c = collectionProviders.size(); i < c; i++) {
Collection providedCollection = collectionProviders.get(i).get();
size += providedCollection.size();
providedCollections.add(providedCollection);
}
Set providedValues = newHashSetWithExpectedSize(size);
for (int i = 0, c = individualProviders.size(); i < c; i++) {
providedValues.add(checkNotNull(individualProviders.get(i).get()));
}
for (int i = 0, c = providedCollections.size(); i < c; i++) {
for (T element : providedCollections.get(i)) {
providedValues.add(checkNotNull(element));
}
}
return unmodifiableSet(providedValues);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy