• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

torand / openapi2java / 22519240185

28 Feb 2026 10:47AM UTC coverage: 84.535% (+0.1%) from 84.425%
22519240185

push

github

torand
chore: prepare release

572 of 795 branches covered (71.95%)

Branch coverage included in aggregate %.

1702 of 1895 relevant lines covered (89.82%)

5.39 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.33
/src/main/java/io/github/torand/openapi2java/collectors/ResourceInfoCollector.java
1
/*
2
 * Copyright (c) 2024-2026 Tore Eide Andersen
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package io.github.torand.openapi2java.collectors;
17

18
import io.github.torand.openapi2java.generators.Options;
19
import io.github.torand.openapi2java.model.AnnotationInfo;
20
import io.github.torand.openapi2java.model.ConstantValue;
21
import io.github.torand.openapi2java.model.MethodInfo;
22
import io.github.torand.openapi2java.model.ResourceInfo;
23
import io.github.torand.openapi2java.model.SecurityRequirementInfo;
24
import io.swagger.v3.oas.models.Operation;
25
import io.swagger.v3.oas.models.PathItem;
26
import io.swagger.v3.oas.models.security.SecurityRequirement;
27
import io.swagger.v3.oas.models.tags.Tag;
28

29
import java.util.ArrayList;
30
import java.util.List;
31
import java.util.Map;
32
import java.util.Optional;
33

34
import static io.github.torand.javacommons.collection.CollectionHelper.isEmpty;
35
import static io.github.torand.javacommons.collection.CollectionHelper.nonEmpty;
36
import static io.github.torand.javacommons.lang.StringHelper.isBlank;
37
import static io.github.torand.javacommons.lang.StringHelper.nonBlank;
38
import static io.github.torand.openapi2java.collectors.Extensions.EXT_RESTCLIENT_CONFIGKEY;
39
import static io.github.torand.openapi2java.collectors.Extensions.EXT_RESTCLIENT_HEADERS;
40
import static io.github.torand.openapi2java.collectors.Extensions.EXT_RESTCLIENT_HEADERSFACTORY;
41
import static io.github.torand.openapi2java.collectors.Extensions.EXT_RESTCLIENT_PROVIDERS;
42
import static io.github.torand.openapi2java.collectors.Extensions.extensions;
43
import static io.github.torand.openapi2java.utils.PackageUtils.getClassNameFromFqn;
44
import static java.util.Collections.emptyList;
45
import static java.util.Objects.isNull;
46
import static java.util.Objects.nonNull;
47

48
/**
49
 * Collects information about a resource from a collection of path items.
50
 */
51
public class ResourceInfoCollector extends BaseCollector {
52
    private final MethodInfoCollector methodInfoCollector;
53
    private final SecurityRequirementCollector securityRequirementCollector;
54

55
    public ResourceInfoCollector(ComponentResolver componentResolver, Options opts) {
56
        super(opts);
3✔
57
        TypeInfoCollector typeInfoCollector = new TypeInfoCollector(componentResolver.schemas(), opts);
7✔
58
        this.methodInfoCollector = new MethodInfoCollector(componentResolver, typeInfoCollector, opts);
8✔
59
        this.securityRequirementCollector = new SecurityRequirementCollector(opts);
6✔
60
    }
1✔
61

62
    public ResourceInfo getResourceInfo(String resourceName, Map<String, PathItem> paths, List<SecurityRequirement> securityRequirements, Tag tag) {
63
        ResourceInfo resourceInfo = new ResourceInfo(resourceName + opts.resourceNameSuffix());
9✔
64

65
        if (opts.useResteasyResponse()) {
4✔
66
            resourceInfo = resourceInfo.withAddedNormalImport("org.jboss.resteasy.reactive.RestResponse");
5✔
67
        } else {
68
            resourceInfo = resourceInfo.withAddedNormalImport("jakarta.ws.rs.core.Response");
4✔
69
        }
70

71
        if (nonEmpty(securityRequirements)) {
3!
72
            SecurityRequirementInfo secReqInfo = securityRequirementCollector.getSequrityRequirementInfo(securityRequirements);
5✔
73
            resourceInfo = resourceInfo.withAddedAnnotation(secReqInfo.annotation());
5✔
74
        }
75

76
        if (opts.addMpOpenApiAnnotations() && nonNull(tag)) {
7!
77
            AnnotationInfo tagAnnotation = getTagAnnotation(tag);
4✔
78
            resourceInfo = resourceInfo.withAddedAnnotation(tagAnnotation);
4✔
79
        }
80

81
        if (opts.addMpRestClientAnnotations()) {
4!
82
            String configKey = opts.resourceConfigKeyOverride();
4✔
83
            if (isBlank(configKey)) {
3✔
84
                configKey = nonNull(tag) ?
3✔
85
                    extensions(tag.getExtensions())
3✔
86
                        .getString(EXT_RESTCLIENT_CONFIGKEY)
2✔
87
                        .orElse(tag.getName().toLowerCase() + "-api") :
7✔
88
                    resourceName.toLowerCase() + "-api";
4✔
89
            }
90

91
            AnnotationInfo registerRestClientAnnotation = getRegisterRestClientAnnotation(configKey);
3✔
92
            resourceInfo = resourceInfo.withAddedAnnotation(registerRestClientAnnotation);
4✔
93

94
            if (nonNull(tag)) {
3✔
95
                Optional<Map<String, Object>> maybeHeaders = extensions(tag.getExtensions())
4✔
96
                    .getMap(EXT_RESTCLIENT_HEADERS);
2✔
97

98
                if (maybeHeaders.isPresent()) {
3✔
99
                    List<AnnotationInfo> clientHeaderAnnotations = getClientHeaderParamAnnotations(maybeHeaders.get());
6✔
100
                    resourceInfo = resourceInfo.withAddedAnnotations(clientHeaderAnnotations);
4✔
101
                }
102
            }
103

104
            String clientHeadersFactory = opts.resourceClientHeadersFactoryOverride();
4✔
105
            if (isBlank(clientHeadersFactory)) {
3✔
106
                clientHeadersFactory = nonNull(tag) ?
3✔
107
                    extensions(tag.getExtensions())
3✔
108
                        .getString(EXT_RESTCLIENT_HEADERSFACTORY)
2✔
109
                        .orElse("") :
4✔
110
                    "";
2✔
111
            }
112

113
            if (nonBlank(clientHeadersFactory)) {
3✔
114
                AnnotationInfo registerClientHeadersAnnotation = getRegisterClientHeadersAnnotation(clientHeadersFactory);
4✔
115
                resourceInfo = resourceInfo.withAddedAnnotation(registerClientHeadersAnnotation);
4✔
116
            }
117

118
            List<String> providers = opts.resourceProvidersOverride();
4✔
119
            if (isEmpty(providers)) {
3✔
120
                providers = nonNull(tag) ?
3✔
121
                    extensions(tag.getExtensions())
3✔
122
                        .getStringArray(EXT_RESTCLIENT_PROVIDERS)
1✔
123
                        .orElse(emptyList()) :
5✔
124
                    emptyList();
2✔
125
            }
126

127
            if (nonEmpty(providers)) {
3✔
128
                List<AnnotationInfo> registerProviderAnnotations = getRegisterProviderAnnotations(providers);
4✔
129
                resourceInfo = resourceInfo.withAddedAnnotations(registerProviderAnnotations);
4✔
130
            }
131

132
            if (opts.useOidcClientAnnotation()) {
4✔
133
                AnnotationInfo oidcClientFilterAnnotation = getOidcClientFilterAnnotation(configKey);
3✔
134
                resourceInfo = resourceInfo.withAddedAnnotation(oidcClientFilterAnnotation);
4✔
135
            }
136
        }
137

138
        AnnotationInfo pathAnnotation = getPathAnnotation(resourceInfo);
4✔
139
        resourceInfo = resourceInfo.withAddedAnnotation(pathAnnotation);
4✔
140

141
        String tagName = nonNull(tag) ? tag.getName() : null;
8✔
142

143
        List<MethodInfo> methods = new ArrayList<>();
4✔
144
        paths.forEach((path, pathInfo) -> {
6✔
145
            if (shouldProcessOperation(pathInfo.getGet(), tagName)) {
6✔
146
                methods.add(methodInfoCollector.getMethodInfo("GET", path, pathInfo.getGet()));
10✔
147
            }
148
            if (shouldProcessOperation(pathInfo.getPost(), tagName)) {
6✔
149
                methods.add(methodInfoCollector.getMethodInfo("POST", path, pathInfo.getPost()));
10✔
150
            }
151
            if (shouldProcessOperation(pathInfo.getDelete(), tagName)) {
6!
152
                methods.add(methodInfoCollector.getMethodInfo("DELETE", path, pathInfo.getDelete()));
×
153
            }
154
            if (shouldProcessOperation(pathInfo.getPut(), tagName)) {
6!
155
                methods.add(methodInfoCollector.getMethodInfo("PUT", path, pathInfo.getPut()));
×
156
            }
157
            if (shouldProcessOperation(pathInfo.getPatch(), tagName)) {
6!
158
                methods.add(methodInfoCollector.getMethodInfo("PATCH", path, pathInfo.getPatch()));
×
159
            }
160
        });
1✔
161

162
        for (MethodInfo method : methods) {
10✔
163
            resourceInfo = resourceInfo.withAddedMethod(method);
4✔
164
        }
1✔
165

166
        return resourceInfo;
2✔
167
    }
168

169
    private List<AnnotationInfo> getRegisterProviderAnnotations(List<String> providers) {
170
        List<AnnotationInfo> registerProviderAnnotations = new ArrayList<>();
4✔
171

172
        providers.forEach(provider -> {
5✔
173
            AnnotationInfo registerProviderAnnotation = new AnnotationInfo(
9✔
174
                "@RegisterProvider(%s)".formatted(formatClassRef(getClassNameFromFqn(provider))),
7✔
175
                "org.eclipse.microprofile.rest.client.annotation.RegisterProvider"
176
            ).withAddedNormalImport(provider);
2✔
177
            registerProviderAnnotations.add(registerProviderAnnotation);
4✔
178
        });
1✔
179

180
        return registerProviderAnnotations;
2✔
181
    }
182

183
    private static AnnotationInfo getOidcClientFilterAnnotation(String configKey) {
184
        return new AnnotationInfo(
10✔
185
            "@OidcClientFilter(\"%s\")".formatted(configKey),
3✔
186
            "io.quarkus.oidc.client.filter.OidcClientFilter");
187
    }
188

189
    private AnnotationInfo getRegisterClientHeadersAnnotation(String headerFactory) {
190
        return new AnnotationInfo(
10✔
191
            "@RegisterClientHeaders(%s)".formatted(formatClassRef(getClassNameFromFqn(headerFactory))),
7✔
192
            "org.eclipse.microprofile.rest.client.annotation.RegisterClientHeaders"
193
        ).withAddedNormalImport(headerFactory);
1✔
194
    }
195

196
    private AnnotationInfo getPathAnnotation(ResourceInfo resourceInfo) {
197
        return new AnnotationInfo("@Path(ROOT_PATH)", "jakarta.ws.rs.Path")
13✔
198
            .withAddedStaticImport("%s.%s.ROOT_PATH".formatted(opts.rootPackage(), resourceInfo.name()));
9✔
199
    }
200

201
    private AnnotationInfo getTagAnnotation(Tag tag) {
202
        return new AnnotationInfo(
9✔
203
            "@Tag(name = \"%s\", description = \"%s\")".formatted(tag.getName(), normalizeDescription(tag.getDescription())),
12✔
204
            "org.eclipse.microprofile.openapi.annotations.tags.Tag"
205
        );
206
    }
207

208
    private static AnnotationInfo getRegisterRestClientAnnotation(String configKey) {
209
        return new AnnotationInfo(
10✔
210
            "@RegisterRestClient(configKey = \"%s\")".formatted(configKey),
3✔
211
            "org.eclipse.microprofile.rest.client.inject.RegisterRestClient"
212
        );
213
    }
214

215
    private List<AnnotationInfo> getClientHeaderParamAnnotations(Map<String, Object> headers) {
216
        List<AnnotationInfo> clientHeaderAnnotations = new ArrayList<>();
4✔
217

218
        if (nonEmpty(headers)) {
3!
219
            headers.forEach((header, value) -> {
5✔
220
                ConstantValue headerName = getHeaderNameConstant(header);
4✔
221
                String formattedValue = formatAnnotationNamedParam(List.of("\"%s\"".formatted(value)));
12✔
222
                AnnotationInfo clientHeaderAnnotation = new AnnotationInfo("@ClientHeaderParam(name = %s, value = %s)".formatted(headerName.value(), formattedValue))
17✔
223
                    .withAddedNormalImport("org.eclipse.microprofile.rest.client.annotation.ClientHeaderParam")
2✔
224
                    .withAddedImports(headerName);
2✔
225
                clientHeaderAnnotations.add(clientHeaderAnnotation);
4✔
226
            });
1✔
227
        }
228

229
        return clientHeaderAnnotations;
2✔
230
    }
231

232
    private boolean shouldProcessOperation(Operation operation, String tag) {
233
        if (isNull(operation)) {
3✔
234
            return false;
2✔
235
        }
236

237
        if (isNull(tag)) {
3✔
238
            return true;
2✔
239
        }
240

241
        return nonNull(operation.getTags()) && operation.getTags().contains(tag);
13!
242
    }
243
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc