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

org.gradle.normalization.internal.DefaultRuntimeClasspathNormalization Maven / Gradle / Ivy

There is a newer version: 8.10.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.normalization.internal;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import org.gradle.api.Action;
import org.gradle.api.GradleException;
import org.gradle.api.internal.changedetection.state.IgnoringResourceEntryFilter;
import org.gradle.api.internal.changedetection.state.IgnoringResourceFilter;
import org.gradle.api.internal.changedetection.state.PropertiesFileFilter;
import org.gradle.api.internal.changedetection.state.ResourceEntryFilter;
import org.gradle.api.internal.changedetection.state.ResourceFilter;
import org.gradle.normalization.MetaInfNormalization;
import org.gradle.normalization.PropertiesFileNormalization;

import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;

public class DefaultRuntimeClasspathNormalization implements RuntimeClasspathNormalizationInternal {
    private final MetaInfNormalization metaInfNormalization = new RuntimeMetaInfNormalization();
    private final EvaluatableFilter resourceFilter = filter(IgnoringResourceFilter::new, ResourceFilter.FILTER_NOTHING);
    private final EvaluatableFilter manifestAttributeResourceFilter = filter(IgnoringResourceEntryFilter::new, ResourceEntryFilter.FILTER_NOTHING);
    private final DefaultPropertiesFileFilter propertyFileFilters = new DefaultPropertiesFileFilter();

    @Override
    public void ignore(String pattern) {
        resourceFilter.ignore(pattern);
    }

    @Override
    public void metaInf(Action configuration) {
        configuration.execute(metaInfNormalization);
    }

    @Override
    public void properties(String pattern, Action configuration) {
        propertyFileFilters.configure(pattern, configuration);
    }

    @Override
    public void properties(Action configuration) {
        properties(PropertiesFileFilter.ALL_PROPERTIES, configuration);
    }

    @Override
    public ResourceFilter getClasspathResourceFilter() {
        return resourceFilter.evaluate();
    }

    @Override
    public ResourceEntryFilter getManifestAttributeResourceEntryFilter() {
        return manifestAttributeResourceFilter.evaluate();
    }

    @Override
    public Map getPropertiesFileFilters() {
        return propertyFileFilters.getFilters();
    }

    public class RuntimeMetaInfNormalization implements MetaInfNormalization {
        @Override
        public void ignoreCompletely() {
            ignore("META-INF/*");
        }

        @Override
        public void ignoreManifest() {
            ignore("META-INF/MANIFEST.MF");
        }

        @Override
        public void ignoreAttribute(String name) {
            manifestAttributeResourceFilter.ignore(name.toLowerCase(Locale.ROOT));
        }

        @Override
        public void ignoreProperty(String name) {
            propertyFileFilters.configure("META-INF/**/*.properties", propertiesFileNormalization -> propertiesFileNormalization.ignoreProperty(name));
        }
    }

    private static  EvaluatableFilter filter(Function, T> initializer, T emptyValue) {
        return new EvaluatableFilter<>(initializer, emptyValue);
    }

    private static class EvaluatableFilter {
        private T value;
        private final Supplier valueSupplier;
        private final ImmutableSet.Builder builder;

        public EvaluatableFilter(Function, T> initializer, T emptyValue) {
            this.builder = ImmutableSet.builder();
            // if there are configured ignores, use the initializer to create the value, otherwise return emptyValue
            this.valueSupplier = () -> Optional.of(builder.build())
                                                .filter(ignores -> !ignores.isEmpty())
                                                .map(initializer)
                                                .orElse(emptyValue);
        }

        public T evaluate() {
            if (value == null) {
                value = valueSupplier.get();
            }
            return value;
        }

        private void checkNotEvaluated() {
            if (value != null) {
                throw new GradleException("Cannot configure runtime classpath normalization after execution started.");
            }
        }

        public void ignore(String ignore) {
            checkNotEvaluated();
            builder.add(ignore);
        }
    }

    private static class DefaultPropertiesFileFilter implements PropertiesFileFilter {
        private final Map> propertyFilters = Maps.newHashMap();
        private Map finalPropertyFilters;

        DefaultPropertiesFileFilter() {
            propertyFilters.put(PropertiesFileFilter.ALL_PROPERTIES, filter(IgnoringResourceEntryFilter::new, ResourceEntryFilter.FILTER_NOTHING));
        }

        @Override
        public Map getFilters() {
            if (finalPropertyFilters == null) {
                ImmutableMap.Builder builder = ImmutableMap.builder();
                propertyFilters.forEach((pattern, filter) -> builder.put(pattern, filter.evaluate()));
                finalPropertyFilters = builder.build();
            }
            return finalPropertyFilters;
        }

        void configure(String pattern, Action configuration) {
            EvaluatableFilter filter;
            if (finalPropertyFilters == null) {
                if (propertyFilters.containsKey(pattern)) {
                    filter = propertyFilters.get(pattern);
                } else {
                    filter = filter(IgnoringResourceEntryFilter::new, ResourceEntryFilter.FILTER_NOTHING);
                    propertyFilters.put(pattern, filter);
                }
                PropertiesFileNormalization normalization = filter::ignore;
                configuration.execute(normalization);
            } else {
                throw new IllegalStateException("Cannot configure runtime classpath normalization after execution started.");
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy