001package org.apache.maven.tools.plugin.extractor.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.tools.plugin.extractor.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$
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            reader.close();
083            reader = null;
084        }
085        catch ( IOException e )
086        {
087            throw new PluginMetadataParseException( metadataFile, "Cannot parse plugin metadata from file.", e );
088        }
089        catch ( XmlPullParserException e )
090        {
091            throw new PluginMetadataParseException( metadataFile, "Cannot parse plugin metadata from file.", e );
092        }
093        finally
094        {
095            IOUtil.close( reader );
096        }
097
098        return descriptors;
099    }
100
101    /**
102     * @param metadataFile not null
103     * @param mojo not null
104     * @return a mojo descriptor instance
105     * @throws PluginMetadataParseException if any
106     */
107    private MojoDescriptor asDescriptor( File metadataFile, Mojo mojo )
108        throws PluginMetadataParseException
109    {
110        MojoDescriptor descriptor = new MojoDescriptor();
111
112        if ( mojo.getCall() != null )
113        {
114            descriptor.setImplementation( IMPL_BASE_PLACEHOLDER + ":" + mojo.getCall() );
115        }
116        else
117        {
118            descriptor.setImplementation( IMPL_BASE_PLACEHOLDER );
119        }
120
121        descriptor.setGoal( mojo.getGoal() );
122        descriptor.setPhase( mojo.getPhase() );
123        descriptor.setDependencyResolutionRequired( mojo.getRequiresDependencyResolution() );
124        descriptor.setAggregator( mojo.isAggregator() );
125        descriptor.setInheritedByDefault( mojo.isInheritByDefault() );
126        descriptor.setDirectInvocationOnly( mojo.isRequiresDirectInvocation() );
127        descriptor.setOnlineRequired( mojo.isRequiresOnline() );
128        descriptor.setProjectRequired( mojo.isRequiresProject() );
129        descriptor.setRequiresReports( mojo.isRequiresReports() );
130        descriptor.setDescription( mojo.getDescription() );
131        descriptor.setDeprecated( mojo.getDeprecation() );
132        descriptor.setSince( mojo.getSince() );
133
134        LifecycleExecution le = mojo.getExecution();
135        if ( le != null )
136        {
137            descriptor.setExecuteLifecycle( le.getLifecycle() );
138            descriptor.setExecutePhase( le.getPhase() );
139            descriptor.setExecuteGoal( le.getGoal() );
140        }
141
142        List<org.apache.maven.tools.plugin.extractor.model.Parameter> parameters = mojo.getParameters();
143
144        if ( parameters != null && !parameters.isEmpty() )
145        {
146            for ( org.apache.maven.tools.plugin.extractor.model.Parameter param : parameters )
147            {
148                Parameter dParam = new Parameter();
149                dParam.setAlias( param.getAlias() );
150                dParam.setDeprecated( param.getDeprecation() );
151                dParam.setDescription( param.getDescription() );
152                dParam.setEditable( !param.isReadonly() );
153                dParam.setExpression( param.getExpression() );
154                dParam.setDefaultValue( param.getDefaultValue() );
155                dParam.setSince( param.getSince() );
156
157                String property = param.getProperty();
158                if ( StringUtils.isNotEmpty( property ) )
159                {
160                    dParam.setName( property );
161                }
162                else
163                {
164                    dParam.setName( param.getName() );
165                }
166
167                if ( StringUtils.isEmpty( dParam.getName() ) )
168                {
169                    throw new PluginMetadataParseException( metadataFile, "Mojo: \'" + mojo.getGoal()
170                        + "\' has a parameter without either property or name attributes. Please specify one." );
171                }
172
173                dParam.setRequired( param.isRequired() );
174                dParam.setType( param.getType() );
175
176                try
177                {
178                    descriptor.addParameter( dParam );
179                }
180                catch ( DuplicateParameterException e )
181                {
182                    throw new PluginMetadataParseException( metadataFile,
183                                                            "Duplicate parameters detected for mojo: "
184                                                                + mojo.getGoal(), e );
185                }
186            }
187        }
188
189        List<Component> components = mojo.getComponents();
190
191        if ( components != null && !components.isEmpty() )
192        {
193            for ( Component component : components )
194            {
195                ComponentRequirement cr = new ComponentRequirement();
196                cr.setRole( component.getRole() );
197                cr.setRoleHint( component.getHint() );
198
199                descriptor.addRequirement( cr );
200            }
201        }
202
203        return descriptor;
204    }
205}