001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.maven.enforcer.rules;
020
021import javax.inject.Inject;
022import javax.inject.Named;
023
024import java.util.List;
025import java.util.Objects;
026import java.util.function.Predicate;
027
028import org.apache.maven.artifact.Artifact;
029import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
030import org.apache.maven.enforcer.rules.utils.ArtifactUtils;
031import org.apache.maven.execution.MavenSession;
032
033/**
034 * This rule checks that lists of plugins are not included.
035 *
036 * @author <a href="mailto:velo.br@gmail.com">Marvin Froeder</a>
037 */
038@Named("bannedPlugins")
039public final class BannedPlugins extends AbstractStandardEnforcerRule {
040
041    /**
042     * Specify the banned plugins. This can be a list of plugins in the format
043     * <code>groupId[:artifactId][:version]</code>. Any of the sections can be a wildcard
044     * by using '*' (ie group:*:1.0) <br>
045     * The rule will fail if any plugin matches any exclude, unless it also matches
046     * an include rule.
047     */
048    private List<String> excludes = null;
049
050    /**
051     * Specify the allowed plugins. This can be a list of plugins in the format
052     * <code>groupId[:artifactId][:version]</code>. Any of the sections can be a wildcard
053     * by using '*' (ie group:*:1.0) <br>
054     * Includes override the exclude rules. It is meant to allow wide exclusion rules
055     * with wildcards and still allow a
056     * smaller set of includes. <br>
057     * For example, to ban all xerces except xerces-api -&gt; exclude "xerces", include "xerces:xerces-api"
058     */
059    private List<String> includes = null;
060
061    private final MavenSession session;
062
063    @Inject
064    public BannedPlugins(MavenSession session) {
065        this.session = Objects.requireNonNull(session);
066    }
067
068    @Override
069    public void execute() throws EnforcerRuleException {
070        Predicate<Artifact> shouldExclude = ArtifactUtils.prepareDependencyArtifactMatcher(excludes);
071        Predicate<Artifact> shouldInclude = ArtifactUtils.prepareDependencyArtifactMatcher(includes);
072        String result = session.getCurrentProject().getPluginArtifacts().stream()
073                .filter(a -> !(!shouldExclude.test(a) || shouldInclude.test(a)))
074                .collect(
075                        StringBuilder::new,
076                        (messageBuilder, node) ->
077                                messageBuilder.append(node.getId()).append(" <--- banned plugin"),
078                        (m1, m2) -> m1.append(m2.toString()))
079                .toString();
080        if (!result.isEmpty()) {
081            throw new EnforcerRuleException(result);
082        }
083    }
084
085    @Override
086    public String toString() {
087        return String.format("BannedPlugins[excludes=%s, includes=%s]", excludes, includes);
088    }
089}