View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.archetype.common;
20  
21  import javax.inject.Named;
22  import javax.inject.Singleton;
23  
24  import java.io.File;
25  import java.io.IOException;
26  import java.util.ArrayList;
27  import java.util.HashSet;
28  import java.util.List;
29  import java.util.Set;
30  
31  import org.apache.maven.archetype.common.util.ListScanner;
32  import org.apache.maven.archetype.common.util.PathUtils;
33  import org.apache.maven.archetype.metadata.FileSet;
34  import org.codehaus.plexus.util.FileUtils;
35  import org.codehaus.plexus.util.StringUtils;
36  import org.slf4j.Logger;
37  import org.slf4j.LoggerFactory;
38  
39  @Named
40  @Singleton
41  public class DefaultArchetypeFilesResolver implements ArchetypeFilesResolver {
42      private static final Logger LOGGER = LoggerFactory.getLogger(DefaultArchetypeFilesResolver.class);
43  
44      @Override
45      public List<String> getFilesWithExtension(List<String> files, String extension) {
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          ListScanner scanner = new ListScanner();
58          scanner.setBasedir("");
59  
60          scanner.setIncludes(filtered);
61          scanner.setExcludes("");
62  
63          List<String> result = scanner.scan(files);
64          LOGGER.debug("Scanned " + result.size() + " filtered files in " + files.size() + " files");
65  
66          return result;
67      }
68  
69      @Override
70      public List<String> filterFiles(String moduleOffset, FileSet fileSet, List<String> archetypeResources) {
71          ListScanner scanner = new ListScanner();
72          scanner.setBasedir(((moduleOffset == null || moduleOffset.isEmpty()) ? "" : (moduleOffset + File.separatorChar))
73                  + fileSet.getDirectory());
74          scanner.setIncludes(fileSet.getIncludes());
75          scanner.setExcludes(fileSet.getExcludes());
76          scanner.setCaseSensitive(true);
77  
78          return scanner.scan(archetypeResources);
79      }
80  
81      @Override
82      public List<String> findOtherResources(int level, List<String> files, String languages) {
83          ListScanner scanner = new ListScanner();
84  
85          scanner.setBasedir("");
86  
87          StringBuilder includes = new StringBuilder();
88          for (int i = 0; i < level; i++) {
89              includes.append("*/");
90          }
91  
92          includes.append("**");
93          scanner.setIncludes(includes.toString());
94          scanner.setExcludes(languages);
95  
96          List<String> result = scanner.scan(files);
97          LOGGER.debug("Scanned " + result.size() + " other resources in " + files.size() + " files at level " + level);
98  
99          return result;
100     }
101 
102     @Override
103     public List<String> findOtherResources(int level, List<String> files, List<String> sourcesFiles, String languages) {
104         ListScanner scanner = new ListScanner();
105 
106         scanner.setBasedir("");
107 
108         Set<String> selectedDirectories = new HashSet<>();
109 
110         List<String> includes = new ArrayList<>();
111 
112         for (String sourcesFile : sourcesFiles) {
113             String directory = PathUtils.getDirectory(sourcesFile, level - 1);
114             if (!selectedDirectories.contains(directory)) {
115                 includes.add(directory + "/**");
116             }
117 
118             selectedDirectories.add(directory);
119         }
120 
121         scanner.setExcludes(languages);
122 
123         List<String> result = scanner.scan(files);
124         LOGGER.debug("Scanned " + result.size() + " other resources in " + files.size() + " files at level " + level);
125 
126         return result;
127     }
128 
129     @Override
130     public List<String> findOtherSources(int level, List<String> files, String languages) {
131         ListScanner scanner = new ListScanner();
132         scanner.setBasedir("");
133 
134         StringBuilder levelDirectory = new StringBuilder();
135         for (int i = 0; i < (level - 1); i++) {
136             levelDirectory.append("*/");
137         }
138 
139         StringBuilder includes = new StringBuilder();
140         String[] languagesAsArray = StringUtils.split(languages);
141         for (int i = 0; i < languagesAsArray.length; i++) {
142             includes.append(levelDirectory).append(languagesAsArray[i]);
143         }
144 
145         scanner.setIncludes(includes.toString());
146 
147         List<String> result = scanner.scan(files);
148         LOGGER.debug("Scanned " + result.size() + " other sources in " + files.size() + " files at level " + level);
149 
150         return result;
151     }
152 
153     @Override
154     public List<String> findResourcesMainFiles(List<String> files, String languages) {
155         ListScanner scanner = new ListScanner();
156         scanner.setBasedir("src/main");
157 
158         scanner.setIncludes("**");
159         scanner.setExcludes(languages);
160 
161         List<String> result = scanner.scan(files);
162         LOGGER.debug("Scanned " + result.size() + " resources in " + files.size() + " files");
163 
164         return result;
165     }
166 
167     @Override
168     public List<String> findResourcesTestFiles(List<String> files, String languages) {
169         ListScanner scanner = new ListScanner();
170         scanner.setBasedir("src/test");
171 
172         scanner.setIncludes("**");
173         scanner.setExcludes(languages);
174 
175         List<String> result = scanner.scan(files);
176         LOGGER.debug("Scanned " + result.size() + " test resources in " + files.size() + " files");
177 
178         return result;
179     }
180 
181     @Override
182     public List<String> findSiteFiles(List<String> files, String languages) {
183         ListScanner scanner = new ListScanner();
184         scanner.setBasedir("src/site");
185 
186         scanner.setIncludes("**");
187         scanner.setExcludes(languages);
188 
189         List<String> result = scanner.scan(files);
190         LOGGER.debug("Scanned " + result.size() + " site resources in " + files.size() + " files");
191 
192         return result;
193     }
194 
195     @Override
196     public List<String> findSourcesMainFiles(List<String> files, String languages) {
197         ListScanner scanner = new ListScanner();
198         scanner.setBasedir("src/main");
199 
200         scanner.setIncludes(languages);
201 
202         List<String> result = scanner.scan(files);
203         LOGGER.debug("Scanned " + result.size() + " sources in " + files.size() + " files");
204 
205         return result;
206     }
207 
208     @Override
209     public List<String> findSourcesTestFiles(List<String> files, String languages) {
210         ListScanner scanner = new ListScanner();
211         scanner.setBasedir("src/test");
212 
213         scanner.setIncludes(languages);
214 
215         List<String> result = scanner.scan(files);
216         LOGGER.debug("Scanned " + result.size() + " test sources in " + files.size() + " files");
217 
218         return result;
219     }
220 
221     @Override
222     public List<String> getPackagedFiles(List<String> files, String packageName) {
223         List<String> packagedFiles = new ArrayList<>();
224         for (String file : files) {
225             if (file.startsWith(packageName)) {
226                 packagedFiles.add(file.substring(packageName.length() + 1));
227             }
228         }
229         LOGGER.debug("Scanned " + packagedFiles.size() + " packaged files in " + files.size() + " files");
230         return packagedFiles;
231     }
232 
233     @Override
234     public String resolvePackage(File basedir, List<String> languages) throws IOException {
235         LOGGER.debug("Resolving package in " + basedir + " using languages " + languages);
236 
237         List<String> files = resolveFiles(basedir, languages);
238 
239         return resolvePackage(files);
240     }
241 
242     @Override
243     public List<String> getUnpackagedFiles(List<String> files, String packageName) {
244         List<String> unpackagedFiles = new ArrayList<>();
245         for (String file : files) {
246             if (!file.startsWith(packageName)) {
247                 unpackagedFiles.add(file);
248             }
249         }
250         LOGGER.debug("Scanned " + unpackagedFiles.size() + " unpackaged files in " + files.size() + " files");
251         return unpackagedFiles;
252     }
253 
254     private String getCommonPackage(String packageName, String templatePackage) {
255         String common = "";
256 
257         String difference = StringUtils.difference(packageName, templatePackage);
258         if (difference != null && !difference.isEmpty()) {
259             String temporaryCommon = StringUtils.substring(templatePackage, 0, templatePackage.lastIndexOf(difference));
260             if (!difference.startsWith(".")) {
261                 common = StringUtils.substring(temporaryCommon, 0, temporaryCommon.lastIndexOf("."));
262             } else {
263                 common = temporaryCommon;
264             }
265         } else {
266             common = packageName;
267         }
268 
269         return common;
270     }
271 
272     private List<String> resolveFiles(File basedir, List<String> languages) throws IOException {
273         String[] languagesArray = languages.toArray(new String[0]);
274         String[] languagesPathesArray = new String[languagesArray.length];
275         for (int i = 0; i < languagesArray.length; i++) {
276             languagesPathesArray[i] = "**/src/**/" + languagesArray[i] + "/**";
277         }
278 
279         String excludes = "target";
280         for (String defaultExclude : ListScanner.DEFAULTEXCLUDES) {
281             excludes += "," + defaultExclude + "/**";
282         }
283 
284         List<File> absoluteFiles = FileUtils.getFiles(basedir, StringUtils.join(languagesPathesArray, ","), excludes);
285 
286         LOGGER.debug("Found " + absoluteFiles.size() + " potential archetype files");
287 
288         List<String> files = new ArrayList<>(absoluteFiles.size());
289 
290         for (File file : absoluteFiles) {
291             String filePath = StringUtils.prechomp(file.getAbsolutePath(), basedir.getAbsolutePath() + File.separator);
292 
293             String minusSrc = StringUtils.prechomp(filePath, "src" + File.separator);
294 
295             for (int i = 0; i < languagesArray.length; i++) {
296                 String language = languagesArray[i];
297 
298                 if (StringUtils.countMatches(minusSrc, File.separator + language + File.separator) > 0) {
299                     String minusLanguage = StringUtils.prechomp(minusSrc, language + File.separator);
300 
301                     files.add(toUnixPath(minusLanguage));
302                 }
303             }
304         }
305 
306         LOGGER.debug("Found " + files.size() + " archetype files for package resolution ");
307 
308         return files;
309     }
310 
311     private String resolvePackage(List<String> files) {
312         String packageName = null;
313         for (String minusLanguage : files) {
314             String filePackage;
315             if (minusLanguage.indexOf("/") >= 0) {
316                 filePackage = StringUtils.replace(minusLanguage.substring(0, minusLanguage.lastIndexOf("/")), "/", ".");
317             } else {
318                 filePackage = "";
319             }
320 
321             if (packageName == null) {
322                 packageName = filePackage;
323             } else {
324                 packageName = getCommonPackage(packageName, filePackage);
325             }
326         }
327 
328         LOGGER.debug("Package resolved to " + packageName);
329 
330         return packageName;
331     }
332 
333     private String toUnixPath(String path) {
334         return path.replace(File.separatorChar, '/');
335     }
336 }