1414import java .util .regex .Pattern ;
1515import java .util .stream .Stream ;
1616import org .jspecify .annotations .NullMarked ;
17+ import org .jspecify .annotations .Nullable ;
1718
1819/**
1920 * Utility class providing factory and composition methods for {@link PathMatcher}s.
@@ -192,13 +193,15 @@ public static PathMatcher anyOf(Iterable<PathMatcher> matchers) {
192193 return combineMatchers (matchers , Mode .ANY );
193194 }
194195
195- private static List <PathMatcher > buildSafeList (PathMatcher matcher , PathMatcher ... matchers ) {
196+ private static List <PathMatcher > buildSafeList (PathMatcher matcher , @ Nullable PathMatcher ... matchers ) {
196197 Objects .requireNonNull (matcher , "matcher is null" );
197198 var list = new ArrayList <PathMatcher >(1 + (matchers == null ? 0 : matchers .length ));
198199 list .add (matcher );
199- for (PathMatcher m : matchers ) {
200- Objects .requireNonNull (m , "some matcher is null" );
201- list .add (m );
200+ if (matchers != null ) {
201+ for (PathMatcher m : matchers ) {
202+ Objects .requireNonNull (m , "some matcher is null" );
203+ list .add (m );
204+ }
202205 }
203206 return List .copyOf (list );
204207 }
@@ -219,32 +222,37 @@ private static PathMatcher combineMatchers(Iterable<PathMatcher> matchers, Mode
219222 if (list .isEmpty ()) {
220223 throw new IllegalArgumentException ("No matcher provided" );
221224 }
222- return path -> {
223- switch (mode ) {
224- case ALL :
225- for (PathMatcher m : list ) {
226- if (!m .matches (path ))
227- return false ;
228- }
229- return true ;
230- case ANY :
231- for (PathMatcher m : list ) {
232- if (m .matches (path ))
233- return true ;
234- }
235- return false ;
236- case NONE :
237- for (PathMatcher m : list ) {
238- if (m .matches (path ))
239- return false ;
240- }
241- return true ;
242- default :
243- throw new AssertionError ("Unknown mode: " + mode );
244- }
225+ return switch (mode ) {
226+ case ALL -> path -> all (path , list );
227+ case ANY -> path -> any (path , list );
228+ case NONE -> path -> none (path , list );
245229 };
246230 }
247231
232+ private static boolean all (Path path , List <PathMatcher > matchers ) {
233+ for (PathMatcher m : matchers ) {
234+ if (!m .matches (path ))
235+ return false ;
236+ }
237+ return true ;
238+ }
239+
240+ private static boolean any (Path path , List <PathMatcher > matchers ) {
241+ for (PathMatcher m : matchers ) {
242+ if (m .matches (path ))
243+ return true ;
244+ }
245+ return false ;
246+ }
247+
248+ private static boolean none (Path path , List <PathMatcher > matchers ) {
249+ for (PathMatcher m : matchers ) {
250+ if (m .matches (path ))
251+ return false ;
252+ }
253+ return true ;
254+ }
255+
248256 /**
249257 * Returns a conditional matcher.
250258 *
@@ -589,7 +597,7 @@ public static PathMatcher isRegularFile() {
589597 * @return matcher returning {@code true} if the path is a symbolic link
590598 */
591599 public static PathMatcher isSymbolicLink () {
592- return path -> Files . isSymbolicLink ( path ) ;
600+ return Files :: isSymbolicLink ;
593601 }
594602
595603 // ---------- Hierarchy ----------
@@ -688,7 +696,7 @@ private static final boolean testDescendants(Path path, int depth, PathMatcher d
688696 return stream
689697 .skip (1 ) // skip the root path itself
690698 .filter (inclusionFilter )
691- .anyMatch (p -> descendantMatcher . matches ( p ) );
699+ .anyMatch (descendantMatcher :: matches );
692700 } catch (IOException e ) {
693701 throw new UncheckedIOException ("Exception while walking files of " + path , e );
694702 }
0 commit comments