All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.gradle.api.internal.provider.AbstractCollectionProperty Maven / Gradle / Ivy

There is a newer version: 8.11.1
Show newest version
/*
 * Copyright 2017 the original author or 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 org.gradle.api.internal.provider;

import com.google.common.base.Preconditions;
import org.gradle.api.internal.provider.Collectors.ElementFromProvider;
import org.gradle.api.internal.provider.Collectors.ElementsFromArray;
import org.gradle.api.internal.provider.Collectors.ElementsFromCollection;
import org.gradle.api.internal.provider.Collectors.ElementsFromCollectionProvider;
import org.gradle.api.internal.provider.Collectors.EmptyCollection;
import org.gradle.api.internal.provider.Collectors.NoValueCollector;
import org.gradle.api.internal.provider.Collectors.SingleElement;
import org.gradle.api.internal.tasks.TaskDependencyResolveContext;
import org.gradle.api.provider.HasMultipleValues;
import org.gradle.api.provider.Provider;

import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

public abstract class AbstractCollectionProperty> extends AbstractProperty implements CollectionPropertyInternal {
    private static final EmptyCollection EMPTY_COLLECTION = new EmptyCollection();
    private static final NoValueCollector NO_VALUE_COLLECTOR = new NoValueCollector();
    private final Class collectionType;
    private final Class elementType;
    private final ValueCollector valueCollector;
    private Collector value;
    private List> collectors = new LinkedList>();

    AbstractCollectionProperty(Class collectionType, Class elementType) {
        applyDefaultValue();
        this.collectionType = collectionType;
        this.elementType = elementType;
        valueCollector = new ValidatingValueCollector(collectionType, elementType, ValueSanitizers.forType(elementType));
    }

    /**
     * Creates an immutable collection from the given current values of this property.
     */
    protected abstract C fromValue(Collection values);

    @Override
    public void add(final T element) {
        Preconditions.checkNotNull(element, String.format("Cannot add a null element to a property of type %s.", collectionType.getSimpleName()));
        if (!beforeMutate()) {
            return;
        }
        addCollector(new SingleElement(element));
    }

    @Override
    public void add(final Provider providerOfElement) {
        if (!beforeMutate()) {
            return;
        }
        addCollector(new ElementFromProvider(Providers.internal(providerOfElement)));
    }

    @Override
    public void addAll(T... elements) {
        if (!beforeMutate()) {
            return;
        }
        addCollector(new ElementsFromArray(elements));
    }

    @Override
    public void addAll(Iterable elements) {
        if (!beforeMutate()) {
            return;
        }
        addCollector(new ElementsFromCollection(elements));
    }

    @Override
    public void addAll(Provider> provider) {
        if (!beforeMutate()) {
            return;
        }
        addCollector(new ElementsFromCollectionProvider(Providers.internal(provider)));
    }

    private void addCollector(Collector collector) {
        collectors.add(collector);
        afterMutate();
    }

    @Nullable
    @Override
    public Class getType() {
        return (Class) collectionType;
    }

    @Override
    public Class getElementType() {
        return elementType;
    }

    @Override
    public boolean maybeVisitBuildDependencies(TaskDependencyResolveContext context) {
        if (super.maybeVisitBuildDependencies(context)) {
            return true;
        }

        boolean visitedAll = true;
        if (!value.maybeVisitBuildDependencies(context)) {
            visitedAll = false;
        }
        for (Collector collector : collectors) {
            if (!collector.maybeVisitBuildDependencies(context)) {
                visitedAll = false;
            }
        }
        return visitedAll;
    }

    @Override
    public boolean isPresent() {
        beforeRead();
        if (!value.present()) {
            return false;
        }
        for (Collector collector : collectors) {
            if (!collector.present()) {
                return false;
            }
        }
        return true;
    }

    @Override
    public C get() {
        beforeRead();
        List values = new ArrayList(1 + collectors.size());
        value.collectInto(valueCollector, values);
        for (Collector collector : collectors) {
            collector.collectInto(valueCollector, values);
        }
        return fromValue(values);
    }

    @Nullable
    @Override
    public C getOrNull() {
        beforeRead();
        return doGetOrNull();
    }

    @Nullable
    private C doGetOrNull() {
        List values = new ArrayList(1 + collectors.size());
        if (!value.maybeCollectInto(valueCollector, values)) {
            return null;
        }
        for (Collector collector : collectors) {
            if (!collector.maybeCollectInto(valueCollector, values)) {
                return null;
            }
        }
        return fromValue(values);
    }

    @Override
    public void setFromAnyValue(Object object) {
        if (object instanceof Provider) {
            set((Provider) object);
        } else {
            if (object != null && !(object instanceof Iterable)) {
                throw new IllegalArgumentException(String.format("Cannot set the value of a property of type %s using an instance of type %s.", collectionType.getName(), object.getClass().getName()));
            }
            set((Iterable) object);
        }
    }

    @Override
    public void set(@Nullable final Iterable elements) {
        if (!beforeMutate()) {
            return;
        }
        if (elements == null) {
            set((Collector) NO_VALUE_COLLECTOR);
        } else {
            set(new ElementsFromCollection(elements));
        }
    }

    @Override
    public void set(final Provider> provider) {
        if (!beforeMutate()) {
            return;
        }
        if (provider == null) {
            throw new IllegalArgumentException("Cannot set the value of a property using a null provider.");
        }
        ProviderInternal> p = Providers.internal(provider);
        if (p.getType() != null && !Iterable.class.isAssignableFrom(p.getType())) {
            throw new IllegalArgumentException(String.format("Cannot set the value of a property of type %s using a provider of type %s.", collectionType.getName(), p.getType().getName()));
        }
        if (p instanceof CollectionPropertyInternal) {
            CollectionPropertyInternal collectionProp = (CollectionPropertyInternal) p;
            if (!elementType.isAssignableFrom(collectionProp.getElementType())) {
                throw new IllegalArgumentException(String.format("Cannot set the value of a property of type %s with element type %s using a provider with element type %s.", collectionType.getName(), elementType.getName(), collectionProp.getElementType().getName()));
            }
        }
        set(new ElementsFromCollectionProvider(p));
    }

    @Override
    public HasMultipleValues empty() {
        if (!beforeMutate()) {
            return this;
        }
        set((Collector) EMPTY_COLLECTION);
        return this;
    }

    @Override
    protected void applyDefaultValue() {
        value = (Collector) EMPTY_COLLECTION;
        collectors.clear();
    }

    @Override
    protected void makeFinal() {
        C collection = doGetOrNull();
        if (collection != null) {
            set(new ElementsFromCollection(collection));
        } else {
            set((Collector) NO_VALUE_COLLECTOR);
        }
    }

    private void set(Collector collector) {
        collectors.clear();
        value = collector;
        afterMutate();
    }

    @Override
    public HasMultipleValues convention(Iterable elements) {
        if (shouldApplyConvention()) {
            value = new ElementsFromCollection(elements);
            collectors.clear();
        }
        return this;
    }

    @Override
    public HasMultipleValues convention(Provider> provider) {
        if (shouldApplyConvention()) {
            value = new ElementsFromCollectionProvider(Providers.internal(provider));
            collectors.clear();
        }
        return this;
    }

    @Override
    public String toString() {
        List values = new ArrayList(1 + collectors.size());
        values.add(value.toString());
        for (Collector collector : collectors) {
            values.add(collector.toString());
        }
        return String.format("%s(%s, %s)", collectionType.getSimpleName().toLowerCase(), elementType, values);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy