or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

auto-configuration.mdcontrollers.mdcore-api-generation.mdindex.mdresource-processing.mdweb-configuration.md

resource-processing.mddocs/

0

# Resource Processing

1

2

Resource transformation and resolution for Swagger UI assets, including dynamic configuration injection and web jar handling. This system ensures that Swagger UI resources are properly located, resolved, and configured at runtime.

3

4

## Capabilities

5

6

### SwaggerIndexPageTransformer

7

8

Resource transformer that dynamically injects configuration into Swagger UI initializer JavaScript.

9

10

```java { .api }

11

/**

12

* Resource transformer for Swagger UI index page and initializer JavaScript

13

* Dynamically injects runtime configuration into Swagger UI assets

14

*/

15

public class SwaggerIndexPageTransformer extends AbstractSwaggerIndexTransformer

16

implements SwaggerIndexTransformer {

17

18

/**

19

* Constructor for index page transformer

20

* @param swaggerUiConfig Swagger UI configuration properties

21

* @param swaggerUiOAuthProperties OAuth configuration properties

22

* @param swaggerWelcomeCommon Common welcome functionality for URL building

23

* @param objectMapperProvider JSON object mapper for configuration serialization

24

*/

25

public SwaggerIndexPageTransformer(SwaggerUiConfigProperties swaggerUiConfig,

26

SwaggerUiOAuthProperties swaggerUiOAuthProperties, SwaggerWelcomeCommon swaggerWelcomeCommon,

27

ObjectMapperProvider objectMapperProvider);

28

29

/**

30

* Transforms resources to inject dynamic configuration

31

* Identifies Swagger UI initializer JavaScript and injects runtime configuration

32

* @param request HTTP request for context-specific configuration

33

* @param resource Original resource to transform

34

* @param transformerChain Resource transformer chain for further processing

35

* @return Transformed resource with injected configuration or original resource

36

* @throws IOException if resource transformation fails

37

*/

38

@Override

39

public Resource transform(HttpServletRequest request, Resource resource,

40

ResourceTransformerChain transformerChain) throws IOException;

41

}

42

```

43

44

### SwaggerIndexTransformer

45

46

Interface marker for Swagger UI resource transformation.

47

48

```java { .api }

49

/**

50

* Interface for Swagger UI resource transformation

51

* Extends Spring's ResourceTransformer for integration with resource handling

52

*/

53

public interface SwaggerIndexTransformer extends ResourceTransformer {

54

// Marker interface - inherits all methods from ResourceTransformer

55

}

56

```

57

58

### SwaggerResourceResolver

59

60

Resource resolver that handles Swagger UI web jar asset resolution with version management.

61

62

```java { .api }

63

/**

64

* Resource resolver for Swagger UI web jar assets

65

* Extends Spring's LiteWebJarsResourceResolver with Swagger-specific functionality

66

*/

67

public class SwaggerResourceResolver extends LiteWebJarsResourceResolver {

68

69

/**

70

* Constructor for Swagger resource resolver

71

* @param swaggerUiConfigProperties Configuration properties containing version information

72

*/

73

public SwaggerResourceResolver(SwaggerUiConfigProperties swaggerUiConfigProperties);

74

75

/**

76

* Finds web jar resource paths for Swagger UI assets

77

* First attempts standard web jar resolution, then falls back to Swagger-specific resolution

78

* @param pathStr Resource path to resolve

79

* @return Resolved resource path or null if not found

80

*/

81

@Nullable

82

@Override

83

protected String findWebJarResourcePath(String pathStr);

84

}

85

```

86

87

## Resource Transformation Process

88

89

### Transformation Detection

90

91

The transformer identifies Swagger UI initializer JavaScript using pattern matching:

92

93

```java { .api }

94

/**

95

* Resource pattern matching for transformation

96

*/

97

interface TransformationDetection {

98

/**

99

* Pattern used to identify Swagger UI initializer JavaScript

100

*/

101

String SWAGGER_INITIALIZER_PATTERN = "**/swagger-ui/**/swagger-initializer.js";

102

103

/**

104

* AntPathMatcher used for pattern matching against resource URLs

105

*/

106

AntPathMatcher ANT_PATH_MATCHER = new AntPathMatcher();

107

108

/**

109

* Checks if resource matches transformation pattern

110

* @param resourceUrl URL of the resource to check

111

* @return true if resource should be transformed

112

*/

113

boolean shouldTransform(String resourceUrl);

114

}

115

```

116

117

### Configuration Injection Process

118

119

When a matching resource is found, the transformer:

120

121

1. **Builds Configuration**: Creates `SwaggerUiConfigParameters` from request context

122

2. **Updates URLs**: Calls `SwaggerWelcomeCommon.buildFromCurrentContextPath()`

123

3. **Applies Transformations**: Injects configuration into JavaScript content

124

4. **Returns Resource**: Wraps transformed content in `TransformedResource`

125

126

```java { .api }

127

/**

128

* Configuration injection steps

129

*/

130

interface ConfigurationInjection {

131

/**

132

* Create configuration parameters from current request

133

*/

134

SwaggerUiConfigParameters createConfigParameters(HttpServletRequest request);

135

136

/**

137

* Build context-specific URLs and paths

138

*/

139

void buildContextPaths(SwaggerUiConfigParameters parameters, HttpServletRequest request);

140

141

/**

142

* Apply default transformations to resource content

143

*/

144

String applyTransformations(SwaggerUiConfigParameters parameters, InputStream resourceStream);

145

146

/**

147

* Wrap transformed content in Spring Resource

148

*/

149

TransformedResource wrapTransformedContent(Resource originalResource, byte[] transformedContent);

150

}

151

```

152

153

## Resource Resolution Process

154

155

### Web Jar Resolution

156

157

The resolver follows a two-tier resolution strategy:

158

159

```java { .api }

160

/**

161

* Web jar resolution strategy

162

*/

163

interface WebJarResolution {

164

/**

165

* Primary resolution using Spring's LiteWebJarsResourceResolver

166

* Handles standard web jar path resolution and version matching

167

*/

168

String primaryResolution(String pathStr);

169

170

/**

171

* Fallback resolution using Swagger-specific utilities

172

* Uses SwaggerResourceResolverUtils.findSwaggerResourcePath()

173

*/

174

String fallbackResolution(String pathStr, String swaggerUiVersion);

175

176

/**

177

* Combined resolution logic

178

*/

179

@Nullable

180

default String resolveResourcePath(String pathStr, String version) {

181

String primaryResult = primaryResolution(pathStr);

182

return primaryResult != null ? primaryResult : fallbackResolution(pathStr, version);

183

}

184

}

185

```

186

187

### Version Management

188

189

Resource resolution uses version information from configuration:

190

191

```java { .api }

192

/**

193

* Version-aware resource resolution

194

*/

195

interface VersionManagement {

196

/**

197

* Gets Swagger UI version from configuration properties

198

*/

199

String getSwaggerUiVersion(SwaggerUiConfigProperties properties);

200

201

/**

202

* Resolves versioned web jar paths

203

*/

204

String resolveVersionedPath(String basePath, String version);

205

206

/**

207

* Handles version conflicts and fallbacks

208

*/

209

String handleVersionConflict(String requestedVersion, String availableVersion);

210

}

211

```

212

213

## Usage Examples

214

215

### Basic Resource Processing

216

217

Resource processing happens automatically during resource serving:

218

219

```java

220

// When browser requests: /swagger-ui/swagger-initializer.js

221

// 1. SwaggerResourceResolver locates the web jar asset

222

// 2. SwaggerIndexPageTransformer injects runtime configuration

223

// 3. Transformed resource served to browser with current API URLs

224

```

225

226

### Custom Transformation

227

228

Extend transformation for custom requirements:

229

230

```java

231

@Component

232

public class CustomSwaggerTransformer implements SwaggerIndexTransformer {

233

234

@Override

235

public Resource transform(HttpServletRequest request, Resource resource,

236

ResourceTransformerChain transformerChain) throws IOException {

237

238

if (isCustomResource(resource)) {

239

String customContent = addCustomConfiguration(resource);

240

return new TransformedResource(resource, customContent.getBytes(StandardCharsets.UTF_8));

241

}

242

243

return resource;

244

}

245

246

private boolean isCustomResource(Resource resource) {

247

try {

248

return resource.getURL().toString().contains("custom-swagger");

249

} catch (IOException e) {

250

return false;

251

}

252

}

253

254

private String addCustomConfiguration(Resource resource) throws IOException {

255

String originalContent = StreamUtils.copyToString(resource.getInputStream(), StandardCharsets.UTF_8);

256

return originalContent.replace("// CUSTOM_CONFIG_PLACEHOLDER",

257

"window.customSwaggerConfig = { theme: 'dark', layout: 'sidebar' };");

258

}

259

}

260

```

261

262

### Custom Resource Resolution

263

264

Override resource resolution for specific requirements:

265

266

```java

267

@Component

268

@Primary

269

public class CustomSwaggerResourceResolver extends SwaggerResourceResolver {

270

271

public CustomSwaggerResourceResolver(SwaggerUiConfigProperties properties) {

272

super(properties);

273

}

274

275

@Override

276

protected String findWebJarResourcePath(String pathStr) {

277

// Try custom resolution first

278

String customPath = findCustomSwaggerResource(pathStr);

279

if (customPath != null) {

280

return customPath;

281

}

282

283

// Fall back to standard resolution

284

return super.findWebJarResourcePath(pathStr);

285

}

286

287

private String findCustomSwaggerResource(String pathStr) {

288

if (pathStr.contains("swagger-ui-custom")) {

289

return "META-INF/resources/custom-swagger/" + pathStr;

290

}

291

return null;

292

}

293

}

294

```

295

296

### Configuration-Specific Transformations

297

298

Apply different transformations based on configuration:

299

300

```java

301

@Configuration

302

public class ConditionalTransformationConfig {

303

304

@Bean

305

@ConditionalOnProperty("app.swagger.custom-branding")

306

public SwaggerIndexTransformer brandedTransformer() {

307

return new BrandedSwaggerTransformer();

308

}

309

310

@Bean

311

@ConditionalOnProperty("app.swagger.development-mode")

312

public SwaggerIndexTransformer developmentTransformer() {

313

return new DevelopmentSwaggerTransformer();

314

}

315

}

316

317

class BrandedSwaggerTransformer implements SwaggerIndexTransformer {

318

@Override

319

public Resource transform(HttpServletRequest request, Resource resource,

320

ResourceTransformerChain transformerChain) throws IOException {

321

322

if (isSwaggerInitializer(resource)) {

323

String content = injectBrandingConfiguration(resource);

324

return new TransformedResource(resource, content.getBytes(StandardCharsets.UTF_8));

325

}

326

327

return resource;

328

}

329

330

private String injectBrandingConfiguration(Resource resource) throws IOException {

331

String content = StreamUtils.copyToString(resource.getInputStream(), StandardCharsets.UTF_8);

332

return content.replace(

333

"// Configuration placeholder",

334

"window.ui = SwaggerUIBundle({ " +

335

"customCss: '.swagger-ui .topbar { background-color: #1976d2; }', " +

336

"customSiteTitle: 'Custom API Documentation' })"

337

);

338

}

339

}

340

```

341

342

## Performance Optimization

343

344

### Caching Strategy

345

346

Resource processing can be optimized through strategic caching:

347

348

```java { .api }

349

/**

350

* Caching considerations for resource processing

351

*/

352

interface CachingStrategy {

353

/**

354

* Static assets (CSS, images) can be cached longer

355

*/

356

void cacheStaticAssets(int cacheSeconds);

357

358

/**

359

* Dynamic content (initializer JS) should not be cached

360

*/

361

void disableCacheForDynamicContent();

362

363

/**

364

* Version-based cache invalidation

365

*/

366

void versionBasedCacheInvalidation(String version);

367

368

/**

369

* Production vs development caching strategies

370

*/

371

void environmentSpecificCaching(String environment);

372

}

373

```

374

375

### Resource Processing Pipeline

376

377

```java

378

// Optimized processing pipeline:

379

// 1. Quick pattern check (avoid expensive operations for non-matching resources)

380

// 2. Lazy configuration building (only when transformation needed)

381

// 3. Efficient string replacement (avoid full parsing when possible)

382

// 4. Resource wrapping optimization (minimal object creation)

383

```

384

385

### Memory Management

386

387

```java { .api }

388

/**

389

* Memory optimization for resource processing

390

*/

391

interface MemoryOptimization {

392

/**

393

* Stream-based processing to avoid loading large resources into memory

394

*/

395

void streamBasedProcessing();

396

397

/**

398

* Resource pooling for frequently accessed assets

399

*/

400

void resourcePooling();

401

402

/**

403

* Lazy initialization of expensive components

404

*/

405

void lazyInitialization();

406

407

/**

408

* Proper resource cleanup after transformation

409

*/

410

void resourceCleanup();

411

}

412

```

413

414

## Error Handling

415

416

Resource processing includes robust error handling:

417

418

```java { .api }

419

/**

420

* Error handling strategies for resource processing

421

*/

422

interface ErrorHandling {

423

/**

424

* Handle missing web jar resources

425

*/

426

void handleMissingResource(String resourcePath);

427

428

/**

429

* Handle transformation failures

430

*/

431

void handleTransformationError(Exception error, Resource resource);

432

433

/**

434

* Handle version conflicts

435

*/

436

void handleVersionConflict(String requestedVersion, String availableVersion);

437

438

/**

439

* Graceful degradation for configuration errors

440

*/

441

void gracefulDegradation(ConfigurationException error);

442

}

443

```

444

445

Common error scenarios and handling:

446

447

```java

448

// 1. Missing Swagger UI web jar → Fall back to CDN or show error page

449

// 2. Transformation failure → Serve original resource without configuration

450

// 3. Configuration building error → Use default configuration

451

// 4. Resource access error → Return 404 with helpful error message

452

```