001package org.apache.maven.plugin.tools.model;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.io.File;
023import java.io.IOException;
024import java.io.Reader;
025import java.util.HashSet;
026import java.util.List;
027import java.util.Set;
028
029import org.apache.maven.plugin.descriptor.DuplicateParameterException;
030import org.apache.maven.plugin.descriptor.MojoDescriptor;
031import org.apache.maven.plugin.descriptor.Parameter;
032import org.apache.maven.plugin.tools.model.io.xpp3.PluginMetadataXpp3Reader;
033import org.codehaus.plexus.component.repository.ComponentRequirement;
034import org.codehaus.plexus.util.IOUtil;
035import org.codehaus.plexus.util.ReaderFactory;
036import org.codehaus.plexus.util.StringUtils;
037import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
038
039/**
040 * Parser for plugin metadata.
041 *
042 * @version $Id: PluginMetadataParser.html 907040 2014-04-27 09:50:12Z hboutemy $
043 */
044public class PluginMetadataParser
045{
046    /** Default implementation path which will be replaced in
047     * AbstractScriptedMojoDescriptorExtractor#extractMojoDescriptorsFromMetadata(Map, PluginDescriptor) */
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 )
056        throws PluginMetadataParseException
057    {
058        Set<MojoDescriptor> descriptors = new HashSet<MojoDescriptor>();
059
060        Reader reader = null;
061
062        try
063        {
064            reader = ReaderFactory.newXmlReader( metadataFile );
065
066            PluginMetadataXpp3Reader metadataReader = new PluginMetadataXpp3Reader();
067
068            PluginMetadata pluginMetadata = metadataReader.read( reader );
069
070            List<Mojo> mojos = pluginMetadata.getMojos();
071
072            if ( mojos != null && !mojos.isEmpty() )
073            {
074                for ( Mojo mojo :mojos )
075                {
076                    MojoDescriptor descriptor = asDescriptor( metadataFile, mojo );
077
078                    descriptors.add( descriptor );
079                }
080            }
081        }
082        catch ( IOException e )
083        {
084            throw new PluginMetadataParseException( metadataFile, "Cannot parse plugin metadata from file.", e );
085        }
086        catch ( XmlPullParserException e )
087        {
088            throw new PluginMetadataParseException( metadataFile, "Cannot parse plugin metadata from file.", e );
089        }
090        finally
091        {
092            IOUtil.close( reader );
093        }
094
095        return descriptors;
096    }
097
098    /**
099     * @param metadataFile not null
100     * @param mojo not null
101     * @return a mojo descriptor instance
102     * @throws PluginMetadataParseException if any
103     */
104    private MojoDescriptor asDescriptor( File metadataFile, Mojo mojo )
105        throws PluginMetadataParseException
106    {
107        MojoDescriptor descriptor = new MojoDescriptor();
108
109        if ( mojo.getCall() != null )
110        {
111            descriptor.setImplementation( IMPL_BASE_PLACEHOLDER + ":" + mojo.getCall() );
112        }
113        else
114        {
115            descriptor.setImplementation( IMPL_BASE_PLACEHOLDER );
116        }
117
118        descriptor.setGoal( mojo.getGoal() );
119        descriptor.setPhase( mojo.getPhase() );
120        descriptor.setDependencyResolutionRequired( mojo.getRequiresDependencyResolution() );
121        descriptor.setAggregator( mojo.isAggregator() );
122        descriptor.setInheritedByDefault( mojo.isInheritByDefault() );
123        descriptor.setDirectInvocationOnly( mojo.isRequiresDirectInvocation() );
124        descriptor.setOnlineRequired( mojo.isRequiresOnline() );
125        descriptor.setProjectRequired( mojo.isRequiresProject() );
126        descriptor.setRequiresReports( mojo.isRequiresReports() );
127        descriptor.setDescription( mojo.getDescription() );
128        descriptor.setDeprecated( mojo.getDeprecation() );
129        descriptor.setSince( mojo.getSince() );
130
131        LifecycleExecution le = mojo.getExecution();
132        if ( le != null )
133        {
134            descriptor.setExecuteLifecycle( le.getLifecycle() );
135            descriptor.setExecutePhase( le.getPhase() );
136            descriptor.setExecuteGoal( le.getGoal() );
137        }
138
139        List<org.apache.maven.plugin.tools.model.Parameter> parameters = mojo.getParameters();
140
141        if ( parameters != null && !parameters.isEmpty() )
142        {
143            for ( org.apache.maven.plugin.tools.model.Parameter param : parameters )
144            {
145                Parameter dParam = new Parameter();
146                dParam.setAlias( param.getAlias() );
147                dParam.setDeprecated( param.getDeprecation() );
148                dParam.setDescription( param.getDescription() );
149                dParam.setEditable( !param.isReadonly() );
150                dParam.setExpression( param.getExpression() );
151                dParam.setDefaultValue( param.getDefaultValue() );
152                dParam.setSince( param.getSince() );
153
154                String property = param.getProperty();
155                if ( StringUtils.isNotEmpty( property ) )
156                {
157                    dParam.setName( property );
158                }
159                else
160                {
161                    dParam.setName( param.getName() );
162                }
163
164                if ( StringUtils.isEmpty( dParam.getName() ) )
165                {
166                    throw new PluginMetadataParseException( metadataFile, "Mojo: \'" + mojo.getGoal()
167                        + "\' has a parameter without either property or name attributes. Please specify one." );
168                }
169
170                dParam.setRequired( param.isRequired() );
171                dParam.setType( param.getType() );
172
173                try
174                {
175                    descriptor.addParameter( dParam );
176                }
177                catch ( DuplicateParameterException e )
178                {
179                    throw new PluginMetadataParseException( metadataFile,
180                                                            "Duplicate parameters detected for mojo: "
181                                                                + mojo.getGoal(), e );
182                }
183            }
184        }
185
186        List<Component> components = mojo.getComponents();
187
188        if ( components != null && !components.isEmpty() )
189        {
190            for ( Component component : components )
191            {
192                ComponentRequirement cr = new ComponentRequirement();
193                cr.setRole( component.getRole() );
194                cr.setRoleHint( component.getHint() );
195
196                descriptor.addRequirement( cr );
197            }
198        }
199
200        return descriptor;
201    }
202}