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.utils;
020
021import java.util.ArrayList;
022import java.util.Collections;
023import java.util.List;
024import java.util.Optional;
025
026import org.apache.maven.model.InputLocation;
027import org.apache.maven.model.InputLocationTracker;
028import org.apache.maven.model.Plugin;
029import org.apache.maven.model.ReportPlugin;
030
031/**
032 * @author Brian Fox
033 *
034 */
035public class PluginWrapper {
036    private final String groupId;
037
038    private final String artifactId;
039
040    private final String version;
041
042    private final InputLocationTracker locationTracker;
043
044    public static List<PluginWrapper> addAll(List<? extends InputLocationTracker> plugins, boolean banMavenDefaults) {
045        if (plugins.isEmpty()) {
046            return Collections.emptyList();
047        }
048
049        List<PluginWrapper> results = new ArrayList<>(plugins.size());
050        for (InputLocationTracker o : plugins) {
051            // null or true means it is most assumed a Maven default
052            if (banMavenDefaults
053                    && (isVersionFromDefaultLifecycleBindings(o).orElse(true)
054                            || isVersionFromSuperpom(o).orElse(true))) {
055                continue;
056            }
057
058            if (o instanceof Plugin) {
059                results.add(new PluginWrapper((Plugin) o));
060            } else {
061                if (o instanceof ReportPlugin) {
062                    results.add(new PluginWrapper((ReportPlugin) o));
063                }
064            }
065        }
066        return results;
067    }
068
069    /**
070     * Whether the version is coming from the default lifecycle bindings.
071     * Cannot be determined before Maven 3.6.1
072     *
073     * @param o either Plugin or ReportPlugin
074     * @return null if untraceable, otherwise its matching value
075     * @see <a href="https://issues.apache.org/jira/browse/MNG-6600">MNG-6600</a>
076     */
077    public static Optional<Boolean> isVersionFromDefaultLifecycleBindings(InputLocationTracker o) {
078        InputLocation versionLocation = o.getLocation("version");
079        if (versionLocation == null) {
080            return Optional.empty();
081        }
082
083        String modelId = versionLocation.getSource().getModelId();
084        return Optional.of(
085                modelId.startsWith("org.apache.maven:maven-core:") && modelId.endsWith(":default-lifecycle-bindings"));
086    }
087
088    /**
089     * Whether the version is coming from the super POM.
090     * Cannot be determined before Maven 3.6.1
091     *
092     * @param o either Plugin or ReportPlugin
093     * @return null if untraceable, otherwise its matching value
094     * @see <a href="https://issues.apache.org/jira/browse/MNG-6593">MNG-6593</a>
095     */
096    public static Optional<Boolean> isVersionFromSuperpom(InputLocationTracker o) {
097        InputLocation versionLocation = o.getLocation("version");
098        if (versionLocation == null) {
099            return Optional.empty();
100        }
101
102        String modelId = versionLocation.getSource().getModelId();
103        return Optional.of(
104                modelId.startsWith("org.apache.maven:maven-model-builder:") && modelId.endsWith(":super-pom"));
105    }
106
107    private PluginWrapper(Plugin plugin) {
108        this.groupId = plugin.getGroupId();
109        this.artifactId = plugin.getArtifactId();
110        this.version = plugin.getVersion();
111        this.locationTracker = plugin;
112    }
113
114    private PluginWrapper(ReportPlugin plugin) {
115        this.groupId = plugin.getGroupId();
116        this.artifactId = plugin.getArtifactId();
117        this.version = plugin.getVersion();
118        this.locationTracker = plugin;
119    }
120
121    public String getGroupId() {
122        return groupId;
123    }
124
125    public String getArtifactId() {
126        return artifactId;
127    }
128
129    public String getVersion() {
130        return version;
131    }
132
133    public String getSource() {
134        InputLocation inputLocation = locationTracker.getLocation("version");
135
136        if (inputLocation == null) {
137            // most likely super-pom or default-lifecycle-bindings in Maven 3.6.0 or before (MNG-6593 / MNG-6600)
138            return "unknown";
139        } else {
140            return inputLocation.getSource().getLocation();
141        }
142    }
143}