001package org.apache.maven.tools.plugin.extractor.ant;
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 javax.inject.Named;
023import javax.inject.Singleton;
024
025import java.io.File;
026import java.util.ArrayList;
027import java.util.HashMap;
028import java.util.List;
029import java.util.Map;
030import java.util.Set;
031
032import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException;
033import org.apache.maven.plugin.descriptor.MojoDescriptor;
034import org.apache.maven.plugin.descriptor.Parameter;
035import org.apache.maven.project.MavenProject;
036import org.apache.maven.project.path.PathTranslator;
037import org.apache.maven.tools.plugin.PluginToolsRequest;
038import org.apache.maven.tools.plugin.extractor.AbstractScriptedMojoDescriptorExtractor;
039import org.apache.maven.tools.plugin.extractor.ExtractionException;
040import org.apache.maven.tools.plugin.extractor.GroupKey;
041import org.apache.maven.tools.plugin.extractor.model.PluginMetadataParseException;
042import org.apache.maven.tools.plugin.extractor.model.PluginMetadataParser;
043import org.codehaus.plexus.component.repository.ComponentRequirement;
044import org.codehaus.plexus.util.StringUtils;
045
046/**
047 * Extracts Mojo descriptors from <a href="http://ant.apache.org">Ant</a> sources.
048 *
049 * @deprecated Scripting support for mojos is deprecated and is planned tp be removed in maven 4.0
050 */
051@Deprecated
052@Named( AntMojoDescriptorExtractor.NAME )
053@Singleton
054public class AntMojoDescriptorExtractor
055    extends AbstractScriptedMojoDescriptorExtractor
056{
057    public static final String NAME = "ant";
058
059    private static final GroupKey GROUP_KEY = new GroupKey( "ant", 100 );
060
061    /** Default metadata file extension */
062    private static final String METADATA_FILE_EXTENSION = ".mojos.xml";
063
064    /** Default Ant build file extension */
065    private static final String SCRIPT_FILE_EXTENSION = ".build.xml";
066
067    @Override
068    public String getName()
069    {
070        return NAME;
071    }
072
073    @Override
074    public GroupKey getGroupKey()
075    {
076        return GROUP_KEY;
077    }
078
079    /** {@inheritDoc} */
080    @Override
081    protected List<MojoDescriptor> extractMojoDescriptorsFromMetadata(
082                                                                  Map<String, Set<File>> metadataFilesKeyedByBasedir,
083                                                                  PluginToolsRequest request )
084        throws ExtractionException, InvalidPluginDescriptorException
085    {
086        List<MojoDescriptor> descriptors = new ArrayList<>();
087
088        PluginMetadataParser parser = new PluginMetadataParser();
089
090        for ( Map.Entry<String, Set<File>> entry : metadataFilesKeyedByBasedir.entrySet() )
091        {
092            String basedir = entry.getKey();
093            Set<File> metadataFiles = entry.getValue();
094
095            for ( File metadataFile : metadataFiles )
096            {
097                String basename = metadataFile.getName();
098                basename = basename.substring( 0, basename.length() - METADATA_FILE_EXTENSION.length() );
099
100                File scriptFile = new File( metadataFile.getParentFile(), basename + SCRIPT_FILE_EXTENSION );
101
102                if ( !scriptFile.exists() )
103                {
104                    throw new InvalidPluginDescriptorException(
105                        "Found orphaned plugin metadata file: " + metadataFile );
106                }
107
108                String relativePath = scriptFile.getPath().substring( basedir.length() ).replace( '\\', '/' );
109                
110                if ( relativePath.startsWith( "/" ) )
111                {
112                    relativePath = relativePath.substring( 1 );
113                }
114
115                try
116                {
117                    Set<MojoDescriptor> mojoDescriptors = parser.parseMojoDescriptors( metadataFile );
118
119                    for ( MojoDescriptor descriptor : mojoDescriptors )
120                    {
121                        @SuppressWarnings( "unchecked" )
122                        Map<String, ?> paramMap = descriptor.getParameterMap();
123
124                        if ( !paramMap.containsKey( "basedir" ) )
125                        {
126                            Parameter param = new Parameter();
127                            param.setName( "basedir" );
128                            param.setAlias( "ant.basedir" );
129                            param.setExpression( "${antBasedir}" );
130                            param.setDefaultValue( "${basedir}" );
131                            param.setType( "java.io.File" );
132                            param.setDescription( "The base directory from which to execute the Ant script." );
133                            param.setEditable( true );
134                            param.setRequired( true );
135
136                            descriptor.addParameter( param );
137                        }
138
139                        if ( !paramMap.containsKey( "antMessageLevel" ) )
140                        {
141                            Parameter param = new Parameter();
142                            param.setName( "messageLevel" );
143                            param.setAlias( "ant.messageLevel" );
144                            param.setExpression( "${antMessageLevel}" );
145                            param.setDefaultValue( "info" );
146                            param.setType( "java.lang.String" );
147                            param.setDescription( "The message-level used to tune the verbosity of Ant logging." );
148                            param.setEditable( true );
149                            param.setRequired( false );
150
151                            descriptor.addParameter( param );
152                        }
153                        
154                        if ( !paramMap.containsKey( "project" ) )
155                        {
156                            Parameter param = new Parameter();
157                            param.setName( "project" );
158                            param.setDefaultValue( "${project}" );
159                            param.setType( MavenProject.class.getName() );
160                            param.setDescription( "The current MavenProject instance, which contains classpath "
161                                + "elements." );
162                            param.setEditable( false );
163                            param.setRequired( true );
164
165                            descriptor.addParameter( param );
166                        }
167
168                        if ( !paramMap.containsKey( "session" ) )
169                        {
170                            Parameter param = new Parameter();
171                            param.setName( "session" );
172                            param.setDefaultValue( "${session}" );
173                            param.setType( "org.apache.maven.execution.MavenSession" );
174                            param.setDescription( "The current MavenSession instance, which is used for "
175                                + "plugin-style expression resolution." );
176                            param.setEditable( false );
177                            param.setRequired( true );
178
179                            descriptor.addParameter( param );
180                        }
181
182                        if ( !paramMap.containsKey( "mojoExecution" ) )
183                        {
184                            Parameter param = new Parameter();
185                            param.setName( "mojoExecution" );
186                            param.setDefaultValue( "${mojoExecution}" );
187                            param.setType( "org.apache.maven.plugin.MojoExecution" );
188                            param.setDescription( "The current Maven MojoExecution instance, which contains "
189                                + "information about the mojo currently executing." );
190                            param.setEditable( false );
191                            param.setRequired( true );
192
193                            descriptor.addParameter( param );
194                        }
195                        
196                        @SuppressWarnings( "unchecked" )
197                        List<ComponentRequirement> requirements = descriptor.getRequirements();
198                        Map<String, ComponentRequirement> reqMap = new HashMap<>();
199
200                        if ( requirements != null )
201                        {
202                            for ( ComponentRequirement req : requirements )
203                            {
204                                reqMap.put( req.getRole(), req );
205                            }
206                        }
207                        
208                        if ( !reqMap.containsKey( PathTranslator.class.getName() ) )
209                        {
210                            ComponentRequirement req = new ComponentRequirement();
211                            req.setRole( PathTranslator.class.getName() );
212                            
213                            descriptor.addRequirement( req );
214                        }
215
216                        String implementation = relativePath;
217
218                        String dImpl = descriptor.getImplementation();
219                        if ( StringUtils.isNotEmpty( dImpl ) )
220                        {
221                            if ( PluginMetadataParser.IMPL_BASE_PLACEHOLDER.equals( dImpl ) )
222                            {
223                                implementation = relativePath;
224                            }
225                            else
226                            {
227                                implementation =
228                                    relativePath
229                                        + dImpl.substring( PluginMetadataParser.IMPL_BASE_PLACEHOLDER.length() );
230                            }
231                        }
232
233                        descriptor.setImplementation( implementation );
234
235                        descriptor.setLanguage( "ant-mojo" );
236                        descriptor.setComponentComposer( "map-oriented" );
237                        descriptor.setComponentConfigurator( "map-oriented" );
238
239                        descriptor.setPluginDescriptor( request.getPluginDescriptor() );
240
241                        descriptors.add( descriptor );
242                    }
243                }
244                catch ( PluginMetadataParseException e )
245                {
246                    throw new ExtractionException( "Error extracting mojo descriptor from script: " + metadataFile, e );
247                }
248            }
249        }
250
251        return descriptors;
252    }
253
254    /** {@inheritDoc} */
255    @Override
256    protected String getScriptFileExtension( PluginToolsRequest request )
257    {
258        return SCRIPT_FILE_EXTENSION;
259    }
260
261    /** {@inheritDoc} */
262    @Override
263    protected String getMetadataFileExtension( PluginToolsRequest request )
264    {
265        return METADATA_FILE_EXTENSION;
266    }
267}