0
# Functional Queries
1
2
Modern functional query system using QueryFunction for composable, type-safe metadata queries with filtering, mapping, and transformation capabilities. This system provides a powerful and flexible API for querying scanned metadata.
3
4
## Capabilities
5
6
### QueryFunction Interface
7
8
Core functional interface for creating composable queries with type safety and functional composition.
9
10
```java { .api }
11
/**
12
* Functional interface for store queries
13
*/
14
interface QueryFunction<C, T> extends Function<C, Set<T>>, NameHelper {
15
/** Apply query to context and return results */
16
Set<T> apply(C ctx);
17
18
/** Filter results using predicate */
19
default QueryFunction<C, T> filter(Predicate<? super T> predicate);
20
21
/** Map results to different type */
22
default <R> QueryFunction<C, R> map(Function<? super T, ? extends R> function);
23
24
/** Flat map results with nested queries */
25
default <R> QueryFunction<C, R> flatMap(Function<T, ? extends Function<C, Set<R>>> function);
26
27
/** Get transitive results using builder function */
28
default QueryFunction<C, T> getAll(Function<T, QueryFunction<C, T>> builder);
29
30
/** Get transitive results with traverse function */
31
default <R> QueryFunction<C, R> getAll(Function<T, QueryFunction<C, R>> builder, Function<R, T> traverse);
32
33
/** Concatenate results with another query function */
34
default <R> QueryFunction<C, T> add(QueryFunction<C, T> function);
35
36
/** Convert results to specific type with class loaders */
37
default <R> QueryFunction<C, R> as(Class<? extends R> type, ClassLoader... loaders);
38
39
/** Convert results to Class objects */
40
default <R> QueryFunction<C, Class<?>> asClass(ClassLoader... loaders);
41
42
/** Convert results to strings */
43
default QueryFunction<C, String> asString();
44
45
/** Unsafe cast to different type */
46
default <R> QueryFunction<C, Class<? extends R>> as();
47
}
48
```
49
50
### Static Factory Methods
51
52
Static methods for creating basic QueryFunction instances.
53
54
```java { .api }
55
/**
56
* Static factory methods for QueryFunction
57
*/
58
interface QueryFunction<C, T> extends Function<C, Set<T>>, NameHelper {
59
/** Create empty result query */
60
static <C, T> QueryFunction<Store, T> empty();
61
62
/** Create single element query */
63
static <C, T> QueryFunction<Store, T> single(T element);
64
65
/** Create query from collection of elements */
66
static <C, T> QueryFunction<Store, T> set(Collection<T> elements);
67
}
68
```
69
70
### ReflectionUtils Query Builders
71
72
Pre-built query builders for common reflection operations using the modern functional API.
73
74
```java { .api }
75
/**
76
* ReflectionUtils query builders for common operations
77
*/
78
abstract class ReflectionUtils extends ReflectionUtilsPredicates {
79
/** Apply query function to context */
80
static <C, T> Set<T> get(QueryFunction<C, T> function);
81
82
/** Apply query function with additional predicates */
83
static <T> Set<T> get(QueryFunction<Store, T> queryFunction, Predicate<? super T>... predicates);
84
85
/** Query builder for super class */
86
static final UtilQueryBuilder<Class<?>, Class<?>> SuperClass;
87
88
/** Query builder for interfaces */
89
static final UtilQueryBuilder<Class<?>, Class<?>> Interfaces;
90
91
/** Query builder for super types and interfaces */
92
static final UtilQueryBuilder<Class<?>, Class<?>> SuperTypes;
93
94
/** Query builder for annotations */
95
static final UtilQueryBuilder<AnnotatedElement, Annotation> Annotations;
96
97
/** Query builder for annotation types */
98
static final UtilQueryBuilder<AnnotatedElement, Class<? extends Annotation>> AnnotationTypes;
99
100
/** Query builder for methods */
101
static final UtilQueryBuilder<Class<?>, Method> Methods;
102
103
/** Query builder for constructors */
104
static final UtilQueryBuilder<Class<?>, Constructor> Constructors;
105
106
/** Query builder for fields */
107
static final UtilQueryBuilder<Class<?>, Field> Fields;
108
109
/** Query builder for URL resources */
110
static final UtilQueryBuilder<String, URL> Resources;
111
112
/** Predicate to filter out Object methods */
113
static final Predicate<Method> notObjectMethod;
114
}
115
```
116
117
### UtilQueryBuilder
118
119
Specialized query builder for ReflectionUtils operations with enhanced capabilities.
120
121
```java { .api }
122
/**
123
* Query builder for ReflectionUtils operations
124
*/
125
class UtilQueryBuilder<C, T> implements QueryBuilder {
126
/** Get scanner index name */
127
String index();
128
129
/** Get values for specific key */
130
QueryFunction<Store, String> get(String key);
131
132
/** Get values for annotated element */
133
QueryFunction<Store, String> get(AnnotatedElement element);
134
135
/** Get values for collection of keys */
136
QueryFunction<Store, String> get(Collection<String> keys);
137
138
/** Get transitive values for keys */
139
QueryFunction<Store, String> getAll(Collection<String> keys);
140
141
/** Get transitive values including specific key */
142
QueryFunction<Store, String> getAllIncluding(String key);
143
144
/** Get transitive values including collection of keys */
145
QueryFunction<Store, String> getAllIncluding(Collection<String> keys);
146
147
/** Alias for getAll(Collection) */
148
QueryFunction<Store, String> of(Collection<String> keys);
149
150
/** Alias for getAll with single key */
151
QueryFunction<Store, String> of(String key);
152
153
/** Get transitive values for annotated elements */
154
QueryFunction<Store, String> of(AnnotatedElement... elements);
155
156
/** Get transitive values for set of annotated elements */
157
QueryFunction<Store, String> of(Set<? extends AnnotatedElement> elements);
158
159
/** Various "with" aliases for "of" methods */
160
QueryFunction<Store, String> with(String key);
161
QueryFunction<Store, String> with(String... keys);
162
QueryFunction<Store, String> with(AnnotatedElement... elements);
163
QueryFunction<Store, String> with(Collection<String> keys);
164
QueryFunction<Store, String> with(Set<? extends AnnotatedElement> elements);
165
166
/** Compose with another query function */
167
<R> QueryFunction<Store, R> of(QueryFunction queryFunction);
168
}
169
```
170
171
## Usage Examples
172
173
### Basic Functional Queries
174
175
```java
176
import org.reflections.Reflections;
177
import org.reflections.util.QueryFunction;
178
import static org.reflections.scanners.Scanners.*;
179
180
Reflections reflections = new Reflections("com.mycompany");
181
182
// Basic queries using scanner builders
183
Set<String> subtypeNames = reflections.get(SubTypes.of(MyInterface.class));
184
Set<Class<?>> subtypeClasses = reflections.get(SubTypes.of(MyInterface.class).asClass());
185
186
Set<String> annotatedTypeNames = reflections.get(TypesAnnotated.with(MyAnnotation.class));
187
Set<Class<?>> annotatedTypes = reflections.get(TypesAnnotated.with(MyAnnotation.class).asClass());
188
189
Set<Method> annotatedMethods = reflections.get(MethodsAnnotated.with(RequestMapping.class).as(Method.class));
190
```
191
192
### Functional Composition and Filtering
193
194
```java
195
import java.lang.reflect.Modifier;
196
import static org.reflections.scanners.Scanners.*;
197
198
// Filter results using predicates
199
Set<Method> publicMethods = reflections.get(
200
MethodsAnnotated.with(RequestMapping.class)
201
.as(Method.class)
202
.filter(method -> Modifier.isPublic(method.getModifiers())));
203
204
// Chain multiple filters
205
Set<Class<?>> concreteServices = reflections.get(
206
SubTypes.of(Service.class)
207
.asClass()
208
.filter(clazz -> !Modifier.isAbstract(clazz.getModifiers()))
209
.filter(clazz -> !clazz.isInterface()));
210
211
// Map results to different type
212
Set<String> methodNames = reflections.get(
213
MethodsAnnotated.with(RequestMapping.class)
214
.as(Method.class)
215
.map(Method::getName));
216
217
// Complex filtering with business logic
218
Set<Class<?>> validControllers = reflections.get(
219
TypesAnnotated.with(Controller.class)
220
.asClass()
221
.filter(clazz -> clazz.getPackage().getName().startsWith("com.mycompany"))
222
.filter(clazz -> !clazz.getSimpleName().contains("Test"))
223
.filter(clazz -> clazz.getDeclaredMethods().length > 0));
224
```
225
226
### ReflectionUtils Functional Queries
227
228
```java
229
import org.reflections.ReflectionUtils;
230
import static org.reflections.ReflectionUtils.*;
231
232
// Query super types
233
Set<Class<?>> superTypes = get(SuperTypes.of(MyClass.class));
234
Set<Class<?>> allSuperTypes = get(SuperTypes.of(MyClass.class)
235
.filter(clazz -> !clazz.equals(Object.class)));
236
237
// Query annotations
238
Set<Annotation> annotations = get(Annotations.of(MyClass.class));
239
Set<Class<? extends Annotation>> annotationTypes = get(AnnotationTypes.of(MyClass.class));
240
241
// Query methods with filtering
242
Set<Method> getters = get(Methods.of(MyClass.class)
243
.filter(method -> method.getName().startsWith("get"))
244
.filter(method -> method.getParameterCount() == 0));
245
246
Set<Method> setters = get(Methods.of(MyClass.class)
247
.filter(method -> method.getName().startsWith("set"))
248
.filter(method -> method.getParameterCount() == 1));
249
250
// Query fields
251
Set<Field> privateFields = get(Fields.of(MyClass.class)
252
.filter(field -> Modifier.isPrivate(field.getModifiers())));
253
254
// Query constructors
255
Set<Constructor> publicConstructors = get(Constructors.of(MyClass.class)
256
.filter(constructor -> Modifier.isPublic(constructor.getModifiers())));
257
```
258
259
### Advanced Functional Composition
260
261
```java
262
// Create custom query functions
263
QueryFunction<Store, Method> serviceMethodsQuery = store ->
264
reflections.get(TypesAnnotated.with(Service.class).asClass())
265
.stream()
266
.flatMap(clazz -> Arrays.stream(clazz.getDeclaredMethods()))
267
.collect(Collectors.toSet());
268
269
// Combine multiple queries
270
QueryFunction<Store, Class<?>> allServiceTypes =
271
SubTypes.of(Service.class)
272
.asClass()
273
.add(TypesAnnotated.with(Service.class).asClass());
274
275
Set<Class<?>> services = reflections.get(allServiceTypes);
276
277
// Create transitive queries
278
QueryFunction<Store, String> transitiveSubTypes = SubTypes.getAll(
279
Arrays.asList("com.mycompany.BaseService", "com.mycompany.BaseRepository"));
280
281
// Use flatMap for complex transformations
282
Set<Method> allServiceMethods = reflections.get(
283
TypesAnnotated.with(Service.class)
284
.asClass()
285
.flatMap(clazz -> store -> Arrays.stream(clazz.getDeclaredMethods()).collect(Collectors.toSet())));
286
```
287
288
### Query Function Factory Methods
289
290
```java
291
// Create empty query
292
QueryFunction<Store, String> empty = QueryFunction.empty();
293
294
// Create single element query
295
QueryFunction<Store, String> single = QueryFunction.single("com.mycompany.MyClass");
296
297
// Create query from collection
298
QueryFunction<Store, String> fromSet = QueryFunction.set(
299
Arrays.asList("com.mycompany.Class1", "com.mycompany.Class2"));
300
301
// Use in complex compositions
302
Set<Class<?>> combinedResults = reflections.get(
303
SubTypes.of(MyInterface.class)
304
.asClass()
305
.add(fromSet.asClass()));
306
```
307
308
### Type Conversion and Resolution
309
310
```java
311
// Convert strings to classes
312
Set<Class<?>> classes = reflections.get(
313
SubTypes.of(MyInterface.class).asClass());
314
315
// Convert with specific class loaders
316
ClassLoader customClassLoader = MyClass.class.getClassLoader();
317
Set<Class<?>> customLoaderClasses = reflections.get(
318
SubTypes.of(MyInterface.class).as(Class.class, customClassLoader));
319
320
// Convert to methods
321
Set<Method> methods = reflections.get(
322
MethodsAnnotated.with(RequestMapping.class).as(Method.class));
323
324
// Convert to fields
325
Set<Field> fields = reflections.get(
326
FieldsAnnotated.with(Autowired.class).as(Field.class));
327
328
// Convert to constructors
329
Set<Constructor> constructors = reflections.get(
330
ConstructorsAnnotated.with(Inject.class).as(Constructor.class));
331
```
332
333
### Resource Queries
334
335
```java
336
// Query resources with patterns
337
Set<String> xmlFiles = reflections.get(Resources.with(".*\\.xml"));
338
Set<String> propertyFiles = reflections.get(Resources.with(".*\\.properties"));
339
Set<String> configFiles = reflections.get(Resources.with(".*config.*"));
340
341
// Complex resource filtering
342
Set<String> filteredResources = reflections.get(
343
Resources.with(".*")
344
.filter(resource -> resource.contains("config"))
345
.filter(resource -> !resource.contains("test")));
346
```
347
348
### Custom Query Functions
349
350
```java
351
// Create custom query function for business logic
352
public class CustomQueries {
353
public static QueryFunction<Store, Class<?>> domainEntities(Reflections reflections) {
354
return store -> reflections.get(TypesAnnotated.with(Entity.class).asClass())
355
.stream()
356
.filter(clazz -> clazz.getPackage().getName().contains("domain"))
357
.filter(clazz -> !Modifier.isAbstract(clazz.getModifiers()))
358
.collect(Collectors.toSet());
359
}
360
361
public static QueryFunction<Store, Method> businessMethods(Reflections reflections) {
362
return store -> reflections.get(TypesAnnotated.with(Service.class).asClass())
363
.stream()
364
.flatMap(clazz -> Arrays.stream(clazz.getDeclaredMethods()))
365
.filter(method -> Modifier.isPublic(method.getModifiers()))
366
.filter(method -> !method.getName().startsWith("get"))
367
.filter(method -> !method.getName().startsWith("set"))
368
.collect(Collectors.toSet());
369
}
370
}
371
372
// Use custom queries
373
Set<Class<?>> entities = reflections.get(CustomQueries.domainEntities(reflections));
374
Set<Method> businessMethods = reflections.get(CustomQueries.businessMethods(reflections));
375
```
376
377
### Error Handling and Validation
378
379
```java
380
// Validate query results
381
QueryFunction<Store, Class<?>> validatedQuery = SubTypes.of(MyInterface.class)
382
.asClass()
383
.filter(clazz -> {
384
try {
385
// Validate class can be instantiated
386
clazz.getDeclaredConstructor();
387
return true;
388
} catch (NoSuchMethodException e) {
389
return false;
390
}
391
});
392
393
// Handle empty results
394
Set<Class<?>> results = reflections.get(SubTypes.of(RareInterface.class).asClass());
395
if (results.isEmpty()) {
396
results = reflections.get(QueryFunction.single(DefaultImplementation.class));
397
}
398
399
// Combine with fallback queries
400
QueryFunction<Store, Class<?>> withFallback =
401
SubTypes.of(PreferredInterface.class)
402
.asClass()
403
.add(SubTypes.of(FallbackInterface.class).asClass());
404
```
405
406
## Functional Query Patterns
407
408
### Builder Pattern with Queries
409
410
```java
411
public class QueryBuilder {
412
private final Reflections reflections;
413
private QueryFunction<Store, Class<?>> query = QueryFunction.empty();
414
415
public QueryBuilder(Reflections reflections) {
416
this.reflections = reflections;
417
}
418
419
public QueryBuilder subtypesOf(Class<?> type) {
420
query = query.add(SubTypes.of(type).asClass());
421
return this;
422
}
423
424
public QueryBuilder annotatedWith(Class<? extends Annotation> annotation) {
425
query = query.add(TypesAnnotated.with(annotation).asClass());
426
return this;
427
}
428
429
public QueryBuilder inPackage(String packageName) {
430
query = query.filter(clazz -> clazz.getPackage().getName().startsWith(packageName));
431
return this;
432
}
433
434
public QueryBuilder excludeAbstract() {
435
query = query.filter(clazz -> !Modifier.isAbstract(clazz.getModifiers()));
436
return this;
437
}
438
439
public Set<Class<?>> build() {
440
return reflections.get(query);
441
}
442
}
443
444
// Usage
445
Set<Class<?>> results = new QueryBuilder(reflections)
446
.subtypesOf(Service.class)
447
.annotatedWith(Component.class)
448
.inPackage("com.mycompany")
449
.excludeAbstract()
450
.build();
451
```
452
453
### Lazy Evaluation Pattern
454
455
```java
456
// Create lazy queries that are evaluated on demand
457
public class LazyQueries {
458
private final Reflections reflections;
459
private Supplier<Set<Class<?>>> servicesSupplier;
460
private Supplier<Set<Method>> methodsSupplier;
461
462
public LazyQueries(Reflections reflections) {
463
this.reflections = reflections;
464
465
// Define lazy queries
466
this.servicesSupplier = () -> reflections.get(
467
TypesAnnotated.with(Service.class).asClass());
468
469
this.methodsSupplier = () -> reflections.get(
470
MethodsAnnotated.with(RequestMapping.class).as(Method.class));
471
}
472
473
public Set<Class<?>> getServices() {
474
return servicesSupplier.get();
475
}
476
477
public Set<Method> getMethods() {
478
return methodsSupplier.get();
479
}
480
}
481
```
482
483
## Types
484
485
```java { .api }
486
/**
487
* Predicates for reflection filtering operations
488
*/
489
abstract class ReflectionUtilsPredicates {
490
/** Check if member is public */
491
static Predicate<Member> withPublic();
492
493
/** Check parameter count */
494
static Predicate<Member> withParametersCount(int count);
495
496
/** Check for annotation presence */
497
static <T extends AnnotatedElement> Predicate<T> withAnnotation(Annotation annotation);
498
499
/** Check for annotation type presence */
500
static <T extends AnnotatedElement> Predicate<T> withAnnotation(Class<? extends Annotation> annotation);
501
502
/** Check method parameters */
503
static Predicate<Method> withParameters(Class<?>... types);
504
505
/** Check any parameter has annotation */
506
static Predicate<Method> withAnyParameterAnnotation(Class<? extends Annotation> annotation);
507
508
/** Check method prefix */
509
static <T extends Member> Predicate<T> withPrefix(String prefix);
510
511
/** Check method return type */
512
static <T extends Method> Predicate<T> withReturnType(Class<?> type);
513
}
514
```