View Javadoc
1   package org.apache.maven.tools.plugin.extractor;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.util.HashSet;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.Set;
28  import java.util.TreeMap;
29  
30  import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException;
31  import org.apache.maven.plugin.descriptor.MojoDescriptor;
32  import org.apache.maven.project.MavenProject;
33  import org.apache.maven.tools.plugin.PluginToolsRequest;
34  import org.codehaus.plexus.logging.AbstractLogEnabled;
35  import org.codehaus.plexus.util.DirectoryScanner;
36  import org.codehaus.plexus.util.FileUtils;
37  import org.codehaus.plexus.util.StringUtils;
38  
39  /**
40   * @author jdcasey
41   * @version $Id: AbstractScriptedMojoDescriptorExtractor.html 907947 2014-05-03 19:43:49Z hboutemy $
42   */
43  public abstract class AbstractScriptedMojoDescriptorExtractor
44      extends AbstractLogEnabled
45      implements MojoDescriptorExtractor
46  {
47      /** {@inheritDoc} */
48      public List<MojoDescriptor> execute( PluginToolsRequest request )
49          throws ExtractionException, InvalidPluginDescriptorException
50      {
51          getLogger().debug( "Running: " + getClass().getName() );
52          String metadataExtension = getMetadataFileExtension( request );
53          String scriptExtension = getScriptFileExtension( request );
54          
55          MavenProject project = request.getProject();
56  
57          @SuppressWarnings( "unchecked" )
58          Map<String, Set<File>> scriptFilesKeyedByBasedir =
59              gatherFilesByBasedir( project.getBasedir(), project.getScriptSourceRoots(), scriptExtension, request );
60  
61          List<MojoDescriptor> mojoDescriptors;
62          if ( !StringUtils.isEmpty( metadataExtension ) )
63          {
64              @SuppressWarnings( "unchecked" )
65              Map<String, Set<File>> metadataFilesKeyedByBasedir =
66                  gatherFilesByBasedir( project.getBasedir(), project.getScriptSourceRoots(), metadataExtension,
67                                        request );
68  
69              mojoDescriptors = extractMojoDescriptorsFromMetadata( metadataFilesKeyedByBasedir, request );
70          }
71          else
72          {
73              mojoDescriptors = extractMojoDescriptors( scriptFilesKeyedByBasedir, request );
74          }
75  
76          copyScriptsToOutputDirectory( scriptFilesKeyedByBasedir, project.getBuild().getOutputDirectory(), request );
77  
78          return mojoDescriptors;
79      }
80  
81      /**
82       * @param scriptFilesKeyedByBasedir not null
83       * @param outputDirectory not null
84       * @throws ExtractionException if any
85       */
86      protected void copyScriptsToOutputDirectory( Map<String, Set<File>> scriptFilesKeyedByBasedir, String outputDirectory, PluginToolsRequest request )
87          throws ExtractionException
88      {
89          File outputDir = new File( outputDirectory );
90  
91          if ( !outputDir.exists() )
92          {
93              outputDir.mkdirs();
94          }
95  
96          for ( Map.Entry<String, Set<File>> entry : scriptFilesKeyedByBasedir.entrySet() )
97          {
98              File sourceDir = new File( entry.getKey() );
99  
100             Set<File> scripts = entry.getValue();
101 
102             for ( File scriptFile : scripts )
103             {
104                 String relativePath = scriptFile.getPath().substring( sourceDir.getPath().length() );
105 
106                 if ( relativePath.charAt( 0 ) == File.separatorChar )
107                 {
108                     relativePath = relativePath.substring( 1 );
109                 }
110 
111                 File outputFile = new File( outputDir, relativePath ).getAbsoluteFile();
112 
113                 if ( !outputFile.getParentFile().exists() )
114                 {
115                     outputFile.getParentFile().mkdirs();
116                 }
117 
118                 try
119                 {
120                     FileUtils.copyFile( scriptFile, outputFile );
121                 }
122                 catch ( IOException e )
123                 {
124                     throw new ExtractionException(
125                         "Cannot copy script file: " + scriptFile + " to output: " + outputFile, e );
126                 }
127             }
128         }
129     }
130 
131     /**
132      * @param basedir not null
133      * @param directories not null
134      * @param scriptFileExtension not null
135      * @return map with subdirs paths as key
136      */
137     protected Map<String, Set<File>> gatherFilesByBasedir( File basedir, List<String> directories, String scriptFileExtension, PluginToolsRequest request )
138     {
139         Map<String, Set<File>> sourcesByBasedir = new TreeMap<String, Set<File>>();
140 
141         for ( String resourceDir : directories )
142         {
143             Set<File> sources = new HashSet<File>();
144 
145             getLogger().debug( "Scanning script dir: " + resourceDir + " with extractor: " + getClass().getName() );
146             File dir = new File( resourceDir );
147             if ( !dir.isAbsolute() )
148             {
149                 dir = new File( basedir, resourceDir ).getAbsoluteFile();
150             }
151 
152             resourceDir = dir.getPath();
153 
154             if ( dir.exists() )
155             {
156                 DirectoryScanner scanner = new DirectoryScanner();
157 
158                 scanner.setBasedir( dir );
159                 scanner.addDefaultExcludes();
160                 scanner.setIncludes( new String[]{"**/*" + scriptFileExtension} );
161                 scanner.scan();
162 
163                 String[] relativePaths = scanner.getIncludedFiles();
164 
165                 for ( String relativePath : relativePaths )
166                 {
167                     File scriptFile = new File( dir, relativePath ).getAbsoluteFile();
168 
169                     if ( scriptFile.isFile() && relativePath.endsWith( scriptFileExtension ) )
170                     {
171                         sources.add( scriptFile );
172                     }
173                 }
174 
175                 sourcesByBasedir.put( resourceDir, sources );
176             }
177         }
178 
179         return sourcesByBasedir;
180     }
181 
182     /**
183      * Should be implemented in the sub classes.
184      *
185      * @param metadataFilesKeyedByBasedir could be null
186      * @param request The plugin request, never <code>null</code>.
187      * @return always null
188      * @throws ExtractionException if any
189      * @throws InvalidPluginDescriptorException if any
190      */
191     protected List<MojoDescriptor> extractMojoDescriptorsFromMetadata( Map<String, Set<File>> metadataFilesKeyedByBasedir,
192                                                        PluginToolsRequest request )
193         throws ExtractionException, InvalidPluginDescriptorException
194     {
195         return null;
196     }
197 
198     /**
199      * Should be implemented in the sub classes.
200      *
201      * @return always null
202      */
203     protected String getMetadataFileExtension( PluginToolsRequest request )
204     {
205         return null;
206     }
207 
208     /**
209      * Should be implemented in the sub classes.
210      *
211      * @param scriptFilesKeyedByBasedir could be null
212      * @param request The plugin request, never <code>null</code>.
213      * @return always null
214      * @throws ExtractionException if any
215      * @throws InvalidPluginDescriptorException if any
216      */
217     protected List<MojoDescriptor> extractMojoDescriptors( Map<String, Set<File>> scriptFilesKeyedByBasedir, PluginToolsRequest request )
218         throws ExtractionException, InvalidPluginDescriptorException
219     {
220         return null;
221     }
222 
223     /**
224      * @return the file extension like <code>.bsh</code> for BeanShell.
225      */
226     protected abstract String getScriptFileExtension( PluginToolsRequest request );
227 
228 }