asyncapi / modelina

A library for generating typed models based on inputs such as AsyncAPI, OpenAPI, and JSON Schema documents with high customization
https://modelina.org
Apache License 2.0
283 stars 165 forks source link

Java output - Using jakarta.validation.constraints instead of javax.validation.constraints #1807

Open jmleyman opened 4 months ago

jmleyman commented 4 months ago

Reason/Context

Description

Solution one

Add in the file modelina/src/generators/java/presets/constraitntsPreset.ts the code below. It's a copy of JAVA_CONSTRAINTS_PRESET with the only change in for the addDependency

export const JAKARTA_CONSTRAINTS_PRESET: JavaPreset = {
    class: {
        self({renderer, content}) {
            renderer.dependencyManager.addDependency(
                'import jakarta.validation.constraints.*;'
            );
            return content;
        },
        // eslint-disable-next-line sonarjs/cognitive-complexity
        property({ renderer, property, content, model }) {
            if (model.options.isExtended) {
                return '';
            }

            const annotations: string[] = [];

            if (property.required) {
                annotations.push(renderer.renderAnnotation('NotNull'));
            }
            const originalInput = property.property.originalInput;

            // string
            if (property.property instanceof ConstrainedStringModel) {
                const pattern = originalInput['pattern'];
                if (pattern !== undefined) {
                    annotations.push(
                        renderer.renderAnnotation('Pattern', {
                            regexp: renderer.renderStringLiteral(pattern)
                        })
                    );
                }
                const minLength = originalInput['minLength'];
                const maxLength = originalInput['maxLength'];
                if (minLength !== undefined || maxLength !== undefined) {
                    annotations.push(
                        renderer.renderAnnotation('Size', {
                            min: minLength,
                            max: maxLength
                        })
                    );
                }
            }

            // number/integer
            if (
                property.property instanceof ConstrainedFloatModel ||
                property.property instanceof ConstrainedIntegerModel
            ) {
                const minimum = originalInput['minimum'];
                if (minimum !== undefined) {
                    annotations.push(renderer.renderAnnotation('Min', minimum));
                }
                const exclusiveMinimum = originalInput['exclusiveMinimum'];
                if (exclusiveMinimum !== undefined) {
                    annotations.push(
                        renderer.renderAnnotation('Min', exclusiveMinimum + 1)
                    );
                }
                const maximum = originalInput['maximum'];
                if (maximum !== undefined) {
                    annotations.push(renderer.renderAnnotation('Max', maximum));
                }
                const exclusiveMaximum = originalInput['exclusiveMaximum'];
                if (exclusiveMaximum !== undefined) {
                    annotations.push(
                        renderer.renderAnnotation('Max', exclusiveMaximum - 1)
                    );
                }
            }

            // array
            if (property.property instanceof ConstrainedArrayModel) {
                const minItems = originalInput['minItems'];
                const maxItems = originalInput['maxItems'];
                if (minItems !== undefined || maxItems !== undefined) {
                    annotations.push(
                        renderer.renderAnnotation('Size', { min: minItems, max: maxItems })
                    );
                }
            }

            return renderer.renderBlock([...annotations, content]);
        }
    }
};

Solution two:

Modify the file modelina/src/generators/java/presets/constraitntsPreset.ts with the code below.

export interface ConstraintPresetOptions {
    useJakarta: boolean
}
export const JAVA_CONSTRAINTS_PRESET: JavaPreset<ConstraintPresetOptions> = {
    class: {
        self({ renderer, model, content, options }) {
            options = options || {};
            if (options.useJakarta === undefined || options.useJakarta === false) {
                renderer.dependencyManager.addDependency(
                    'import javax.validation.constraints.*;'
                );
            } else  {
                renderer.dependencyManager.addDependency(
                    'import jakarta.validation.constraints.*;'
                );
            }

            return content;
        },
        // eslint-disable-next-line sonarjs/cognitive-complexity
        property({ renderer, property, content, model }) {
            [...]
        }
    }
};
github-actions[bot] commented 4 months ago

Welcome to AsyncAPI. Thanks a lot for reporting your first issue. Please check out our contributors guide and the instructions about a basic recommended setup useful for opening a pull request.
Keep in mind there are also other channels you can use to interact with AsyncAPI community. For more details check out this issue.

jonaslagoni commented 4 months ago

Makes sense to use options for this @jmleyman :v: Want to provide the PR?

jmleyman commented 4 months ago

I will try to provide the PR with options soon.

github-actions[bot] commented 3 weeks ago

This issue has been automatically marked as stale because it has not had recent activity :sleeping:

It will be closed in 120 days if no further activity occurs. To unstale this issue, add a comment with a detailed explanation.

There can be many reasons why some specific issue has no activity. The most probable cause is lack of time, not lack of interest. AsyncAPI Initiative is a Linux Foundation project not owned by a single for-profit company. It is a community-driven initiative ruled under open governance model.

Let us figure out together how to push this issue forward. Connect with us through one of many communication channels we established here.

Thank you for your patience :heart: