19
19
import java .util .List ;
20
20
import java .util .Optional ;
21
21
import java .util .function .Predicate ;
22
+ import java .util .stream .Stream ;
22
23
23
24
import org .apiguardian .api .API ;
24
25
import org .junit .platform .commons .JUnitException ;
@@ -114,6 +115,31 @@ public static List<Class<?>> findAllClassesInClasspathRoot(URI root, Predicate<C
114
115
return ReflectionUtils .findAllClassesInClasspathRoot (root , classFilter , classNameFilter );
115
116
}
116
117
118
+ /**
119
+ * Find all {@linkplain Class classes} in the supplied classpath {@code root}
120
+ * that match the specified {@code classFilter} and {@code classNameFilter}
121
+ * predicates.
122
+ *
123
+ * <p>The classpath scanning algorithm searches recursively in subpackages
124
+ * beginning with the root of the classpath.
125
+ *
126
+ * @param root the URI for the classpath root in which to scan; never
127
+ * {@code null}
128
+ * @param classFilter the class type filter; never {@code null}
129
+ * @param classNameFilter the class name filter; never {@code null}
130
+ * @return a stream of all such classes found; never {@code null}
131
+ * but potentially empty
132
+ * @since 1.10
133
+ * @see #findAllClassesInPackage(String, Predicate, Predicate)
134
+ * @see #findAllClassesInModule(String, Predicate, Predicate)
135
+ */
136
+ @ API (status = MAINTAINED , since = "1.10" )
137
+ public static Stream <Class <?>> streamAllClassesInClasspathRoot (URI root , Predicate <Class <?>> classFilter ,
138
+ Predicate <String > classNameFilter ) {
139
+
140
+ return ReflectionUtils .streamAllClassesInClasspathRoot (root , classFilter , classNameFilter );
141
+ }
142
+
117
143
/**
118
144
* Find all {@linkplain Class classes} in the supplied {@code basePackageName}
119
145
* that match the specified {@code classFilter} and {@code classNameFilter}
@@ -138,6 +164,32 @@ public static List<Class<?>> findAllClassesInPackage(String basePackageName, Pre
138
164
return ReflectionUtils .findAllClassesInPackage (basePackageName , classFilter , classNameFilter );
139
165
}
140
166
167
+ /**
168
+ * Find all {@linkplain Class classes} in the supplied {@code basePackageName}
169
+ * that match the specified {@code classFilter} and {@code classNameFilter}
170
+ * predicates.
171
+ *
172
+ * <p>The classpath scanning algorithm searches recursively in subpackages
173
+ * beginning within the supplied base package.
174
+ *
175
+ * @param basePackageName the name of the base package in which to start
176
+ * scanning; must not be {@code null} and must be valid in terms of Java
177
+ * syntax
178
+ * @param classFilter the class type filter; never {@code null}
179
+ * @param classNameFilter the class name filter; never {@code null}
180
+ * @return a stream of all such classes found; never {@code null}
181
+ * but potentially empty
182
+ * @since 1.10
183
+ * @see #findAllClassesInClasspathRoot(URI, Predicate, Predicate)
184
+ * @see #findAllClassesInModule(String, Predicate, Predicate)
185
+ */
186
+ @ API (status = MAINTAINED , since = "1.10" )
187
+ public static Stream <Class <?>> streamAllClassesInPackage (String basePackageName , Predicate <Class <?>> classFilter ,
188
+ Predicate <String > classNameFilter ) {
189
+
190
+ return ReflectionUtils .streamAllClassesInPackage (basePackageName , classFilter , classNameFilter );
191
+ }
192
+
141
193
/**
142
194
* Find all {@linkplain Class classes} in the supplied {@code moduleName}
143
195
* that match the specified {@code classFilter} and {@code classNameFilter}
@@ -162,6 +214,31 @@ public static List<Class<?>> findAllClassesInModule(String moduleName, Predicate
162
214
return ReflectionUtils .findAllClassesInModule (moduleName , classFilter , classNameFilter );
163
215
}
164
216
217
+ /**
218
+ * Find all {@linkplain Class classes} in the supplied {@code moduleName}
219
+ * that match the specified {@code classFilter} and {@code classNameFilter}
220
+ * predicates.
221
+ *
222
+ * <p>The module-path scanning algorithm searches recursively in all
223
+ * packages contained in the module.
224
+ *
225
+ * @param moduleName the name of the module to scan; never {@code null} or
226
+ * <em>empty</em>
227
+ * @param classFilter the class type filter; never {@code null}
228
+ * @param classNameFilter the class name filter; never {@code null}
229
+ * @return a stream of all such classes found; never {@code null}
230
+ * but potentially empty
231
+ * @since 1.10
232
+ * @see #findAllClassesInClasspathRoot(URI, Predicate, Predicate)
233
+ * @see #findAllClassesInPackage(String, Predicate, Predicate)
234
+ */
235
+ @ API (status = MAINTAINED , since = "1.10" )
236
+ public static Stream <Class <?>> streamAllClassesInModule (String moduleName , Predicate <Class <?>> classFilter ,
237
+ Predicate <String > classNameFilter ) {
238
+
239
+ return ReflectionUtils .streamAllClassesInModule (moduleName , classFilter , classNameFilter );
240
+ }
241
+
165
242
/**
166
243
* Create a new instance of the specified {@link Class} by invoking
167
244
* the constructor whose argument list matches the types of the supplied
@@ -225,6 +302,31 @@ public static List<Field> findFields(Class<?> clazz, Predicate<Field> predicate,
225
302
ReflectionUtils .HierarchyTraversalMode .valueOf (traversalMode .name ()));
226
303
}
227
304
305
+ /**
306
+ * Find all {@linkplain Field fields} of the supplied class or interface
307
+ * that match the specified {@code predicate}.
308
+ *
309
+ * <p>Fields declared in the same class or interface will be ordered using
310
+ * an algorithm that is deterministic but intentionally nonobvious.
311
+ *
312
+ * <p>The results will not contain fields that are <em>hidden</em> or
313
+ * {@linkplain Field#isSynthetic() synthetic}.
314
+ *
315
+ * @param clazz the class or interface in which to find the fields; never {@code null}
316
+ * @param predicate the field filter; never {@code null}
317
+ * @param traversalMode the hierarchy traversal mode; never {@code null}
318
+ * @return a stream of all such fields found; never {@code null}
319
+ * but potentially empty
320
+ * @since 1.10
321
+ */
322
+ @ API (status = MAINTAINED , since = "1.10" )
323
+ public static Stream <Field > streamFields (Class <?> clazz , Predicate <Field > predicate ,
324
+ HierarchyTraversalMode traversalMode ) {
325
+ Preconditions .notNull (traversalMode , "HierarchyTraversalMode must not be null" );
326
+ return ReflectionUtils .streamFields (clazz , predicate ,
327
+ ReflectionUtils .HierarchyTraversalMode .valueOf (traversalMode .name ()));
328
+ }
329
+
228
330
/**
229
331
* Try to read the value of a potentially inaccessible field.
230
332
*
@@ -307,6 +409,34 @@ public static List<Method> findMethods(Class<?> clazz, Predicate<Method> predica
307
409
ReflectionUtils .HierarchyTraversalMode .valueOf (traversalMode .name ()));
308
410
}
309
411
412
+ /**
413
+ * Find all distinct {@linkplain Method methods} of the supplied class or
414
+ * interface that match the specified {@code predicate}.
415
+ *
416
+ * <p>The results will not contain instance methods that are <em>overridden</em>
417
+ * or {@code static} methods that are <em>hidden</em>.
418
+ *
419
+ * <p>If you're are looking for methods annotated with a certain annotation
420
+ * type, consider using
421
+ * {@link AnnotationSupport#findAnnotatedMethods(Class, Class, HierarchyTraversalMode)}.
422
+ *
423
+ * @param clazz the class or interface in which to find the methods; never {@code null}
424
+ * @param predicate the method filter; never {@code null}
425
+ * @param traversalMode the hierarchy traversal mode; never {@code null}
426
+ * @return a stream of all such methods found; never {@code null}
427
+ * @since 1.10
428
+ * but potentially empty
429
+ */
430
+ @ API (status = MAINTAINED , since = "1.10" )
431
+ public static Stream <Method > streamMethods (Class <?> clazz , Predicate <Method > predicate ,
432
+ HierarchyTraversalMode traversalMode ) {
433
+
434
+ Preconditions .notNull (traversalMode , "HierarchyTraversalMode must not be null" );
435
+
436
+ return ReflectionUtils .streamMethods (clazz , predicate ,
437
+ ReflectionUtils .HierarchyTraversalMode .valueOf (traversalMode .name ()));
438
+ }
439
+
310
440
/**
311
441
* Find all nested classes within the supplied class, or inherited by the
312
442
* supplied class, that conform to the supplied predicate.
@@ -333,4 +463,32 @@ public static List<Class<?>> findNestedClasses(Class<?> clazz, Predicate<Class<?
333
463
return ReflectionUtils .findNestedClasses (clazz , predicate );
334
464
}
335
465
466
+ /**
467
+ * Find all nested classes within the supplied class, or inherited by the
468
+ * supplied class, that conform to the supplied predicate.
469
+ *
470
+ * <p>This method does <strong>not</strong> search for nested classes
471
+ * recursively.
472
+ *
473
+ * <p>As of JUnit Platform 1.6, this method detects cycles in <em>inner</em>
474
+ * class hierarchies — from the supplied class up to the outermost
475
+ * enclosing class — and throws a {@link JUnitException} if such a cycle
476
+ * is detected. Cycles within inner class hierarchies <em>below</em> the
477
+ * supplied class are not detected by this method.
478
+ *
479
+ * @param clazz the class to be searched; never {@code null}
480
+ * @param predicate the predicate against which the list of nested classes is
481
+ * checked; never {@code null}
482
+ * @return a stream of all such classes found; never {@code null}
483
+ * but potentially empty
484
+ * @throws JUnitException if a cycle is detected within an inner class hierarchy
485
+ * @since 1.10
486
+ */
487
+ @ API (status = MAINTAINED , since = "1.10" )
488
+ public static Stream <Class <?>> streamNestedClasses (Class <?> clazz , Predicate <Class <?>> predicate )
489
+ throws JUnitException {
490
+
491
+ return ReflectionUtils .streamNestedClasses (clazz , predicate );
492
+ }
493
+
336
494
}
0 commit comments