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