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.plugin.surefire.util;
20  
21  import java.io.File;
22  import java.util.Collection;
23  
24  import org.apache.maven.surefire.api.testset.TestFilter;
25  
26  import static org.apache.maven.surefire.shared.utils.StringUtils.isBlank;
27  
28  final class FileScanner {
29      private final File basedir;
30  
31      private final String ext;
32  
33      FileScanner(File basedir, String ext) {
34          this.basedir = basedir;
35          ext = ext.trim();
36          if (isBlank(ext)) {
37              throw new IllegalArgumentException("No file extension");
38          }
39          this.ext = ext.startsWith(".") ? ext : "." + ext;
40      }
41  
42      void scanTo(Collection<String> scannedJavaClassNames, TestFilter<String, String> filter) {
43          scan(scannedJavaClassNames, filter, basedir);
44      }
45  
46      private void scan(
47              Collection<String> scannedJavaClassNames,
48              TestFilter<String, String> filter,
49              File basedir,
50              String... subDirectories) {
51          File[] filesAndDirs = basedir.listFiles();
52          if (filesAndDirs != null) {
53              final String pAckage = toJavaPackage(subDirectories);
54              final String path = toPath(subDirectories);
55              final String ext = this.ext;
56              final boolean hasExtension = ext != null;
57              final int extLength = hasExtension ? ext.length() : 0;
58              for (File fileOrDir : filesAndDirs) {
59                  String name = fileOrDir.getName();
60                  if (!name.isEmpty()) {
61                      if (fileOrDir.isFile()) {
62                          final int clsLength = name.length() - extLength;
63                          if (clsLength > 0
64                                  && (!hasExtension || name.regionMatches(true, clsLength, ext, 0, extLength))) {
65                              String simpleClassName = hasExtension ? name.substring(0, clsLength) : name;
66                              if (filter.shouldRun(toFile(path, simpleClassName), null)) {
67                                  String fullyQualifiedClassName =
68                                          pAckage.isEmpty() ? simpleClassName : pAckage + '.' + simpleClassName;
69                                  scannedJavaClassNames.add(fullyQualifiedClassName);
70                              }
71                          }
72                      } else if (fileOrDir.isDirectory()) {
73                          String[] paths = new String[subDirectories.length + 1];
74                          System.arraycopy(subDirectories, 0, paths, 0, subDirectories.length);
75                          paths[subDirectories.length] = name;
76                          scan(scannedJavaClassNames, filter, fileOrDir, paths);
77                      }
78                  }
79              }
80          }
81      }
82  
83      private static String toJavaPackage(String... subDirectories) {
84          StringBuilder pkg = new StringBuilder();
85          for (int i = 0; i < subDirectories.length; i++) {
86              if (i > 0 && i < subDirectories.length) {
87                  pkg.append('.');
88              }
89              pkg.append(subDirectories[i]);
90          }
91          return pkg.toString();
92      }
93  
94      private static String toPath(String... subDirectories) {
95          StringBuilder pkg = new StringBuilder();
96          for (int i = 0; i < subDirectories.length; i++) {
97              if (i > 0 && i < subDirectories.length) {
98                  pkg.append('/');
99              }
100             pkg.append(subDirectories[i]);
101         }
102         return pkg.toString();
103     }
104 
105     private String toFile(String path, String fileNameWithoutExtension) {
106         String pathWithoutExtension = path.isEmpty() ? fileNameWithoutExtension : path + '/' + fileNameWithoutExtension;
107         return pathWithoutExtension + ext;
108     }
109 }