View Javadoc
1   package org.apache.maven.archetype.common;
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 org.apache.maven.archetype.common.util.ListScanner;
23  import org.apache.maven.archetype.common.util.PathUtils;
24  import org.apache.maven.archetype.metadata.FileSet;
25  import org.codehaus.plexus.component.annotations.Component;
26  import org.codehaus.plexus.logging.AbstractLogEnabled;
27  import org.codehaus.plexus.util.FileUtils;
28  import org.codehaus.plexus.util.StringUtils;
29  
30  import java.io.File;
31  import java.io.IOException;
32  import java.util.ArrayList;
33  import java.util.Arrays;
34  import java.util.HashSet;
35  import java.util.List;
36  import java.util.Set;
37  
38  @Component( role = ArchetypeFilesResolver.class )
39  public class DefaultArchetypeFilesResolver
40      extends AbstractLogEnabled
41      implements ArchetypeFilesResolver
42  {
43      @Override
44      public List<String> getFilesWithExtension( List<String> files, String extension )
45      {
46          ListScanner scanner = new ListScanner();
47          scanner.setBasedir( "" );
48  
49          scanner.setIncludes( "**/*." + extension );
50          scanner.setExcludes( "" );
51  
52          return scanner.scan( files );
53      }
54  
55      @Override
56      public List<String> getFilteredFiles( List<String> files, String filtered )
57      {
58          ListScanner scanner = new ListScanner();
59          scanner.setBasedir( "" );
60  
61          scanner.setIncludes( filtered );
62          scanner.setExcludes( "" );
63  
64          List<String> result = scanner.scan( files );
65          getLogger().debug( "Scanned " + result.size() + " filtered files in " + files.size() + " files" );
66  
67          return result;
68      }
69  
70      @Override
71      public List<String> filterFiles( String moduleOffset, FileSet fileSet, List<String> archetypeResources )
72      {
73          ListScanner scanner = new ListScanner();
74          scanner.setBasedir( ( StringUtils.isEmpty( moduleOffset ) ? "" : ( moduleOffset + File.separatorChar ) )
75                                  + fileSet.getDirectory() );
76          scanner.setIncludes( fileSet.getIncludes() );
77          scanner.setExcludes( fileSet.getExcludes() );
78          scanner.setCaseSensitive( true );
79  
80          return scanner.scan( archetypeResources );
81      }
82  
83      @Override
84      public List<String> findOtherResources( int level, List<String> files, String languages )
85      {
86          ListScanner scanner = new ListScanner();
87  
88          scanner.setBasedir( "" );
89  
90          StringBuilder includes = new StringBuilder();
91          for ( int i = 0; i < level; i++ )
92          {
93              includes.append( "*/" );
94          }
95  
96          includes.append( "**" );
97          scanner.setIncludes( includes.toString() );
98          scanner.setExcludes( languages );
99  
100         List<String> result = scanner.scan( files );
101         getLogger().debug(
102             "Scanned " + result.size() + " other resources in " + files.size() + " files at level " + level );
103 
104         return result;
105     }
106 
107     @Override
108     public List<String> findOtherResources( int level, List<String> files, List<String> sourcesFiles, String languages )
109     {
110         ListScanner scanner = new ListScanner();
111 
112         scanner.setBasedir( "" );
113 
114         Set<String> selectedDirectories = new HashSet<>();
115 
116         List<String> includes = new ArrayList<>();
117 
118         for ( String sourcesFile : sourcesFiles )
119         {
120             String directory = PathUtils.getDirectory( sourcesFile, level - 1 );
121             if ( !selectedDirectories.contains( directory ) )
122             {
123                 includes.add( directory + "/**" );
124             }
125 
126             selectedDirectories.add( directory );
127         }
128 
129         scanner.setExcludes( languages );
130 
131         List<String> result = scanner.scan( files );
132         getLogger().debug(
133             "Scanned " + result.size() + " other resources in " + files.size() + " files at level " + level );
134 
135         return result;
136     }
137 
138     @Override
139     public List<String> findOtherSources( int level, List<String> files, String languages )
140     {
141         ListScanner scanner = new ListScanner();
142         scanner.setBasedir( "" );
143 
144         StringBuilder levelDirectory = new StringBuilder();
145         for ( int i = 0; i < ( level - 1 ); i++ )
146         {
147             levelDirectory.append( "*/" );
148         }
149 
150         StringBuilder includes = new StringBuilder();
151         String[] languagesAsArray = StringUtils.split( languages );
152         for ( int i = 0; i < languagesAsArray.length; i++ )
153         {
154             includes.append( levelDirectory ).append( languagesAsArray[i] );
155         }
156 
157         scanner.setIncludes( includes.toString() );
158 
159         List<String> result = scanner.scan( files );
160         getLogger().debug(
161             "Scanned " + result.size() + " other sources in " + files.size() + " files at level " + level );
162 
163         return result;
164     }
165 
166     @Override
167     public List<String> findResourcesMainFiles( List<String> files, String languages )
168     {
169         ListScanner scanner = new ListScanner();
170         scanner.setBasedir( "src/main" );
171 
172         scanner.setIncludes( "**" );
173         scanner.setExcludes( languages );
174 
175         List<String> result = scanner.scan( files );
176         getLogger().debug( "Scanned " + result.size() + " resources in " + files.size() + " files" );
177 
178         return result;
179     }
180 
181     @Override
182     public List<String> findResourcesTestFiles( List<String> files, String languages )
183     {
184         ListScanner scanner = new ListScanner();
185         scanner.setBasedir( "src/test" );
186 
187         scanner.setIncludes( "**" );
188         scanner.setExcludes( languages );
189 
190         List<String> result = scanner.scan( files );
191         getLogger().debug( "Scanned " + result.size() + " test resources in " + files.size() + " files" );
192 
193         return result;
194     }
195 
196     @Override
197     public List<String> findSiteFiles( List<String> files, String languages )
198     {
199         ListScanner scanner = new ListScanner();
200         scanner.setBasedir( "src/site" );
201 
202         scanner.setIncludes( "**" );
203         scanner.setExcludes( languages );
204 
205         List<String> result = scanner.scan( files );
206         getLogger().debug( "Scanned " + result.size() + " site resources in " + files.size() + " files" );
207 
208         return result;
209     }
210 
211     @Override
212     public List<String> findSourcesMainFiles( List<String> files, String languages )
213     {
214         ListScanner scanner = new ListScanner();
215         scanner.setBasedir( "src/main" );
216 
217         scanner.setIncludes( languages );
218 
219         List<String> result = scanner.scan( files );
220         getLogger().debug( "Scanned " + result.size() + " sources in " + files.size() + " files" );
221 
222         return result;
223     }
224 
225     @Override
226     public List<String> findSourcesTestFiles( List<String> files, String languages )
227     {
228         ListScanner scanner = new ListScanner();
229         scanner.setBasedir( "src/test" );
230 
231         scanner.setIncludes( languages );
232 
233         List<String> result = scanner.scan( files );
234         getLogger().debug( "Scanned " + result.size() + " test sources in " + files.size() + " files" );
235 
236         return result;
237     }
238 
239     @Override
240     public List<String> getPackagedFiles( List<String> files, String packageName )
241     {
242         List<String> packagedFiles = new ArrayList<>();
243         for ( String file : files )
244         {
245             if ( file.startsWith( packageName ) )
246             {
247                 packagedFiles.add( file.substring( packageName.length() + 1 ) );
248             }
249         }
250         getLogger().debug( "Scanned " + packagedFiles.size() + " packaged files in " + files.size() + " files" );
251         return packagedFiles;
252     }
253 
254     @Override
255     public String resolvePackage( File basedir, List<String> languages )
256         throws IOException
257     {
258         getLogger().debug( "Resolving package in " + basedir + " using languages " + languages );
259 
260         List<String> files = resolveFiles( basedir, languages );
261 
262         return resolvePackage( files );
263     }
264 
265     @Override
266     public List<String> getUnpackagedFiles( List<String> files, String packageName )
267     {
268         List<String> unpackagedFiles = new ArrayList<>();
269         for ( String file : files )
270         {
271             if ( !file.startsWith( packageName ) )
272             {
273                 unpackagedFiles.add( file );
274             }
275         }
276         getLogger().debug( "Scanned " + unpackagedFiles.size() + " unpackaged files in " + files.size() + " files" );
277         return unpackagedFiles;
278     }
279 
280     private String getCommonPackage( String packageName, String templatePackage )
281     {
282         String common = "";
283 
284         String difference = StringUtils.difference( packageName, templatePackage );
285         if ( StringUtils.isNotEmpty( difference ) )
286         {
287             String temporaryCommon =
288                 StringUtils.substring( templatePackage, 0, templatePackage.lastIndexOf( difference ) );
289             if ( !difference.startsWith( "." ) )
290             {
291                 common = StringUtils.substring( temporaryCommon, 0, temporaryCommon.lastIndexOf( "." ) );
292             }
293             else
294             {
295                 common = temporaryCommon;
296             }
297         }
298         else
299         {
300             common = packageName;
301         }
302 
303         return common;
304     }
305 
306     private List<String> resolveFiles( File basedir, List<String> languages )
307         throws IOException
308     {
309         String[] languagesArray = languages.toArray( new String[languages.size()] );
310         String[] languagesPathesArray = new String[languagesArray.length];
311         for ( int i = 0; i < languagesArray.length; i++ )
312         {
313             languagesPathesArray[i] = "**/src/**/" + languagesArray[i] + "/**";
314         }
315 
316         String excludes = "target";
317         for ( String defaultExclude : Arrays.asList( ListScanner.DEFAULTEXCLUDES ) )
318         {
319             excludes += "," + defaultExclude + "/**";
320         }
321 
322         List<File> absoluteFiles =
323             FileUtils.getFiles( basedir, StringUtils.join( languagesPathesArray, "," ), excludes );
324 
325         getLogger().debug( "Found " + absoluteFiles.size() + " potential archetype files" );
326 
327         List<String> files = new ArrayList<>( absoluteFiles.size() );
328 
329         for ( File file : absoluteFiles )
330         {
331             String filePath =
332                 StringUtils.prechomp( file.getAbsolutePath(), basedir.getAbsolutePath() + File.separator );
333 
334             String minusSrc = StringUtils.prechomp( filePath, "src" + File.separator );
335 
336             for ( int i = 0; i < languagesArray.length; i++ )
337             {
338                 String language = languagesArray[i];
339 
340                 if ( StringUtils.countMatches( minusSrc, File.separator + language + File.separator ) > 0 )
341                 {
342                     String minusLanguage = StringUtils.prechomp( minusSrc, language + File.separator );
343 
344                     files.add( toUnixPath( minusLanguage ) );
345                 }
346             }
347         }
348 
349         getLogger().debug( "Found " + files.size() + " archetype files for package resolution " );
350 
351         return files;
352     }
353 
354     private String resolvePackage( List<String> files )
355     {
356         String packageName = null;
357         for ( String minusLanguage : files )
358         {
359             String filePackage;
360             if ( minusLanguage.indexOf( "/" ) >= 0 )
361             {
362                 filePackage =
363                     StringUtils.replace( minusLanguage.substring( 0, minusLanguage.lastIndexOf( "/" ) ), "/", "." );
364             }
365             else
366             {
367                 filePackage = "";
368             }
369 
370             if ( packageName == null )
371             {
372                 packageName = filePackage;
373             }
374             else
375             {
376                 packageName = getCommonPackage( packageName, filePackage );
377             }
378         }
379 
380         getLogger().debug( "Package resolved to " + packageName );
381 
382         return packageName;
383     }
384 
385     private String toUnixPath( String path )
386     {
387         return path.replace( File.separatorChar, '/' );
388     }
389 }