Files
Stirling-PDF/stirling-pdf/src/main/java/stirling/software/SPDF/service/ApiDocService.java
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

170 lines
6.7 KiB
Java
Raw Normal View History

2025-06-09 12:51:41 +01:00
package stirling.software.SPDF.service;
2023-12-30 19:11:27 +00:00
2024-01-18 21:57:41 +00:00
import java.util.Arrays;
2023-12-25 16:16:50 +00:00
import java.util.HashMap;
2024-01-18 23:28:39 +00:00
import java.util.List;
2023-12-25 16:16:50 +00:00
import java.util.Map;
2023-12-28 17:23:19 +00:00
import java.util.regex.Matcher;
import java.util.regex.Pattern;
2023-12-25 16:15:42 +00:00
import org.springframework.beans.factory.annotation.Autowired;
2023-12-25 16:16:50 +00:00
import org.springframework.http.HttpEntity;
2023-12-25 16:15:42 +00:00
import org.springframework.http.HttpHeaders;
2023-12-25 16:16:50 +00:00
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
2023-12-25 16:15:42 +00:00
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.ServletContext;
import lombok.extern.slf4j.Slf4j;
2025-01-06 18:58:26 +00:00
import stirling.software.SPDF.SPDFApplication;
2023-12-25 16:15:42 +00:00
import stirling.software.SPDF.model.ApiEndpoint;
import stirling.software.common.model.enumeration.Role;
2025-05-27 13:01:52 +01:00
import stirling.software.common.service.UserServiceInterface;
2024-01-18 23:28:39 +00:00
2023-12-25 16:15:42 +00:00
@Service
2024-12-17 10:26:18 +01:00
@Slf4j
2023-12-25 16:15:42 +00:00
public class ApiDocService {
private final Map<String, ApiEndpoint> apiDocumentation = new HashMap<>();
private final ServletContext servletContext;
private final UserServiceInterface userService;
Map<String, List<String>> outputToFileTypes = new HashMap<>();
JsonNode apiDocsJsonRootNode;
public ApiDocService(
ServletContext servletContext,
@Autowired(required = false) UserServiceInterface userService) {
this.servletContext = servletContext;
this.userService = userService;
}
2023-12-28 13:50:31 +00:00
private String getApiDocsUrl() {
String contextPath = servletContext.getContextPath();
2025-01-06 18:58:26 +00:00
String port = SPDFApplication.getStaticPort();
2023-12-29 20:48:21 +00:00
return "http://localhost:" + port + contextPath + "/v1/api-docs";
2023-12-30 19:11:27 +00:00
}
2024-01-18 23:28:39 +00:00
2024-08-23 12:52:45 +02:00
public List<String> getExtensionTypes(boolean output, String operationName) {
2024-01-18 23:28:39 +00:00
if (outputToFileTypes.size() == 0) {
outputToFileTypes.put("PDF", Arrays.asList("pdf"));
outputToFileTypes.put(
"IMAGE",
Arrays.asList(
"png", "jpg", "jpeg", "gif", "webp", "bmp", "tif", "tiff", "svg", "psd",
"ai", "eps"));
outputToFileTypes.put(
"ZIP",
Arrays.asList("zip", "rar", "7z", "tar", "gz", "bz2", "xz", "lz", "lzma", "z"));
outputToFileTypes.put("WORD", Arrays.asList("doc", "docx", "odt", "rtf"));
outputToFileTypes.put("CSV", Arrays.asList("csv"));
outputToFileTypes.put("JS", Arrays.asList("js", "jsx"));
outputToFileTypes.put("HTML", Arrays.asList("html", "htm", "xhtml"));
outputToFileTypes.put("JSON", Arrays.asList("json"));
outputToFileTypes.put("TXT", Arrays.asList("txt", "text", "md", "markdown"));
outputToFileTypes.put("PPT", Arrays.asList("ppt", "pptx", "odp"));
outputToFileTypes.put("XML", Arrays.asList("xml", "xsd", "xsl"));
outputToFileTypes.put(
"BOOK", Arrays.asList("epub", "mobi", "azw3", "fb2", "txt", "docx"));
2024-01-18 23:28:39 +00:00
// type.
}
if (apiDocsJsonRootNode == null || apiDocumentation.size() == 0) {
2024-01-18 21:57:41 +00:00
loadApiDocumentation();
}
if (!apiDocumentation.containsKey(operationName)) {
return null;
}
ApiEndpoint endpoint = apiDocumentation.get(operationName);
String description = endpoint.getDescription();
Pattern pattern = null;
2024-01-18 23:28:39 +00:00
if (output) {
pattern = Pattern.compile("Output:(\\w+)");
2024-01-18 21:57:41 +00:00
} else {
2024-01-18 23:28:39 +00:00
pattern = Pattern.compile("Input:(\\w+)");
2024-01-18 21:57:41 +00:00
}
Matcher matcher = pattern.matcher(description);
while (matcher.find()) {
String type = matcher.group(1).toUpperCase();
2024-01-18 23:28:39 +00:00
if (outputToFileTypes.containsKey(type)) {
return outputToFileTypes.get(type);
2024-01-18 21:57:41 +00:00
}
}
return null;
}
2023-12-30 19:11:27 +00:00
2023-12-25 16:15:42 +00:00
private String getApiKeyForUser() {
if (userService == null) return "";
return userService.getApiKeyForUser(Role.INTERNAL_API_USER.getRoleId());
2023-12-28 13:50:31 +00:00
}
2023-12-30 19:11:27 +00:00
2023-12-27 15:18:26 +00:00
// @EventListener(ApplicationReadyEvent.class)
private synchronized void loadApiDocumentation() {
2023-12-30 02:19:30 +00:00
String apiDocsJson = "";
2023-12-25 16:15:42 +00:00
try {
HttpHeaders headers = new HttpHeaders();
String apiKey = getApiKeyForUser();
if (!apiKey.isEmpty()) {
headers.set("X-API-KEY", apiKey);
}
HttpEntity<String> entity = new HttpEntity<>(headers);
RestTemplate restTemplate = new RestTemplate();
2023-12-28 13:50:31 +00:00
ResponseEntity<String> response =
restTemplate.exchange(getApiDocsUrl(), HttpMethod.GET, entity, String.class);
2023-12-30 02:19:30 +00:00
apiDocsJson = response.getBody();
2023-12-25 16:15:42 +00:00
ObjectMapper mapper = new ObjectMapper();
2023-12-28 17:23:19 +00:00
apiDocsJsonRootNode = mapper.readTree(apiDocsJson);
JsonNode paths = apiDocsJsonRootNode.path("paths");
2023-12-25 16:15:42 +00:00
paths.fields()
.forEachRemaining(
entry -> {
String path = entry.getKey();
JsonNode pathNode = entry.getValue();
if (pathNode.has("post")) {
JsonNode postNode = pathNode.get("post");
2023-12-26 20:10:37 +00:00
ApiEndpoint endpoint = new ApiEndpoint(path, postNode);
apiDocumentation.put(path, endpoint);
2023-12-25 16:15:42 +00:00
}
});
} catch (Exception e) {
// Handle exceptions
2024-12-17 10:26:18 +01:00
log.error("Error grabbing swagger doc, body result {}", apiDocsJson);
2023-12-25 16:15:42 +00:00
}
}
public boolean isValidOperation(String operationName, Map<String, Object> parameters) {
2023-12-27 15:18:26 +00:00
if (apiDocumentation.size() == 0) {
loadApiDocumentation();
}
2023-12-25 16:15:42 +00:00
if (!apiDocumentation.containsKey(operationName)) {
return false;
}
ApiEndpoint endpoint = apiDocumentation.get(operationName);
return endpoint.areParametersValid(parameters);
}
2023-12-30 19:11:27 +00:00
2023-12-28 17:23:19 +00:00
public boolean isMultiInput(String operationName) {
if (apiDocsJsonRootNode == null || apiDocumentation.size() == 0) {
loadApiDocumentation();
}
if (!apiDocumentation.containsKey(operationName)) {
return false;
}
ApiEndpoint endpoint = apiDocumentation.get(operationName);
String description = endpoint.getDescription();
Pattern pattern = Pattern.compile("Type:(\\w+)");
Matcher matcher = pattern.matcher(description);
if (matcher.find()) {
String type = matcher.group(1);
return type.startsWith("MI");
}
return false;
}
2023-12-25 16:15:42 +00:00
}
// Model class for API Endpoint