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