Skip to content

Commit e42e360

Browse files
committed
Take in account more information provided by the <source> elements of the pom.xml file.
With this commit, the include/exclude filters declared in `<source>` are combined with the include/exclude filters declared in the puglin configuration. The module name and release information are also stored, but only partially supported yet.
1 parent 8a3dd9f commit e42e360

File tree

6 files changed

+169
-83
lines changed

6 files changed

+169
-83
lines changed

src/main/java/org/apache/maven/plugin/compiler/AbstractCompilerMojo.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1372,7 +1372,7 @@ && getIncrementalExcludes().isEmpty())) {
13721372
logger.warn(sb);
13731373
}
13741374
/*
1375-
* Configure all paths to source files. Each compilation unit has its own set of source.
1375+
* Configure all paths to source files. Each compilation unit has its own set of sources.
13761376
* More than one compilation unit may exist in the case of a multi-releases project.
13771377
* Units are compiled in the order of the release version, with base compiled first.
13781378
*/

src/main/java/org/apache/maven/plugin/compiler/CompilerMojo.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ protected Set<String> getIncrementalExcludes() {
219219
@Override
220220
protected Path getOutputDirectory() {
221221
if (SUPPORT_LEGACY && multiReleaseOutput && release != null) {
222-
return outputDirectory.resolve(Path.of("META-INF", "versions", release));
222+
return SourceDirectory.outputDirectoryForReleases(outputDirectory).resolve(release);
223223
}
224224
return outputDirectory;
225225
}
@@ -245,12 +245,12 @@ protected String getDebugFileName() {
245245
*/
246246
@Override
247247
@Deprecated(since = "4.0.0")
248-
protected void addImplicitDependencies(
248+
void addImplicitDependencies(
249249
List<SourceDirectory> sourceDirectories, Map<PathType, List<Path>> addTo, boolean hasModuleDeclaration)
250250
throws IOException {
251251
if (SUPPORT_LEGACY && multiReleaseOutput) {
252252
var paths = new TreeMap<Integer, Path>();
253-
Path root = outputDirectory.resolve(Path.of("META-INF", "versions"));
253+
Path root = SourceDirectory.outputDirectoryForReleases(outputDirectory);
254254
Files.walk(root, 1).forEach((path) -> {
255255
int version;
256256
if (path.equals(root)) {

src/main/java/org/apache/maven/plugin/compiler/PathFilter.java

Lines changed: 52 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818
*/
1919
package org.apache.maven.plugin.compiler;
2020

21-
import javax.tools.JavaFileObject;
22-
2321
import java.io.IOException;
2422
import java.io.UncheckedIOException;
2523
import java.nio.file.FileSystem;
@@ -61,17 +59,22 @@ final class PathFilter extends SimpleFileVisitor<Path> implements Predicate<Path
6159
* Whether to use the default include pattern.
6260
* The pattern depends on the type of source file.
6361
*/
64-
private final boolean defaultInclude;
62+
private final boolean useDefaultInclude;
6563

6664
/**
67-
* All inclusion filters for the files in the directories to walk. The array shall contain at least one element.
68-
* If {@link #defaultInclude} is {@code true}, then this array length shall be exactly 1 and the single element
69-
* is overwritten for each directory to walk.
65+
* Inclusion filters for the files in the directories to walk as specified in the plugin configuration.
66+
* The array should contain at least one element, unless {@link SourceDirectory#includes} is non-empty.
67+
* If {@link #useDefaultInclude} is {@code true}, then this array length shall be exactly 1 and the
68+
* single element is overwritten for each directory to walk.
69+
*
70+
* @see SourceDirectory#includes
7071
*/
7172
private final String[] includes;
7273

7374
/**
74-
* All exclusion filters for the files in the directories to walk, or an empty array if none.
75+
* Exclusion filters for the files in the directories to walk as specified in the plugin configuration.
76+
*
77+
* @see SourceDirectory#excludes
7578
*/
7679
private final String[] excludes;
7780

@@ -83,32 +86,32 @@ final class PathFilter extends SimpleFileVisitor<Path> implements Predicate<Path
8386

8487
/**
8588
* The matchers for inclusion filters (never empty).
86-
* The array length shall be equal to the {@link #includes} array length.
87-
* The values are initially null and overwritten when first needed, then when the file system changes.
89+
* The array length shall be equal or greater than the {@link #includes} array length.
90+
* The array is initially null and created when first needed, then when the file system changes.
8891
*/
89-
private final PathMatcher[] includeMatchers;
92+
private PathMatcher[] includeMatchers;
9093

9194
/**
9295
* The matchers for exclusion filters (potentially empty).
93-
* The array length shall be equal to the {@link #excludes} array length.
94-
* The values are initially null and overwritten when first needed, then when the file system changes.
96+
* The array length shall be equal or greater than the {@link #excludes} array length.
97+
* The array is initially null and created when first needed, then when the file system changes.
9598
*/
96-
private final PathMatcher[] excludeMatchers;
99+
private PathMatcher[] excludeMatchers;
97100

98101
/**
99102
* The matchers for exclusion filters for incremental build calculation.
100103
* The array length shall be equal to the {@link #incrementalExcludes} array length.
101-
* The values are initially null and overwritten when first needed, then when the file system changes.
104+
* The array is initially null and created when first needed, then when the file system changes.
102105
*/
103-
private final PathMatcher[] incrementalExcludeMatchers;
106+
private PathMatcher[] incrementalExcludeMatchers;
104107

105108
/**
106109
* Whether paths must be relativized before to be given to a matcher. If {@code true} (the default),
107110
* then every paths will be made relative to the source root directory for allowing patterns like
108111
* {@code "foo/bar/*.java"} to work. As a slight optimization, we can skip this step if all patterns
109112
* start with {@code "**"}.
110113
*/
111-
private final boolean needRelativize;
114+
private boolean needRelativize;
112115

113116
/**
114117
* The file system of the path matchers, or {@code null} if not yet determined.
@@ -138,17 +141,13 @@ final class PathFilter extends SimpleFileVisitor<Path> implements Predicate<Path
138141
* @param incrementalExcludes exclusion filters for incremental build calculation
139142
*/
140143
PathFilter(Collection<String> includes, Collection<String> excludes, Collection<String> incrementalExcludes) {
141-
defaultInclude = includes.isEmpty();
142-
if (defaultInclude) {
143-
includes = List.of("**");
144+
useDefaultInclude = includes.isEmpty();
145+
if (useDefaultInclude) {
146+
includes = List.of("**"); // Place-holder replaced by "**/*.java" in `test(…)`.
144147
}
145148
this.includes = includes.toArray(String[]::new);
146149
this.excludes = excludes.toArray(String[]::new);
147150
this.incrementalExcludes = incrementalExcludes.toArray(String[]::new);
148-
includeMatchers = new PathMatcher[this.includes.length];
149-
excludeMatchers = new PathMatcher[this.excludes.length];
150-
incrementalExcludeMatchers = new PathMatcher[this.incrementalExcludes.length];
151-
needRelativize = needRelativize(this.includes) || needRelativize(this.excludes);
152151
}
153152

154153
/**
@@ -158,44 +157,40 @@ final class PathFilter extends SimpleFileVisitor<Path> implements Predicate<Path
158157
*/
159158
private static boolean needRelativize(String[] patterns) {
160159
for (String pattern : patterns) {
161-
if (!pattern.startsWith("**")) {
160+
if (!pattern.startsWith("**", pattern.indexOf(':') + 1)) {
162161
return true;
163162
}
164163
}
165164
return false;
166165
}
167166

168167
/**
169-
* If the default include patterns is used, updates it for the given kind of source files.
170-
*
171-
* @param sourceFileKind the kind of files to compile
172-
*/
173-
private void updateDefaultInclude(JavaFileObject.Kind sourceFileKind) {
174-
if (defaultInclude) {
175-
String pattern = "glob:**" + sourceFileKind.extension;
176-
if (!pattern.equals(includes[0])) {
177-
includes[0] = pattern;
178-
if (fs != null) {
179-
createMatchers(includes, includeMatchers, fs);
180-
}
181-
}
182-
}
183-
}
184-
185-
/**
186-
* Fills the target array with path matchers created from the given patterns.
168+
* Creates the matchers for the given patterns.
187169
* If a pattern does not specify a syntax, then the "glob" syntax is used by default.
170+
* If the {@code forDirectory} list contains at least one element and {@code patterns}
171+
* is the default pattern, then the latter is ignored in favor of the former.
188172
*
189173
* <p>This method should be invoked only once, unless different paths are on different file systems.</p>
174+
*
175+
* @param forDirectory the matchers declared in the {@code <source>} element for the current {@link #sourceRoot}
176+
* @param patterns the matterns declared in the compiler plugin configuration
177+
* @param hasDefault whether the first element of {@code patterns} is the default pattern
178+
* @param fs the file system
179+
* @return all matchers from the source, followed by matchers from the given patterns
190180
*/
191-
private static void createMatchers(String[] patterns, PathMatcher[] target, FileSystem fs) {
192-
for (int i = 0; i < patterns.length; i++) {
181+
private static PathMatcher[] createMatchers(
182+
List<PathMatcher> forDirectory, String[] patterns, boolean hasDefault, FileSystem fs) {
183+
final int base = forDirectory.size();
184+
final int skip = (hasDefault && base != 0) ? 1 : 0;
185+
final var target = forDirectory.toArray(new PathMatcher[base + patterns.length - skip]);
186+
for (int i = skip; i < patterns.length; i++) {
193187
String pattern = patterns[i];
194188
if (pattern.indexOf(':') < 0) {
195189
pattern = "glob:" + pattern;
196190
}
197-
target[i] = fs.getPathMatcher(pattern);
191+
target[base + i] = fs.getPathMatcher(pattern);
198192
}
193+
return target;
199194
}
200195

201196
/**
@@ -207,11 +202,19 @@ private static void createMatchers(String[] patterns, PathMatcher[] target, File
207202
*/
208203
@Override
209204
public boolean test(Path path) {
205+
@SuppressWarnings("LocalVariableHidesMemberVariable")
206+
final SourceDirectory sourceRoot = this.sourceRoot; // Protect from changes.
210207
FileSystem pfs = path.getFileSystem();
211208
if (pfs != fs) {
212-
createMatchers(includes, includeMatchers, pfs);
213-
createMatchers(excludes, excludeMatchers, pfs);
214-
createMatchers(incrementalExcludes, incrementalExcludeMatchers, pfs);
209+
if (useDefaultInclude) {
210+
includes[0] = "glob:**" + sourceRoot.fileKind.extension;
211+
}
212+
includeMatchers = createMatchers(sourceRoot.includes, includes, useDefaultInclude, pfs);
213+
excludeMatchers = createMatchers(sourceRoot.excludes, excludes, false, pfs);
214+
incrementalExcludeMatchers = createMatchers(List.of(), incrementalExcludes, false, pfs);
215+
needRelativize = !(sourceRoot.includes.isEmpty() && sourceRoot.excludes.isEmpty())
216+
|| needRelativize(includes)
217+
|| needRelativize(excludes);
215218
fs = pfs;
216219
}
217220
if (needRelativize) {
@@ -291,8 +294,8 @@ public List<SourceFile> walkSourceFiles(Iterable<SourceDirectory> rootDirectorie
291294
sourceFiles = result;
292295
for (SourceDirectory directory : rootDirectories) {
293296
sourceRoot = directory;
294-
updateDefaultInclude(directory.fileKind);
295297
Files.walkFileTree(directory.root, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, this);
298+
fs = null; // Will force a recalculation of matchers in next iteration.
296299
}
297300
} catch (UncheckedIOException e) {
298301
throw e.getCause();

0 commit comments

Comments
 (0)