Skip to content

Commit cc1a4e5

Browse files
committed
Abstract shared Swagger configurer logic
1 parent 9962081 commit cc1a4e5

File tree

4 files changed

+316
-134
lines changed

4 files changed

+316
-134
lines changed

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/Constants.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,11 @@ public final class Constants {
376376
*/
377377
public static final String SWAGGER_INITIALIZER_PATTERN = "/*" + SWAGGER_INITIALIZER_JS;
378378

379+
/**
380+
* The constant SWAGGER_RESOURCE_CACHE_NAME.
381+
*/
382+
public static final String SWAGGER_RESOURCE_CACHE_NAME = "swagger-resource-chain-cache";
383+
379384
/**
380385
* The constant HEALTH_PATTERN.
381386
*/
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
package org.springdoc.ui;
2+
3+
import org.springdoc.core.properties.SwaggerUiConfigProperties;
4+
import org.springframework.boot.autoconfigure.web.WebProperties;
5+
import org.springframework.web.util.pattern.PathPattern;
6+
import org.springframework.web.util.pattern.PathPatternParser;
7+
import org.springframework.web.util.pattern.PatternParseException;
8+
9+
import java.util.Arrays;
10+
11+
import static org.springdoc.core.utils.Constants.ALL_PATTERN;
12+
import static org.springdoc.core.utils.Constants.SWAGGER_INITIALIZER_PATTERN;
13+
import static org.springdoc.core.utils.Constants.SWAGGER_UI_PREFIX;
14+
import static org.springdoc.core.utils.Constants.SWAGGER_UI_WEBJAR_NAME;
15+
import static org.springdoc.core.utils.Constants.SWAGGER_UI_WEBJAR_NAME_PATTERN;
16+
import static org.springdoc.core.utils.Constants.WEBJARS_RESOURCE_LOCATION;
17+
import static org.springframework.util.AntPathMatcher.DEFAULT_PATH_SEPARATOR;
18+
19+
/**
20+
* The type Abstract swagger configurer.
21+
*/
22+
public abstract class AbstractSwaggerConfigurer {
23+
24+
/**
25+
* The Swagger ui config properties.
26+
*/
27+
private final SwaggerUiConfigProperties swaggerUiConfigProperties;
28+
29+
/**
30+
* The Spring Web config properties.
31+
*/
32+
private final WebProperties springWebProperties;
33+
34+
/**
35+
* The path pattern parser.
36+
*/
37+
private final PathPatternParser parser = new PathPatternParser();
38+
39+
/**
40+
* Instantiates a new Abstract swagger configurer.
41+
*
42+
* @param swaggerUiConfigProperties the swagger ui calculated config
43+
* @param springWebProperties the spring web config
44+
*/
45+
protected AbstractSwaggerConfigurer(SwaggerUiConfigProperties swaggerUiConfigProperties, WebProperties springWebProperties) {
46+
this.swaggerUiConfigProperties = swaggerUiConfigProperties;
47+
this.springWebProperties = springWebProperties;
48+
}
49+
50+
/**
51+
* Gets the handler configs for mapping Swagger UI resources.
52+
*
53+
* @return the Swagger UI handler configs.
54+
*/
55+
protected SwaggerResourceHandlerConfig[] getSwaggerHandlerConfigs() {
56+
String swaggerUiPattern = getUiRootPath() + SWAGGER_UI_PREFIX + ALL_PATTERN;
57+
String swaggerUiInitializerPattern = combinePatterns(swaggerUiPattern, SWAGGER_INITIALIZER_PATTERN);
58+
String swaggerUiResourceLocation = WEBJARS_RESOURCE_LOCATION + SWAGGER_UI_WEBJAR_NAME + DEFAULT_PATH_SEPARATOR +
59+
swaggerUiConfigProperties.getVersion() + DEFAULT_PATH_SEPARATOR;
60+
61+
return new SwaggerResourceHandlerConfig[]{
62+
SwaggerResourceHandlerConfig.createCached()
63+
.setPatterns(swaggerUiPattern)
64+
.setLocations(swaggerUiResourceLocation),
65+
SwaggerResourceHandlerConfig.createUncached()
66+
.setPatterns(swaggerUiInitializerPattern)
67+
.setLocations(swaggerUiResourceLocation)
68+
};
69+
}
70+
71+
/**
72+
* Gets the handler configs for mapping webjar resources for the Swagger UI.
73+
*
74+
* @return the Swagger UI webjar handler configs.
75+
*/
76+
protected SwaggerResourceHandlerConfig[] getSwaggerWebjarHandlerConfigs() {
77+
if (!springWebProperties.getResources().isAddMappings()) return new SwaggerResourceHandlerConfig[]{};
78+
79+
String swaggerUiWebjarPattern = combinePatterns(getWebjarsPathPattern(), SWAGGER_UI_WEBJAR_NAME_PATTERN) + ALL_PATTERN;
80+
String swaggerUiWebjarInitializerPattern = combinePatterns(swaggerUiWebjarPattern, SWAGGER_INITIALIZER_PATTERN);
81+
String swaggerUiWebjarVersionInitializerPattern = combinePatterns(swaggerUiWebjarPattern,
82+
swaggerUiConfigProperties.getVersion() + SWAGGER_INITIALIZER_PATTERN);
83+
String swaggerUiWebjarResourceLocation = WEBJARS_RESOURCE_LOCATION;
84+
85+
return new SwaggerResourceHandlerConfig[]{
86+
SwaggerResourceHandlerConfig.createCached()
87+
.setPatterns(swaggerUiWebjarPattern)
88+
.setLocations(swaggerUiWebjarResourceLocation),
89+
SwaggerResourceHandlerConfig.createUncached()
90+
.setPatterns(swaggerUiWebjarInitializerPattern, swaggerUiWebjarVersionInitializerPattern)
91+
.setLocations(swaggerUiWebjarResourceLocation)
92+
};
93+
}
94+
95+
/**
96+
* Gets the root path for the Swagger UI.
97+
*
98+
* @return the Swagger UI root path.
99+
*/
100+
protected abstract String getUiRootPath();
101+
102+
/**
103+
* Gets the path pattern for webjar resources.
104+
*
105+
* @return the webjars path pattern.
106+
*/
107+
protected abstract String getWebjarsPathPattern();
108+
109+
/**
110+
* Combines pattern strings into a new pattern according to the rules of {@link PathPattern#combine}.
111+
*
112+
* <p>For example:
113+
* <ul>
114+
* <li><code>/webjars/&#42;&#42;</code> + <code>/swagger-ui/&#42;&#42;</code> => <code>/webjars/swagger-ui/&#42;&#42;</code></li>
115+
* <li><code>/documentation/swagger-ui&#42;/&#42;&#42;</code> + <code>/&#42;.js</code> => <code>/documentation/swagger-ui&#42;/&#42;.js</code></li>
116+
* </ul>
117+
*
118+
* @param patterns the patterns to combine.
119+
*
120+
* @return the combination of the patterns strings.
121+
*
122+
* @throws IllegalArgumentException if the patterns cannot be combined.
123+
*
124+
* @see PathPattern#combine
125+
*/
126+
protected String combinePatterns(String... patterns) {
127+
return Arrays.stream(patterns)
128+
.map(this::parsePattern)
129+
.reduce(PathPattern::combine)
130+
.map(PathPattern::getPatternString)
131+
.orElseThrow(IllegalArgumentException::new);
132+
}
133+
134+
/**
135+
* Parses a pattern string as a path pattern.
136+
*
137+
* @param pattern the pattern string.
138+
*
139+
* @return the parsed path pattern.
140+
*
141+
* @throws PatternParseException if the pattern string cannot be parsed.
142+
*/
143+
private PathPattern parsePattern(String pattern) {
144+
return parser.parse(parser.initFullPathPattern(pattern));
145+
}
146+
147+
/**
148+
* The type Swagger resource handler config.
149+
*
150+
* @param cacheResources whether to cache resources.
151+
* @param patterns the patterns to match.
152+
* @param locations the locations to use.
153+
*/
154+
protected record SwaggerResourceHandlerConfig(boolean cacheResources, String[] patterns, String[] locations) {
155+
156+
private SwaggerResourceHandlerConfig(boolean cacheResources) {
157+
this(cacheResources, new String[]{}, new String[]{});
158+
}
159+
160+
/**
161+
* Sets the patterns.
162+
*
163+
* @param patterns the patterns to match.
164+
*
165+
* @return the updated config.
166+
*/
167+
public SwaggerResourceHandlerConfig setPatterns(String... patterns) {
168+
return new SwaggerResourceHandlerConfig(cacheResources, patterns, locations);
169+
}
170+
171+
/**
172+
* Sets the locations.
173+
*
174+
* @param locations the locations to use.
175+
*
176+
* @return the updated config.
177+
*/
178+
public SwaggerResourceHandlerConfig setLocations(String... locations) {
179+
return new SwaggerResourceHandlerConfig(cacheResources, patterns, locations);
180+
}
181+
182+
/**
183+
* Create a Swagger resource handler config with resource caching enabled.
184+
*/
185+
public static SwaggerResourceHandlerConfig createCached() {
186+
return new SwaggerResourceHandlerConfig(true);
187+
}
188+
189+
/**
190+
* Create a Swagger resource handler config with resource caching disabled.
191+
*/
192+
public static SwaggerResourceHandlerConfig createUncached() {
193+
return new SwaggerResourceHandlerConfig(false);
194+
}
195+
}
196+
}

0 commit comments

Comments
 (0)