-
Notifications
You must be signed in to change notification settings - Fork 2.2k
/
JaxrsAnnotationScanner.java
129 lines (111 loc) · 4.7 KB
/
JaxrsAnnotationScanner.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package io.swagger.v3.jaxrs2.integration;
import io.github.classgraph.ClassGraph;
import io.github.classgraph.ScanResult;
import io.swagger.v3.jaxrs2.integration.api.JaxrsOpenApiScanner;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.Webhooks;
import io.swagger.v3.oas.integration.IgnoredPackages;
import io.swagger.v3.oas.integration.SwaggerConfiguration;
import io.swagger.v3.oas.integration.api.OpenAPIConfiguration;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class JaxrsAnnotationScanner<T extends JaxrsAnnotationScanner<T>> implements JaxrsOpenApiScanner {
static final Set<String> ignored = new HashSet<>();
static {
ignored.addAll(IgnoredPackages.ignored);
}
protected OpenAPIConfiguration openApiConfiguration;
protected Application application;
protected static final Logger LOGGER = LoggerFactory.getLogger(JaxrsAnnotationScanner.class);
protected boolean onlyConsiderResourcePackages = false;
public JaxrsAnnotationScanner application(Application application) {
this.application = application;
return this;
}
@Override
public void setApplication(Application application) {
this.application = application;
}
public T openApiConfiguration(OpenAPIConfiguration openApiConfiguration) {
this.openApiConfiguration = openApiConfiguration;
return (T) this;
}
@Override
public void setConfiguration(OpenAPIConfiguration openApiConfiguration) {
this.openApiConfiguration = openApiConfiguration;
}
@Override
public Set<Class<?>> classes() {
if (openApiConfiguration == null) {
openApiConfiguration = new SwaggerConfiguration();
}
ClassGraph graph = new ClassGraph().enableAllInfo();
Set<String> acceptablePackages = new HashSet<>();
Set<Class<?>> output = new HashSet<>();
// if classes are passed, use them
if (openApiConfiguration.getResourceClasses() != null && !openApiConfiguration.getResourceClasses().isEmpty()) {
for (String className : openApiConfiguration.getResourceClasses()) {
if (!isIgnored(className)) {
try {
output.add(Class.forName(className));
} catch (ClassNotFoundException e) {
LOGGER.warn("error loading class from resourceClasses: " + e.getMessage(), e);
}
}
}
return output;
}
boolean allowAllPackages = false;
if (openApiConfiguration.getResourcePackages() != null && !openApiConfiguration.getResourcePackages().isEmpty()) {
for (String pkg : openApiConfiguration.getResourcePackages()) {
if (!isIgnored(pkg)) {
acceptablePackages.add(pkg);
graph.whitelistPackages(pkg);
}
}
} else {
if (!onlyConsiderResourcePackages) {
allowAllPackages = true;
}
}
final Set<Class<?>> classes;
try (ScanResult scanResult = graph.scan()) {
classes = new HashSet<>(scanResult.getClassesWithAnnotation(javax.ws.rs.Path.class.getName()).loadClasses());
classes.addAll(new HashSet<>(scanResult.getClassesWithAnnotation(OpenAPIDefinition.class.getName()).loadClasses()));
classes.addAll(new HashSet<>(scanResult.getClassesWithAnnotation(Webhooks.class.getName()).loadClasses()));
if (Boolean.TRUE.equals(openApiConfiguration.isAlwaysResolveAppPath())) {
classes.addAll(new HashSet<>(scanResult.getClassesWithAnnotation(ApplicationPath.class.getName()).loadClasses()));
}
}
for (Class<?> cls : classes) {
if (allowAllPackages) {
output.add(cls);
} else {
for (String pkg : acceptablePackages) {
if (cls.getPackage().getName().startsWith(pkg)) {
output.add(cls);
}
}
}
}
LOGGER.trace("classes() - output size {}", output.size());
return output;
}
protected boolean isIgnored(String classOrPackageName) {
if (StringUtils.isBlank(classOrPackageName)) {
return true;
}
return ignored.stream().anyMatch(classOrPackageName::startsWith);
}
@Override
public Map<String, Object> resources() {
return new HashMap<>();
}
}