001    package 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    
022    import java.io.File;
023    import java.io.IOException;
024    import java.io.Reader;
025    import java.util.HashSet;
026    import java.util.List;
027    import java.util.Set;
028    
029    import org.apache.maven.plugin.descriptor.DuplicateParameterException;
030    import org.apache.maven.plugin.descriptor.MojoDescriptor;
031    import org.apache.maven.plugin.descriptor.Parameter;
032    import org.apache.maven.plugin.tools.model.io.xpp3.PluginMetadataXpp3Reader;
033    import org.codehaus.plexus.component.repository.ComponentRequirement;
034    import org.codehaus.plexus.util.IOUtil;
035    import org.codehaus.plexus.util.ReaderFactory;
036    import org.codehaus.plexus.util.StringUtils;
037    import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
038    
039    /**
040     * Parser for plugin metadata.
041     *
042     * @version $Id: PluginMetadataParser.java 1367250 2012-07-30 19:57:20Z olamy $
043     */
044    public 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            }
137    
138            List<org.apache.maven.plugin.tools.model.Parameter> parameters = mojo.getParameters();
139    
140            if ( parameters != null && !parameters.isEmpty() )
141            {
142                for ( org.apache.maven.plugin.tools.model.Parameter param : parameters )
143                {
144                    Parameter dParam = new Parameter();
145                    dParam.setAlias( param.getAlias() );
146                    dParam.setDeprecated( param.getDeprecation() );
147                    dParam.setDescription( param.getDescription() );
148                    dParam.setEditable( !param.isReadonly() );
149                    dParam.setExpression( param.getExpression() );
150                    dParam.setDefaultValue( param.getDefaultValue() );
151                    dParam.setSince( param.getSince() );
152    
153                    String property = param.getProperty();
154                    if ( StringUtils.isNotEmpty( property ) )
155                    {
156                        dParam.setName( property );
157                    }
158                    else
159                    {
160                        dParam.setName( param.getName() );
161                    }
162    
163                    if ( StringUtils.isEmpty( dParam.getName() ) )
164                    {
165                        throw new PluginMetadataParseException( metadataFile, "Mojo: \'" + mojo.getGoal()
166                            + "\' has a parameter without either property or name attributes. Please specify one." );
167                    }
168    
169                    dParam.setRequired( param.isRequired() );
170                    dParam.setType( param.getType() );
171    
172                    try
173                    {
174                        descriptor.addParameter( dParam );
175                    }
176                    catch ( DuplicateParameterException e )
177                    {
178                        throw new PluginMetadataParseException( metadataFile,
179                                                                "Duplicate parameters detected for mojo: "
180                                                                    + mojo.getGoal(), e );
181                    }
182                }
183            }
184    
185            List<Component> components = mojo.getComponents();
186    
187            if ( components != null && !components.isEmpty() )
188            {
189                for ( Component component : components )
190                {
191                    ComponentRequirement cr = new ComponentRequirement();
192                    cr.setRole( component.getRole() );
193                    cr.setRoleHint( component.getHint() );
194    
195                    descriptor.addRequirement( cr );
196                }
197            }
198    
199            return descriptor;
200        }
201    }