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.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 }