org.babyfish.jimmer.spring.client.OpenApiUiController Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jimmer-spring-boot-starter Show documentation
Show all versions of jimmer-spring-boot-starter Show documentation
A revolutionary ORM framework for both java and kotlin
package org.babyfish.jimmer.spring.client;
import org.babyfish.jimmer.client.meta.ApiService;
import org.babyfish.jimmer.client.meta.Schema;
import org.babyfish.jimmer.client.runtime.impl.MetadataBuilder;
import org.babyfish.jimmer.spring.cfg.JimmerProperties;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
import java.io.*;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Enumeration;
@Controller
public class OpenApiUiController {
private static final String CSS_RESOURCE = "META-INF/jimmer/swagger/swagger-ui.css";
private static final String JS_RESOURCE = "META-INF/jimmer/swagger/swagger-ui.js";
private static final String CSS_URL = "/jimmer-client/swagger-ui.css";
private static final String JS_URL = "/jimmer-client/swagger-ui.js";
private final JimmerProperties properties;
public OpenApiUiController(JimmerProperties properties) {
this.properties = properties;
}
@GetMapping("${jimmer.client.openapi.ui-path}")
public ResponseEntity download(
@RequestParam(name = "groups", required = false) String groups
) {
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "text/html");
StreamingResponseBody body = out -> {
Writer writer = new OutputStreamWriter(out, StandardCharsets.UTF_8);
String html = this.html(groups);
writer.write(html);
writer.flush();
};
return ResponseEntity.ok().headers(headers).body(body);
}
private String html(String groups) {
String refPath = properties.getClient().getOpenapi().getRefPath();
String resource;
if (hasMetadata()) {
resource = refPath != null && !refPath.isEmpty() ?
"META-INF/jimmer/openapi/index.html.template" :
"META-INF/jimmer/openapi/no-api.html";
} else {
resource = "META-INF/jimmer/openapi/no-metadata.html";
}
StringBuilder builder = new StringBuilder();
char[] buf = new char[1024];
InputStream inputStream = OpenApiController.class.getClassLoader().getResourceAsStream(resource);
assert inputStream != null;
try (Reader reader = new InputStreamReader(inputStream)) {
int len;
if ((len = reader.read(buf)) != -1) {
builder.append(buf, 0, len);
}
} catch (IOException ex) {
throw new AssertionError("Internal bug: Can read \"" + resource + "\"");
}
boolean isTemplate = resource.endsWith(".template");
if (!isTemplate) {
return builder.toString();
}
if (groups != null && !groups.isEmpty()) {
try {
refPath += "?groups=" + URLEncoder.encode(groups, "utf-8");
} catch (UnsupportedEncodingException ex) {
throw new AssertionError("Internal bug: utf-8 is not supported");
}
}
return builder
.toString()
.replace("${openapi.css}",
exists(CSS_RESOURCE) ?
CSS_URL :
"https://unpkg.com/[email protected]/swagger-ui.css"
)
.replace("${openapi.js}",
exists(JS_RESOURCE) ?
JS_URL :
"https://unpkg.com/[email protected]/swagger-ui-bundle.js"
)
.replace(
"${openapi.refPath}",
refPath
);
}
private boolean hasMetadata() {
Schema schema = MetadataBuilder.loadSchema(Collections.emptySet());
for (ApiService service : schema.getApiServiceMap().values()) {
if (!service.getOperations().isEmpty()) {
return true;
}
}
return false;
}
@GetMapping(CSS_URL)
public ResponseEntity css() throws IOException {
return downloadResource(CSS_RESOURCE, "text/css");
}
@GetMapping(JS_URL)
public ResponseEntity js() throws IOException {
return downloadResource(JS_RESOURCE, "text/javascript");
}
private ResponseEntity downloadResource(String resource, String contentType) throws IOException {
byte[] buf = new byte[4 * 1024];
InputStream in = OpenApiController.class.getClassLoader().getResourceAsStream(resource);
if (in == null) {
throw new IllegalStateException("The resource \"" + resource + "\" does not exist");
}
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", contentType);
StreamingResponseBody body = out -> {
try {
int len;
while ((len = in.read(buf)) != -1) {
out.write(buf, 0, len);
}
out.flush();
} finally {
in.close();
}
};
return ResponseEntity.ok().headers(headers).body(body);
}
private static boolean exists(String resource) {
Enumeration enumeration;
try {
enumeration = OpenApiController.class.getClassLoader().getResources(resource);
} catch (IOException e) {
throw new IllegalStateException("Failed to check the existence of resource \"" + resource + "\"");
}
return enumeration.hasMoreElements();
}
}