Skip to content

Commit d504fd8

Browse files
committed
scalar upgrade to version 0.4.3
1 parent 98f1973 commit d504fd8

File tree

48 files changed

+203
-444
lines changed

Some content is hidden

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

48 files changed

+203
-444
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
<spring-cloud-function.version>4.2.2</spring-cloud-function.version>
6464
<spring-security-oauth2-authorization-server.version>1.4.3
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
<commons-lang3.version>3.18.0</commons-lang3.version>
6969
</properties>

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

Lines changed: 31 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
* * * *
2222
* * *
2323
* *
24-
*
24+
*
2525
*/
2626

2727
package org.springdoc.scalar;
@@ -30,15 +30,17 @@
3030
import java.io.InputStream;
3131
import java.net.URLDecoder;
3232
import java.nio.charset.StandardCharsets;
33-
import java.util.List;
34-
import java.util.stream.Collectors;
3533

34+
import com.fasterxml.jackson.core.JsonProcessingException;
35+
import com.fasterxml.jackson.databind.ObjectMapper;
3636
import com.scalar.maven.webjar.ScalarProperties;
37-
import com.scalar.maven.webjar.ScalarProperties.ScalarSource;
37+
import com.scalar.maven.webjar.internal.ScalarConfiguration;
38+
import com.scalar.maven.webjar.internal.ScalarConfigurationMapper;
3839

3940
import org.springframework.http.MediaType;
4041
import org.springframework.http.ResponseEntity;
4142

43+
import static org.springdoc.scalar.ScalarConstants.HTML_TEMPLATE_PATH;
4244
import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_URL;
4345
import static org.springdoc.scalar.ScalarConstants.SCALAR_JS_FILENAME;
4446
import static org.springframework.util.AntPathMatcher.DEFAULT_PATH_SEPARATOR;
@@ -60,14 +62,21 @@ public abstract class AbstractScalarController {
6062
*/
6163
protected final String originalScalarUrl;
6264

65+
/**
66+
* The Object mapper.
67+
*/
68+
private final ObjectMapper objectMapper;
69+
6370
/**
6471
* Instantiates a new Abstract scalar controller.
6572
*
6673
* @param scalarProperties the scalar properties
74+
* @param objectMapper the object mapper
6775
*/
68-
protected AbstractScalarController(ScalarProperties scalarProperties) {
76+
protected AbstractScalarController(ScalarProperties scalarProperties, ObjectMapper objectMapper) {
6977
this.scalarProperties = scalarProperties;
7078
this.originalScalarUrl = scalarProperties.getUrl();
79+
this.objectMapper = objectMapper;
7180
}
7281

7382
/**
@@ -82,22 +91,18 @@ protected AbstractScalarController(ScalarProperties scalarProperties) {
8291
*/
8392
protected ResponseEntity<String> getDocs(String requestUrl) throws IOException {
8493
// Load the template HTML
85-
InputStream inputStream = getClass().getResourceAsStream("/META-INF/resources/webjars/scalar/index.html");
94+
InputStream inputStream = getClass().getResourceAsStream(HTML_TEMPLATE_PATH);
8695
if (inputStream == null) {
87-
return ResponseEntity.notFound().build();
96+
throw new IOException("HTML template not found at: " + HTML_TEMPLATE_PATH);
8897
}
8998

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

102107
return ResponseEntity.ok()
103108
.contentType(MediaType.TEXT_HTML)
@@ -163,7 +168,7 @@ protected String buildJsBundleUrl(String requestUrl, String scalarPath) {
163168
if (SCALAR_DEFAULT_URL.equals(originalScalarUrl)) {
164169
int firstPathSlash = requestUrl.indexOf('/', requestUrl.indexOf("://") + 3);
165170
String path = firstPathSlash >= 0 ? requestUrl.substring(firstPathSlash) : "/";
166-
if( path.endsWith("/"))
171+
if (path.endsWith("/"))
167172
path = path.substring(0, path.length() - 1);
168173
return path + DEFAULT_PATH_SEPARATOR + SCALAR_JS_FILENAME;
169174
}
@@ -187,158 +192,20 @@ protected String buildJsBundleUrl(String requestUrl, String scalarPath) {
187192
protected abstract String buildJsBundleUrl(String requestUrl);
188193

189194
/**
190-
* Builds the configuration JSON for the Scalar API Reference.
195+
* Build configuration json string.
191196
*
192-
* @return the configuration JSON as a string
197+
* @param requestUrl the request url
198+
* @return the string
193199
*/
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("\"");
200+
private String buildConfigurationJson(String requestUrl) {
201+
try {
202+
this.scalarProperties.setUrl(requestUrl);
203+
ScalarConfiguration config = ScalarConfigurationMapper.map(scalarProperties);
204+
return objectMapper.writeValueAsString(config);
234205
}
235-
236-
// Add theme
237-
if (scalarProperties.getTheme() != null && !"default".equals(scalarProperties.getTheme())) {
238-
config.append(",\n theme: \"").append(escapeJson(scalarProperties.getTheme())).append("\"");
206+
catch (JsonProcessingException e) {
207+
throw new RuntimeException("Failed to serialize Scalar configuration", e);
239208
}
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();
258209
}
259210

260-
/**
261-
* Escapes a string for JSON output.
262-
*
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<ScalarProperties.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 ScalarProperties.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
312-
*/
313-
private String buildSourceJson(ScalarProperties.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("\"");
321-
}
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());
329-
}
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();
343-
}
344211
}

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,15 @@ 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";
5560
}

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
@@ -28,6 +28,7 @@
2828

2929
import java.io.IOException;
3030

31+
import com.fasterxml.jackson.databind.ObjectMapper;
3132
import com.scalar.maven.webjar.ScalarProperties;
3233
import io.swagger.v3.oas.annotations.Operation;
3334
import org.springdoc.scalar.AbstractScalarController;
@@ -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
@@ -26,6 +26,7 @@
2626

2727
package org.springdoc.webflux.scalar;
2828

29+
import com.fasterxml.jackson.databind.ObjectMapper;
2930
import com.scalar.maven.webjar.ScalarProperties;
3031
import org.springdoc.core.configuration.SpringDocConfiguration;
3132
import org.springdoc.core.events.SpringDocAppInitializer;
@@ -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: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
import java.io.IOException;
3030

31+
import com.fasterxml.jackson.databind.ObjectMapper;
3132
import com.scalar.maven.webjar.ScalarProperties;
3233
import org.springdoc.core.properties.SpringDocConfigProperties;
3334
import org.springdoc.scalar.AbstractScalarController;
@@ -61,12 +62,20 @@ 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

72+
/**
73+
* Gets docs.
74+
*
75+
* @param serverHttpRequest the server http request
76+
* @return the docs
77+
* @throws IOException the io exception
78+
*/
7079
@GetMapping
7180
public ResponseEntity<String> getDocs(ServerHttpRequest serverHttpRequest) throws IOException {
7281
return super.getDocs(serverHttpRequest.getURI().toString());

0 commit comments

Comments
 (0)