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.tools.plugin.extractor.model;
020
021import java.io.File;
022import java.io.IOException;
023import java.io.Reader;
024import java.util.HashSet;
025import java.util.List;
026import java.util.Set;
027
028import org.apache.maven.plugin.descriptor.DuplicateParameterException;
029import org.apache.maven.plugin.descriptor.MojoDescriptor;
030import org.apache.maven.plugin.descriptor.Parameter;
031import org.apache.maven.tools.plugin.extractor.model.io.xpp3.PluginMetadataXpp3Reader;
032import org.codehaus.plexus.component.repository.ComponentRequirement;
033import org.codehaus.plexus.util.ReaderFactory;
034import org.codehaus.plexus.util.StringUtils;
035import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
036
037/**
038 * Parser for plugin metadata.
039 *
040 * @deprecated Scripting support for mojos is deprecated and is planned tp be removed in maven 4.0
041 */
042@Deprecated
043public class PluginMetadataParser {
044    /**
045     * Default implementation path which will be replaced in
046     * AbstractScriptedMojoDescriptorExtractor#extractMojoDescriptorsFromMetadata(Map, PluginDescriptor)
047     */
048    public static final String IMPL_BASE_PLACEHOLDER = "<REPLACE-WITH-MOJO-PATH>";
049
050    /**
051     * @param metadataFile the metadata file to be parse
052     * @return a set of <code>MojoDescriptor</code>
053     * @throws PluginMetadataParseException if any
054     */
055    public Set<MojoDescriptor> parseMojoDescriptors(File metadataFile) throws PluginMetadataParseException {
056        Set<MojoDescriptor> descriptors = new HashSet<>();
057
058        try (Reader reader = ReaderFactory.newXmlReader(metadataFile)) {
059
060            PluginMetadataXpp3Reader metadataReader = new PluginMetadataXpp3Reader();
061
062            PluginMetadata pluginMetadata = metadataReader.read(reader);
063
064            List<Mojo> mojos = pluginMetadata.getMojos();
065
066            if (mojos != null) {
067                for (Mojo mojo : mojos) {
068                    MojoDescriptor descriptor = asDescriptor(metadataFile, mojo);
069
070                    descriptors.add(descriptor);
071                }
072            }
073        } catch (IOException | XmlPullParserException e) {
074            throw new PluginMetadataParseException(metadataFile, "Cannot parse plugin metadata from file.", e);
075        }
076
077        return descriptors;
078    }
079
080    /**
081     * @param metadataFile not null
082     * @param mojo         not null
083     * @return a mojo descriptor instance
084     * @throws PluginMetadataParseException if any
085     */
086    private MojoDescriptor asDescriptor(File metadataFile, Mojo mojo) throws PluginMetadataParseException {
087        MojoDescriptor descriptor = new MojoDescriptor();
088
089        if (mojo.getCall() != null) {
090            descriptor.setImplementation(IMPL_BASE_PLACEHOLDER + ":" + mojo.getCall());
091        } else {
092            descriptor.setImplementation(IMPL_BASE_PLACEHOLDER);
093        }
094
095        descriptor.setGoal(mojo.getGoal());
096        descriptor.setPhase(mojo.getPhase());
097        descriptor.setDependencyResolutionRequired(mojo.getRequiresDependencyResolution());
098        descriptor.setAggregator(mojo.isAggregator());
099        descriptor.setInheritedByDefault(mojo.isInheritByDefault());
100        descriptor.setDirectInvocationOnly(mojo.isRequiresDirectInvocation());
101        descriptor.setOnlineRequired(mojo.isRequiresOnline());
102        descriptor.setProjectRequired(mojo.isRequiresProject());
103        descriptor.setRequiresReports(mojo.isRequiresReports());
104        descriptor.setDescription(mojo.getDescription());
105        descriptor.setDeprecated(mojo.getDeprecation());
106        descriptor.setSince(mojo.getSince());
107
108        LifecycleExecution le = mojo.getExecution();
109        if (le != null) {
110            descriptor.setExecuteLifecycle(le.getLifecycle());
111            descriptor.setExecutePhase(le.getPhase());
112            descriptor.setExecuteGoal(le.getGoal());
113        }
114
115        List<org.apache.maven.tools.plugin.extractor.model.Parameter> parameters = mojo.getParameters();
116
117        if (parameters != null && !parameters.isEmpty()) {
118            for (org.apache.maven.tools.plugin.extractor.model.Parameter param : parameters) {
119                Parameter dParam = new Parameter();
120                dParam.setAlias(param.getAlias());
121                dParam.setDeprecated(param.getDeprecation());
122                dParam.setDescription(param.getDescription());
123                dParam.setEditable(!param.isReadonly());
124                dParam.setExpression(param.getExpression());
125                dParam.setDefaultValue(param.getDefaultValue());
126                dParam.setSince(param.getSince());
127
128                String property = param.getProperty();
129                if (property != null && !property.isEmpty()) {
130                    dParam.setName(property);
131                } else {
132                    dParam.setName(param.getName());
133                }
134
135                if (StringUtils.isEmpty(dParam.getName())) {
136                    throw new PluginMetadataParseException(
137                            metadataFile,
138                            "Mojo: \'" + mojo.getGoal()
139                                    + "\' has a parameter without either property or name attributes. Please specify one.");
140                }
141
142                dParam.setRequired(param.isRequired());
143                dParam.setType(param.getType());
144
145                try {
146                    descriptor.addParameter(dParam);
147                } catch (DuplicateParameterException e) {
148                    throw new PluginMetadataParseException(
149                            metadataFile, "Duplicate parameters detected for mojo: " + mojo.getGoal(), e);
150                }
151            }
152        }
153
154        List<Component> components = mojo.getComponents();
155
156        if (components != null && !components.isEmpty()) {
157            for (Component component : components) {
158                ComponentRequirement cr = new ComponentRequirement();
159                cr.setRole(component.getRole());
160                cr.setRoleHint(component.getHint());
161
162                descriptor.addRequirement(cr);
163            }
164        }
165
166        return descriptor;
167    }
168}