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   * @deprecated Scripting support for mojos is deprecated and is planned tp be removed in maven 4.0
41   * @author jdcasey
42   */
43  @Deprecated
44  public abstract class AbstractScriptedMojoDescriptorExtractor
45      extends AbstractLogEnabled
46      implements MojoDescriptorExtractor
47  {
48      @Override
49      public boolean isDeprecated()
50      {
51          return false;
52      }
53  
54      /** {@inheritDoc} */
55      @Override
56      public List<MojoDescriptor> execute( PluginToolsRequest request )
57          throws ExtractionException, InvalidPluginDescriptorException
58      {
59          getLogger().debug( "Running: " + getClass().getName() );
60          String metadataExtension = getMetadataFileExtension( request );
61          String scriptExtension = getScriptFileExtension( request );
62          
63          MavenProject project = request.getProject();
64  
65          @SuppressWarnings( "unchecked" )
66          Map<String, Set<File>> scriptFilesKeyedByBasedir =
67              gatherFilesByBasedir( project.getBasedir(), project.getScriptSourceRoots(), scriptExtension, request );
68  
69          List<MojoDescriptor> mojoDescriptors;
70          if ( !StringUtils.isEmpty( metadataExtension ) )
71          {
72              @SuppressWarnings( "unchecked" )
73              Map<String, Set<File>> metadataFilesKeyedByBasedir =
74                  gatherFilesByBasedir( project.getBasedir(), project.getScriptSourceRoots(), metadataExtension,
75                                        request );
76  
77              mojoDescriptors = extractMojoDescriptorsFromMetadata( metadataFilesKeyedByBasedir, request );
78          }
79          else
80          {
81              mojoDescriptors = extractMojoDescriptors( scriptFilesKeyedByBasedir, request );
82          }
83  
84          copyScriptsToOutputDirectory( scriptFilesKeyedByBasedir, project.getBuild().getOutputDirectory(), request );
85  
86          if ( !mojoDescriptors.isEmpty() )
87          {
88              getLogger().warn( "Scripting support for mojos is deprecated and is planned to be removed in Maven 4." );
89              getLogger().warn( "Found " + mojoDescriptors.size() + " scripted mojos." );
90          }
91  
92          return mojoDescriptors;
93      }
94  
95      /**
96       * @param scriptFilesKeyedByBasedir not null
97       * @param outputDirectory not null
98       * @param request the request
99       * @throws ExtractionException if any
100      */
101     protected void copyScriptsToOutputDirectory( Map<String, Set<File>> scriptFilesKeyedByBasedir,
102                                                  String outputDirectory, PluginToolsRequest request )
103         throws ExtractionException
104     {
105         File outputDir = new File( outputDirectory );
106 
107         if ( !outputDir.exists() )
108         {
109             outputDir.mkdirs();
110         }
111 
112         for ( Map.Entry<String, Set<File>> entry : scriptFilesKeyedByBasedir.entrySet() )
113         {
114             File sourceDir = new File( entry.getKey() );
115 
116             Set<File> scripts = entry.getValue();
117 
118             for ( File scriptFile : scripts )
119             {
120                 String relativePath = scriptFile.getPath().substring( sourceDir.getPath().length() );
121 
122                 if ( relativePath.charAt( 0 ) == File.separatorChar )
123                 {
124                     relativePath = relativePath.substring( 1 );
125                 }
126 
127                 File outputFile = new File( outputDir, relativePath ).getAbsoluteFile();
128 
129                 if ( !outputFile.getParentFile().exists() )
130                 {
131                     outputFile.getParentFile().mkdirs();
132                 }
133 
134                 try
135                 {
136                     FileUtils.copyFile( scriptFile, outputFile );
137                 }
138                 catch ( IOException e )
139                 {
140                     throw new ExtractionException(
141                         "Cannot copy script file: " + scriptFile + " to output: " + outputFile, e );
142                 }
143             }
144         }
145     }
146 
147     /**
148      * @param basedir not null
149      * @param directories not null
150      * @param scriptFileExtension not null
151      * @param request the request
152      * @return map with subdirs paths as key
153      */
154     protected Map<String, Set<File>> gatherFilesByBasedir( File basedir, List<String> directories,
155                                                            String scriptFileExtension, PluginToolsRequest request )
156     {
157         Map<String, Set<File>> sourcesByBasedir = new TreeMap<>();
158 
159         for ( String resourceDir : directories )
160         {
161             Set<File> sources = new HashSet<>();
162 
163             getLogger().debug( "Scanning script dir: " + resourceDir + " with extractor: " + getClass().getName() );
164             File dir = new File( resourceDir );
165             if ( !dir.isAbsolute() )
166             {
167                 dir = new File( basedir, resourceDir ).getAbsoluteFile();
168             }
169 
170             resourceDir = dir.getPath();
171 
172             if ( dir.exists() )
173             {
174                 DirectoryScanner scanner = new DirectoryScanner();
175 
176                 scanner.setBasedir( dir );
177                 scanner.addDefaultExcludes();
178                 scanner.setIncludes( new String[]{"**/*" + scriptFileExtension} );
179                 scanner.scan();
180 
181                 String[] relativePaths = scanner.getIncludedFiles();
182 
183                 for ( String relativePath : relativePaths )
184                 {
185                     File scriptFile = new File( dir, relativePath ).getAbsoluteFile();
186 
187                     if ( scriptFile.isFile() && relativePath.endsWith( scriptFileExtension ) )
188                     {
189                         sources.add( scriptFile );
190                     }
191                 }
192 
193                 sourcesByBasedir.put( resourceDir, sources );
194             }
195         }
196 
197         return sourcesByBasedir;
198     }
199 
200     /**
201      * Should be implemented in the sub classes.
202      *
203      * @param metadataFilesByBasedir could be null
204      * @param request The plugin request, never <code>null</code>.
205      * @return always null
206      * @throws ExtractionException if any
207      * @throws InvalidPluginDescriptorException if any
208      */
209     protected List<MojoDescriptor> extractMojoDescriptorsFromMetadata( Map<String, Set<File>> metadataFilesByBasedir,
210                                                                        PluginToolsRequest request )
211         throws ExtractionException, InvalidPluginDescriptorException
212     {
213         return null;
214     }
215 
216     /**
217      * Should be implemented in the sub classes.
218      * @param request the request
219      * @return always null
220      */
221     protected String getMetadataFileExtension( PluginToolsRequest request )
222     {
223         return null;
224     }
225 
226     /**
227      * Should be implemented in the sub classes.
228      *
229      * @param scriptFilesKeyedByBasedir could be null
230      * @param request The plugin request, never <code>null</code>.
231      * @return always null
232      * @throws ExtractionException if any
233      * @throws InvalidPluginDescriptorException if any
234      */
235     protected List<MojoDescriptor> extractMojoDescriptors( Map<String, Set<File>> scriptFilesKeyedByBasedir,
236                                                            PluginToolsRequest request )
237         throws ExtractionException, InvalidPluginDescriptorException
238     {
239         return null;
240     }
241 
242     /**
243      * @param request the request
244      * @return the file extension like <code>.bsh</code> for BeanShell.
245      */
246     protected abstract String getScriptFileExtension( PluginToolsRequest request );
247 
248 }