View Javadoc
1   /*
2    * The MIT License (MIT)
3    *
4    * Copyright (c) 2013-2026 The Coveralls Maven Plugin Project Contributors:
5    *     https://github.com/hazendaz/coveralls-maven-plugin/graphs/contributors
6    *
7    * Permission is hereby granted, free of charge, to any person obtaining a copy
8    * of this software and associated documentation files (the "Software"), to deal
9    * in the Software without restriction, including without limitation the rights
10   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11   * copies of the Software, and to permit persons to whom the Software is
12   * furnished to do so, subject to the following conditions:
13   *
14   * The above copyright notice and this permission notice shall be included in
15   * all copies or substantial portions of the Software.
16   *
17   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23   * THE SOFTWARE.
24   */
25  package org.eluder.coveralls.maven.plugin.source;
26  
27  import java.io.BufferedInputStream;
28  import java.io.File;
29  import java.io.IOException;
30  import java.io.InputStream;
31  import java.nio.charset.Charset;
32  import java.nio.file.Files;
33  import java.nio.file.Path;
34  import java.util.HashMap;
35  import java.util.Map;
36  
37  import org.apache.commons.io.FilenameUtils;
38  import org.codehaus.plexus.util.DirectoryScanner;
39  import org.codehaus.plexus.util.SelectorUtils;
40  
41  /**
42   * The Class ScanSourceLoader.
43   */
44  public class ScanSourceLoader extends AbstractSourceLoader {
45  
46      /** The cache. */
47      private final Map<String, String[]> cache = new HashMap<>();
48  
49      /** The source directory. */
50      private final File sourceDirectory;
51  
52      /**
53       * Instantiates a new scan source loader.
54       *
55       * @param base
56       *            the base
57       * @param sourceDirectory
58       *            the source directory
59       * @param sourceEncoding
60       *            the source encoding
61       */
62      public ScanSourceLoader(final File base, final File sourceDirectory, final Charset sourceEncoding) {
63          super(base.toURI(), sourceDirectory.toURI(), sourceEncoding);
64          this.sourceDirectory = sourceDirectory;
65      }
66  
67      @Override
68      protected InputStream locate(final String sourceFile) throws IOException {
69          final var path = Path.of(this.sourceDirectory.toString(), this.getFileName(sourceFile));
70  
71          if (Files.exists(path)) {
72              if (!Files.isRegularFile(path)) {
73                  throw new IllegalArgumentException(path.toAbsolutePath() + " is not file");
74              }
75              return new BufferedInputStream(Files.newInputStream(path));
76          }
77          return null;
78      }
79  
80      /**
81       * Scan for.
82       *
83       * @param extension
84       *            the extension
85       *
86       * @return the string[]
87       */
88      private String[] scanFor(final String extension) {
89          return this.cache.computeIfAbsent(extension, ext -> {
90              final var scanner = new DirectoryScanner();
91              scanner.setBasedir(this.sourceDirectory);
92              scanner.addDefaultExcludes();
93              scanner.setIncludes(new String[] { "**/*." + ext });
94              scanner.scan();
95              return scanner.getIncludedFiles();
96          });
97      }
98  
99      @Override
100     protected String getFileName(final String sourceFile) {
101         final var extension = FilenameUtils.getExtension(sourceFile);
102         final var matchingExtensionFiles = this.scanFor(extension);
103 
104         for (final String matchingExtensionFile : matchingExtensionFiles) {
105             if (SelectorUtils.matchPath("**/" + sourceFile, matchingExtensionFile, true)) {
106                 return matchingExtensionFile;
107             }
108         }
109 
110         return sourceFile;
111     }
112 
113 }