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.plugins.plugin.descriptor;
020
021import java.io.Reader;
022import java.net.URI;
023import java.util.ArrayList;
024import java.util.Collections;
025import java.util.LinkedHashMap;
026import java.util.List;
027import java.util.Map;
028import java.util.Optional;
029
030import org.apache.maven.plugin.descriptor.MojoDescriptor;
031import org.apache.maven.plugin.descriptor.Parameter;
032import org.apache.maven.plugin.descriptor.PluginDescriptor;
033import org.apache.maven.plugin.descriptor.PluginDescriptorBuilder;
034import org.apache.maven.plugin.plugin.report.PluginReport;
035import org.apache.maven.rtinfo.RuntimeInformation;
036import org.apache.maven.tools.plugin.EnhancedParameterWrapper;
037import org.apache.maven.tools.plugin.ExtendedPluginDescriptor;
038import org.apache.maven.tools.plugin.generator.PluginDescriptorFilesGenerator;
039import org.codehaus.plexus.configuration.PlexusConfiguration;
040import org.codehaus.plexus.configuration.PlexusConfigurationException;
041
042/**
043 * Reads enhanced plugin.xml files as generated by
044 * {@link PluginDescriptorFilesGenerator} and used by {@link PluginReport}.
045 * Populates the slightly extended {@link Parameter} object {@link EnhancedParameterWrapper}.
046 * In addition populates all (optional) elements added after Maven Plugin API 3.2.5.
047 */
048public class EnhancedPluginDescriptorBuilder extends PluginDescriptorBuilder {
049    private final boolean requireAddingMissingParameterSinceField;
050    private PlexusConfiguration configuration;
051
052    public EnhancedPluginDescriptorBuilder(RuntimeInformation rtInfo) {
053        this(rtInfo.isMavenVersion("[,3.3.9]"));
054    }
055
056    EnhancedPluginDescriptorBuilder(boolean requireAddingMissingParameterSinceField) {
057        this.requireAddingMissingParameterSinceField = requireAddingMissingParameterSinceField;
058    }
059
060    /**
061     * Cache the returned configuration for additional evaluation in {@link #build(Reader, String)}.
062     */
063    @Override
064    public PlexusConfiguration buildConfiguration(Reader reader) throws PlexusConfigurationException {
065        configuration = super.buildConfiguration(reader);
066        return configuration;
067    }
068
069    @Override
070    public PluginDescriptor build(Reader reader, String source) throws PlexusConfigurationException {
071        PluginDescriptor pluginDescriptor = super.build(reader, source);
072        // elements added in plugin descriptor 1.1
073        ExtendedPluginDescriptor extendedPluginDescriptor = new ExtendedPluginDescriptor(pluginDescriptor);
074        extendedPluginDescriptor.setRequiredJavaVersion(
075                configuration.getChild("requiredJavaVersion").getValue());
076        extendedPluginDescriptor.setRequiredMavenVersion(
077                configuration.getChild("requiredMavenVersion").getValue());
078        return extendedPluginDescriptor;
079    }
080
081    @Override
082    public MojoDescriptor buildComponentDescriptor(PlexusConfiguration c, PluginDescriptor pluginDescriptor)
083            throws PlexusConfigurationException {
084        MojoDescriptor mojoDescriptor = super.buildComponentDescriptor(c, pluginDescriptor);
085
086        // ----------------------------------------------------------------------
087        // Parameters
088        // ----------------------------------------------------------------------
089
090        PlexusConfiguration[] parameterConfigurations = c.getChild("parameters").getChildren("parameter");
091
092        List<Parameter> parameters = new ArrayList<>(
093                Optional.ofNullable(mojoDescriptor.getParameters()).orElseGet(Collections::emptyList));
094        Map<String, Parameter> parameterMap = new LinkedHashMap<>(mojoDescriptor.getParameterMap());
095
096        for (PlexusConfiguration d : parameterConfigurations) {
097            String parameterName = d.getChild("name").getValue();
098            // don't call getParameterMap() to not populate
099            Parameter pd = parameterMap.get(parameterName);
100            if (requireAddingMissingParameterSinceField) {
101                addMissingParameterSinceField(pd, d);
102            }
103            PlexusConfiguration configTypeJavadocUrl = d.getChild("typeJavadocUrl", false);
104            if (configTypeJavadocUrl != null) {
105                String parameterTypeJavadocUrl = configTypeJavadocUrl.getValue();
106                EnhancedParameterWrapper enhancedParameter = new EnhancedParameterWrapper(pd);
107                enhancedParameter.setTypeJavadocUrl(URI.create(parameterTypeJavadocUrl));
108                parameters.set(mojoDescriptor.getParameters().indexOf(pd), enhancedParameter);
109                parameterMap.put(parameterName, enhancedParameter);
110            }
111        }
112
113        // TODO This cruft has been resolved in Maven 3.8.9/3.9.7/4.0.0-alpha-1 with MNG-6776/MNG-7309
114        if (mojoDescriptor.getParameters() != null) {
115            mojoDescriptor.getParameters().clear();
116        }
117        // set parameters
118        mojoDescriptor.setParameters(parameters);
119        mojoDescriptor.getParameterMap().putAll(parameterMap);
120
121        return mojoDescriptor;
122    }
123
124    /**
125     * Reads the plugin descriptor and adds the fix for <a href="https://issues.apache.org/jira/browse/MNG-6109">
126     * MNG-6109</a> when using Maven-3.3.9 and before.
127     * Method can be removed once Maven 3.5.0 is the prerequisite for this plugin.
128     * @throws PlexusConfigurationException
129     *
130     * @since 3.5.1
131     * @see <a href="https://issues.apache.org/jira/browse/MNG-6109">MNG-6109</a>
132     * @see <a href="https://issues.apache.org/jira/browse/MPLUGIN-319">MPLUGIN-319</a>
133     */
134    void addMissingParameterSinceField(Parameter pd, PlexusConfiguration d) throws PlexusConfigurationException {
135        String parameterSince = d.getChild("since").getValue();
136        pd.setSince(parameterSince);
137    }
138}