001 package org.apache.maven.tools.plugin.extractor; 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.util.HashSet; 025 import java.util.List; 026 import java.util.Map; 027 import java.util.Set; 028 import java.util.TreeMap; 029 030 import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException; 031 import org.apache.maven.plugin.descriptor.MojoDescriptor; 032 import org.apache.maven.plugin.descriptor.PluginDescriptor; 033 import org.apache.maven.project.MavenProject; 034 import org.apache.maven.tools.plugin.DefaultPluginToolsRequest; 035 import org.apache.maven.tools.plugin.PluginToolsRequest; 036 import org.codehaus.plexus.logging.AbstractLogEnabled; 037 import org.codehaus.plexus.util.DirectoryScanner; 038 import org.codehaus.plexus.util.FileUtils; 039 import org.codehaus.plexus.util.StringUtils; 040 041 /** 042 * @author jdcasey 043 * @version $Id: AbstractScriptedMojoDescriptorExtractor.java 1212905 2011-12-10 22:31:48Z hboutemy $ 044 */ 045 public abstract class AbstractScriptedMojoDescriptorExtractor 046 extends AbstractLogEnabled 047 implements MojoDescriptorExtractor 048 { 049 /** {@inheritDoc} */ 050 public List<MojoDescriptor> execute( MavenProject project, PluginDescriptor pluginDescriptor ) 051 throws ExtractionException, InvalidPluginDescriptorException 052 { 053 return execute( new DefaultPluginToolsRequest( project, pluginDescriptor ) ); 054 } 055 056 /** {@inheritDoc} */ 057 public List<MojoDescriptor> execute( PluginToolsRequest request ) 058 throws ExtractionException, InvalidPluginDescriptorException 059 { 060 getLogger().debug( "Running: " + getClass().getName() ); 061 String metadataExtension = getMetadataFileExtension( request ); 062 String scriptExtension = getScriptFileExtension( request ); 063 064 MavenProject project = request.getProject(); 065 066 @SuppressWarnings( "unchecked" ) 067 Map<String, Set<File>> scriptFilesKeyedByBasedir = 068 gatherFilesByBasedir( project.getBasedir(), project.getScriptSourceRoots(), scriptExtension, request ); 069 070 List<MojoDescriptor> mojoDescriptors; 071 if ( !StringUtils.isEmpty( metadataExtension ) ) 072 { 073 @SuppressWarnings( "unchecked" ) 074 Map<String, Set<File>> metadataFilesKeyedByBasedir = 075 gatherFilesByBasedir( project.getBasedir(), project.getScriptSourceRoots(), metadataExtension, 076 request ); 077 078 mojoDescriptors = extractMojoDescriptorsFromMetadata( metadataFilesKeyedByBasedir, request ); 079 } 080 else 081 { 082 mojoDescriptors = extractMojoDescriptors( scriptFilesKeyedByBasedir, request ); 083 } 084 085 copyScriptsToOutputDirectory( scriptFilesKeyedByBasedir, project.getBuild().getOutputDirectory(), request ); 086 087 return mojoDescriptors; 088 } 089 090 /** 091 * @param scriptFilesKeyedByBasedir not null 092 * @param outputDirectory not null 093 * @throws ExtractionException if any 094 */ 095 protected void copyScriptsToOutputDirectory( Map<String, Set<File>> scriptFilesKeyedByBasedir, String outputDirectory, PluginToolsRequest request ) 096 throws ExtractionException 097 { 098 File outputDir = new File( outputDirectory ); 099 100 if ( !outputDir.exists() ) 101 { 102 outputDir.mkdirs(); 103 } 104 105 for ( Map.Entry<String, Set<File>> entry : scriptFilesKeyedByBasedir.entrySet() ) 106 { 107 File sourceDir = new File( entry.getKey() ); 108 109 Set<File> scripts = entry.getValue(); 110 111 for ( File scriptFile : scripts ) 112 { 113 String relativePath = scriptFile.getPath().substring( sourceDir.getPath().length() ); 114 115 if ( relativePath.charAt( 0 ) == File.separatorChar ) 116 { 117 relativePath = relativePath.substring( 1 ); 118 } 119 120 File outputFile = new File( outputDir, relativePath ).getAbsoluteFile(); 121 122 if ( !outputFile.getParentFile().exists() ) 123 { 124 outputFile.getParentFile().mkdirs(); 125 } 126 127 try 128 { 129 FileUtils.copyFile( scriptFile, outputFile ); 130 } 131 catch ( IOException e ) 132 { 133 throw new ExtractionException( 134 "Cannot copy script file: " + scriptFile + " to output: " + outputFile, e ); 135 } 136 } 137 } 138 } 139 140 /** 141 * @param basedir not null 142 * @param directories not null 143 * @param scriptFileExtension not null 144 * @return map with subdirs paths as key 145 */ 146 protected Map<String, Set<File>> gatherFilesByBasedir( File basedir, List<String> directories, String scriptFileExtension, PluginToolsRequest request ) 147 { 148 Map<String, Set<File>> sourcesByBasedir = new TreeMap<String, Set<File>>(); 149 150 for ( String resourceDir : directories ) 151 { 152 Set<File> sources = new HashSet<File>(); 153 154 getLogger().debug( "Scanning script dir: " + resourceDir + " with extractor: " + getClass().getName() ); 155 File dir = new File( resourceDir ); 156 if ( !dir.isAbsolute() ) 157 { 158 dir = new File( basedir, resourceDir ).getAbsoluteFile(); 159 } 160 161 resourceDir = dir.getPath(); 162 163 if ( dir.exists() ) 164 { 165 DirectoryScanner scanner = new DirectoryScanner(); 166 167 scanner.setBasedir( dir ); 168 scanner.addDefaultExcludes(); 169 scanner.setIncludes( new String[]{"**/*" + scriptFileExtension} ); 170 scanner.scan(); 171 172 String[] relativePaths = scanner.getIncludedFiles(); 173 174 for ( String relativePath : relativePaths ) 175 { 176 File scriptFile = new File( dir, relativePath ).getAbsoluteFile(); 177 178 if ( scriptFile.isFile() && relativePath.endsWith( scriptFileExtension ) ) 179 { 180 sources.add( scriptFile ); 181 } 182 } 183 184 sourcesByBasedir.put( resourceDir, sources ); 185 } 186 } 187 188 return sourcesByBasedir; 189 } 190 191 /** 192 * Should be implemented in the sub classes. 193 * 194 * @param metadataFilesKeyedByBasedir could be null 195 * @param request The plugin request, never <code>null</code>. 196 * @return always null 197 * @throws ExtractionException if any 198 * @throws InvalidPluginDescriptorException if any 199 */ 200 protected List<MojoDescriptor> extractMojoDescriptorsFromMetadata( Map<String, Set<File>> metadataFilesKeyedByBasedir, 201 PluginToolsRequest request ) 202 throws ExtractionException, InvalidPluginDescriptorException 203 { 204 return null; 205 } 206 207 /** 208 * Should be implemented in the sub classes. 209 * 210 * @return always null 211 */ 212 protected String getMetadataFileExtension( PluginToolsRequest request ) 213 { 214 return null; 215 } 216 217 /** 218 * Should be implemented in the sub classes. 219 * 220 * @param scriptFilesKeyedByBasedir could be null 221 * @param request The plugin request, never <code>null</code>. 222 * @return always null 223 * @throws ExtractionException if any 224 * @throws InvalidPluginDescriptorException if any 225 */ 226 protected List<MojoDescriptor> extractMojoDescriptors( Map<String, Set<File>> scriptFilesKeyedByBasedir, PluginToolsRequest request ) 227 throws ExtractionException, InvalidPluginDescriptorException 228 { 229 return null; 230 } 231 232 /** 233 * @return the file extension like <code>.bsh</code> for BeanShell. 234 */ 235 protected abstract String getScriptFileExtension( PluginToolsRequest request ); 236 237 }