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.plugin.descriptor.PluginDescriptor;
33  import org.apache.maven.project.MavenProject;
34  import org.apache.maven.tools.plugin.DefaultPluginToolsRequest;
35  import org.apache.maven.tools.plugin.PluginToolsRequest;
36  import org.codehaus.plexus.logging.AbstractLogEnabled;
37  import org.codehaus.plexus.util.DirectoryScanner;
38  import org.codehaus.plexus.util.FileUtils;
39  import org.codehaus.plexus.util.StringUtils;
40  
41  /**
42   * @author jdcasey
43   * @version $Id: AbstractScriptedMojoDescriptorExtractor.java 1212905 2011-12-10 22:31:48Z hboutemy $
44   */
45  public abstract class AbstractScriptedMojoDescriptorExtractor
46      extends AbstractLogEnabled
47      implements MojoDescriptorExtractor
48  {
49      /** {@inheritDoc} */
50      public List<MojoDescriptor> execute( MavenProject project, PluginDescriptor pluginDescriptor )
51          throws ExtractionException, InvalidPluginDescriptorException
52      {
53          return execute( new DefaultPluginToolsRequest( project, pluginDescriptor ) );
54      }
55      
56      /** {@inheritDoc} */
57      public List<MojoDescriptor> execute( PluginToolsRequest request )
58          throws ExtractionException, InvalidPluginDescriptorException
59      {
60          getLogger().debug( "Running: " + getClass().getName() );
61          String metadataExtension = getMetadataFileExtension( request );
62          String scriptExtension = getScriptFileExtension( request );
63          
64          MavenProject project = request.getProject();
65  
66          @SuppressWarnings( "unchecked" )
67          Map<String, Set<File>> scriptFilesKeyedByBasedir =
68              gatherFilesByBasedir( project.getBasedir(), project.getScriptSourceRoots(), scriptExtension, request );
69  
70          List<MojoDescriptor> mojoDescriptors;
71          if ( !StringUtils.isEmpty( metadataExtension ) )
72          {
73              @SuppressWarnings( "unchecked" )
74              Map<String, Set<File>> metadataFilesKeyedByBasedir =
75                  gatherFilesByBasedir( project.getBasedir(), project.getScriptSourceRoots(), metadataExtension,
76                                        request );
77  
78              mojoDescriptors = extractMojoDescriptorsFromMetadata( metadataFilesKeyedByBasedir, request );
79          }
80          else
81          {
82              mojoDescriptors = extractMojoDescriptors( scriptFilesKeyedByBasedir, request );
83          }
84  
85          copyScriptsToOutputDirectory( scriptFilesKeyedByBasedir, project.getBuild().getOutputDirectory(), request );
86  
87          return mojoDescriptors;
88      }
89  
90      /**
91       * @param scriptFilesKeyedByBasedir not null
92       * @param outputDirectory not null
93       * @throws ExtractionException if any
94       */
95      protected void copyScriptsToOutputDirectory( Map<String, Set<File>> scriptFilesKeyedByBasedir, String outputDirectory, PluginToolsRequest request )
96          throws ExtractionException
97      {
98          File outputDir = new File( outputDirectory );
99  
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 }