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.api.services;
20
21 import java.nio.file.Path;
22 import java.nio.file.PathMatcher;
23 import java.util.Collection;
24 import java.util.Objects;
25
26 import org.apache.maven.api.Service;
27 import org.apache.maven.api.annotations.Experimental;
28 import org.apache.maven.api.annotations.Nonnull;
29
30 /**
31 * Service for creating {@link PathMatcher} objects that can be used to filter files
32 * based on include/exclude patterns. This service provides a clean API for plugins
33 * to create path matchers without directly depending on implementation classes.
34 * <p>
35 * The path matchers created by this service support Maven's traditional include/exclude
36 * pattern syntax, which is compatible with the behavior of Maven 3 plugins like
37 * maven-compiler-plugin and maven-clean-plugin.
38 * <p>
39 * Pattern syntax supports:
40 * <ul>
41 * <li>Standard glob patterns with {@code *}, {@code ?}, and {@code **} wildcards</li>
42 * <li>Explicit syntax prefixes like {@code "glob:"} or {@code "regex:"}</li>
43 * <li>Maven 3 compatible behavior for patterns without explicit syntax</li>
44 * <li>Default exclusion patterns for SCM files when requested</li>
45 * </ul>
46 *
47 * @since 4.0.0
48 * @see PathMatcher
49 */
50 @Experimental
51 public interface PathMatcherFactory extends Service {
52
53 /**
54 * Creates a path matcher for filtering files based on include and exclude patterns.
55 * <p>
56 * The pathnames used for matching will be relative to the specified base directory
57 * and use {@code '/'} as separator, regardless of the hosting operating system.
58 *
59 * @param baseDirectory the base directory for relativizing paths during matching
60 * @param includes the patterns of files to include, or null/empty for including all files
61 * @param excludes the patterns of files to exclude, or null/empty for no exclusion
62 * @param useDefaultExcludes whether to augment excludes with default SCM exclusion patterns
63 * @return a PathMatcher that can be used to test if paths should be included
64 * @throws NullPointerException if baseDirectory is null
65 */
66 @Nonnull
67 PathMatcher createPathMatcher(
68 @Nonnull Path baseDirectory,
69 Collection<String> includes,
70 Collection<String> excludes,
71 boolean useDefaultExcludes);
72
73 /**
74 * Creates a path matcher for filtering files based on include and exclude patterns,
75 * without using default exclusion patterns.
76 * <p>
77 * This is equivalent to calling {@link #createPathMatcher(Path, Collection, Collection, boolean)}
78 * with {@code useDefaultExcludes = false}.
79 *
80 * @param baseDirectory the base directory for relativizing paths during matching
81 * @param includes the patterns of files to include, or null/empty for including all files
82 * @param excludes the patterns of files to exclude, or null/empty for no exclusion
83 * @return a PathMatcher that can be used to test if paths should be included
84 * @throws NullPointerException if baseDirectory is null
85 */
86 @Nonnull
87 default PathMatcher createPathMatcher(
88 @Nonnull Path baseDirectory, Collection<String> includes, Collection<String> excludes) {
89 return createPathMatcher(baseDirectory, includes, excludes, false);
90 }
91
92 /**
93 * Creates a path matcher that includes all files except those matching the exclude patterns.
94 * <p>
95 * This is equivalent to calling {@link #createPathMatcher(Path, Collection, Collection, boolean)}
96 * with {@code includes = null}.
97 *
98 * @param baseDirectory the base directory for relativizing paths during matching
99 * @param excludes the patterns of files to exclude, or null/empty for no exclusion
100 * @param useDefaultExcludes whether to augment excludes with default SCM exclusion patterns
101 * @return a PathMatcher that can be used to test if paths should be included
102 * @throws NullPointerException if baseDirectory is null
103 */
104 @Nonnull
105 default PathMatcher createExcludeOnlyMatcher(
106 @Nonnull Path baseDirectory, Collection<String> excludes, boolean useDefaultExcludes) {
107 return createPathMatcher(baseDirectory, null, excludes, useDefaultExcludes);
108 }
109
110 /**
111 * Creates a path matcher that only includes files matching the include patterns.
112 * <p>
113 * This is equivalent to calling {@link #createPathMatcher(Path, Collection, Collection, boolean)}
114 * with {@code excludes = null} and {@code useDefaultExcludes = false}.
115 *
116 * @param baseDirectory the base directory for relativizing paths during matching
117 * @param includes the patterns of files to include, or null/empty for including all files
118 * @return a PathMatcher that can be used to test if paths should be included
119 * @throws NullPointerException if baseDirectory is null
120 */
121 @Nonnull
122 default PathMatcher createIncludeOnlyMatcher(@Nonnull Path baseDirectory, Collection<String> includes) {
123 return createPathMatcher(baseDirectory, includes, null, false);
124 }
125
126 /**
127 * Returns a filter for directories that may contain paths accepted by the given matcher.
128 * The given path matcher should be an instance created by this service.
129 * The path matcher returned by this method expects <em>directory</em> paths.
130 * If that matcher returns {@code false}, then the directory will definitively not contain
131 * the paths selected by the matcher given in argument to this method.
132 * In such case, the whole directory and all its sub-directories can be skipped.
133 * In case of doubt, or if the matcher given in argument is not recognized by this method,
134 * then the matcher returned by this method will return {@code true}.
135 *
136 * @param fileMatcher a matcher created by one of the other methods of this interface
137 * @return filter for directories that may contain the selected files
138 * @throws NullPointerException if fileMatcher is null
139 */
140 @Nonnull
141 PathMatcher deriveDirectoryMatcher(@Nonnull PathMatcher fileMatcher);
142
143 /**
144 * Returns the path matcher that unconditionally returns {@code true} for all files.
145 * It should be the matcher returned by the other methods of this interface when the
146 * given patterns match all files.
147 *
148 * @return path matcher that unconditionally returns {@code true} for all files
149 */
150 @Nonnull
151 PathMatcher includesAll();
152
153 /**
154 * {@return whether the given matcher includes all files}.
155 * This method may conservatively returns {@code false} if case of doubt.
156 * A return value of {@code true} means that the pattern is certain to match all files.
157 *
158 * @param matcher the matcher to test
159 */
160 default boolean isIncludesAll(@Nonnull PathMatcher matcher) {
161 return Objects.requireNonNull(matcher) == includesAll();
162 }
163 }