Skip to content

Commit ae5749b

Browse files
committed
open-api: Allow to specify a custom openapi file fix #3571
1 parent 628ac85 commit ae5749b

1 file changed

Lines changed: 54 additions & 17 deletions

File tree

jooby/src/main/java/io/jooby/OpenAPIModule.java

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,7 @@
88
import java.io.ByteArrayInputStream;
99
import java.io.InputStream;
1010
import java.nio.charset.StandardCharsets;
11-
import java.util.Arrays;
12-
import java.util.EnumSet;
13-
import java.util.HashMap;
14-
import java.util.Map;
15-
import java.util.Optional;
11+
import java.util.*;
1612

1713
import edu.umd.cs.findbugs.annotations.NonNull;
1814
import edu.umd.cs.findbugs.annotations.Nullable;
@@ -109,13 +105,23 @@ public enum Format {
109105
JSON,
110106

111107
/** YAML. */
112-
YAML
108+
YAML;
109+
110+
public static Format from(@NonNull String filePath) {
111+
for (Format value : values()) {
112+
if (filePath.endsWith("." + value.name().toLowerCase())) {
113+
return value;
114+
}
115+
}
116+
throw new IllegalArgumentException("Unsupported format: " + filePath);
117+
}
113118
}
114119

115120
private final String openAPIPath;
116121
private String swaggerUIPath = "/swagger";
117122
private String redocPath = "/redoc";
118123
private EnumSet<Format> format = EnumSet.of(Format.JSON, Format.YAML);
124+
private final Set<String> customFiles = new LinkedHashSet<>();
119125

120126
/**
121127
* Creates an OpenAPI module. The path is used to route the open API files. For example:
@@ -141,6 +147,17 @@ public OpenAPIModule() {
141147
this("/");
142148
}
143149

150+
/**
151+
* Set custom openapi file to use. Could be a file system or classpath resource.
152+
*
153+
* @param path Path.
154+
* @return This module.
155+
*/
156+
public @NonNull OpenAPIModule file(String path) {
157+
customFiles.add(path);
158+
return this;
159+
}
160+
144161
/**
145162
* Customize the swagger-ui path. Defaults is <code>/swagger</code>.
146163
*
@@ -178,22 +195,42 @@ public OpenAPIModule() {
178195

179196
@Override
180197
public void install(@NonNull Jooby application) throws Exception {
181-
String dir = Optional.ofNullable(application.getBasePackage()).orElse("/").replace(".", "/");
182-
183-
String appName = application.getClass().getSimpleName()
184-
.replace("Jooby", "openapi")
185-
.replace("Kooby", "openapi");
186-
for (Format ext : format) {
187-
String filename = String.format("/%s.%s", appName, ext.name().toLowerCase());
188-
String openAPIFileLocation = Router.normalizePath(dir) + filename;
189-
application.assets(
190-
fullPath(openAPIPath, "/openapi." + ext.name().toLowerCase()), openAPIFileLocation);
191-
}
198+
var filePaths = computeOpenAPIFiles(application);
199+
200+
/*
201+
Add /openapi.json and/or /openapi.yaml paths
202+
*/
203+
filePaths.forEach((path, source) -> application.assets(fullPath(openAPIPath, path), source));
192204

193205
/** Configure UI: */
194206
configureUI(application);
195207
}
196208

209+
private Map<String, String> computeOpenAPIFiles(Jooby application) {
210+
final Map<String, String> filePaths = new LinkedHashMap<>();
211+
if (customFiles.isEmpty()) {
212+
// Generated by open api
213+
String dir = Optional.ofNullable(application.getBasePackage()).orElse("/").replace(".", "/");
214+
String appName =
215+
application
216+
.getClass()
217+
.getSimpleName()
218+
.replace("Jooby", "openapi")
219+
.replace("Kooby", "openapi");
220+
for (Format ext : format) {
221+
String filename = String.format("/%s.%s", appName, ext.name().toLowerCase());
222+
String openAPIFileLocation = Router.normalizePath(dir) + filename;
223+
filePaths.put("/openapi." + ext.name().toLowerCase(), openAPIFileLocation);
224+
}
225+
} else {
226+
// Custom files
227+
for (String file : customFiles) {
228+
filePaths.put("/openapi." + Format.from(file).name().toLowerCase(), file);
229+
}
230+
}
231+
return filePaths;
232+
}
233+
197234
private void configureUI(Jooby application) {
198235
Map<String, Consumer2<Jooby, AssetSource>> ui = new HashMap<>();
199236
ui.put("swagger-ui", this::swaggerUI);

0 commit comments

Comments
 (0)