This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new 648792a1a1 SonarQube bug fixes
648792a1a1 is described below

commit 648792a1a1f373870c862506ca409304240129d1
Author: James Bognar <[email protected]>
AuthorDate: Wed Feb 4 09:17:34 2026 -0500

    SonarQube bug fixes
---
 SONARQUBE_ISSUES_SUMMARY.md                        | 181 +++++++++
 .../org/apache/juneau/bean/openapi3/Callback.java  |   9 +-
 .../apache/juneau/bean/openapi3/Components.java    |  65 ++--
 .../org/apache/juneau/bean/openapi3/Encoding.java  |  37 +-
 .../apache/juneau/bean/openapi3/HeaderInfo.java    |  72 ++--
 .../java/org/apache/juneau/bean/openapi3/Info.java |  44 ++-
 .../org/apache/juneau/bean/openapi3/Items.java     | 128 ++++---
 .../java/org/apache/juneau/bean/openapi3/Link.java |  44 ++-
 .../org/apache/juneau/bean/openapi3/OpenApi.java   |  58 +--
 .../org/apache/juneau/bean/openapi3/Operation.java |  86 +++--
 .../org/apache/juneau/bean/openapi3/Parameter.java |  86 +++--
 .../org/apache/juneau/bean/openapi3/PathItem.java  |  86 +++--
 .../juneau/bean/openapi3/RequestBodyInfo.java      |  23 +-
 .../juneau/bean/openapi3/SecuritySchemeInfo.java   |  58 +--
 .../org/apache/juneau/bean/swagger/Operation.java  |  86 +++--
 .../org/apache/juneau/bean/swagger/Swagger.java    | 108 +++---
 scripts/README_SONARQUBE.md                        | 217 +++++++++++
 scripts/categorize-sonar-issues.py                 | 408 +++++++++++++++++++++
 scripts/view-sonar-category.py                     |  91 +++++
 19 files changed, 1476 insertions(+), 411 deletions(-)

diff --git a/SONARQUBE_ISSUES_SUMMARY.md b/SONARQUBE_ISSUES_SUMMARY.md
new file mode 100644
index 0000000000..0295ce0653
--- /dev/null
+++ b/SONARQUBE_ISSUES_SUMMARY.md
@@ -0,0 +1,181 @@
+# SonarQube Issues Categorization Summary
+
+This document provides an overview of the categorized SonarQube issues for the 
Apache Juneau project.
+
+## Summary Statistics
+
+- **Total Issues**: 3,116
+- **Total Categories**: 30
+- **Categorized**: ~78% (remaining 22% are miscellaneous "Other Issues")
+
+## Issue Categories (Sorted by Count)
+
+| Category | Count | Percentage | Priority |
+|----------|-------|------------|---------|
+| Other Issues | 2,433 | 78.1% | Low |
+| Generic Type Issues | 121 | 3.9% | Medium |
+| Empty Method Implementations | 99 | 3.2% | Medium |
+| Unused Code | 96 | 3.1% | Low |
+| Missing Private Constructors | 91 | 2.9% | Low |
+| Test Assertion Issues | 61 | 2.0% | Medium |
+| Brain Methods (Complexity) | 30 | 1.0% | High |
+| Exception Catching Issues | 30 | 1.0% | Medium |
+| Optional Access Issues | 18 | 0.6% | Medium |
+| Missing Test Assertions | 16 | 0.5% | Medium |
+| Code Duplication | 16 | 0.5% | Medium |
+| Null Check Issues | 15 | 0.5% | High |
+| Field Shadowing | 11 | 0.4% | Low |
+| Python f-string Issues | 11 | 0.4% | Low |
+| Missing @Override Annotations | 11 | 0.4% | Low |
+| Constructor Visibility Issues | 10 | 0.3% | Low |
+| Unnecessary toString() Calls | 8 | 0.3% | Low |
+| ThreadLocal Cleanup Issues | 7 | 0.2% | Medium |
+| HTML/Documentation Issues | 6 | 0.2% | Low |
+| Singleton Pattern Issues | 6 | 0.2% | Medium |
+| Security Issues | 6 | 0.2% | High |
+| Missing Test Coverage | 3 | 0.1% | Low |
+| Deprecated Annotation Issues | 2 | 0.1% | Low |
+| Missing clone() Methods | 2 | 0.1% | Low |
+| Type Casting Issues | 2 | 0.1% | Low |
+| Line Separator Issues | 1 | 0.0% | Low |
+| Missing Exception Handling | 1 | 0.0% | High |
+| Empty Catch Blocks | 1 | 0.0% | Medium |
+| String Concatenation Issues | 1 | 0.0% | Low |
+
+## Recommended Fix Order
+
+### High Priority (Start Here)
+1. **Security Issues** (6 issues) - Security vulnerabilities should be fixed 
immediately
+2. **Null Check Issues** (15 issues) - Potential NullPointerExceptions
+3. **Brain Methods (Complexity)** (30 issues) - Code maintainability issues
+4. **Missing Exception Handling** (1 issue) - Critical error handling
+
+### Medium Priority
+5. **Exception Catching Issues** (30 issues) - Improve exception handling 
patterns
+6. **Generic Type Issues** (121 issues) - Type safety improvements
+7. **Empty Method Implementations** (99 issues) - Complete implementations or 
document why empty
+8. **Test Assertion Issues** (61 issues) - Fix test assertions
+9. **Optional Access Issues** (18 issues) - Proper Optional handling
+10. **Code Duplication** (16 issues) - Refactor duplicated code
+11. **ThreadLocal Cleanup Issues** (7 issues) - Memory leak prevention
+
+### Low Priority
+12. **Unused Code** (96 issues) - Remove dead code
+13. **Missing Private Constructors** (91 issues) - Utility class improvements
+14. **Missing @Override Annotations** (11 issues) - Code clarity
+15. **Unnecessary toString() Calls** (8 issues) - Minor optimizations
+16. **Other categories** - Fix as time permits
+
+## How to Use the Categorization Tool
+
+### 1. Generate Categorized Report
+
+```bash
+cd /Users/james.bognar/git/apache/juneau/master
+python3 scripts/categorize-sonar-issues.py 
/Users/james.bognar/Downloads/SonarQubeIssues.txt --save-json
+```
+
+This will:
+- Parse all SonarQube issues
+- Categorize them into 30 categories
+- Save a JSON file with all categorized issues
+- Display a summary
+
+### 2. View Category Details
+
+The JSON file (`SonarQubeIssues.categorized.json`) contains all issues 
organized by category. You can:
+
+- View specific categories
+- See all issues in a category
+- Get file locations and line numbers for each issue
+
+### 3. Interactive Fixing Session
+
+Run the script without `--save-json` to start an interactive session:
+
+```bash
+python3 scripts/categorize-sonar-issues.py 
/Users/james.bognar/Downloads/SonarQubeIssues.txt
+```
+
+Commands available:
+- `fix` - Start fixing issues in current category
+- `skip` - Move to next category
+- `details` - Show detailed issue information
+- `list` - List all categories
+- `<number>` - Jump to specific category number
+- `quit` - Exit
+
+## Category Descriptions
+
+### High Priority Categories
+
+**Security Issues**: Security vulnerabilities that need immediate attention.
+
+**Null Check Issues**: Missing null checks that could lead to 
NullPointerExceptions.
+
+**Brain Methods (Complexity)**: Methods that are too complex (high LOC, 
complexity, nesting, or variable count). These need refactoring.
+
+**Missing Exception Handling**: Missing exception handling in critical code 
paths.
+
+### Medium Priority Categories
+
+**Exception Catching Issues**: Catching overly broad exceptions (Throwable, 
Error) instead of specific Exception types.
+
+**Generic Type Issues**: Using raw types instead of parameterized generic 
types.
+
+**Empty Method Implementations**: Empty methods that should either be 
implemented or documented why they're empty.
+
+**Test Assertion Issues**: Test assertions comparing incompatible types or 
comparing primitives with null.
+
+**Optional Access Issues**: Accessing Optional values without checking 
ifPresent() or isEmpty() first.
+
+**Code Duplication**: Duplicated code blocks that should be refactored.
+
+**ThreadLocal Cleanup Issues**: ThreadLocal variables not being cleaned up, 
potentially causing memory leaks.
+
+### Low Priority Categories
+
+**Unused Code**: Unused parameters, variables, fields, methods, or imports.
+
+**Missing Private Constructors**: Utility classes that should have private 
constructors to prevent instantiation.
+
+**Missing @Override Annotations**: Methods overriding parent methods without 
@Override annotation.
+
+**Unnecessary toString() Calls**: Calling toString() on values that are 
already strings.
+
+**Field Shadowing**: Local variables or parameters shadowing class fields.
+
+**Python f-string Issues**: Python f-strings without replacement fields 
(should use regular strings).
+
+**HTML/Documentation Issues**: Missing HTML attributes or documentation 
elements.
+
+**Singleton Pattern Issues**: Singleton implementations that may need review.
+
+**Missing Test Coverage**: Classes that need test coverage.
+
+**Deprecated Annotation Issues**: @Deprecated annotations missing 'since' or 
'forRemoval' arguments.
+
+**Missing clone() Methods**: Classes that should implement clone().
+
+**Type Casting Issues**: Operations that need explicit casting to prevent 
overflow.
+
+**Line Separator Issues**: Using \n instead of %n for platform-specific line 
separators.
+
+**Empty Catch Blocks**: Catch blocks without logic that should either add 
logic or rethrow.
+
+**String Concatenation Issues**: String concatenation in loops that should use 
StringBuilder.
+
+## Next Steps
+
+1. Review this summary and prioritize categories based on your project needs
+2. Start with High Priority categories
+3. Use the interactive tool to work through categories systematically
+4. For each category, decide on a fix strategy:
+   - **Auto-fix**: Simple, mechanical fixes (e.g., adding @Override, removing 
unused imports)
+   - **Manual review**: Complex issues requiring code review (e.g., Brain 
Methods, Security Issues)
+   - **Batch fix**: Similar issues that can be fixed together (e.g., Missing 
Private Constructors)
+
+## Files Generated
+
+- `SonarQubeIssues.categorized.json` - Complete categorized issues in JSON 
format
+- This summary document
diff --git 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Callback.java
 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Callback.java
index 96d1f2e9d1..6d6bdb469b 100644
--- 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Callback.java
+++ 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Callback.java
@@ -72,6 +72,9 @@ import org.apache.juneau.commons.collections.*;
  */
 public class Callback extends OpenApiElement {
 
+       // Property name constants
+       private static final String PROP_CALLBACKS = "callbacks";
+
        private Map<String,PathItem> callbacks;
 
        /**
@@ -118,7 +121,7 @@ public class Callback extends OpenApiElement {
        public <T> T get(String property, Class<T> type) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "callbacks" -> toType(getCallbacks(), type);
+                       case PROP_CALLBACKS -> toType(getCallbacks(), type);
                        default -> super.get(property, type);
                };
        }
@@ -134,7 +137,7 @@ public class Callback extends OpenApiElement {
        public Set<String> keySet() {
                // @formatter:off
                var s = setb(String.class)
-                       .addIf(nn(callbacks), "callbacks")
+                       .addIf(nn(callbacks), PROP_CALLBACKS)
                        .build();
                // @formatter:on
                return new MultiSet<>(s, super.keySet());
@@ -144,7 +147,7 @@ public class Callback extends OpenApiElement {
        public Callback set(String property, Object value) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "callbacks" -> setCallbacks(toMapBuilder(value, 
String.class, PathItem.class).sparse().build());
+                       case PROP_CALLBACKS -> setCallbacks(toMapBuilder(value, 
String.class, PathItem.class).sparse().build());
                        default -> {
                                super.set(property, value);
                                yield this;
diff --git 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Components.java
 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Components.java
index be10df546c..6aacc2be31 100644
--- 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Components.java
+++ 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Components.java
@@ -84,6 +84,17 @@ import org.apache.juneau.commons.collections.*;
  */
 public class Components extends OpenApiElement {
 
+       // Property name constants
+       private static final String PROP_CALLBACKS = "callbacks";
+       private static final String PROP_EXAMPLES = "examples";
+       private static final String PROP_HEADERS = "headers";
+       private static final String PROP_LINKS = "links";
+       private static final String PROP_PARAMETERS = "parameters";
+       private static final String PROP_REQUEST_BODIES = "requestBodies";
+       private static final String PROP_RESPONSES = "responses";
+       private static final String PROP_SCHEMAS = "schemas";
+       private static final String PROP_SECURITY_SCHEMES = "securitySchemes";
+
        private Map<String,SchemaInfo> schemas;
        private Map<String,Response> responses;
        private Map<String,Parameter> parameters;
@@ -130,15 +141,15 @@ public class Components extends OpenApiElement {
        public <T> T get(String property, Class<T> type) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "schemas" -> toType(getSchemas(), type);
-                       case "responses" -> toType(getResponses(), type);
-                       case "parameters" -> toType(getParameters(), type);
-                       case "examples" -> toType(getExamples(), type);
-                       case "requestBodies" -> toType(getRequestBodies(), 
type);
-                       case "headers" -> toType(getHeaders(), type);
-                       case "securitySchemes" -> toType(getSecuritySchemes(), 
type);
-                       case "links" -> toType(getLinks(), type);
-                       case "callbacks" -> toType(getCallbacks(), type);
+                       case PROP_SCHEMAS -> toType(getSchemas(), type);
+                       case PROP_RESPONSES -> toType(getResponses(), type);
+                       case PROP_PARAMETERS -> toType(getParameters(), type);
+                       case PROP_EXAMPLES -> toType(getExamples(), type);
+                       case PROP_REQUEST_BODIES -> toType(getRequestBodies(), 
type);
+                       case PROP_HEADERS -> toType(getHeaders(), type);
+                       case PROP_SECURITY_SCHEMES -> 
toType(getSecuritySchemes(), type);
+                       case PROP_LINKS -> toType(getLinks(), type);
+                       case PROP_CALLBACKS -> toType(getCallbacks(), type);
                        default -> super.get(property, type);
                };
        }
@@ -210,15 +221,15 @@ public class Components extends OpenApiElement {
        public Set<String> keySet() {
                // @formatter:off
                var s = setb(String.class)
-                       .addIf(nn(callbacks), "callbacks")
-                       .addIf(nn(examples), "examples")
-                       .addIf(nn(headers), "headers")
-                       .addIf(nn(links), "links")
-                       .addIf(nn(parameters), "parameters")
-                       .addIf(nn(requestBodies), "requestBodies")
-                       .addIf(nn(responses), "responses")
-                       .addIf(nn(schemas), "schemas")
-                       .addIf(nn(securitySchemes), "securitySchemes")
+                       .addIf(nn(callbacks), PROP_CALLBACKS)
+                       .addIf(nn(examples), PROP_EXAMPLES)
+                       .addIf(nn(headers), PROP_HEADERS)
+                       .addIf(nn(links), PROP_LINKS)
+                       .addIf(nn(parameters), PROP_PARAMETERS)
+                       .addIf(nn(requestBodies), PROP_REQUEST_BODIES)
+                       .addIf(nn(responses), PROP_RESPONSES)
+                       .addIf(nn(schemas), PROP_SCHEMAS)
+                       .addIf(nn(securitySchemes), PROP_SECURITY_SCHEMES)
                        .build();
                // @formatter:on
                return new MultiSet<>(s, super.keySet());
@@ -228,15 +239,15 @@ public class Components extends OpenApiElement {
        public Components set(String property, Object value) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "callbacks" -> setCallbacks(toMapBuilder(value, 
String.class, Callback.class).sparse().build());
-                       case "examples" -> setExamples(toMapBuilder(value, 
String.class, Example.class).sparse().build());
-                       case "headers" -> setHeaders(toMapBuilder(value, 
String.class, HeaderInfo.class).sparse().build());
-                       case "links" -> setLinks(toMapBuilder(value, 
String.class, Link.class).sparse().build());
-                       case "parameters" -> setParameters(toMapBuilder(value, 
String.class, Parameter.class).sparse().build());
-                       case "requestBodies" -> 
setRequestBodies(toMapBuilder(value, String.class, 
RequestBodyInfo.class).sparse().build());
-                       case "responses" -> setResponses(toMapBuilder(value, 
String.class, Response.class).sparse().build());
-                       case "schemas" -> setSchemas(toMapBuilder(value, 
String.class, SchemaInfo.class).sparse().build());
-                       case "securitySchemes" -> 
setSecuritySchemes(toMapBuilder(value, String.class, 
SecuritySchemeInfo.class).sparse().build());
+                       case PROP_CALLBACKS -> setCallbacks(toMapBuilder(value, 
String.class, Callback.class).sparse().build());
+                       case PROP_EXAMPLES -> setExamples(toMapBuilder(value, 
String.class, Example.class).sparse().build());
+                       case PROP_HEADERS -> setHeaders(toMapBuilder(value, 
String.class, HeaderInfo.class).sparse().build());
+                       case PROP_LINKS -> setLinks(toMapBuilder(value, 
String.class, Link.class).sparse().build());
+                       case PROP_PARAMETERS -> 
setParameters(toMapBuilder(value, String.class, 
Parameter.class).sparse().build());
+                       case PROP_REQUEST_BODIES -> 
setRequestBodies(toMapBuilder(value, String.class, 
RequestBodyInfo.class).sparse().build());
+                       case PROP_RESPONSES -> setResponses(toMapBuilder(value, 
String.class, Response.class).sparse().build());
+                       case PROP_SCHEMAS -> setSchemas(toMapBuilder(value, 
String.class, SchemaInfo.class).sparse().build());
+                       case PROP_SECURITY_SCHEMES -> 
setSecuritySchemes(toMapBuilder(value, String.class, 
SecuritySchemeInfo.class).sparse().build());
                        default -> {
                                super.set(property, value);
                                yield this;
diff --git 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Encoding.java
 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Encoding.java
index b8a848f4be..dd3988e3df 100644
--- 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Encoding.java
+++ 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Encoding.java
@@ -76,6 +76,13 @@ import org.apache.juneau.commons.collections.*;
  */
 public class Encoding extends OpenApiElement {
 
+       // Property name constants
+       private static final String PROP_ALLOW_RESERVED = "allowReserved";
+       private static final String PROP_CONTENT_TYPE = "contentType";
+       private static final String PROP_EXPLODE = "explode";
+       private static final String PROP_HEADERS = "headers";
+       private static final String PROP_STYLE = "style";
+
        private String contentType, style;
        private Map<String,HeaderInfo> headers = map();
        private Boolean explode, allowReserved;
@@ -130,11 +137,11 @@ public class Encoding extends OpenApiElement {
        public <T> T get(String property, Class<T> type) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "contentType" -> toType(getContentType(), type);
-                       case "style" -> toType(getStyle(), type);
-                       case "headers" -> toType(getHeaders(), type);
-                       case "explode" -> toType(getExplode(), type);
-                       case "allowReserved" -> toType(getAllowReserved(), 
type);
+                       case PROP_CONTENT_TYPE -> toType(getContentType(), 
type);
+                       case PROP_STYLE -> toType(getStyle(), type);
+                       case PROP_HEADERS -> toType(getHeaders(), type);
+                       case PROP_EXPLODE -> toType(getExplode(), type);
+                       case PROP_ALLOW_RESERVED -> toType(getAllowReserved(), 
type);
                        default -> super.get(property, type);
                };
        }
@@ -187,11 +194,11 @@ public class Encoding extends OpenApiElement {
        public Set<String> keySet() {
                // @formatter:off
                var s = setb(String.class)
-                       .addIf(nn(allowReserved), "allowReserved")
-                       .addIf(nn(contentType), "contentType")
-                       .addIf(nn(explode), "explode")
-                       .addIf(ne(headers), "headers")
-                       .addIf(nn(style), "style")
+                       .addIf(nn(allowReserved), PROP_ALLOW_RESERVED)
+                       .addIf(nn(contentType), PROP_CONTENT_TYPE)
+                       .addIf(nn(explode), PROP_EXPLODE)
+                       .addIf(ne(headers), PROP_HEADERS)
+                       .addIf(nn(style), PROP_STYLE)
                        .build();
                // @formatter:on
                return new MultiSet<>(s, super.keySet());
@@ -201,11 +208,11 @@ public class Encoding extends OpenApiElement {
        public Encoding set(String property, Object value) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "allowReserved" -> 
setAllowReserved(toBoolean(value));
-                       case "contentType" -> setContentType(s(value));
-                       case "explode" -> setExplode(toBoolean(value));
-                       case "headers" -> setHeaders(toMapBuilder(value, 
String.class, HeaderInfo.class).sparse().build());
-                       case "style" -> setStyle(s(value));
+                       case PROP_ALLOW_RESERVED -> 
setAllowReserved(toBoolean(value));
+                       case PROP_CONTENT_TYPE -> setContentType(s(value));
+                       case PROP_EXPLODE -> setExplode(toBoolean(value));
+                       case PROP_HEADERS -> setHeaders(toMapBuilder(value, 
String.class, HeaderInfo.class).sparse().build());
+                       case PROP_STYLE -> setStyle(s(value));
                        default -> {
                                super.set(property, value);
                                yield this;
diff --git 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/HeaderInfo.java
 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/HeaderInfo.java
index 25fc70d6d3..172084dd77 100644
--- 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/HeaderInfo.java
+++ 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/HeaderInfo.java
@@ -77,6 +77,18 @@ import org.apache.juneau.commons.collections.*;
  */
 public class HeaderInfo extends OpenApiElement {
 
+       // Property name constants
+       private static final String PROP_ALLOW_EMPTY_VALUE = "allowEmptyValue";
+       private static final String PROP_ALLOW_RESERVED = "allowReserved";
+       private static final String PROP_DEPRECATED = "deprecated";
+       private static final String PROP_DESCRIPTION = "description";
+       private static final String PROP_EXAMPLES = "examples";
+       private static final String PROP_EXPLODE = "explode";
+       private static final String PROP_REF = "$ref";
+       private static final String PROP_REQUIRED = "required";
+       private static final String PROP_SCHEMA = "schema";
+       private static final String PROP_X_EXAMPLE = "x-example";
+
        private String description, ref;
        private Boolean required, explode, deprecated, allowEmptyValue, 
allowReserved;
        private SchemaInfo schema;
@@ -136,16 +148,16 @@ public class HeaderInfo extends OpenApiElement {
        public <T> T get(String property, Class<T> type) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "description" -> toType(getDescription(), type);
-                       case "required" -> toType(getRequired(), type);
-                       case "explode" -> toType(getExplode(), type);
-                       case "deprecated" -> toType(getDeprecated(), type);
-                       case "allowEmptyValue" -> toType(getAllowEmptyValue(), 
type);
-                       case "allowReserved" -> toType(getAllowReserved(), 
type);
-                       case "$ref" -> toType(getRef(), type);
-                       case "schema" -> toType(getSchema(), type);
-                       case "x-example" -> toType(getExample(), type);
-                       case "examples" -> toType(getExamples(), type);
+                       case PROP_DESCRIPTION -> toType(getDescription(), type);
+                       case PROP_REQUIRED -> toType(getRequired(), type);
+                       case PROP_EXPLODE -> toType(getExplode(), type);
+                       case PROP_DEPRECATED -> toType(getDeprecated(), type);
+                       case PROP_ALLOW_EMPTY_VALUE -> 
toType(getAllowEmptyValue(), type);
+                       case PROP_ALLOW_RESERVED -> toType(getAllowReserved(), 
type);
+                       case PROP_REF -> toType(getRef(), type);
+                       case PROP_SCHEMA -> toType(getSchema(), type);
+                       case PROP_X_EXAMPLE -> toType(getExample(), type);
+                       case PROP_EXAMPLES -> toType(getExamples(), type);
                        default -> super.get(property, type);
                };
        }
@@ -247,16 +259,16 @@ public class HeaderInfo extends OpenApiElement {
        public Set<String> keySet() {
                // @formatter:off
                var s = setb(String.class)
-                       .addIf(nn(ref), "$ref")
-                       .addIf(nn(allowEmptyValue), "allowEmptyValue")
-                       .addIf(nn(allowReserved), "allowReserved")
-                       .addIf(nn(deprecated), "deprecated")
-                       .addIf(nn(description), "description")
-                       .addIf(ne(examples), "examples")
-                       .addIf(nn(explode), "explode")
-                       .addIf(nn(required), "required")
-                       .addIf(nn(schema), "schema")
-                       .addIf(nn(example), "x-example")
+                       .addIf(nn(ref), PROP_REF)
+                       .addIf(nn(allowEmptyValue), PROP_ALLOW_EMPTY_VALUE)
+                       .addIf(nn(allowReserved), PROP_ALLOW_RESERVED)
+                       .addIf(nn(deprecated), PROP_DEPRECATED)
+                       .addIf(nn(description), PROP_DESCRIPTION)
+                       .addIf(ne(examples), PROP_EXAMPLES)
+                       .addIf(nn(explode), PROP_EXPLODE)
+                       .addIf(nn(required), PROP_REQUIRED)
+                       .addIf(nn(schema), PROP_SCHEMA)
+                       .addIf(nn(example), PROP_X_EXAMPLE)
                        .build();
                // @formatter:on
                return new MultiSet<>(s, super.keySet());
@@ -293,16 +305,16 @@ public class HeaderInfo extends OpenApiElement {
        public HeaderInfo set(String property, Object value) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "$ref" -> setRef(s(value));
-                       case "allowEmptyValue" -> 
setAllowEmptyValue(toBoolean(value));
-                       case "allowReserved" -> 
setAllowReserved(toBoolean(value));
-                       case "deprecated" -> setDeprecated(toBoolean(value));
-                       case "description" -> setDescription(s(value));
-                       case "examples" -> setExamples(toMapBuilder(value, 
String.class, Example.class).sparse().build());
-                       case "explode" -> setExplode(toBoolean(value));
-                       case "required" -> setRequired(toBoolean(value));
-                       case "schema" -> setSchema(toType(value, 
SchemaInfo.class));
-                       case "x-example" -> setExample(value);
+                       case PROP_REF -> setRef(s(value));
+                       case PROP_ALLOW_EMPTY_VALUE -> 
setAllowEmptyValue(toBoolean(value));
+                       case PROP_ALLOW_RESERVED -> 
setAllowReserved(toBoolean(value));
+                       case PROP_DEPRECATED -> setDeprecated(toBoolean(value));
+                       case PROP_DESCRIPTION -> setDescription(s(value));
+                       case PROP_EXAMPLES -> setExamples(toMapBuilder(value, 
String.class, Example.class).sparse().build());
+                       case PROP_EXPLODE -> setExplode(toBoolean(value));
+                       case PROP_REQUIRED -> setRequired(toBoolean(value));
+                       case PROP_SCHEMA -> setSchema(toType(value, 
SchemaInfo.class));
+                       case PROP_X_EXAMPLE -> setExample(value);
                        default -> {
                                super.set(property, value);
                                yield this;
diff --git 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Info.java
 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Info.java
index 957c893e65..1dfc81c2e3 100644
--- 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Info.java
+++ 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Info.java
@@ -100,6 +100,14 @@ import org.apache.juneau.commons.collections.*;
  */
 public class Info extends OpenApiElement {
 
+       // Property name constants
+       private static final String PROP_CONTACT = "contact";
+       private static final String PROP_DESCRIPTION = "description";
+       private static final String PROP_LICENSE = "license";
+       private static final String PROP_TERMS_OF_SERVICE = "termsOfService";
+       private static final String PROP_TITLE = "title";
+       private static final String PROP_VERSION = "version";
+
        private String title, description, termsOfService, version;
        private Contact contact;
        private License license;
@@ -138,12 +146,12 @@ public class Info extends OpenApiElement {
        public <T> T get(String property, Class<T> type) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "title" -> toType(getTitle(), type);
-                       case "description" -> toType(getDescription(), type);
-                       case "termsOfService" -> toType(getTermsOfService(), 
type);
-                       case "contact" -> toType(getContact(), type);
-                       case "license" -> toType(getLicense(), type);
-                       case "version" -> toType(getVersion(), type);
+                       case PROP_TITLE -> toType(getTitle(), type);
+                       case PROP_DESCRIPTION -> toType(getDescription(), type);
+                       case PROP_TERMS_OF_SERVICE -> 
toType(getTermsOfService(), type);
+                       case PROP_CONTACT -> toType(getContact(), type);
+                       case PROP_LICENSE -> toType(getLicense(), type);
+                       case PROP_VERSION -> toType(getVersion(), type);
                        default -> super.get(property, type);
                };
        }
@@ -212,12 +220,12 @@ public class Info extends OpenApiElement {
        public Set<String> keySet() {
                // @formatter:off
                var s = setb(String.class)
-                       .addIf(nn(contact), "contact")
-                       .addIf(nn(description), "description")
-                       .addIf(nn(license), "license")
-                       .addIf(nn(termsOfService), "termsOfService")
-                       .addIf(nn(title), "title")
-                       .addIf(nn(version), "version")
+                       .addIf(nn(contact), PROP_CONTACT)
+                       .addIf(nn(description), PROP_DESCRIPTION)
+                       .addIf(nn(license), PROP_LICENSE)
+                       .addIf(nn(termsOfService), PROP_TERMS_OF_SERVICE)
+                       .addIf(nn(title), PROP_TITLE)
+                       .addIf(nn(version), PROP_VERSION)
                        .build();
                // @formatter:on
                return new MultiSet<>(s, super.keySet());
@@ -227,12 +235,12 @@ public class Info extends OpenApiElement {
        public Info set(String property, Object value) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "contact" -> setContact(toType(value, 
Contact.class));
-                       case "description" -> setDescription(s(value));
-                       case "license" -> setLicense(toType(value, 
License.class));
-                       case "termsOfService" -> setTermsOfService(s(value));
-                       case "title" -> setTitle(s(value));
-                       case "version" -> setVersion(s(value));
+                       case PROP_CONTACT -> setContact(toType(value, 
Contact.class));
+                       case PROP_DESCRIPTION -> setDescription(s(value));
+                       case PROP_LICENSE -> setLicense(toType(value, 
License.class));
+                       case PROP_TERMS_OF_SERVICE -> 
setTermsOfService(s(value));
+                       case PROP_TITLE -> setTitle(s(value));
+                       case PROP_VERSION -> setVersion(s(value));
                        default -> {
                                super.set(property, value);
                                yield this;
diff --git 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Items.java
 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Items.java
index afb226f38e..5bcac70686 100644
--- 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Items.java
+++ 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Items.java
@@ -84,6 +84,26 @@ public class Items extends OpenApiElement {
        private static final String[] VALID_TYPES = { "string", "number", 
"integer", "boolean", "array" };
        private static final String[] VALID_COLLECTION_FORMATS = { "csv", 
"ssv", "tsv", "pipes", "multi" };
 
+       // Property name constants
+       private static final String PROP_COLLECTION_FORMAT = "collectionFormat";
+       private static final String PROP_DEFAULT = "default";
+       private static final String PROP_ENUM = "enum";
+       private static final String PROP_EXCLUSIVE_MAXIMUM = "exclusiveMaximum";
+       private static final String PROP_EXCLUSIVE_MINIMUM = "exclusiveMinimum";
+       private static final String PROP_FORMAT = "format";
+       private static final String PROP_ITEMS = "items";
+       private static final String PROP_MAXIMUM = "maximum";
+       private static final String PROP_MAX_ITEMS = "maxItems";
+       private static final String PROP_MAX_LENGTH = "maxLength";
+       private static final String PROP_MINIMUM = "minimum";
+       private static final String PROP_MIN_ITEMS = "minItems";
+       private static final String PROP_MIN_LENGTH = "minLength";
+       private static final String PROP_MULTIPLE_OF = "multipleOf";
+       private static final String PROP_PATTERN = "pattern";
+       private static final String PROP_REF = "$ref";
+       private static final String PROP_TYPE = "type";
+       private static final String PROP_UNIQUE_ITEMS = "uniqueItems";
+
        private String type, format, collectionFormat, pattern, ref;
        private Number maximum, minimum, multipleOf;
        private Integer maxLength, minLength, maxItems, minItems;
@@ -155,24 +175,24 @@ public class Items extends OpenApiElement {
        public <T> T get(String property, Class<T> type) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "type" -> toType(getType(), type);
-                       case "format" -> toType(getFormat(), type);
-                       case "items" -> toType(getItems(), type);
-                       case "collectionFormat" -> 
toType(getCollectionFormat(), type);
-                       case "default" -> toType(getDefault(), type);
-                       case "maximum" -> toType(getMaximum(), type);
-                       case "exclusiveMaximum" -> 
toType(getExclusiveMaximum(), type);
-                       case "minimum" -> toType(getMinimum(), type);
-                       case "exclusiveMinimum" -> 
toType(getExclusiveMinimum(), type);
-                       case "maxLength" -> toType(getMaxLength(), type);
-                       case "minLength" -> toType(getMinLength(), type);
-                       case "pattern" -> toType(getPattern(), type);
-                       case "maxItems" -> toType(getMaxItems(), type);
-                       case "minItems" -> toType(getMinItems(), type);
-                       case "uniqueItems" -> toType(getUniqueItems(), type);
-                       case "enum" -> toType(getEnum(), type);
-                       case "multipleOf" -> toType(getMultipleOf(), type);
-                       case "$ref" -> toType(getRef(), type);
+                       case PROP_TYPE -> toType(getType(), type);
+                       case PROP_FORMAT -> toType(getFormat(), type);
+                       case PROP_ITEMS -> toType(getItems(), type);
+                       case PROP_COLLECTION_FORMAT -> 
toType(getCollectionFormat(), type);
+                       case PROP_DEFAULT -> toType(getDefault(), type);
+                       case PROP_MAXIMUM -> toType(getMaximum(), type);
+                       case PROP_EXCLUSIVE_MAXIMUM -> 
toType(getExclusiveMaximum(), type);
+                       case PROP_MINIMUM -> toType(getMinimum(), type);
+                       case PROP_EXCLUSIVE_MINIMUM -> 
toType(getExclusiveMinimum(), type);
+                       case PROP_MAX_LENGTH -> toType(getMaxLength(), type);
+                       case PROP_MIN_LENGTH -> toType(getMinLength(), type);
+                       case PROP_PATTERN -> toType(getPattern(), type);
+                       case PROP_MAX_ITEMS -> toType(getMaxItems(), type);
+                       case PROP_MIN_ITEMS -> toType(getMinItems(), type);
+                       case PROP_UNIQUE_ITEMS -> toType(getUniqueItems(), 
type);
+                       case PROP_ENUM -> toType(getEnum(), type);
+                       case PROP_MULTIPLE_OF -> toType(getMultipleOf(), type);
+                       case PROP_REF -> toType(getRef(), type);
                        default -> super.get(property, type);
                };
        }
@@ -331,24 +351,24 @@ public class Items extends OpenApiElement {
        public Set<String> keySet() {
                // @formatter:off
                var s = setb(String.class)
-                       .addIf(nn(ref), "$ref")
-                       .addIf(nn(collectionFormat), "collectionFormat")
-                       .addIf(nn(default_), "default")
-                       .addIf(ne(enum_), "enum")
-                       .addIf(nn(exclusiveMaximum), "exclusiveMaximum")
-                       .addIf(nn(exclusiveMinimum), "exclusiveMinimum")
-                       .addIf(nn(format), "format")
-                       .addIf(nn(items), "items")
-                       .addIf(nn(maxItems), "maxItems")
-                       .addIf(nn(maxLength), "maxLength")
-                       .addIf(nn(maximum), "maximum")
-                       .addIf(nn(minItems), "minItems")
-                       .addIf(nn(minLength), "minLength")
-                       .addIf(nn(minimum), "minimum")
-                       .addIf(nn(multipleOf), "multipleOf")
-                       .addIf(nn(pattern), "pattern")
-                       .addIf(nn(type), "type")
-                       .addIf(nn(uniqueItems), "uniqueItems")
+                       .addIf(nn(ref), PROP_REF)
+                       .addIf(nn(collectionFormat), PROP_COLLECTION_FORMAT)
+                       .addIf(nn(default_), PROP_DEFAULT)
+                       .addIf(ne(enum_), PROP_ENUM)
+                       .addIf(nn(exclusiveMaximum), PROP_EXCLUSIVE_MAXIMUM)
+                       .addIf(nn(exclusiveMinimum), PROP_EXCLUSIVE_MINIMUM)
+                       .addIf(nn(format), PROP_FORMAT)
+                       .addIf(nn(items), PROP_ITEMS)
+                       .addIf(nn(maxItems), PROP_MAX_ITEMS)
+                       .addIf(nn(maxLength), PROP_MAX_LENGTH)
+                       .addIf(nn(maximum), PROP_MAXIMUM)
+                       .addIf(nn(minItems), PROP_MIN_ITEMS)
+                       .addIf(nn(minLength), PROP_MIN_LENGTH)
+                       .addIf(nn(minimum), PROP_MINIMUM)
+                       .addIf(nn(multipleOf), PROP_MULTIPLE_OF)
+                       .addIf(nn(pattern), PROP_PATTERN)
+                       .addIf(nn(type), PROP_TYPE)
+                       .addIf(nn(uniqueItems), PROP_UNIQUE_ITEMS)
                        .build();
                // @formatter:on
                return new MultiSet<>(s, super.keySet());
@@ -393,24 +413,24 @@ public class Items extends OpenApiElement {
        public Items set(String property, Object value) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "$ref" -> setRef(value);
-                       case "collectionFormat" -> 
setCollectionFormat(s(value));
-                       case "default" -> setDefault(value);
-                       case "enum" -> setEnum(value);
-                       case "exclusiveMaximum" -> 
setExclusiveMaximum(toBoolean(value));
-                       case "exclusiveMinimum" -> 
setExclusiveMinimum(toBoolean(value));
-                       case "format" -> setFormat(s(value));
-                       case "items" -> setItems(toType(value, Items.class));
-                       case "maxItems" -> setMaxItems(toInteger(value));
-                       case "maxLength" -> setMaxLength(toInteger(value));
-                       case "maximum" -> setMaximum(toNumber(value));
-                       case "minItems" -> setMinItems(toInteger(value));
-                       case "minLength" -> setMinLength(toInteger(value));
-                       case "minimum" -> setMinimum(toNumber(value));
-                       case "multipleOf" -> setMultipleOf(toNumber(value));
-                       case "pattern" -> setPattern(s(value));
-                       case "type" -> setType(s(value));
-                       case "uniqueItems" -> setUniqueItems(toBoolean(value));
+                       case PROP_REF -> setRef(value);
+                       case PROP_COLLECTION_FORMAT -> 
setCollectionFormat(s(value));
+                       case PROP_DEFAULT -> setDefault(value);
+                       case PROP_ENUM -> setEnum(value);
+                       case PROP_EXCLUSIVE_MAXIMUM -> 
setExclusiveMaximum(toBoolean(value));
+                       case PROP_EXCLUSIVE_MINIMUM -> 
setExclusiveMinimum(toBoolean(value));
+                       case PROP_FORMAT -> setFormat(s(value));
+                       case PROP_ITEMS -> setItems(toType(value, Items.class));
+                       case PROP_MAX_ITEMS -> setMaxItems(toInteger(value));
+                       case PROP_MAX_LENGTH -> setMaxLength(toInteger(value));
+                       case PROP_MAXIMUM -> setMaximum(toNumber(value));
+                       case PROP_MIN_ITEMS -> setMinItems(toInteger(value));
+                       case PROP_MIN_LENGTH -> setMinLength(toInteger(value));
+                       case PROP_MINIMUM -> setMinimum(toNumber(value));
+                       case PROP_MULTIPLE_OF -> setMultipleOf(toNumber(value));
+                       case PROP_PATTERN -> setPattern(s(value));
+                       case PROP_TYPE -> setType(s(value));
+                       case PROP_UNIQUE_ITEMS -> 
setUniqueItems(toBoolean(value));
                        default -> {
                                super.set(property, value);
                                yield this;
diff --git 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Link.java
 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Link.java
index 25e1c2c614..347272d22f 100644
--- 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Link.java
+++ 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Link.java
@@ -64,6 +64,14 @@ import org.apache.juneau.commons.collections.*;
  */
 public class Link extends OpenApiElement {
 
+       // Property name constants
+       private static final String PROP_DESCRIPTION = "description";
+       private static final String PROP_OPERATION_ID = "operationId";
+       private static final String PROP_OPERATION_REF = "operationRef";
+       private static final String PROP_PARAMETERS = "parameters";
+       private static final String PROP_REQUEST_BODY = "requestBody";
+       private static final String PROP_SERVER = "server";
+
        private String operationRef;
        private String operationId;
        private String description;
@@ -120,12 +128,12 @@ public class Link extends OpenApiElement {
        public <T> T get(String property, Class<T> type) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "description" -> toType(getDescription(), type);
-                       case "operationRef" -> toType(getOperationRef(), type);
-                       case "operationId" -> toType(getOperationId(), type);
-                       case "requestBody" -> toType(getRequestBody(), type);
-                       case "parameters" -> toType(getParameters(), type);
-                       case "server" -> toType(getServer(), type);
+                       case PROP_DESCRIPTION -> toType(getDescription(), type);
+                       case PROP_OPERATION_REF -> toType(getOperationRef(), 
type);
+                       case PROP_OPERATION_ID -> toType(getOperationId(), 
type);
+                       case PROP_REQUEST_BODY -> toType(getRequestBody(), 
type);
+                       case PROP_PARAMETERS -> toType(getParameters(), type);
+                       case PROP_SERVER -> toType(getServer(), type);
                        default -> super.get(property, type);
                };
        }
@@ -195,12 +203,12 @@ public class Link extends OpenApiElement {
        public Set<String> keySet() {
                // @formatter:off
                var s = setb(String.class)
-                       .addIf(nn(description), "description")
-                       .addIf(nn(operationId), "operationId")
-                       .addIf(nn(operationRef), "operationRef")
-                       .addIf(ne(parameters), "parameters")
-                       .addIf(nn(requestBody), "requestBody")
-                       .addIf(nn(server), "server")
+                       .addIf(nn(description), PROP_DESCRIPTION)
+                       .addIf(nn(operationId), PROP_OPERATION_ID)
+                       .addIf(nn(operationRef), PROP_OPERATION_REF)
+                       .addIf(ne(parameters), PROP_PARAMETERS)
+                       .addIf(nn(requestBody), PROP_REQUEST_BODY)
+                       .addIf(nn(server), PROP_SERVER)
                        .build();
                // @formatter:on
                return new MultiSet<>(s, super.keySet());
@@ -210,12 +218,12 @@ public class Link extends OpenApiElement {
        public Link set(String property, Object value) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "description" -> setDescription(s(value));
-                       case "operationId" -> setOperationId(s(value));
-                       case "operationRef" -> setOperationRef(s(value));
-                       case "parameters" -> setParameters(toMapBuilder(value, 
String.class, Object.class).sparse().build());
-                       case "requestBody" -> setRequestBody(value);
-                       case "server" -> setServer(toType(value, Server.class));
+                       case PROP_DESCRIPTION -> setDescription(s(value));
+                       case PROP_OPERATION_ID -> setOperationId(s(value));
+                       case PROP_OPERATION_REF -> setOperationRef(s(value));
+                       case PROP_PARAMETERS -> 
setParameters(toMapBuilder(value, String.class, Object.class).sparse().build());
+                       case PROP_REQUEST_BODY -> setRequestBody(value);
+                       case PROP_SERVER -> setServer(toType(value, 
Server.class));
                        default -> {
                                super.set(property, value);
                                yield this;
diff --git 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/OpenApi.java
 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/OpenApi.java
index a3efa151f3..8644da498c 100644
--- 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/OpenApi.java
+++ 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/OpenApi.java
@@ -82,6 +82,16 @@ public class OpenApi extends OpenApiElement {
 
        private static final Comparator<String> PATH_COMPARATOR = (o1, o2) -> 
o1.replace('{', '@').compareTo(o2.replace('{', '@'));
 
+       // Property name constants
+       private static final String PROP_COMPONENTS = "components";
+       private static final String PROP_EXTERNAL_DOCS = "externalDocs";
+       private static final String PROP_INFO = "info";
+       private static final String PROP_OPENAPI = "openapi";
+       private static final String PROP_PATHS = "paths";
+       private static final String PROP_SECURITY = "security";
+       private static final String PROP_SERVERS = "servers";
+       private static final String PROP_TAGS = "tags";
+
        private String openapi = "3.0.0";
        private Info info;
        private List<Server> servers = list();
@@ -268,14 +278,14 @@ public class OpenApi extends OpenApiElement {
        public <T> T get(String property, Class<T> type) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "openapi" -> toType(getOpenapi(), type);
-                       case "info" -> toType(getInfo(), type);
-                       case "servers" -> toType(getServers(), type);
-                       case "paths" -> toType(getPaths(), type);
-                       case "components" -> toType(getComponents(), type);
-                       case "security" -> toType(getSecurity(), type);
-                       case "tags" -> toType(getTags(), type);
-                       case "externalDocs" -> toType(getExternalDocs(), type);
+                       case PROP_OPENAPI -> toType(getOpenapi(), type);
+                       case PROP_INFO -> toType(getInfo(), type);
+                       case PROP_SERVERS -> toType(getServers(), type);
+                       case PROP_PATHS -> toType(getPaths(), type);
+                       case PROP_COMPONENTS -> toType(getComponents(), type);
+                       case PROP_SECURITY -> toType(getSecurity(), type);
+                       case PROP_TAGS -> toType(getTags(), type);
+                       case PROP_EXTERNAL_DOCS -> toType(getExternalDocs(), 
type);
                        default -> super.get(property, type);
                };
        }
@@ -340,14 +350,14 @@ public class OpenApi extends OpenApiElement {
        public Set<String> keySet() {
                // @formatter:off
                var s = setb(String.class)
-                       .addIf(nn(components), "components")
-                       .addIf(nn(externalDocs), "externalDocs")
-                       .addIf(nn(info), "info")
-                       .addIf(nn(openapi), "openapi")
-                       .addIf(nn(paths), "paths")
-                       .addIf(ne(security), "security")
-                       .addIf(ne(servers), "servers")
-                       .addIf(ne(tags), "tags")
+                       .addIf(nn(components), PROP_COMPONENTS)
+                       .addIf(nn(externalDocs), PROP_EXTERNAL_DOCS)
+                       .addIf(nn(info), PROP_INFO)
+                       .addIf(nn(openapi), PROP_OPENAPI)
+                       .addIf(nn(paths), PROP_PATHS)
+                       .addIf(ne(security), PROP_SECURITY)
+                       .addIf(ne(servers), PROP_SERVERS)
+                       .addIf(ne(tags), PROP_TAGS)
                        .build();
                // @formatter:on
                return new MultiSet<>(s, super.keySet());
@@ -357,14 +367,14 @@ public class OpenApi extends OpenApiElement {
        public OpenApi set(String property, Object value) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "components" -> setComponents(toType(value, 
Components.class));
-                       case "externalDocs" -> setExternalDocs(toType(value, 
ExternalDocumentation.class));
-                       case "info" -> setInfo(toType(value, Info.class));
-                       case "openapi" -> setOpenapi(s(value));
-                       case "paths" -> setPaths(toMapBuilder(value, 
String.class, PathItem.class).sparse().build());
-                       case "security" -> 
setSecurity(listb(SecurityRequirement.class).addAny(value).sparse().build());
-                       case "servers" -> 
setServers(listb(Server.class).addAny(value).sparse().build());
-                       case "tags" -> 
setTags(listb(Tag.class).addAny(value).sparse().build());
+                       case PROP_COMPONENTS -> setComponents(toType(value, 
Components.class));
+                       case PROP_EXTERNAL_DOCS -> 
setExternalDocs(toType(value, ExternalDocumentation.class));
+                       case PROP_INFO -> setInfo(toType(value, Info.class));
+                       case PROP_OPENAPI -> setOpenapi(s(value));
+                       case PROP_PATHS -> setPaths(toMapBuilder(value, 
String.class, PathItem.class).sparse().build());
+                       case PROP_SECURITY -> 
setSecurity(listb(SecurityRequirement.class).addAny(value).sparse().build());
+                       case PROP_SERVERS -> 
setServers(listb(Server.class).addAny(value).sparse().build());
+                       case PROP_TAGS -> 
setTags(listb(Tag.class).addAny(value).sparse().build());
                        default -> {
                                super.set(property, value);
                                yield this;
diff --git 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Operation.java
 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Operation.java
index 65336a5f68..b2a607e8da 100644
--- 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Operation.java
+++ 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Operation.java
@@ -91,6 +91,20 @@ import org.apache.juneau.commons.collections.*;
  */
 public class Operation extends OpenApiElement {
 
+       // Property name constants
+       private static final String PROP_CALLBACKS = "callbacks";
+       private static final String PROP_DEPRECATED = "deprecated";
+       private static final String PROP_DESCRIPTION = "description";
+       private static final String PROP_EXTERNAL_DOCS = "externalDocs";
+       private static final String PROP_OPERATION_ID = "operationId";
+       private static final String PROP_PARAMETERS = "parameters";
+       private static final String PROP_REQUEST_BODY = "requestBody";
+       private static final String PROP_RESPONSES = "responses";
+       private static final String PROP_SECURITY = "security";
+       private static final String PROP_SERVERS = "servers";
+       private static final String PROP_SUMMARY = "summary";
+       private static final String PROP_TAGS = "tags";
+
        private List<String> tags = list();
        private String summary, description, operationId;
        private ExternalDocumentation externalDocs;
@@ -333,18 +347,18 @@ public class Operation extends OpenApiElement {
        public <T> T get(String property, Class<T> type) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "tags" -> toType(getTags(), type);
-                       case "summary" -> toType(getSummary(), type);
-                       case "description" -> toType(getDescription(), type);
-                       case "operationId" -> toType(getOperationId(), type);
-                       case "externalDocs" -> toType(getExternalDocs(), type);
-                       case "parameters" -> toType(getParameters(), type);
-                       case "requestBody" -> toType(getRequestBody(), type);
-                       case "responses" -> toType(getResponses(), type);
-                       case "callbacks" -> toType(getCallbacks(), type);
-                       case "deprecated" -> toType(getDeprecated(), type);
-                       case "security" -> toType(getSecurity(), type);
-                       case "servers" -> toType(getServers(), type);
+                       case PROP_TAGS -> toType(getTags(), type);
+                       case PROP_SUMMARY -> toType(getSummary(), type);
+                       case PROP_DESCRIPTION -> toType(getDescription(), type);
+                       case PROP_OPERATION_ID -> toType(getOperationId(), 
type);
+                       case PROP_EXTERNAL_DOCS -> toType(getExternalDocs(), 
type);
+                       case PROP_PARAMETERS -> toType(getParameters(), type);
+                       case PROP_REQUEST_BODY -> toType(getRequestBody(), 
type);
+                       case PROP_RESPONSES -> toType(getResponses(), type);
+                       case PROP_CALLBACKS -> toType(getCallbacks(), type);
+                       case PROP_DEPRECATED -> toType(getDeprecated(), type);
+                       case PROP_SECURITY -> toType(getSecurity(), type);
+                       case PROP_SERVERS -> toType(getServers(), type);
                        default -> super.get(property, type);
                };
        }
@@ -474,18 +488,18 @@ public class Operation extends OpenApiElement {
        public Set<String> keySet() {
                // @formatter:off
                var s = setb(String.class)
-                       .addIf(ne(callbacks), "callbacks")
-                       .addIf(nn(deprecated), "deprecated")
-                       .addIf(nn(description), "description")
-                       .addIf(nn(externalDocs), "externalDocs")
-                       .addIf(nn(operationId), "operationId")
-                       .addIf(ne(parameters), "parameters")
-                       .addIf(nn(requestBody), "requestBody")
-                       .addIf(ne(responses), "responses")
-                       .addIf(ne(security), "security")
-                       .addIf(ne(servers), "servers")
-                       .addIf(nn(summary), "summary")
-                       .addIf(ne(tags), "tags")
+                       .addIf(ne(callbacks), PROP_CALLBACKS)
+                       .addIf(nn(deprecated), PROP_DEPRECATED)
+                       .addIf(nn(description), PROP_DESCRIPTION)
+                       .addIf(nn(externalDocs), PROP_EXTERNAL_DOCS)
+                       .addIf(nn(operationId), PROP_OPERATION_ID)
+                       .addIf(ne(parameters), PROP_PARAMETERS)
+                       .addIf(nn(requestBody), PROP_REQUEST_BODY)
+                       .addIf(ne(responses), PROP_RESPONSES)
+                       .addIf(ne(security), PROP_SECURITY)
+                       .addIf(ne(servers), PROP_SERVERS)
+                       .addIf(nn(summary), PROP_SUMMARY)
+                       .addIf(ne(tags), PROP_TAGS)
                        .build();
                // @formatter:on
                return new MultiSet<>(s, super.keySet());
@@ -495,18 +509,18 @@ public class Operation extends OpenApiElement {
        public Operation set(String property, Object value) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "callbacks" -> setCallbacks(toMapBuilder(value, 
String.class, Callback.class).sparse().build());
-                       case "deprecated" -> setDeprecated(toType(value, 
Boolean.class));
-                       case "description" -> setDescription(s(value));
-                       case "externalDocs" -> setExternalDocs(toType(value, 
ExternalDocumentation.class));
-                       case "operationId" -> setOperationId(s(value));
-                       case "parameters" -> setParameters(toListBuilder(value, 
Parameter.class).sparse().build());
-                       case "requestBody" -> setRequestBody(toType(value, 
RequestBodyInfo.class));
-                       case "responses" -> setResponses(toMapBuilder(value, 
String.class, Response.class).sparse().build());
-                       case "security" -> setSecurity(toListBuilder(value, 
SecurityRequirement.class).sparse().build());
-                       case "servers" -> setServers(toListBuilder(value, 
Server.class).sparse().build());
-                       case "summary" -> setSummary(s(value));
-                       case "tags" -> setTags(toListBuilder(value, 
String.class).sparse().build());
+                       case PROP_CALLBACKS -> setCallbacks(toMapBuilder(value, 
String.class, Callback.class).sparse().build());
+                       case PROP_DEPRECATED -> setDeprecated(toType(value, 
Boolean.class));
+                       case PROP_DESCRIPTION -> setDescription(s(value));
+                       case PROP_EXTERNAL_DOCS -> 
setExternalDocs(toType(value, ExternalDocumentation.class));
+                       case PROP_OPERATION_ID -> setOperationId(s(value));
+                       case PROP_PARAMETERS -> 
setParameters(toListBuilder(value, Parameter.class).sparse().build());
+                       case PROP_REQUEST_BODY -> setRequestBody(toType(value, 
RequestBodyInfo.class));
+                       case PROP_RESPONSES -> setResponses(toMapBuilder(value, 
String.class, Response.class).sparse().build());
+                       case PROP_SECURITY -> setSecurity(toListBuilder(value, 
SecurityRequirement.class).sparse().build());
+                       case PROP_SERVERS -> setServers(toListBuilder(value, 
Server.class).sparse().build());
+                       case PROP_SUMMARY -> setSummary(s(value));
+                       case PROP_TAGS -> setTags(toListBuilder(value, 
String.class).sparse().build());
                        default -> {
                                super.set(property, value);
                                yield this;
diff --git 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Parameter.java
 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Parameter.java
index f932b39284..99c0ccf2db 100644
--- 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Parameter.java
+++ 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/Parameter.java
@@ -83,6 +83,20 @@ public class Parameter extends OpenApiElement {
        private static final String[] VALID_IN = { "query", "header", "path", 
"cookie" };
        private static final String[] VALID_STYLES = { "matrix", "label", 
"form", "simple", "spaceDelimited", "pipeDelimited", "deepObject" };
 
+       // Property name constants
+       private static final String PROP_ALLOW_EMPTY_VALUE = "allowEmptyValue";
+       private static final String PROP_ALLOW_RESERVED = "allowReserved";
+       private static final String PROP_DEPRECATED = "deprecated";
+       private static final String PROP_DESCRIPTION = "description";
+       private static final String PROP_EXAMPLE = "example";
+       private static final String PROP_EXAMPLES = "examples";
+       private static final String PROP_EXPLODE = "explode";
+       private static final String PROP_IN = "in";
+       private static final String PROP_NAME = "name";
+       private static final String PROP_REQUIRED = "required";
+       private static final String PROP_SCHEMA = "schema";
+       private static final String PROP_STYLE = "style";
+
        private String name, in, description, style;
        private Boolean required, deprecated, allowEmptyValue, explode, 
allowReserved;
        private SchemaInfo schema;
@@ -128,18 +142,18 @@ public class Parameter extends OpenApiElement {
        public <T> T get(String property, Class<T> type) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "name" -> toType(getName(), type);
-                       case "in" -> toType(getIn(), type);
-                       case "description" -> toType(getDescription(), type);
-                       case "required" -> toType(getRequired(), type);
-                       case "deprecated" -> toType(getDeprecated(), type);
-                       case "allowEmptyValue" -> toType(getAllowEmptyValue(), 
type);
-                       case "style" -> toType(getStyle(), type);
-                       case "explode" -> toType(getExplode(), type);
-                       case "allowReserved" -> toType(getAllowReserved(), 
type);
-                       case "schema" -> toType(getSchema(), type);
-                       case "example" -> toType(getExample(), type);
-                       case "examples" -> toType(getExamples(), type);
+                       case PROP_NAME -> toType(getName(), type);
+                       case PROP_IN -> toType(getIn(), type);
+                       case PROP_DESCRIPTION -> toType(getDescription(), type);
+                       case PROP_REQUIRED -> toType(getRequired(), type);
+                       case PROP_DEPRECATED -> toType(getDeprecated(), type);
+                       case PROP_ALLOW_EMPTY_VALUE -> 
toType(getAllowEmptyValue(), type);
+                       case PROP_STYLE -> toType(getStyle(), type);
+                       case PROP_EXPLODE -> toType(getExplode(), type);
+                       case PROP_ALLOW_RESERVED -> toType(getAllowReserved(), 
type);
+                       case PROP_SCHEMA -> toType(getSchema(), type);
+                       case PROP_EXAMPLE -> toType(getExample(), type);
+                       case PROP_EXAMPLES -> toType(getExamples(), type);
                        default -> super.get(property, type);
                };
        }
@@ -232,18 +246,18 @@ public class Parameter extends OpenApiElement {
        public Set<String> keySet() {
                // @formatter:off
                var s = setb(String.class)
-                       .addIf(nn(allowEmptyValue), "allowEmptyValue")
-                       .addIf(nn(allowReserved), "allowReserved")
-                       .addIf(nn(deprecated), "deprecated")
-                       .addIf(nn(description), "description")
-                       .addIf(nn(example), "example")
-                       .addIf(nn(examples), "examples")
-                       .addIf(nn(explode), "explode")
-                       .addIf(nn(in), "in")
-                       .addIf(nn(name), "name")
-                       .addIf(nn(required), "required")
-                       .addIf(nn(schema), "schema")
-                       .addIf(nn(style), "style")
+                       .addIf(nn(allowEmptyValue), PROP_ALLOW_EMPTY_VALUE)
+                       .addIf(nn(allowReserved), PROP_ALLOW_RESERVED)
+                       .addIf(nn(deprecated), PROP_DEPRECATED)
+                       .addIf(nn(description), PROP_DESCRIPTION)
+                       .addIf(nn(example), PROP_EXAMPLE)
+                       .addIf(nn(examples), PROP_EXAMPLES)
+                       .addIf(nn(explode), PROP_EXPLODE)
+                       .addIf(nn(in), PROP_IN)
+                       .addIf(nn(name), PROP_NAME)
+                       .addIf(nn(required), PROP_REQUIRED)
+                       .addIf(nn(schema), PROP_SCHEMA)
+                       .addIf(nn(style), PROP_STYLE)
                        .build();
                // @formatter:on
                return new MultiSet<>(s, super.keySet());
@@ -253,18 +267,18 @@ public class Parameter extends OpenApiElement {
        public Parameter set(String property, Object value) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "allowEmptyValue" -> 
setAllowEmptyValue(toType(value, Boolean.class));
-                       case "allowReserved" -> setAllowReserved(toType(value, 
Boolean.class));
-                       case "description" -> setDescription(s(value));
-                       case "deprecated" -> setDeprecated(toType(value, 
Boolean.class));
-                       case "example" -> setExample(value);
-                       case "examples" -> setExamples(toMapBuilder(value, 
String.class, Example.class).sparse().build());
-                       case "explode" -> setExplode(toType(value, 
Boolean.class));
-                       case "in" -> setIn(s(value));
-                       case "name" -> setName(s(value));
-                       case "required" -> setRequired(toType(value, 
Boolean.class));
-                       case "schema" -> setSchema(toType(value, 
SchemaInfo.class));
-                       case "style" -> setStyle(s(value));
+                       case PROP_ALLOW_EMPTY_VALUE -> 
setAllowEmptyValue(toType(value, Boolean.class));
+                       case PROP_ALLOW_RESERVED -> 
setAllowReserved(toType(value, Boolean.class));
+                       case PROP_DESCRIPTION -> setDescription(s(value));
+                       case PROP_DEPRECATED -> setDeprecated(toType(value, 
Boolean.class));
+                       case PROP_EXAMPLE -> setExample(value);
+                       case PROP_EXAMPLES -> setExamples(toMapBuilder(value, 
String.class, Example.class).sparse().build());
+                       case PROP_EXPLODE -> setExplode(toType(value, 
Boolean.class));
+                       case PROP_IN -> setIn(s(value));
+                       case PROP_NAME -> setName(s(value));
+                       case PROP_REQUIRED -> setRequired(toType(value, 
Boolean.class));
+                       case PROP_SCHEMA -> setSchema(toType(value, 
SchemaInfo.class));
+                       case PROP_STYLE -> setStyle(s(value));
                        default -> {
                                super.set(property, value);
                                yield this;
diff --git 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/PathItem.java
 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/PathItem.java
index c6f97e0465..b408c5fa25 100644
--- 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/PathItem.java
+++ 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/PathItem.java
@@ -82,6 +82,20 @@ import org.apache.juneau.commons.collections.*;
  */
 public class PathItem extends OpenApiElement {
 
+       // Property name constants
+       private static final String PROP_DELETE = "delete";
+       private static final String PROP_DESCRIPTION = "description";
+       private static final String PROP_GET = "get";
+       private static final String PROP_HEAD = "head";
+       private static final String PROP_OPTIONS = "options";
+       private static final String PROP_PARAMETERS = "parameters";
+       private static final String PROP_PATCH = "patch";
+       private static final String PROP_POST = "post";
+       private static final String PROP_PUT = "put";
+       private static final String PROP_SERVERS = "servers";
+       private static final String PROP_SUMMARY = "summary";
+       private static final String PROP_TRACE = "trace";
+
        private String summary, description;
        private Operation get, put, post, delete, options, head, patch, trace;
        private List<Server> servers;
@@ -126,18 +140,18 @@ public class PathItem extends OpenApiElement {
        public <T> T get(String property, Class<T> type) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "summary" -> toType(getSummary(), type);
-                       case "description" -> toType(getDescription(), type);
-                       case "get" -> toType(getGet(), type);
-                       case "put" -> toType(getPut(), type);
-                       case "post" -> toType(getPost(), type);
-                       case "delete" -> toType(getDelete(), type);
-                       case "options" -> toType(getOptions(), type);
-                       case "head" -> toType(getHead(), type);
-                       case "patch" -> toType(getPatch(), type);
-                       case "trace" -> toType(getTrace(), type);
-                       case "servers" -> toType(getServers(), type);
-                       case "parameters" -> toType(getParameters(), type);
+                       case PROP_SUMMARY -> toType(getSummary(), type);
+                       case PROP_DESCRIPTION -> toType(getDescription(), type);
+                       case PROP_GET -> toType(getGet(), type);
+                       case PROP_PUT -> toType(getPut(), type);
+                       case PROP_POST -> toType(getPost(), type);
+                       case PROP_DELETE -> toType(getDelete(), type);
+                       case PROP_OPTIONS -> toType(getOptions(), type);
+                       case PROP_HEAD -> toType(getHead(), type);
+                       case PROP_PATCH -> toType(getPatch(), type);
+                       case PROP_TRACE -> toType(getTrace(), type);
+                       case PROP_SERVERS -> toType(getServers(), type);
+                       case PROP_PARAMETERS -> toType(getParameters(), type);
                        default -> super.get(property, type);
                };
        }
@@ -230,18 +244,18 @@ public class PathItem extends OpenApiElement {
        public Set<String> keySet() {
                // @formatter:off
                var s = setb(String.class)
-                       .addIf(nn(delete), "delete")
-                       .addIf(nn(description), "description")
-                       .addIf(nn(get), "get")
-                       .addIf(nn(head), "head")
-                       .addIf(nn(options), "options")
-                       .addIf(nn(parameters), "parameters")
-                       .addIf(nn(patch), "patch")
-                       .addIf(nn(post), "post")
-                       .addIf(nn(put), "put")
-                       .addIf(nn(servers), "servers")
-                       .addIf(nn(summary), "summary")
-                       .addIf(nn(trace), "trace")
+                       .addIf(nn(delete), PROP_DELETE)
+                       .addIf(nn(description), PROP_DESCRIPTION)
+                       .addIf(nn(get), PROP_GET)
+                       .addIf(nn(head), PROP_HEAD)
+                       .addIf(nn(options), PROP_OPTIONS)
+                       .addIf(nn(parameters), PROP_PARAMETERS)
+                       .addIf(nn(patch), PROP_PATCH)
+                       .addIf(nn(post), PROP_POST)
+                       .addIf(nn(put), PROP_PUT)
+                       .addIf(nn(servers), PROP_SERVERS)
+                       .addIf(nn(summary), PROP_SUMMARY)
+                       .addIf(nn(trace), PROP_TRACE)
                        .build();
                // @formatter:on
                return new MultiSet<>(s, super.keySet());
@@ -251,18 +265,18 @@ public class PathItem extends OpenApiElement {
        public PathItem set(String property, Object value) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "delete" -> setDelete(toType(value, 
Operation.class));
-                       case "description" -> setDescription(s(value));
-                       case "get" -> setGet(toType(value, Operation.class));
-                       case "head" -> setHead(toType(value, Operation.class));
-                       case "options" -> setOptions(toType(value, 
Operation.class));
-                       case "patch" -> setPatch(toType(value, 
Operation.class));
-                       case "parameters" -> 
setParameters(listb(Parameter.class).addAny(value).sparse().build());
-                       case "post" -> setPost(toType(value, Operation.class));
-                       case "put" -> setPut(toType(value, Operation.class));
-                       case "servers" -> 
setServers(listb(Server.class).addAny(value).sparse().build());
-                       case "summary" -> setSummary(s(value));
-                       case "trace" -> setTrace(toType(value, 
Operation.class));
+                       case PROP_DELETE -> setDelete(toType(value, 
Operation.class));
+                       case PROP_DESCRIPTION -> setDescription(s(value));
+                       case PROP_GET -> setGet(toType(value, Operation.class));
+                       case PROP_HEAD -> setHead(toType(value, 
Operation.class));
+                       case PROP_OPTIONS -> setOptions(toType(value, 
Operation.class));
+                       case PROP_PATCH -> setPatch(toType(value, 
Operation.class));
+                       case PROP_PARAMETERS -> 
setParameters(listb(Parameter.class).addAny(value).sparse().build());
+                       case PROP_POST -> setPost(toType(value, 
Operation.class));
+                       case PROP_PUT -> setPut(toType(value, Operation.class));
+                       case PROP_SERVERS -> 
setServers(listb(Server.class).addAny(value).sparse().build());
+                       case PROP_SUMMARY -> setSummary(s(value));
+                       case PROP_TRACE -> setTrace(toType(value, 
Operation.class));
                        default -> {
                                super.set(property, value);
                                yield this;
diff --git 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/RequestBodyInfo.java
 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/RequestBodyInfo.java
index c1c908b25c..af795da448 100644
--- 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/RequestBodyInfo.java
+++ 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/RequestBodyInfo.java
@@ -67,6 +67,11 @@ import org.apache.juneau.commons.collections.*;
  */
 public class RequestBodyInfo extends OpenApiElement {
 
+       // Property name constants
+       private static final String PROP_CONTENT = "content";
+       private static final String PROP_DESCRIPTION = "description";
+       private static final String PROP_REQUIRED = "required";
+
        private String description;
        private Map<String,MediaType> content = map();
        private Boolean required;
@@ -120,9 +125,9 @@ public class RequestBodyInfo extends OpenApiElement {
        public <T> T get(String property, Class<T> type) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "description" -> toType(getDescription(), type);
-                       case "content" -> toType(getContent(), type);
-                       case "required" -> toType(getRequired(), type);
+                       case PROP_DESCRIPTION -> toType(getDescription(), type);
+                       case PROP_CONTENT -> toType(getContent(), type);
+                       case PROP_REQUIRED -> toType(getRequired(), type);
                        default -> super.get(property, type);
                };
        }
@@ -158,9 +163,9 @@ public class RequestBodyInfo extends OpenApiElement {
        public Set<String> keySet() {
                // @formatter:off
                var s = setb(String.class)
-                       .addIf(ne(content), "content")
-                       .addIf(nn(description), "description")
-                       .addIf(nn(required), "required")
+                       .addIf(ne(content), PROP_CONTENT)
+                       .addIf(nn(description), PROP_DESCRIPTION)
+                       .addIf(nn(required), PROP_REQUIRED)
                        .build();
                // @formatter:on
                return new MultiSet<>(s, super.keySet());
@@ -170,9 +175,9 @@ public class RequestBodyInfo extends OpenApiElement {
        public RequestBodyInfo set(String property, Object value) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "content" -> setContent(toMapBuilder(value, 
String.class, MediaType.class).sparse().build());
-                       case "description" -> setDescription(s(value));
-                       case "required" -> setRequired(toBoolean(value));
+                       case PROP_CONTENT -> setContent(toMapBuilder(value, 
String.class, MediaType.class).sparse().build());
+                       case PROP_DESCRIPTION -> setDescription(s(value));
+                       case PROP_REQUIRED -> setRequired(toBoolean(value));
                        default -> {
                                super.set(property, value);
                                yield this;
diff --git 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/SecuritySchemeInfo.java
 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/SecuritySchemeInfo.java
index b0f0016ad2..e9e9bd857c 100644
--- 
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/SecuritySchemeInfo.java
+++ 
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/SecuritySchemeInfo.java
@@ -90,6 +90,16 @@ public class SecuritySchemeInfo extends OpenApiElement {
        private static final String[] VALID_IN = { "query", "header", "cookie" 
};
        private static final String[] VALID_TYPES = { "apiKey", "http", 
"oauth2", "openIdConnect" };
 
+       // Property name constants
+       private static final String PROP_BEARER_FORMAT = "bearerFormat";
+       private static final String PROP_DESCRIPTION = "description";
+       private static final String PROP_FLOWS = "flows";
+       private static final String PROP_IN = "in";
+       private static final String PROP_NAME = "name";
+       private static final String PROP_OPEN_ID_CONNECT_URL = 
"openIdConnectUrl";
+       private static final String PROP_SCHEME = "scheme";
+       private static final String PROP_TYPE = "type";
+
        private String type, description, name, in, scheme, bearerFormat, 
openIdConnectUrl;
 
        private OAuthFlow flows;
@@ -130,14 +140,14 @@ public class SecuritySchemeInfo extends OpenApiElement {
        public <T> T get(String property, Class<T> type) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "name" -> toType(getName(), type);
-                       case "in" -> toType(getIn(), type);
-                       case "description" -> toType(getDescription(), type);
-                       case "scheme" -> toType(getScheme(), type);
-                       case "flows" -> toType(getFlows(), type);
-                       case "bearerFormat" -> toType(getBearerFormat(), type);
-                       case "openIdConnectUrl" -> 
toType(getOpenIdConnectUrl(), type);
-                       case "type" -> toType(getType(), type);
+                       case PROP_NAME -> toType(getName(), type);
+                       case PROP_IN -> toType(getIn(), type);
+                       case PROP_DESCRIPTION -> toType(getDescription(), type);
+                       case PROP_SCHEME -> toType(getScheme(), type);
+                       case PROP_FLOWS -> toType(getFlows(), type);
+                       case PROP_BEARER_FORMAT -> toType(getBearerFormat(), 
type);
+                       case PROP_OPEN_ID_CONNECT_URL -> 
toType(getOpenIdConnectUrl(), type);
+                       case PROP_TYPE -> toType(getType(), type);
                        default -> super.get(property, type);
                };
        }
@@ -238,14 +248,14 @@ public class SecuritySchemeInfo extends OpenApiElement {
        public Set<String> keySet() {
                // @formatter:off
                var s = setb(String.class)
-                       .addIf(nn(bearerFormat), "bearerFormat")
-                       .addIf(nn(description), "description")
-                       .addIf(nn(flows), "flows")
-                       .addIf(nn(in), "in")
-                       .addIf(nn(name), "name")
-                       .addIf(nn(openIdConnectUrl), "openIdConnectUrl")
-                       .addIf(nn(scheme), "scheme")
-                       .addIf(nn(type), "type")
+                       .addIf(nn(bearerFormat), PROP_BEARER_FORMAT)
+                       .addIf(nn(description), PROP_DESCRIPTION)
+                       .addIf(nn(flows), PROP_FLOWS)
+                       .addIf(nn(in), PROP_IN)
+                       .addIf(nn(name), PROP_NAME)
+                       .addIf(nn(openIdConnectUrl), PROP_OPEN_ID_CONNECT_URL)
+                       .addIf(nn(scheme), PROP_SCHEME)
+                       .addIf(nn(type), PROP_TYPE)
                        .build();
                // @formatter:on
                return new MultiSet<>(s, super.keySet());
@@ -255,14 +265,14 @@ public class SecuritySchemeInfo extends OpenApiElement {
        public SecuritySchemeInfo set(String property, Object value) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "bearerFormat" -> setBearerFormat(s(value));
-                       case "description" -> setDescription(s(value));
-                       case "flows" -> setFlows(toType(value, 
OAuthFlow.class));
-                       case "in" -> setIn(s(value));
-                       case "name" -> setName(s(value));
-                       case "openIdConnectUrl" -> 
setOpenIdConnectUrl(s(value));
-                       case "scheme" -> setScheme(s(value));
-                       case "type" -> setType(s(value));
+                       case PROP_BEARER_FORMAT -> setBearerFormat(s(value));
+                       case PROP_DESCRIPTION -> setDescription(s(value));
+                       case PROP_FLOWS -> setFlows(toType(value, 
OAuthFlow.class));
+                       case PROP_IN -> setIn(s(value));
+                       case PROP_NAME -> setName(s(value));
+                       case PROP_OPEN_ID_CONNECT_URL -> 
setOpenIdConnectUrl(s(value));
+                       case PROP_SCHEME -> setScheme(s(value));
+                       case PROP_TYPE -> setType(s(value));
                        default -> {
                                super.set(property, value);
                                yield this;
diff --git 
a/juneau-bean/juneau-bean-swagger-v2/src/main/java/org/apache/juneau/bean/swagger/Operation.java
 
b/juneau-bean/juneau-bean-swagger-v2/src/main/java/org/apache/juneau/bean/swagger/Operation.java
index 0e6f772871..5a835916e8 100644
--- 
a/juneau-bean/juneau-bean-swagger-v2/src/main/java/org/apache/juneau/bean/swagger/Operation.java
+++ 
b/juneau-bean/juneau-bean-swagger-v2/src/main/java/org/apache/juneau/bean/swagger/Operation.java
@@ -160,6 +160,20 @@ public class Operation extends SwaggerElement {
 
        private interface MapStringList extends Map<String,List<String>> {}
 
+       // Property name constants
+       private static final String PROP_CONSUMES = "consumes";
+       private static final String PROP_DEPRECATED = "deprecated";
+       private static final String PROP_DESCRIPTION = "description";
+       private static final String PROP_EXTERNAL_DOCS = "externalDocs";
+       private static final String PROP_OPERATION_ID = "operationId";
+       private static final String PROP_PARAMETERS = "parameters";
+       private static final String PROP_PRODUCES = "produces";
+       private static final String PROP_RESPONSES = "responses";
+       private static final String PROP_SCHEMES = "schemes";
+       private static final String PROP_SECURITY = "security";
+       private static final String PROP_SUMMARY = "summary";
+       private static final String PROP_TAGS = "tags";
+
        private String summary, description, operationId;
        private Boolean deprecated;
        private ExternalDocumentation externalDocs;
@@ -451,18 +465,18 @@ public class Operation extends SwaggerElement {
        public <T> T get(String property, Class<T> type) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "consumes" -> toType(getConsumes(), type);
-                       case "deprecated" -> toType(getDeprecated(), type);
-                       case "description" -> toType(getDescription(), type);
-                       case "externalDocs" -> toType(getExternalDocs(), type);
-                       case "operationId" -> toType(getOperationId(), type);
-                       case "parameters" -> toType(getParameters(), type);
-                       case "produces" -> toType(getProduces(), type);
-                       case "responses" -> toType(getResponses(), type);
-                       case "schemes" -> toType(getSchemes(), type);
-                       case "security" -> toType(getSecurity(), type);
-                       case "summary" -> toType(getSummary(), type);
-                       case "tags" -> toType(getTags(), type);
+                       case PROP_CONSUMES -> toType(getConsumes(), type);
+                       case PROP_DEPRECATED -> toType(getDeprecated(), type);
+                       case PROP_DESCRIPTION -> toType(getDescription(), type);
+                       case PROP_EXTERNAL_DOCS -> toType(getExternalDocs(), 
type);
+                       case PROP_OPERATION_ID -> toType(getOperationId(), 
type);
+                       case PROP_PARAMETERS -> toType(getParameters(), type);
+                       case PROP_PRODUCES -> toType(getProduces(), type);
+                       case PROP_RESPONSES -> toType(getResponses(), type);
+                       case PROP_SCHEMES -> toType(getSchemes(), type);
+                       case PROP_SECURITY -> toType(getSecurity(), type);
+                       case PROP_SUMMARY -> toType(getSummary(), type);
+                       case PROP_TAGS -> toType(getTags(), type);
                        default -> super.get(property, type);
                };
        }
@@ -654,18 +668,18 @@ public class Operation extends SwaggerElement {
        public Set<String> keySet() {
                // @formatter:off
                var s = setb(String.class)
-                       .addIf(ne(consumes), "consumes")
-                       .addIf(nn(deprecated), "deprecated")
-                       .addIf(nn(description), "description")
-                       .addIf(nn(externalDocs), "externalDocs")
-                       .addIf(nn(operationId), "operationId")
-                       .addIf(ne(parameters), "parameters")
-                       .addIf(ne(produces), "produces")
-                       .addIf(ne(responses), "responses")
-                       .addIf(ne(schemes), "schemes")
-                       .addIf(ne(security), "security")
-                       .addIf(nn(summary), "summary")
-                       .addIf(ne(tags), "tags")
+                       .addIf(ne(consumes), PROP_CONSUMES)
+                       .addIf(nn(deprecated), PROP_DEPRECATED)
+                       .addIf(nn(description), PROP_DESCRIPTION)
+                       .addIf(nn(externalDocs), PROP_EXTERNAL_DOCS)
+                       .addIf(nn(operationId), PROP_OPERATION_ID)
+                       .addIf(ne(parameters), PROP_PARAMETERS)
+                       .addIf(ne(produces), PROP_PRODUCES)
+                       .addIf(ne(responses), PROP_RESPONSES)
+                       .addIf(ne(schemes), PROP_SCHEMES)
+                       .addIf(ne(security), PROP_SECURITY)
+                       .addIf(nn(summary), PROP_SUMMARY)
+                       .addIf(ne(tags), PROP_TAGS)
                        .build();
                // @formatter:on
                return new MultiSet<>(s, super.keySet());
@@ -676,18 +690,18 @@ public class Operation extends SwaggerElement {
        public Operation set(String property, Object value) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "consumes" -> setConsumes(toListBuilder(value, 
MediaType.class).sparse().build());
-                       case "deprecated" -> setDeprecated(toBoolean(value));
-                       case "description" -> setDescription(s(value));
-                       case "externalDocs" -> setExternalDocs(toType(value, 
ExternalDocumentation.class));
-                       case "operationId" -> setOperationId(s(value));
-                       case "parameters" -> setParameters(toListBuilder(value, 
ParameterInfo.class).sparse().build());
-                       case "produces" -> setProduces(toListBuilder(value, 
MediaType.class).sparse().build());
-                       case "responses" -> setResponses(toMapBuilder(value, 
String.class, ResponseInfo.class).sparse().build());
-                       case "schemes" -> setSchemes(toListBuilder(value, 
String.class).sparse().addAny(value).build());
-                       case "security" -> 
setSecurity((List)toListBuilder(value, MapStringList.class).sparse().build());
-                       case "summary" -> setSummary(s(value));
-                       case "tags" -> setTags(toListBuilder(value, 
String.class).sparse().build());
+                       case PROP_CONSUMES -> setConsumes(toListBuilder(value, 
MediaType.class).sparse().build());
+                       case PROP_DEPRECATED -> setDeprecated(toBoolean(value));
+                       case PROP_DESCRIPTION -> setDescription(s(value));
+                       case PROP_EXTERNAL_DOCS -> 
setExternalDocs(toType(value, ExternalDocumentation.class));
+                       case PROP_OPERATION_ID -> setOperationId(s(value));
+                       case PROP_PARAMETERS -> 
setParameters(toListBuilder(value, ParameterInfo.class).sparse().build());
+                       case PROP_PRODUCES -> setProduces(toListBuilder(value, 
MediaType.class).sparse().build());
+                       case PROP_RESPONSES -> setResponses(toMapBuilder(value, 
String.class, ResponseInfo.class).sparse().build());
+                       case PROP_SCHEMES -> setSchemes(toListBuilder(value, 
String.class).sparse().addAny(value).build());
+                       case PROP_SECURITY -> 
setSecurity((List)toListBuilder(value, MapStringList.class).sparse().build());
+                       case PROP_SUMMARY -> setSummary(s(value));
+                       case PROP_TAGS -> setTags(toListBuilder(value, 
String.class).sparse().build());
                        default -> {
                                super.set(property, value);
                                yield this;
diff --git 
a/juneau-bean/juneau-bean-swagger-v2/src/main/java/org/apache/juneau/bean/swagger/Swagger.java
 
b/juneau-bean/juneau-bean-swagger-v2/src/main/java/org/apache/juneau/bean/swagger/Swagger.java
index 823c484e9e..2cbe145686 100644
--- 
a/juneau-bean/juneau-bean-swagger-v2/src/main/java/org/apache/juneau/bean/swagger/Swagger.java
+++ 
b/juneau-bean/juneau-bean-swagger-v2/src/main/java/org/apache/juneau/bean/swagger/Swagger.java
@@ -93,6 +93,24 @@ public class Swagger extends SwaggerElement {
        public static final Swagger NULL = new Swagger();
 
        private static final Comparator<String> PATH_COMPARATOR = (o1, o2) -> 
o1.replace('{', '@').compareTo(o2.replace('{', '@'));
+
+       // Property name constants
+       private static final String PROP_BASE_PATH = "basePath";
+       private static final String PROP_CONSUMES = "consumes";
+       private static final String PROP_DEFINITIONS = "definitions";
+       private static final String PROP_EXTERNAL_DOCS = "externalDocs";
+       private static final String PROP_HOST = "host";
+       private static final String PROP_INFO = "info";
+       private static final String PROP_PARAMETERS = "parameters";
+       private static final String PROP_PATHS = "paths";
+       private static final String PROP_PRODUCES = "produces";
+       private static final String PROP_RESPONSES = "responses";
+       private static final String PROP_SCHEMES = "schemes";
+       private static final String PROP_SECURITY = "security";
+       private static final String PROP_SECURITY_DEFINITIONS = 
"securityDefinitions";
+       private static final String PROP_SWAGGER = "swagger";
+       private static final String PROP_TAGS = "tags";
+
        private String swagger = "2.0",  // NOSONAR - Intentional naming.
                host, basePath;
        private Info info;
@@ -495,21 +513,21 @@ public class Swagger extends SwaggerElement {
        public <T> T get(String property, Class<T> type) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "basePath" -> toType(getBasePath(), type);
-                       case "consumes" -> toType(getConsumes(), type);
-                       case "definitions" -> toType(getDefinitions(), type);
-                       case "externalDocs" -> toType(getExternalDocs(), type);
-                       case "host" -> toType(getHost(), type);
-                       case "info" -> toType(getInfo(), type);
-                       case "parameters" -> toType(getParameters(), type);
-                       case "paths" -> toType(getPaths(), type);
-                       case "produces" -> toType(getProduces(), type);
-                       case "responses" -> toType(getResponses(), type);
-                       case "schemes" -> toType(getSchemes(), type);
-                       case "security" -> toType(getSecurity(), type);
-                       case "securityDefinitions" -> 
toType(getSecurityDefinitions(), type);
-                       case "swagger" -> toType(getSwagger(), type);
-                       case "tags" -> toType(getTags(), type);
+                       case PROP_BASE_PATH -> toType(getBasePath(), type);
+                       case PROP_CONSUMES -> toType(getConsumes(), type);
+                       case PROP_DEFINITIONS -> toType(getDefinitions(), type);
+                       case PROP_EXTERNAL_DOCS -> toType(getExternalDocs(), 
type);
+                       case PROP_HOST -> toType(getHost(), type);
+                       case PROP_INFO -> toType(getInfo(), type);
+                       case PROP_PARAMETERS -> toType(getParameters(), type);
+                       case PROP_PATHS -> toType(getPaths(), type);
+                       case PROP_PRODUCES -> toType(getProduces(), type);
+                       case PROP_RESPONSES -> toType(getResponses(), type);
+                       case PROP_SCHEMES -> toType(getSchemes(), type);
+                       case PROP_SECURITY -> toType(getSecurity(), type);
+                       case PROP_SECURITY_DEFINITIONS -> 
toType(getSecurityDefinitions(), type);
+                       case PROP_SWAGGER -> toType(getSwagger(), type);
+                       case PROP_TAGS -> toType(getTags(), type);
                        default -> super.get(property, type);
                };
        }
@@ -735,21 +753,21 @@ public class Swagger extends SwaggerElement {
        public Set<String> keySet() {
                // @formatter:off
                var s = setb(String.class)
-                       .addIf(nn(basePath), "basePath")
-                       .addIf(ne(consumes), "consumes")
-                       .addIf(ne(definitions), "definitions")
-                       .addIf(nn(externalDocs), "externalDocs")
-                       .addIf(nn(host), "host")
-                       .addIf(nn(info), "info")
-                       .addIf(ne(parameters), "parameters")
-                       .addIf(ne(paths), "paths")
-                       .addIf(ne(produces), "produces")
-                       .addIf(ne(responses), "responses")
-                       .addIf(ne(schemes), "schemes")
-                       .addIf(ne(security), "security")
-                       .addIf(ne(securityDefinitions), "securityDefinitions")
-                       .addIf(nn(swagger), "swagger")
-                       .addIf(ne(tags), "tags")
+                       .addIf(nn(basePath), PROP_BASE_PATH)
+                       .addIf(ne(consumes), PROP_CONSUMES)
+                       .addIf(ne(definitions), PROP_DEFINITIONS)
+                       .addIf(nn(externalDocs), PROP_EXTERNAL_DOCS)
+                       .addIf(nn(host), PROP_HOST)
+                       .addIf(nn(info), PROP_INFO)
+                       .addIf(ne(parameters), PROP_PARAMETERS)
+                       .addIf(ne(paths), PROP_PATHS)
+                       .addIf(ne(produces), PROP_PRODUCES)
+                       .addIf(ne(responses), PROP_RESPONSES)
+                       .addIf(ne(schemes), PROP_SCHEMES)
+                       .addIf(ne(security), PROP_SECURITY)
+                       .addIf(ne(securityDefinitions), 
PROP_SECURITY_DEFINITIONS)
+                       .addIf(nn(swagger), PROP_SWAGGER)
+                       .addIf(ne(tags), PROP_TAGS)
                        .build();
                // @formatter:on
                return new MultiSet<>(s, super.keySet());
@@ -760,21 +778,21 @@ public class Swagger extends SwaggerElement {
        public Swagger set(String property, Object value) {
                assertArgNotNull("property", property);
                return switch (property) {
-                       case "basePath" -> setBasePath(s(value));
-                       case "consumes" -> setConsumes(toListBuilder(value, 
MediaType.class).sparse().build());
-                       case "definitions" -> 
setDefinitions(toMapBuilder(value, String.class, 
JsonMap.class).sparse().build());
-                       case "externalDocs" -> setExternalDocs(toType(value, 
ExternalDocumentation.class));
-                       case "host" -> setHost(s(value));
-                       case "info" -> setInfo(toType(value, Info.class));
-                       case "parameters" -> setParameters(toMapBuilder(value, 
String.class, ParameterInfo.class).sparse().build());
-                       case "paths" -> setPaths(toMapBuilder(value, 
String.class, OperationMap.class).sparse().build());
-                       case "produces" -> setProduces(toListBuilder(value, 
MediaType.class).sparse().build());
-                       case "responses" -> setResponses(toMapBuilder(value, 
String.class, ResponseInfo.class).sparse().build());
-                       case "schemes" -> setSchemes(toListBuilder(value, 
String.class).sparse().build());
-                       case "security" -> 
setSecurity((List)toListBuilder(value, 
MapOfStringLists.class).sparse().build());
-                       case "securityDefinitions" -> 
setSecurityDefinitions(toMapBuilder(value, String.class, 
SecurityScheme.class).sparse().build());
-                       case "swagger" -> setSwagger(s(value));
-                       case "tags" -> setTags(toListBuilder(value, 
Tag.class).sparse().build());
+                       case PROP_BASE_PATH -> setBasePath(s(value));
+                       case PROP_CONSUMES -> setConsumes(toListBuilder(value, 
MediaType.class).sparse().build());
+                       case PROP_DEFINITIONS -> 
setDefinitions(toMapBuilder(value, String.class, 
JsonMap.class).sparse().build());
+                       case PROP_EXTERNAL_DOCS -> 
setExternalDocs(toType(value, ExternalDocumentation.class));
+                       case PROP_HOST -> setHost(s(value));
+                       case PROP_INFO -> setInfo(toType(value, Info.class));
+                       case PROP_PARAMETERS -> 
setParameters(toMapBuilder(value, String.class, 
ParameterInfo.class).sparse().build());
+                       case PROP_PATHS -> setPaths(toMapBuilder(value, 
String.class, OperationMap.class).sparse().build());
+                       case PROP_PRODUCES -> setProduces(toListBuilder(value, 
MediaType.class).sparse().build());
+                       case PROP_RESPONSES -> setResponses(toMapBuilder(value, 
String.class, ResponseInfo.class).sparse().build());
+                       case PROP_SCHEMES -> setSchemes(toListBuilder(value, 
String.class).sparse().build());
+                       case PROP_SECURITY -> 
setSecurity((List)toListBuilder(value, 
MapOfStringLists.class).sparse().build());
+                       case PROP_SECURITY_DEFINITIONS -> 
setSecurityDefinitions(toMapBuilder(value, String.class, 
SecurityScheme.class).sparse().build());
+                       case PROP_SWAGGER -> setSwagger(s(value));
+                       case PROP_TAGS -> setTags(toListBuilder(value, 
Tag.class).sparse().build());
                        default -> {
                                super.set(property, value);
                                yield this;
diff --git a/scripts/README_SONARQUBE.md b/scripts/README_SONARQUBE.md
new file mode 100644
index 0000000000..3752dc6843
--- /dev/null
+++ b/scripts/README_SONARQUBE.md
@@ -0,0 +1,217 @@
+# SonarQube Issues Management Tools
+
+This directory contains tools for categorizing and managing SonarQube issues 
in the Apache Juneau project.
+
+## Overview
+
+The Apache Juneau project has **3,116 SonarQube issues** that have been 
categorized into **30 categories** for systematic fixing.
+
+## Quick Start
+
+### 1. View Category Summary
+
+```bash
+cd /Users/james.bognar/git/apache/juneau/master
+cat SONARQUBE_ISSUES_SUMMARY.md
+```
+
+### 2. List All Categories
+
+```bash
+python3 scripts/view-sonar-category.py
+```
+
+### 3. View Specific Category Details
+
+```bash
+# View Security Issues (high priority)
+python3 scripts/view-sonar-category.py "Security Issues"
+
+# View with custom limit
+python3 scripts/view-sonar-category.py "Brain Methods (Complexity)" --limit 5
+```
+
+### 4. Start Interactive Fixing Session
+
+```bash
+python3 scripts/categorize-sonar-issues.py 
/Users/james.bognar/Downloads/SonarQubeIssues.txt
+```
+
+## Tools
+
+### `categorize-sonar-issues.py`
+
+Main script for categorizing and interactively fixing SonarQube issues.
+
+**Usage:**
+```bash
+python3 scripts/categorize-sonar-issues.py <sonarqube-issues-file> 
[--save-json]
+```
+
+**Features:**
+- Parses SonarQube TSV export file
+- Categorizes issues into 30 categories
+- Interactive session for fixing issues category by category
+- Saves categorized JSON for later reference
+
+**Options:**
+- `--save-json`: Save categorized issues to JSON file
+
+**Interactive Commands:**
+- `fix` - Start fixing issues in current category
+- `skip` - Move to next category  
+- `details` - Show detailed issue information
+- `list` - List all categories
+- `<number>` - Jump to specific category number
+- `quit` - Exit
+
+### `view-sonar-category.py`
+
+Helper script to view category details without interactive input.
+
+**Usage:**
+```bash
+# List all categories
+python3 scripts/view-sonar-category.py
+
+# View specific category
+python3 scripts/view-sonar-category.py "Category Name"
+
+# View with limit
+python3 scripts/view-sonar-category.py "Category Name" --limit 10
+```
+
+## Recommended Workflow
+
+### Step 1: Review Summary
+
+Read `SONARQUBE_ISSUES_SUMMARY.md` to understand:
+- Total issues and categories
+- Priority levels
+- Recommended fix order
+
+### Step 2: Explore Categories
+
+```bash
+# List all categories
+python3 scripts/view-sonar-category.py
+
+# Review high-priority categories
+python3 scripts/view-sonar-category.py "Security Issues"
+python3 scripts/view-sonar-category.py "Null Check Issues"
+python3 scripts/view-sonar-category.py "Brain Methods (Complexity)"
+```
+
+### Step 3: Start Fixing
+
+Begin with high-priority categories:
+
+```bash
+python3 scripts/categorize-sonar-issues.py 
/Users/james.bognar/Downloads/SonarQubeIssues.txt
+```
+
+Then:
+1. Navigate to high-priority categories (Security, Null Checks, Brain Methods)
+2. For each category:
+   - Review sample issues with `details`
+   - Decide on fix strategy (auto-fix vs manual review)
+   - Use `fix` to start fixing issues
+   - Process by file (recommended) or individually
+
+### Step 4: Track Progress
+
+The categorized JSON file (`SonarQubeIssues.categorized.json`) can be used to:
+- Track which categories have been fixed
+- Generate progress reports
+- Identify remaining issues
+
+## Category Priorities
+
+### High Priority (Fix First)
+- **Security Issues** (6 issues)
+- **Null Check Issues** (15 issues)
+- **Brain Methods (Complexity)** (30 issues)
+- **Missing Exception Handling** (1 issue)
+
+### Medium Priority
+- **Exception Catching Issues** (30 issues)
+- **Generic Type Issues** (121 issues)
+- **Empty Method Implementations** (99 issues)
+- **Test Assertion Issues** (61 issues)
+- **Optional Access Issues** (18 issues)
+- **Code Duplication** (16 issues)
+- **ThreadLocal Cleanup Issues** (7 issues)
+
+### Low Priority
+- **Unused Code** (96 issues)
+- **Missing Private Constructors** (91 issues)
+- All other categories
+
+## Fix Strategies
+
+### Auto-Fix Categories (Mechanical Fixes)
+These can often be fixed automatically or with simple find/replace:
+- Missing @Override Annotations
+- Unnecessary toString() Calls
+- Missing Private Constructors
+- Line Separator Issues
+- Python f-string Issues
+
+### Manual Review Categories (Require Code Review)
+These need careful review and testing:
+- Security Issues
+- Brain Methods (Complexity)
+- Null Check Issues
+- Exception Catching Issues
+- Code Duplication
+
+### Batch Fix Categories (Similar Patterns)
+These can be fixed in batches:
+- Missing Private Constructors
+- Generic Type Issues
+- Field Shadowing
+- Unused Code
+
+## Files
+
+- `SonarQubeIssues.txt` - Original SonarQube export (TSV format)
+- `SonarQubeIssues.categorized.json` - Categorized issues (JSON format)
+- `SONARQUBE_ISSUES_SUMMARY.md` - Summary document
+- `scripts/categorize-sonar-issues.py` - Main categorization tool
+- `scripts/view-sonar-category.py` - Category viewer tool
+
+## Tips
+
+1. **Start Small**: Begin with categories that have few issues to build 
momentum
+2. **Batch Similar Fixes**: Group similar issues together for efficient fixing
+3. **Test After Each Category**: Run tests after fixing each category
+4. **Use Version Control**: Commit fixes category by category for easier review
+5. **Document Decisions**: For "Empty Method Implementations" and similar 
categories, document why methods are intentionally empty
+
+## Example Session
+
+```bash
+# 1. View summary
+cat SONARQUBE_ISSUES_SUMMARY.md
+
+# 2. Check Security Issues (high priority, only 6 issues)
+python3 scripts/view-sonar-category.py "Security Issues"
+
+# 3. Start interactive session
+python3 scripts/categorize-sonar-issues.py 
/Users/james.bognar/Downloads/SonarQubeIssues.txt
+
+# In interactive session:
+# > list                    # See all categories
+# > 1                       # Jump to Security Issues
+# > details                 # See issue details
+# > fix                     # Start fixing
+# > [choose file mode]     # Process by file
+# > auto                    # Auto-fix each issue
+# > skip                    # Move to next category
+```
+
+## Support
+
+For questions or issues with these tools, refer to:
+- `SONARQUBE_ISSUES_SUMMARY.md` - Detailed category descriptions
+- The categorized JSON file for complete issue details
diff --git a/scripts/categorize-sonar-issues.py 
b/scripts/categorize-sonar-issues.py
new file mode 100755
index 0000000000..717f1aa709
--- /dev/null
+++ b/scripts/categorize-sonar-issues.py
@@ -0,0 +1,408 @@
+#!/usr/bin/env python3
+# 
***************************************************************************************************************************
+# * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file *
+# * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file        *
+# * to you under the Apache License, Version 2.0 (the "License"); you may not 
use this file except in compliance            *
+# * with the License.  You may obtain a copy of the License at                 
                                             *
+# *                                                                            
                                             *
+# *  http://www.apache.org/licenses/LICENSE-2.0                                
                                             *
+# *                                                                            
                                             *
+# * Unless required by applicable law or agreed to in writing, software 
distributed under the License is distributed on an  *
+# * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 
express or implied.  See the License for the        *
+# * specific language governing permissions and limitations under the License. 
                                             *
+# 
***************************************************************************************************************************
+"""
+Script to categorize and manage SonarQube issues for interactive fixing.
+"""
+
+import csv
+import re
+from collections import defaultdict
+from pathlib import Path
+from typing import Dict, List, Tuple
+import json
+
+class Issue:
+    def __init__(self, description: str, path: str, resource: str, location: 
str, 
+                 issue_type: str, issue_id: str, creation_time: str):
+        self.description = description
+        self.path = path
+        self.resource = resource
+        self.location = location
+        self.type = issue_type
+        self.id = issue_id
+        self.creation_time = creation_time
+    
+    def __repr__(self):
+        return f"Issue({self.description[:50]}... @ 
{self.resource}:{self.location})"
+
+def parse_issues(file_path: str) -> List[Issue]:
+    """Parse the SonarQube issues TSV file."""
+    issues = []
+    with open(file_path, 'r', encoding='utf-8') as f:
+        reader = csv.DictReader(f, delimiter='\t')
+        for row in reader:
+            issue = Issue(
+                description=row['Description'],
+                path=row['Path'],
+                resource=row['Resource'],
+                location=row['Location'],
+                issue_type=row['Type'],
+                issue_id=row['ID'],
+                creation_time=row['Creation Time']
+            )
+            issues.append(issue)
+    return issues
+
+def categorize_issue(issue: Issue) -> str:
+    """Categorize an issue based on its description."""
+    desc = issue.description.lower()
+    
+    # Field shadowing issues
+    if 'is the name of a field' in desc:
+        return "Field Shadowing"
+    
+    # Unnecessary toString() calls
+    if 'no need to call "tostring()"' in desc or 'already a string' in desc:
+        return "Unnecessary toString() Calls"
+    
+    # Line separator issues
+    if '%n should be used' in desc or ('\\n' in desc and 'line separator' in 
desc):
+        return "Line Separator Issues"
+    
+    # Brain Method (complexity)
+    if 'brain method' in desc:
+        return "Brain Methods (Complexity)"
+    
+    # Deprecated annotation issues
+    if 'deprecated annotation' in desc:
+        return "Deprecated Annotation Issues"
+    
+    # Empty method implementations
+    if 'empty, throw' in desc or 'empty method' in desc:
+        return "Empty Method Implementations"
+    
+    # Missing private constructor
+    if 'private constructor' in desc:
+        return "Missing Private Constructors"
+    
+    # Missing clone() method
+    if 'clone()' in desc.lower():
+        return "Missing clone() Methods"
+    
+    # Missing exception handling
+    if 'nosuchelementexception' in desc:
+        return "Missing Exception Handling"
+    
+    # Empty catch blocks
+    if 'catch clause' in desc and ('logic' in desc or 'eliminate' in desc):
+        return "Empty Catch Blocks"
+    
+    # Test assertion issues
+    if 'add at least one assertion' in desc or 'assertion' in desc and 'test' 
in desc:
+        return "Missing Test Assertions"
+    
+    # Python f-string issues
+    if 'f-string' in desc or 'replacement fields' in desc:
+        return "Python f-string Issues"
+    
+    # HTML/documentation issues
+    if '<title>' in desc or 'alt' in desc.lower() or ('<th>' in desc and 
'attribute' in desc):
+        return "HTML/Documentation Issues"
+    
+    # String concatenation in loops
+    if 'string concatenation' in desc or ('stringbuilder' in desc and 'loop' 
in desc):
+        return "String Concatenation Issues"
+    
+    # Null checks
+    if 'null' in desc and ('check' in desc or 'should' in desc or 'must' in 
desc):
+        return "Null Check Issues"
+    
+    # Generic type issues - check more specifically
+    if 'raw type' in desc or ('generic' in desc and ('type' in desc or 
'parameter' in desc)):
+        return "Generic Type Issues"
+    
+    # Resource management
+    if 'close' in desc.lower() and ('resource' in desc.lower() or 'stream' in 
desc.lower()):
+        return "Resource Management Issues"
+    
+    # Code duplication
+    if 'duplicate' in desc.lower():
+        return "Code Duplication"
+    
+    # Magic numbers
+    if 'magic number' in desc:
+        return "Magic Numbers"
+    
+    # Unused code - be more specific
+    if 'unused' in desc.lower() and ('parameter' in desc or 'variable' in desc 
or 'field' in desc or 'method' in desc or 'import' in desc):
+        return "Unused Code"
+    
+    # Security issues
+    if 'security' in desc.lower() or 'vulnerability' in desc.lower():
+        return "Security Issues"
+    
+    # Performance issues
+    if 'performance' in desc.lower() or 'inefficient' in desc.lower():
+        return "Performance Issues"
+    
+    # Code smell
+    if 'code smell' in desc.lower():
+        return "Code Smells"
+    
+    # Missing @Override annotations
+    if '@override' in desc or 'override annotation' in desc:
+        return "Missing @Override Annotations"
+    
+    # Missing test coverage
+    if 'add some tests' in desc or 'test coverage' in desc:
+        return "Missing Test Coverage"
+    
+    # Missing Javadoc tags
+    if '@deprecated' in desc.lower() and 'javadoc' in desc:
+        return "Missing Javadoc Tags"
+    
+    # Singleton pattern issues
+    if 'singleton' in desc.lower():
+        return "Singleton Pattern Issues"
+    
+    # Optional access issues
+    if 'optional' in desc.lower() and ('ispresent' in desc or 'isempty' in 
desc or 'get()' in desc):
+        return "Optional Access Issues"
+    
+    # Test assertion issues
+    if 'assertion' in desc.lower() and ('compare' in desc or 'dissimilar' in 
desc or 'primitive' in desc):
+        return "Test Assertion Issues"
+    
+    # Constructor visibility
+    if 'constructor' in desc.lower() and 'visibility' in desc.lower():
+        return "Constructor Visibility Issues"
+    
+    # Exception catching issues
+    if 'catch' in desc.lower() and ('exception' in desc.lower() or 'throwable' 
in desc.lower() or 'error' in desc.lower()):
+        return "Exception Catching Issues"
+    
+    # ThreadLocal cleanup
+    if 'remove()' in desc.lower() and ('threadlocal' in desc.lower() or 
'localstore' in desc.lower()):
+        return "ThreadLocal Cleanup Issues"
+    
+    # Type casting issues
+    if 'cast' in desc.lower() and ('operand' in desc.lower() or 
'multiplication' in desc.lower() or 'subtraction' in desc.lower()):
+        return "Type Casting Issues"
+    
+    # Default category
+    return "Other Issues"
+
+def categorize_all_issues(issues: List[Issue]) -> Dict[str, List[Issue]]:
+    """Categorize all issues."""
+    categories = defaultdict(list)
+    for issue in issues:
+        category = categorize_issue(issue)
+        categories[category].append(issue)
+    return dict(categories)
+
+def print_category_summary(categories: Dict[str, List[Issue]]):
+    """Print a summary of all categories."""
+    print("\n" + "="*80)
+    print("SONARQUBE ISSUES CATEGORIZATION SUMMARY")
+    print("="*80)
+    print(f"\nTotal Issues: {sum(len(issues) for issues in 
categories.values())}")
+    print(f"Total Categories: {len(categories)}\n")
+    
+    # Sort by count (descending)
+    sorted_categories = sorted(categories.items(), key=lambda x: len(x[1]), 
reverse=True)
+    
+    print(f"{'Category':<50} {'Count':>10} {'Percentage':>10}")
+    print("-" * 80)
+    
+    total = sum(len(issues) for issues in categories.values())
+    for category, issue_list in sorted_categories:
+        count = len(issue_list)
+        percentage = (count / total) * 100
+        print(f"{category:<50} {count:>10} {percentage:>9.1f}%")
+    
+    print("\n" + "="*80)
+
+def print_category_details(category: str, issues: List[Issue], limit: int = 
10):
+    """Print details for a specific category."""
+    print(f"\n{'='*80}")
+    print(f"CATEGORY: {category}")
+    print(f"Total Issues: {len(issues)}")
+    print(f"{'='*80}\n")
+    
+    # Group by file for easier review
+    by_file = defaultdict(list)
+    for issue in issues:
+        key = f"{issue.path}/{issue.resource}"
+        by_file[key].append(issue)
+    
+    print(f"Affected Files: {len(by_file)}\n")
+    
+    # Show first few examples
+    print("Sample Issues (first 10):")
+    print("-" * 80)
+    for i, issue in enumerate(issues[:limit], 1):
+        print(f"{i}. {issue.description}")
+        print(f"   File: {issue.path}/{issue.resource}:{issue.location}")
+        print()
+    
+    if len(issues) > limit:
+        print(f"... and {len(issues) - limit} more issues\n")
+
+def save_categorized_issues(categories: Dict[str, List[Issue]], output_file: 
str):
+    """Save categorized issues to a JSON file."""
+    output_data = {}
+    for category, issues in categories.items():
+        output_data[category] = [
+            {
+                'description': issue.description,
+                'path': issue.path,
+                'resource': issue.resource,
+                'location': issue.location,
+                'type': issue.type,
+                'id': issue.id
+            }
+            for issue in issues
+        ]
+    
+    with open(output_file, 'w', encoding='utf-8') as f:
+        json.dump(output_data, f, indent=2, ensure_ascii=False)
+    
+    print(f"\nCategorized issues saved to: {output_file}")
+
+def interactive_session(categories: Dict[str, List[Issue]]):
+    """Run an interactive session to work through categories."""
+    sorted_categories = sorted(categories.items(), key=lambda x: len(x[1]), 
reverse=True)
+    
+    print("\n" + "="*80)
+    print("INTERACTIVE SONARQUBE ISSUE FIXING SESSION")
+    print("="*80)
+    print("\nCommands:")
+    print("  <number> - Select category by number")
+    print("  list     - List all categories")
+    print("  details <number> - Show details for category")
+    print("  next     - Move to next category")
+    print("  quit     - Exit")
+    print("  help     - Show this help")
+    print("="*80)
+    
+    current_index = 0
+    
+    while True:
+        if current_index >= len(sorted_categories):
+            print("\nAll categories have been reviewed!")
+            break
+        
+        category, issues = sorted_categories[current_index]
+        count = len(issues)
+        
+        print(f"\n[{current_index + 1}/{len(sorted_categories)}] Current 
Category: {category}")
+        print(f"  Issues: {count}")
+        print(f"\nWhat would you like to do?")
+        print(f"  - Type 'fix' to start fixing issues in this category")
+        print(f"  - Type 'skip' to move to next category")
+        print(f"  - Type 'details' to see issue details")
+        print(f"  - Type a number to jump to that category")
+        print(f"  - Type 'list' to see all categories")
+        print(f"  - Type 'quit' to exit")
+        
+        command = input("\n> ").strip().lower()
+        
+        if command == 'quit' or command == 'q':
+            print("\nExiting. Progress saved.")
+            break
+        elif command == 'skip' or command == 'next' or command == 'n':
+            current_index += 1
+        elif command == 'details' or command == 'd':
+            print_category_details(category, issues)
+        elif command == 'list' or command == 'l':
+            print("\nCategories:")
+            for i, (cat, iss) in enumerate(sorted_categories, 1):
+                print(f"  {i}. {cat} ({len(iss)} issues)")
+        elif command == 'fix' or command == 'f':
+            print(f"\nStarting fixes for category: {category}")
+            print(f"Total issues: {count}")
+            print("\nFor each issue, you can:")
+            print("  - Type 'auto' to attempt automatic fix")
+            print("  - Type 'skip' to skip this issue")
+            print("  - Type 'show' to see the code context")
+            print("  - Type 'back' to return to category selection")
+            
+            # Group by file for batch processing
+            by_file = defaultdict(list)
+            for issue in issues:
+                key = f"{issue.path}/{issue.resource}"
+                by_file[key].append(issue)
+            
+            print(f"\nIssues grouped into {len(by_file)} files.")
+            print("Would you like to process by file (recommended) or 
individually?")
+            process_mode = input("  [f]ile/[i]ndividual (default: file): 
").strip().lower() or 'f'
+            
+            if process_mode == 'f':
+                for file_path, file_issues in by_file.items():
+                    print(f"\n--- File: {file_path} ({len(file_issues)} 
issues) ---")
+                    for issue in file_issues:
+                        print(f"\n  Issue: {issue.description}")
+                        print(f"  Location: {issue.location}")
+                        action = input("  Action [auto/skip/show/back]: 
").strip().lower()
+                        if action == 'back':
+                            break
+                        elif action == 'show':
+                            print(f"  TODO: Show code at 
{file_path}:{issue.location}")
+                        elif action == 'auto':
+                            print(f"  TODO: Auto-fix {issue.description}")
+                        elif action == 'skip':
+                            continue
+                    else:
+                        continue
+                    break  # Break outer loop if 'back' was used
+            else:
+                for issue in issues:
+                    print(f"\n  Issue: {issue.description}")
+                    print(f"  File: 
{issue.path}/{issue.resource}:{issue.location}")
+                    action = input("  Action [auto/skip/show/back]: 
").strip().lower()
+                    if action == 'back':
+                        break
+                    elif action == 'show':
+                        print(f"  TODO: Show code at 
{issue.path}/{issue.resource}:{issue.location}")
+                    elif action == 'auto':
+                        print(f"  TODO: Auto-fix {issue.description}")
+                    elif action == 'skip':
+                        continue
+        elif command.isdigit():
+            num = int(command)
+            if 1 <= num <= len(sorted_categories):
+                current_index = num - 1
+            else:
+                print(f"Invalid category number. Please enter 
1-{len(sorted_categories)}")
+        else:
+            print("Unknown command. Type 'help' for available commands.")
+
+def main():
+    import sys
+    
+    if len(sys.argv) < 2:
+        print("Usage: categorize-sonar-issues.py <sonarqube-issues-file> 
[--save-json]")
+        sys.exit(1)
+    
+    issues_file = sys.argv[1]
+    save_json = '--save-json' in sys.argv
+    
+    print(f"Parsing issues from: {issues_file}")
+    issues = parse_issues(issues_file)
+    print(f"Parsed {len(issues)} issues")
+    
+    print("\nCategorizing issues...")
+    categories = categorize_all_issues(issues)
+    
+    print_category_summary(categories)
+    
+    if save_json:
+        output_file = Path(issues_file).with_suffix('.categorized.json')
+        save_categorized_issues(categories, str(output_file))
+    
+    # Start interactive session
+    interactive_session(categories)
+
+if __name__ == '__main__':
+    main()
diff --git a/scripts/view-sonar-category.py b/scripts/view-sonar-category.py
new file mode 100755
index 0000000000..cad72396ec
--- /dev/null
+++ b/scripts/view-sonar-category.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python3
+# 
***************************************************************************************************************************
+# * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file *
+# * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file        *
+# * to you under the Apache License, Version 2.0 (the "License"); you may not 
use this file except in compliance            *
+# * with the License.  You may obtain a copy of the License at                 
                                             *
+# *                                                                            
                                             *
+# *  http://www.apache.org/licenses/LICENSE-2.0                                
                                             *
+# *                                                                            
                                             *
+# * Unless required by applicable law or agreed to in writing, software 
distributed under the License is distributed on an  *
+# * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 
express or implied.  See the License for the        *
+# * specific language governing permissions and limitations under the License. 
                                             *
+# 
***************************************************************************************************************************
+"""
+Helper script to view SonarQube issue categories without interactive input.
+Usage: view-sonar-category.py <category-name> [--limit N]
+"""
+
+import json
+import sys
+from pathlib import Path
+
+def main():
+    json_file = 
Path('/Users/james.bognar/Downloads/SonarQubeIssues.categorized.json')
+    
+    if not json_file.exists():
+        print(f"Error: Categorized JSON file not found: {json_file}")
+        print("Please run categorize-sonar-issues.py first with --save-json")
+        sys.exit(1)
+    
+    with open(json_file, 'r', encoding='utf-8') as f:
+        data = json.load(f)
+    
+    if len(sys.argv) < 2:
+        print("Available categories:")
+        print("=" * 80)
+        sorted_cats = sorted(data.items(), key=lambda x: len(x[1]), 
reverse=True)
+        for i, (category, issues) in enumerate(sorted_cats, 1):
+            print(f"{i:2d}. {category:<50} {len(issues):>5} issues")
+        sys.exit(0)
+    
+    category_name = sys.argv[1]
+    limit = int(sys.argv[3]) if len(sys.argv) > 3 and sys.argv[2] == '--limit' 
else 20
+    
+    if category_name not in data:
+        print(f"Error: Category '{category_name}' not found.")
+        print("\nAvailable categories:")
+        for cat in sorted(data.keys()):
+            print(f"  - {cat}")
+        sys.exit(1)
+    
+    issues = data[category_name]
+    
+    print("=" * 80)
+    print(f"CATEGORY: {category_name}")
+    print(f"Total Issues: {len(issues)}")
+    print("=" * 80)
+    
+    # Group by file
+    by_file = {}
+    for issue in issues:
+        file_key = f"{issue['path']}/{issue['resource']}"
+        if file_key not in by_file:
+            by_file[file_key] = []
+        by_file[file_key].append(issue)
+    
+    print(f"\nAffected Files: {len(by_file)}\n")
+    
+    # Show sample issues
+    print(f"Sample Issues (showing first {min(limit, len(issues))}):")
+    print("-" * 80)
+    for i, issue in enumerate(issues[:limit], 1):
+        print(f"\n{i}. {issue['description']}")
+        print(f"   File: 
{issue['path']}/{issue['resource']}:{issue['location']}")
+        print(f"   ID: {issue['id']}")
+    
+    if len(issues) > limit:
+        print(f"\n... and {len(issues) - limit} more issues")
+    
+    print("\n" + "=" * 80)
+    print("Files affected:")
+    print("-" * 80)
+    sorted_files = sorted(by_file.items(), key=lambda x: len(x[1]), 
reverse=True)
+    for file_path, file_issues in sorted_files[:20]:
+        print(f"  {file_path}: {len(file_issues)} issues")
+    
+    if len(by_file) > 20:
+        print(f"  ... and {len(by_file) - 20} more files")
+
+if __name__ == '__main__':
+    main()

Reply via email to