Skip to content

Commit 4b95d0e

Browse files
committed
scalar upgrade to version 0.4.3
1 parent 9b3dd90 commit 4b95d0e

File tree

49 files changed

+194
-458
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+194
-458
lines changed

pom.xml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
<spring-cloud-function.version>5.0.0-M1</spring-cloud-function.version>
6464
<spring-security-oauth2-authorization-server.version>2.0.0-M2
6565
</spring-security-oauth2-authorization-server.version>
66-
<scalar.version>0.3.12</scalar.version>
66+
<scalar.version>0.4.3</scalar.version>
6767
<skipPublishing>false</skipPublishing>
6868
</properties>
6969

@@ -123,11 +123,6 @@
123123
<artifactId>spring-boot-starter-test</artifactId>
124124
<scope>test</scope>
125125
</dependency>
126-
<dependency>
127-
<groupId>org.springframework.boot</groupId>
128-
<artifactId>spring-boot-jackson</artifactId>
129-
<scope>test</scope>
130-
</dependency>
131126
</dependencies>
132127
<build>
133128
<plugins>

springdoc-openapi-starter-common/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
<groupId>io.swagger.core.v3</groupId>
2121
<artifactId>swagger-core-jakarta</artifactId>
2222
</dependency>
23+
<dependency>
24+
<groupId>org.springframework.boot</groupId>
25+
<artifactId>spring-boot-jackson</artifactId>
26+
</dependency>
2327
<dependency>
2428
<groupId>org.springframework.boot</groupId>
2529
<artifactId>spring-boot-configuration-processor</artifactId>

springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/AbstractScalarController.java

Lines changed: 30 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,18 @@
2828

2929
import java.io.IOException;
3030
import java.io.InputStream;
31-
import java.net.URLDecoder;
3231
import java.nio.charset.StandardCharsets;
33-
import java.util.List;
34-
import java.util.stream.Collectors;
3532

3633
import com.scalar.maven.webjar.ScalarProperties;
37-
import com.scalar.maven.webjar.ScalarProperties.ScalarSource;
34+
import com.scalar.maven.webjar.internal.ScalarConfiguration;
35+
import com.scalar.maven.webjar.internal.ScalarConfigurationMapper;
36+
import tools.jackson.core.JacksonException;
37+
import tools.jackson.databind.ObjectMapper;
3838

3939
import org.springframework.http.MediaType;
4040
import org.springframework.http.ResponseEntity;
4141

42+
import static org.springdoc.scalar.ScalarConstants.HTML_TEMPLATE_PATH;
4243
import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_URL;
4344
import static org.springdoc.scalar.ScalarConstants.SCALAR_JS_FILENAME;
4445
import static org.springframework.util.AntPathMatcher.DEFAULT_PATH_SEPARATOR;
@@ -60,14 +61,21 @@ public abstract class AbstractScalarController {
6061
*/
6162
protected final String originalScalarUrl;
6263

64+
/**
65+
* The Object mapper.
66+
*/
67+
private final ObjectMapper objectMapper;
68+
6369
/**
6470
* Instantiates a new Abstract scalar controller.
6571
*
6672
* @param scalarProperties the scalar properties
73+
* @param objectMapper the object mapper
6774
*/
68-
protected AbstractScalarController(ScalarProperties scalarProperties) {
75+
protected AbstractScalarController(ScalarProperties scalarProperties, ObjectMapper objectMapper) {
6976
this.scalarProperties = scalarProperties;
7077
this.originalScalarUrl = scalarProperties.getUrl();
78+
this.objectMapper = objectMapper;
7179
}
7280

7381
/**
@@ -82,22 +90,18 @@ protected AbstractScalarController(ScalarProperties scalarProperties) {
8290
*/
8391
protected ResponseEntity<String> getDocs(String requestUrl) throws IOException {
8492
// Load the template HTML
85-
InputStream inputStream = getClass().getResourceAsStream("/META-INF/resources/webjars/scalar/index.html");
93+
InputStream inputStream = getClass().getResourceAsStream(HTML_TEMPLATE_PATH);
8694
if (inputStream == null) {
87-
return ResponseEntity.notFound().build();
95+
throw new IOException("HTML template not found at: " + HTML_TEMPLATE_PATH);
8896
}
8997

9098
String html = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
91-
requestUrl = decode(requestUrl);
99+
92100
// Replace the placeholders with actual values
93-
String cdnUrl = buildJsBundleUrl(requestUrl);
101+
String bundleUrl = buildJsBundleUrl(requestUrl);
94102
String injectedHtml = html
95-
.replace("__JS_BUNDLE_URL__", cdnUrl)
96-
.replace("__CONFIGURATION__", """
97-
{
98-
url: "%s"
99-
}
100-
""".formatted(buildApiDocsUrl(requestUrl)));
103+
.replace("__JS_BUNDLE_URL__", bundleUrl)
104+
.replace("__CONFIGURATION__", buildConfigurationJson(buildApiDocsUrl(requestUrl)));
101105

102106
return ResponseEntity.ok()
103107
.contentType(MediaType.TEXT_HTML)
@@ -126,16 +130,6 @@ protected ResponseEntity<byte[]> getScalarJs() throws IOException {
126130
.body(jsContent);
127131
}
128132

129-
/**
130-
* Decode string.
131-
*
132-
* @param requestURI the request uri
133-
* @return the string
134-
*/
135-
protected String decode(String requestURI) {
136-
return URLDecoder.decode(requestURI, StandardCharsets.UTF_8);
137-
}
138-
139133
/**
140134
* Gets api docs url.
141135
*
@@ -186,159 +180,20 @@ protected String buildJsBundleUrl(String requestUrl, String scalarPath) {
186180
*/
187181
protected abstract String buildJsBundleUrl(String requestUrl);
188182

189-
/**
190-
* Builds the configuration JSON for the Scalar API Reference.
191-
*
192-
* @return the configuration JSON as a string
193-
*/
194-
private String buildConfigurationJson() {
195-
StringBuilder config = new StringBuilder();
196-
config.append("{");
197-
198-
// Add URL
199-
config.append("\n url: \"").append(escapeJson(scalarProperties.getUrl())).append("\"");
200-
201-
// Add sources
202-
if (scalarProperties.getSources() != null && !scalarProperties.getSources().isEmpty()) {
203-
config.append(",\n sources: ").append(buildSourcesJsonArray(scalarProperties.getSources()));
204-
}
205-
206-
// Add showSidebar
207-
if (!scalarProperties.isShowSidebar()) {
208-
config.append(",\n showSidebar: false");
209-
}
210-
211-
// Add hideModels
212-
if (scalarProperties.isHideModels()) {
213-
config.append(",\n hideModels: true");
214-
}
215-
216-
// Add hideTestRequestButton
217-
if (scalarProperties.isHideTestRequestButton()) {
218-
config.append(",\n hideTestRequestButton: true");
219-
}
220-
221-
// Add darkMode
222-
if (scalarProperties.isDarkMode()) {
223-
config.append(",\n darkMode: true");
224-
}
225-
226-
// Add hideDarkModeToggle
227-
if (scalarProperties.isHideDarkModeToggle()) {
228-
config.append(",\n hideDarkModeToggle: true");
229-
}
230-
231-
// Add customCss
232-
if (scalarProperties.getCustomCss() != null && !scalarProperties.getCustomCss().trim().isEmpty()) {
233-
config.append(",\n customCss: \"").append(escapeJson(scalarProperties.getCustomCss())).append("\"");
234-
}
235-
236-
// Add theme
237-
if (scalarProperties.getTheme() != null && !"default".equals(scalarProperties.getTheme())) {
238-
config.append(",\n theme: \"").append(escapeJson(scalarProperties.getTheme())).append("\"");
239-
}
240-
241-
// Add layout
242-
if (scalarProperties.getLayout() != null && !"modern".equals(scalarProperties.getLayout())) {
243-
config.append(",\n layout: \"").append(escapeJson(scalarProperties.getLayout())).append("\"");
244-
}
245-
246-
// Add hideSearch
247-
if (scalarProperties.isHideSearch()) {
248-
config.append(",\n hideSearch: true");
249-
}
250-
251-
// Add documentDownloadType
252-
if (scalarProperties.getDocumentDownloadType() != null && !"both".equals(scalarProperties.getDocumentDownloadType())) {
253-
config.append(",\n documentDownloadType: \"").append(escapeJson(scalarProperties.getDocumentDownloadType())).append("\"");
254-
}
255-
256-
config.append("\n}");
257-
return config.toString();
258-
}
259-
260-
/**
261-
* Escapes a string for JSON output.
183+
/**
184+
* Build configuration json string.
262185
*
263-
* @param input the input string
264-
* @return the escaped string
265-
*/
266-
private String escapeJson(String input) {
267-
if (input == null) {
268-
return "";
269-
}
270-
return input.replace("\\", "\\\\")
271-
.replace("\"", "\\\"")
272-
.replace("\n", "\\n")
273-
.replace("\r", "\\r")
274-
.replace("\t", "\\t");
275-
}
276-
277-
/**
278-
* Builds the JSON for the OpenAPI reference sources
279-
*
280-
* @param sources list of OpenAPI reference sources
281-
* @return the sources as a JSON string
282-
*/
283-
private String buildSourcesJsonArray(List<ScalarSource> sources) {
284-
final StringBuilder builder = new StringBuilder("[");
285-
286-
// Filter out sources with invalid urls
287-
final List<ScalarSource> filteredSources = sources.stream()
288-
.filter(source -> isNotNullOrBlank(source.getUrl()))
289-
.collect(Collectors.toList());
290-
291-
// Append each source to json array
292-
for (int i = 0; i < filteredSources.size(); i++) {
293-
final ScalarSource source = filteredSources.get(i);
294-
295-
final String sourceJson = buildSourceJson(source);
296-
builder.append("\n").append(sourceJson);
297-
298-
if (i != filteredSources.size() - 1) {
299-
builder.append(",");
300-
}
301-
}
302-
303-
builder.append("\n]");
304-
return builder.toString();
305-
}
306-
307-
/**
308-
* Builds the JSON for an OpenAPI reference source
309-
*
310-
* @param source the OpenAPI reference source
311-
* @return the source as a JSON string
186+
* @param requestUrl the request url
187+
* @return the string
312188
*/
313-
private String buildSourceJson(ScalarSource source) {
314-
final StringBuilder builder = new StringBuilder("{");
315-
316-
builder.append("\n url: \"").append(escapeJson(source.getUrl())).append("\"");
317-
318-
319-
if (isNotNullOrBlank(source.getTitle())) {
320-
builder.append(",\n title: \"").append(escapeJson(source.getTitle())).append("\"");
189+
private String buildConfigurationJson(String requestUrl) {
190+
try {
191+
this.scalarProperties.setUrl(requestUrl);
192+
ScalarConfiguration config = ScalarConfigurationMapper.map(scalarProperties);
193+
return objectMapper.writeValueAsString(config);
321194
}
322-
323-
if (isNotNullOrBlank(source.getSlug())) {
324-
builder.append(",\n slug: \"").append(escapeJson(source.getSlug())).append("\"");
325-
}
326-
327-
if (source.isDefault() != null) {
328-
builder.append(",\n default: ").append(source.isDefault());
195+
catch (JacksonException e) {
196+
throw new RuntimeException("Failed to serialize Scalar configuration", e);
329197
}
330-
331-
builder.append("\n}");
332-
return builder.toString();
333-
}
334-
335-
/**
336-
* Returns whether a String is not null or blank
337-
*
338-
* @param input the string
339-
* @return whether the string is not null or blank
340-
*/
341-
private boolean isNotNullOrBlank(String input) {
342-
return input != null && !input.isBlank();
343198
}
344199
}

springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/ScalarConstants.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,16 @@ public class ScalarConstants {
4646
/**
4747
* The constant SCALAR_DEFAULT_URL.
4848
*/
49-
public static final String SCALAR_DEFAULT_URL = "https://registry.scalar.com/@scalar/apis/galaxy/latest?format=json";
49+
public static final String SCALAR_DEFAULT_URL = "https://registry.scalar.com/@scalar/apis/galaxy?format=json";
5050

5151
/**
5252
* The constant DEFAULT_SCALAR_ACTUATOR_PATH.
5353
*/
5454
public static final String DEFAULT_SCALAR_ACTUATOR_PATH = "scalar";
55+
56+
/**
57+
* The constant HTML_TEMPLATE_PATH.
58+
*/
59+
public static final String HTML_TEMPLATE_PATH = "/META-INF/resources/webjars/scalar/index.html";
60+
5561
}

springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarActuatorController.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import com.scalar.maven.webjar.ScalarProperties;
3232
import io.swagger.v3.oas.annotations.Operation;
3333
import org.springdoc.scalar.AbstractScalarController;
34+
import tools.jackson.databind.ObjectMapper;
3435

3536
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
3637
import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint;
@@ -59,9 +60,10 @@ public class ScalarActuatorController extends AbstractScalarController {
5960
*
6061
* @param scalarProperties the scalar properties
6162
* @param webEndpointProperties the web endpoint properties
63+
* @param objectMapper the object mapper
6264
*/
63-
protected ScalarActuatorController(ScalarProperties scalarProperties, WebEndpointProperties webEndpointProperties) {
64-
super(scalarProperties);
65+
protected ScalarActuatorController(ScalarProperties scalarProperties, WebEndpointProperties webEndpointProperties, ObjectMapper objectMapper) {
66+
super(scalarProperties, objectMapper);
6567
this.webEndpointProperties = webEndpointProperties;
6668
}
6769

springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarConfiguration.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.springdoc.core.configuration.SpringDocConfiguration;
3131
import org.springdoc.core.events.SpringDocAppInitializer;
3232
import org.springdoc.core.properties.SpringDocConfigProperties;
33+
import tools.jackson.databind.ObjectMapper;
3334

3435
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
3536
import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort;
@@ -69,14 +70,15 @@ public class ScalarConfiguration {
6970
*
7071
* @param scalarProperties the scalar properties
7172
* @param springDocConfigProperties the spring doc config properties
73+
* @param objectMapper the object mapper
7274
* @return the scalar web mvc controller
7375
*/
7476
@Bean
7577
@ConditionalOnProperty(name = SPRINGDOC_USE_MANAGEMENT_PORT, havingValue = "false", matchIfMissing = true)
7678
@ConditionalOnMissingBean
7779
@Lazy(false)
78-
ScalarWebFluxController scalarWebMvcController(ScalarProperties scalarProperties, SpringDocConfigProperties springDocConfigProperties) {
79-
return new ScalarWebFluxController(scalarProperties,springDocConfigProperties);
80+
ScalarWebFluxController scalarWebMvcController(ScalarProperties scalarProperties, SpringDocConfigProperties springDocConfigProperties, ObjectMapper objectMapper) {
81+
return new ScalarWebFluxController(scalarProperties,springDocConfigProperties, objectMapper);
8082
}
8183

8284
/**
@@ -118,13 +120,14 @@ static class SwaggerActuatorWelcomeConfiguration {
118120
*
119121
* @param properties the properties
120122
* @param webEndpointProperties the web endpoint properties
123+
* @param objectMapper the object mapper
121124
* @return the scalar actuator controller
122125
*/
123126
@Bean
124127
@ConditionalOnMissingBean
125128
@Lazy(false)
126-
ScalarActuatorController scalarActuatorController(ScalarProperties properties, WebEndpointProperties webEndpointProperties) {
127-
return new ScalarActuatorController(properties,webEndpointProperties);
129+
ScalarActuatorController scalarActuatorController(ScalarProperties properties, WebEndpointProperties webEndpointProperties, ObjectMapper objectMapper) {
130+
return new ScalarActuatorController(properties,webEndpointProperties, objectMapper);
128131
}
129132

130133
/**

springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarWebFluxController.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import com.scalar.maven.webjar.ScalarProperties;
3232
import org.springdoc.core.properties.SpringDocConfigProperties;
3333
import org.springdoc.scalar.AbstractScalarController;
34+
import tools.jackson.databind.ObjectMapper;
3435

3536
import org.springframework.http.ResponseEntity;
3637
import org.springframework.http.server.reactive.ServerHttpRequest;
@@ -61,9 +62,10 @@ public class ScalarWebFluxController extends AbstractScalarController {
6162
*
6263
* @param scalarProperties the scalar properties
6364
* @param springDocConfigProperties the spring doc config properties
65+
* @param objectMapper the object mapper
6466
*/
65-
protected ScalarWebFluxController(ScalarProperties scalarProperties, SpringDocConfigProperties springDocConfigProperties) {
66-
super(scalarProperties);
67+
protected ScalarWebFluxController(ScalarProperties scalarProperties, SpringDocConfigProperties springDocConfigProperties, ObjectMapper objectMapper) {
68+
super(scalarProperties, objectMapper);
6769
this.springDocConfigProperties = springDocConfigProperties;
6870
}
6971

0 commit comments

Comments
 (0)