Skip to content

Here's a refactoring of the JSON Schema code to enhance clarity and maintainability. #450

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

wuseal
Copy link
Owner

@wuseal wuseal commented May 22, 2025

This update focuses on several key areas within the JSON Schema processing code:

  1. Improved Readability in JsonSchema.kt:

    • I've broken down the resolveDefinition method into smaller, private helper functions (resolveLocalDefinition, findDefinitionInMaps, findPropertyRecursive). This makes the code easier to follow and understand.
    • The allDefinitions property now uses a more concise functional expression: definitions + (defs ?: emptyMap()).
  2. Enhanced Clarity in JsonObjectDef.kt and PropertyDef.kt:

    • I've added comprehensive KDoc comments to public and protected classes, methods, and properties in JsonSchema.kt, JsonObjectDef.kt, and PropertyDef.kt. These comments explain parameters, return values, and the purpose of each component.
    • I've clarified the expected types for the type property in JsonObjectDef.kt (String or List of Strings) with a comment, while keeping its declared type as Any? for Gson compatibility.
  3. Addressed TODOs and Code Style:

    • I moved the JSON_SCHEMA_FORMAT_MAPPINGS map from its own file into ConfigManager.kt, as suggested by an existing TODO comment.
    • I've updated all usages of JSON_SCHEMA_FORMAT_MAPPINGS to reflect its new location in ConfigManager.
    • The now-empty JSON_SCHEMA_FORMAT_MAPPINGS.kt file has been removed.
    • I've ensured consistent code style and formatting across all modified files.

All existing unit tests pass, confirming that these changes have not introduced any regressions.

…aintainability.

This update focuses on several key areas within the JSON Schema processing code:

1.  **Improved Readability in `JsonSchema.kt`**:
    *   I've broken down the `resolveDefinition` method into smaller, private helper functions (`resolveLocalDefinition`, `findDefinitionInMaps`, `findPropertyRecursive`). This makes the code easier to follow and understand.
    *   The `allDefinitions` property now uses a more concise functional expression: `definitions + (defs ?: emptyMap())`.

2.  **Enhanced Clarity in `JsonObjectDef.kt` and `PropertyDef.kt`**:
    *   I've added comprehensive KDoc comments to public and protected classes, methods, and properties in `JsonSchema.kt`, `JsonObjectDef.kt`, and `PropertyDef.kt`. These comments explain parameters, return values, and the purpose of each component.
    *   I've clarified the expected types for the `type` property in `JsonObjectDef.kt` (String or List of Strings) with a comment, while keeping its declared type as `Any?` for Gson compatibility.

3.  **Addressed TODOs and Code Style**:
    *   I moved the `JSON_SCHEMA_FORMAT_MAPPINGS` map from its own file into `ConfigManager.kt`, as suggested by an existing TODO comment.
    *   I've updated all usages of `JSON_SCHEMA_FORMAT_MAPPINGS` to reflect its new location in `ConfigManager`.
    *   The now-empty `JSON_SCHEMA_FORMAT_MAPPINGS.kt` file has been removed.
    *   I've ensured consistent code style and formatting across all modified files.

All existing unit tests pass, confirming that these changes have not introduced any regressions.
@wuseal wuseal requested a review from Copilot May 22, 2025 16:23
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors JSON Schema processing for better readability and maintainability, adds comprehensive documentation, and centralizes format mappings.

  • Extracted smaller helper functions in JsonSchema.kt and simplified allDefinitions.
  • Added KDoc to schema-related classes (JsonSchema.kt, JsonObjectDef.kt, PropertyDef.kt).
  • Moved JSON_SCHEMA_FORMAT_MAPPINGS into ConfigManager.kt and updated all references.

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/main/kotlin/wu/seal/jsontokotlin/utils/classgenerator/DataClassGeneratorByJSONSchema.kt Updated import and references to JSON_SCHEMA_FORMAT_MAPPINGS from ConfigManager.
src/main/kotlin/wu/seal/jsontokotlin/model/jsonschema/PropertyDef.kt Added KDoc, @SerializedName annotations, and refined tryGetClassName.
src/main/kotlin/wu/seal/jsontokotlin/model/jsonschema/JsonSchema.kt Broke down resolveDefinition into helpers and streamlined allDefinitions.
src/main/kotlin/wu/seal/jsontokotlin/model/jsonschema/JsonObjectDef.kt Added KDoc, updated typeString and isTypeNullable logic.
src/main/kotlin/wu/seal/jsontokotlin/model/ConfigManager.kt Introduced JSON_SCHEMA_FORMAT_MAPPINGS map for format handling.
src/main/kotlin/wu/seal/jsontokotlin/JSON_SCHEMA_FORMAT_MAPPINGS.kt Removed obsolete file.
Comments suppressed due to low confidence (3)

src/main/kotlin/wu/seal/jsontokotlin/model/jsonschema/JsonObjectDef.kt:118

  • Similarly, switch this ArrayList<*> check to List<*> to handle any list type returned by Gson.
type is ArrayList<*> -> type.any { it == null || it == "null" }

src/main/kotlin/wu/seal/jsontokotlin/model/jsonschema/PropertyDef.kt:43

  • [nitpick] Consider renaming to xEnumNames (and xEnumFlags) with @SerializedName to follow Kotlin camelCase conventions.
val x_enumNames: Array<String>? = null,

src/main/kotlin/wu/seal/jsontokotlin/model/ConfigManager.kt:17

  • Add KDoc above this public val to explain the purpose and format of the mapping for generated docs.
val JSON_SCHEMA_FORMAT_MAPPINGS = mapOf(

Comment on lines +67 to 68
path.count() == 1 -> allDefinitions.values.firstOrNull { it.id == path[0] } // TODO: This could be path[0].substring(1) if # is always present
?: throw ClassNotFoundException("Definition $ref not found")
Copy link
Preview

Copilot AI May 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove or resolve this TODO before merging to avoid leaving outdated comments in production code.

Suggested change
path.count() == 1 -> allDefinitions.values.firstOrNull { it.id == path[0] } // TODO: This could be path[0].substring(1) if # is always present
?: throw ClassNotFoundException("Definition $ref not found")
path.count() == 1 -> {
val id = if (path[0].startsWith("#")) path[0].substring(1) else path[0]
allDefinitions.values.firstOrNull { it.id == id }
?: throw ClassNotFoundException("Definition $ref not found")
}

Copilot uses AI. Check for mistakes.

path[1] == "definitions" -> definitions[path[2]]
?: throw ClassNotFoundException("Definition $ref not found")
path[1] == "\$defs" -> defs?.get(path[2])
path.count() == 1 -> allDefinitions.values.firstOrNull { it.id == path[0] } // TODO: This could be path[0].substring(1) if # is always present
Copy link
Preview

Copilot AI May 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When matching a single-segment ref, strip the leading '#' (e.g., use path[0].removePrefix("#")) so local refs without slashes resolve correctly.

Suggested change
path.count() == 1 -> allDefinitions.values.firstOrNull { it.id == path[0] } // TODO: This could be path[0].substring(1) if # is always present
path.count() == 1 -> allDefinitions.values.firstOrNull { it.id == path[0].removePrefix("#") }

Copilot uses AI. Check for mistakes.

val typeString: String?
get() = if (type is ArrayList<*>) type.first { it != "null" } as String else type as? String
get() = if (type is ArrayList<*>) type.firstOrNull { it != "null" } as? String else type as? String
Copy link
Preview

Copilot AI May 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use a more general List<*> check instead of ArrayList<*> to support other collection implementations.

Suggested change
get() = if (type is ArrayList<*>) type.firstOrNull { it != "null" } as? String else type as? String
get() = if (type is List<*>) type.firstOrNull { it != "null" } as? String else type as? String

Copilot uses AI. Check for mistakes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant