diff --git a/datamodel/openapi/OAS31_CHANGES.md b/datamodel/openapi/OAS31_CHANGES.md new file mode 100644 index 0000000000..ed724da43d --- /dev/null +++ b/datamodel/openapi/OAS31_CHANGES.md @@ -0,0 +1,182 @@ +# OAS 3.1 Support — Change Summary + +This document describes all code changes made to add OAS 3.1.x support to the SAP Cloud SDK OpenAPI +generator. The full gap analysis is in [OAS31_GAPS.md](OAS31_GAPS.md). Gaps 9, 12, 14, and 15 are +out of scope and remain documented there for future work. + +--- + +## New File: `OasVersionUtil.java` + +**Path:** `openapi-generator/src/main/java/.../generator/OasVersionUtil.java` + +A small utility class with three static `isOas31(...)` overloads accepting a `String`, an `OpenAPI` +object, or a `JsonNode`. Every version-conditional code path in the other changed files delegates to +this class so the version check is defined in one place. + +--- + +## Changed: `CustomOpenAPINormalizer.java` + +**Gaps addressed:** 1, 2, 4, 7, 8 + +### What changed + +**`isOas31` field** — Set in the constructor via `OasVersionUtil.isOas31(openAPI)`. All new +behaviour in this class is gated on this flag, so OAS 3.0 specs are processed identically to before. + +**`normalizeReferenceSchema` — Gap 1 (nullable deprecation warning)** +When processing an OAS 3.1 spec and encountering a `$ref` schema that still carries `nullable: true` +(which is not valid in 3.1), the normalizer now emits a `WARN` log telling the spec author to use +`anyOf: [{$ref: "..."}, {type: "null"}]` instead. This does not block generation. + +**`normalizeReferenceSchema` — Gap 2 (numeric exclusiveMinimum/Maximum)** +In OAS 3.0 `exclusiveMinimum`/`exclusiveMaximum` are booleans. In OAS 3.1 they are independent +numeric values (`BigDecimal`). The swagger-core model exposes these as separate fields: +`getExclusiveMinimumValue()` / `getExclusiveMaximumValue()`. Both are now included in the +sibling-property condition that triggers `allOf` wrapping, so a `$ref` schema with a numeric +exclusive bound is handled correctly. + +**`normalizeReferenceSchema` — Gap 4 (`const` as $ref sibling)** +The OAS 3.1 `const` keyword (from JSON Schema 2020-12) is now included in the sibling-property +condition, so a `$ref` schema with a `const` sibling is wrapped in `allOf` and the constant +constraint is preserved in generated code. + +**New `normalizeSchema` override — Gap 7 (example deprecation warning)** +In OAS 3.1 the singular `example` keyword inside Schema Objects is deprecated in favour of the +array form `examples: [...]`. When `isOas31` and a schema carries `example`, a `WARN` log is +emitted. Generation is not blocked. + +**New `normalizeSchema` override — Gap 8 (binary file upload encoding)** +OAS 3.1 replaces `format: binary` / `format: byte` with JSON Schema keywords `contentEncoding` and +`contentMediaType`. This normalizer override maps those back to the legacy `format` values before +the upstream code generator sees the schema, preserving the existing `File → byte[]` type mapping: + +| OAS 3.1 input | Mapped to | +|---|---| +| `contentEncoding: base64` | `format: byte` | +| `contentEncoding: ` | `format: binary` | +| `contentMediaType: ` (no encoding) | `format: binary` | + +--- + +## Changed: `ValidationKeywordsPreprocessor.java` + +**Gaps addressed:** 5, 10 + +### What changed + +**Gap 5 — Webhooks-only documents** +OAS 3.1 makes the top-level `paths` field optional. A document with only `webhooks` (and no `paths`) +is now detected early and a clear `OpenApiGeneratorException` is thrown explaining that webhook +client generation is not yet supported. Previously, such a document would silently produce no output +or cause a `NullPointerException` downstream. + +A document with only `components` and neither `paths` nor `webhooks` is allowed to continue — +the upstream generator handles this case gracefully. + +**Gap 10 — Canonical OAS 3.1 nullable-ref pattern** +The preprocessor used to block *any* occurrence of `anyOf` or `oneOf` when +`oneOfAnyOfGenerationEnabled=false`. In OAS 3.1 the standard way to express a nullable `$ref` is: + +```yaml +anyOf: + - $ref: '#/components/schemas/Foo' + - type: "null" +``` + +A new private `isNullUnionPattern(JsonNode)` method recognises this exact two-element array +(one `$ref`-only object, one `{type: "null"}`-only object) and exempts it from the block. All other +multi-element or non-null-union `anyOf`/`oneOf` occurrences are still blocked unless the +`oneOfAnyOfGenerationEnabled` flag is set. + +--- + +## Changed: `CustomJavaClientCodegen.java` + +**Gaps addressed:** 5, 6 + +### What changed + +**Gap 5 — Null-safe `paths` access** +Two places called `openAPI.getPaths()` without guarding against `null`: + +- `preprocessOpenAPI`: the `USE_EXCLUDE_PATHS` loop now checks `openAPI.getPaths() != null` before + calling `.keySet().remove(...)`. +- `preprocessRemoveRedundancies`: an early-return guard is added at the top. If `paths` is null or + empty a warning is logged and the method returns immediately, avoiding a `NullPointerException` on + webhooks-only or components-only documents. + +**Gap 6 — `components/pathItems` traversal** +The `preprocessRemoveRedundancies` method discovers which `components/schemas` are in use by +scanning path definitions for `$ref` strings. In OAS 3.1 reusable path items can be stored in +`components/pathItems` and referenced from both `paths` and `webhooks`. The method now also scans +`openAPI.getComponents().getPathItems()` using the same regex-based approach, so schemas referenced +only via a reusable path item are not wrongly pruned by the remove-unused-components feature. + +--- + +## Changed: `GenerationConfigurationConverter.java` + +**Gap addressed:** 11 + +### What changed + +After the spec is parsed, `OasVersionUtil.isOas31(result)` is checked. If true, an `INFO` log is +emitted stating the detected version and pointing to `OAS31_GAPS.md` for known limitations. This +gives users a clear signal that OAS 3.1 mode is active without blocking generation. + +--- + +## New Test Fixtures + +### `DataModelGeneratorUnitTest/sodastore-31.yaml` + +An OAS 3.1.0 version of the standard sodastore spec that exercises the following 3.1 features: + +- `info.summary` and `info.license.identifier` (SPDX) +- `type: ["string", "null"]` (Gap 1 / Gap 3 — type as array) +- `exclusiveMinimum: 0` / `exclusiveMaximum: 5` as numeric values (Gap 2) +- `$ref` with a sibling `description` (Gap 4) +- `anyOf: [{$ref: ...}, {type: "null"}]` on a schema property (Gap 10) + +### `DataModelGeneratorUnitTest/sodastore-31-mutual-tls.yaml` + +An OAS 3.1.0 spec with a `type: mutualTLS` security scheme in `components/securitySchemes` (Gap 13). +Verifies the generator does not crash on the new security scheme type. + +### `ValidationKeywordsPreprocessorTest/sodastore-31-nullable.json` + +An OAS 3.1.0 spec with null-union `anyOf` patterns in both a path request body and a component +schema. Used by the new preprocessor tests to verify Gap 10. + +--- + +## New Tests + +### `DataModelGeneratorUnitTest` + +| Test | What it verifies | +|---|---| +| `testSuccessfulGenerationWithOas31Spec` | Full generation from `sodastore-31.yaml` succeeds and produces files | +| `testSuccessfulGenerationWithMutualTlsSecurityScheme` | Generation with `mutualTLS` security scheme does not throw | + +### `ValidationKeywordsPreprocessorTest` + +| Test | What it verifies | +|---|---| +| `testOas31NullUnionAnyOfInPaths_isAllowed` | Null-union `anyOf` in a path request body is not blocked (Gap 10) | +| `testOas31NullUnionAnyOfInSchemas_isAllowed` | Null-union `anyOf` in a component schema is not blocked (Gap 10) | +| `testNonNullUnionOneOfInPaths_isBlocked` | A `oneOf` with two `$ref` items (no null type) in a path is still blocked without the `oneOfAnyOfGenerationEnabled` flag | + +--- + +## What Is Not Changed (Out of Scope) + +| Gap | Reason deferred | +|---|---| +| Gap 9 — `if/then/else`, `prefixItems`, `$dynamicRef` | No Java equivalent; left to upstream `openapi-generator` | +| Gap 12 — `info.summary` / `license.identifier` in metadata | No code generation impact; metadata output not changed | +| Gap 13 — `mutualTLS` test coverage | Covered by smoke test above; no custom codegen needed | +| Gap 14 — Server `summary` field | No code generation impact | +| Gap 15 — `jsonSchemaDialect` field | Uncommon; handled by upstream parser | diff --git a/datamodel/openapi/OAS31_GAPS.md b/datamodel/openapi/OAS31_GAPS.md new file mode 100644 index 0000000000..21f12aafcf --- /dev/null +++ b/datamodel/openapi/OAS31_GAPS.md @@ -0,0 +1,386 @@ +# OAS 3.1 Generator Gaps Analysis + +This document summarizes the gaps between the current SAP Cloud SDK OpenAPI generator (targeting OAS 3.0) +and full OAS 3.1.x support. It covers every release from 3.1.0-rc0 (June 2020) through 3.1.2 (September 2025). + +## Background + +The generator is built on top of `openapi-generator` 7.23.0 and `swagger-parser` 2.1.45. +Its custom layers are concentrated in: + +- [CustomOpenAPINormalizer.java](openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/CustomOpenAPINormalizer.java) — schema normalisation before code generation +- [ValidationKeywordsPreprocessor.java](openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/ValidationKeywordsPreprocessor.java) — spec validation on raw `JsonNode` +- [GenerationConfigurationConverter.java](openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java) — parser invocation and additional properties +- [CustomJavaClientCodegen.java](openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/CustomJavaClientCodegen.java) — codegen overrides (composed schemas, array types, etc.) + +All test specs use `openapi: 3.0.0` or `openapi: 3.0.3`. No OAS 3.1 test fixtures exist. + +--- + +## Gap 1 — `nullable` Keyword Removed (Breaking) + +**Spec change (3.1.0-rc0):** `nullable: true` is entirely removed. The replacement is expressing null as a member of a type union: + +```yaml +# OAS 3.0 +type: string +nullable: true + +# OAS 3.1 +type: + - string + - "null" +``` + +**Current code:** +`CustomOpenAPINormalizer.normalizeReferenceSchema()` (line 51) reads `schema.getNullable()` and uses it to decide whether to wrap a `$ref` schema in `allOf`. This logic silently passes when `nullable` is absent (as in a 3.1 spec), leaving nullable intent unexpressed. + +`GenerationConfigurationConverter` forces `openApiNullable=false` (line 184) as a workaround for `JsonNullable` issues (BLI CLOUDECOSYSTEM-9843), which further masks any nullable annotation generated from 3.0's `nullable: true`. + +**Impact:** +- A 3.1 spec using `type: ["string", "null"]` will be parsed with the upstream `swagger-parser`, but the custom normalizer and codegen have no path to propagate "null-union" types to `@Nullable` Java annotations or `JsonNullable` wrappers. +- Any pre-existing 3.0 spec migrated to 3.1 with `nullable: true` kept will have nullability silently dropped. + +**Action required:** +- Replace `getNullable()` checks with inspection of `schema.getTypes()` for the presence of `"null"`. +- Resolve CLOUDECOSYSTEM-9843 to re-enable `openApiNullable` correctly. +- Add test fixtures using `type: ["string", "null"]` and `anyOf: [{$ref: ...}, {type: "null"}]`. + +--- + +## Gap 2 — `exclusiveMinimum` / `exclusiveMaximum` Semantic Inversion (Breaking) + +**Spec change (3.1.0-rc0):** These keywords change from boolean modifiers on `minimum`/`maximum` to standalone numeric bounds: + +```yaml +# OAS 3.0: boolean modifier — minimum is 7, exclusive +minimum: 7 +exclusiveMinimum: true + +# OAS 3.1: standalone — exclusive minimum is 7 (minimum keyword unused) +exclusiveMinimum: 7 +``` + +**Current code:** +`CustomOpenAPINormalizer.normalizeReferenceSchema()` (lines 56–57) reads `schema.getExclusiveMaximum()` and `schema.getExclusiveMinimum()` purely to detect the presence of sibling keywords alongside a `$ref`. In `swagger-parser` 2.1.45 the model class `Schema` maps both 3.0 `Boolean` and 3.1 `BigDecimal` forms, but the current custom code does not branch on version. + +**Impact:** +- A 3.1 spec with `exclusiveMinimum: 7` (numeric) will be parsed as a BigDecimal by `swagger-parser`, but the normalizer checks `!= null` only to trigger `allOf` wrapping — it does not validate or pass through the exclusive bound value. +- Bean-validation annotations generated for 3.0 schemas (e.g., `@DecimalMin(value="7", inclusive=false)`) will be generated incorrectly for 3.1 specs because the numeric value of `exclusiveMinimum` is conflated with the boolean flag. + +**Action required:** +- Detect OAS version at parse time and branch on `exclusiveMinimum`/`exclusiveMaximum` semantics accordingly. +- For 3.1: treat the keyword value directly as the exclusive bound; do not read `minimum`/`maximum` as the companion inclusive bound. +- Add version-conditional normalizer logic or a dedicated preprocessing step. + +--- + +## Gap 3 — `type` as Array (Breaking) + +**Spec change (3.1.0-rc0, JSON Schema 2020-12):** `type` may now be either a string or an array of strings: + +```yaml +# Both valid in 3.1 +type: string +type: ["string", "integer", "null"] +``` + +**Current code:** +`CustomOpenAPINormalizer.normalizeReferenceSchema()` (line 42) correctly checks both `schema.getType()` (single string, OAS 3.0) and `schema.getTypes()` (set, OAS 3.1) in the same condition. However it only *clears* both fields; it does not model or propagate multi-type unions through code generation. + +Downstream in `CustomJavaClientCodegen`, type resolution is delegated entirely to `JavaClientCodegen` from upstream openapi-generator. The upstream library has partial 3.1 support, but union types beyond null-union are not mapped to Java types (there is no direct Java equivalent of `type: ["string", "integer"]`). + +**Impact:** +- Multi-type arrays beyond `["X", "null"]` have no Java representation and will silently fall back to `Object`. +- The `checkForValidatorsInSchemas` in `ValidationKeywordsPreprocessor` does not check for multi-type arrays, so no validation error is raised for unsupported cases. + +**Action required:** +- Document supported subset: only `["X", "null"]` (nullable scalar) is mappable to Java. +- Emit a warning or error for multi-value type arrays that are not null-unions. +- Add a test fixture with multi-type schemas to verify fallback behaviour. + +--- + +## Gap 4 — `$ref` Sibling Properties Now Merged in Schema Objects (Breaking) + +**Spec change (3.1.0-rc0):** In OAS 3.0 any properties alongside a `$ref` were **ignored**. In OAS 3.1 (following JSON Schema 2020-12) sibling keywords are **combined** with the referenced schema: + +```yaml +# 3.0 — description was silently ignored +schema: + $ref: '#/components/schemas/Pet' + description: "ignored in 3.0" + +# 3.1 — description is combined with the referenced schema +schema: + $ref: '#/components/schemas/Pet' + description: "applied in 3.1" +``` + +**Current code:** +`CustomOpenAPINormalizer.normalizeReferenceSchema()` (lines 84–88) already implements an `allOf` wrapping strategy to handle sibling properties on `$ref` schemas. The workaround exists because `swagger-parser` may copy properties from a referenced schema onto the `$ref` node (lines 71–88 comments). This happens to produce correct results for OAS 3.0 sibling-annotation patterns. + +However the logic gates on `schema.getNullable()` (OAS 3.0 only) and several other 3.0-specific fields. A 3.1 schema with a `$ref` + `description` or `$ref` + `const` pair will only trigger wrapping if those properties are among the checked set. + +**Impact:** +- New 3.1 sibling keywords (`const`, `$comment`, JSON Schema 2020-12 vocabulary keywords) are not included in the trigger condition. They will be silently dropped. +- Reference Object contexts (parameter `$ref`, response `$ref`) allow **only** `summary` and `description` as overrides in 3.1. The current preprocessor does not validate this restriction. + +**Action required:** +- Extend the sibling-property condition in `normalizeReferenceSchema()` to cover `const`, `$comment`, `if`/`then`/`else`, `unevaluatedProperties`, and other 3.1 keywords. +- Add a validation check that non-Schema Reference Objects (parameters, responses, headers) carry at most `summary` and `description` alongside `$ref`. + +--- + +## Gap 5 — `webhooks` Top-Level Field Not Supported + +**Spec change (3.1.0-rc0):** A new top-level `webhooks` field maps webhook names to Path Item Objects. The `paths` top-level field is now **optional**. + +**Current code:** +`ValidationKeywordsPreprocessor.execute()` (line 23) reads `input.path(PATHS_NODE)` unconditionally. If `paths` is absent (a valid 3.1 document), `pathsNode` will be a `MissingNode`; the `findValue` calls return `null`, so no exception is thrown — but the document is effectively ignored. + +`CustomJavaClientCodegen.preprocessRemoveRedundancies()` (line 204) calls `openAPI.getPaths().values()` without a null check; a webhooks-only document would throw a `NullPointerException` here. + +No `webhooks` field is traversed anywhere in the custom code. + +**Impact:** +- Webhooks-only or paths-absent 3.1 documents cannot be processed. +- NPE risk in `preprocessRemoveRedundancies` when `paths` is null. + +**Action required:** +- Add null-check guards for `openAPI.getPaths()` wherever it is called. +- Evaluate whether SAP Cloud SDK should support generating webhook subscriber clients and decide on scope. +- At minimum, emit a clear error message when a document contains `webhooks` but no `paths`. + +--- + +## Gap 6 — `components.pathItems` Not Handled + +**Spec change (3.1.0-rc0):** The `components` object gains a `pathItems` map for reusable Path Item Objects. + +**Current code:** +`GenerationConfigurationConverter.preprocessSpecification()` (lines 139–158) and the remove-redundancies logic in `CustomJavaClientCodegen` only walk `components.schemas`, `components.responses`, and paths. No code traverses `components.pathItems`. + +**Impact:** +- `$ref` references pointing into `#/components/pathItems/...` will not be resolved correctly during preprocessing. +- The remove-unused-components feature (`FIX_REMOVE_UNUSED_COMPONENTS`) will not count path item references and may spuriously remove schemas referenced only from a reusable path item. + +**Action required:** +- Extend schema/ref traversal in `preprocessRemoveRedundancies` to descend into `components.pathItems`. +- Verify that `swagger-parser` 2.1.45 correctly resolves `#/components/pathItems/` references (upgrade may be needed). + +--- + +## Gap 7 — `schema.example` Deprecated in Favour of `examples` Array + +**Spec change (3.1.0):** Inside Schema Objects, the singular `example` keyword is deprecated. The JSON Schema 2020-12 standard uses `examples` (an array): + +```yaml +# 3.0 / deprecated 3.1 +example: "Berlin" + +# 3.1 preferred +examples: ["Berlin"] +``` + +**Current code:** +`CustomOpenAPINormalizer.normalizeReferenceSchema()` (line 66) checks `schema.getExample() != null` as a trigger for `allOf` wrapping. This means a 3.1 schema that uses `examples` (array) alongside a `$ref` will not be wrapped, potentially losing those examples. + +Line 67 checks `schema.getExamples() != null` as well, so the array form is covered in the wrap condition. However the two are treated identically — no deprecation warning for singular `example` in 3.1 documents is emitted. + +**Impact:** +- No generation failure, but no deprecation guidance for spec authors using 3.0's `example` in a 3.1 document. +- Example values from the `examples` array are not surfaced differently from the singular `example` in generated code or API documentation. + +**Action required:** +- Emit a deprecation warning when `schema.getExample()` is non-null in a 3.1 document. +- Ensure generated Javadoc/swagger annotations use the `examples` array form when targeting 3.1. + +--- + +## Gap 8 — File Upload / Binary Encoding Pattern Changed (Breaking) + +**Spec change (3.1.0-rc0):** Binary file descriptions change from format-based to JSON Schema content keywords: + +```yaml +# OAS 3.0 (still parseable but deprecated in 3.1) +type: string +format: binary + +# OAS 3.1 (correct) +type: string +contentEncoding: base64 +contentMediaType: image/png +``` + +**Current code:** +`GenerationConfigurationConverter` contains a type mapping for `File -> byte[]` passed from `GenerationConfiguration.typeMappings`. The underlying `JavaClientCodegen` maps `format: binary` to a byte-array or `File` Java type. Neither the custom normalizer nor the preprocessing steps handle `contentEncoding` or `contentMediaType`. + +**Impact:** +- A 3.1 spec using `contentEncoding`/`contentMediaType` for file uploads will not generate a `byte[]` or `InputStream` Java type; it will likely fall back to `Object` or `String`. +- The `format: binary` pattern still works via the upstream library for 3.0-style specs even when served under `openapi: 3.1.0`. + +**Action required:** +- Add a preprocessing step or normalizer hook that maps `contentEncoding: base64` → `format: byte` and `contentMediaType: application/octet-stream` → `format: binary` for compatibility with downstream type mapping. +- Add a test fixture for file upload with `contentEncoding`. + +--- + +## Gap 9 — JSON Schema 2020-12 Vocabulary Keywords Unhandled + +**Spec change (3.1.0):** Full JSON Schema 2020-12 alignment introduces keywords the OAS 3.0-era generator has never seen: + +| Keyword | Description | +|---|---| +| `$defs` | Inline reusable schemas (replaces `definitions`) | +| `$comment` | Non-validating developer annotation | +| `const` | Single-value constraint (cleaner than single-item `enum`) | +| `prefixItems` | Positional array item schemas (replaces array form of `items`) | +| `unevaluatedProperties` | Stricter `additionalProperties` that sees through `$ref`/combinators | +| `unevaluatedItems` | Same as above for array items | +| `if` / `then` / `else` | Conditional schema application | +| `$dynamicRef` / `$dynamicAnchor` | Dynamic references for recursive schemas | + +**Current code:** +None of these keywords are referenced anywhere in the custom generator code. They will either be passed through silently to the upstream `JavaClientCodegen` (which has partial support) or be ignored. + +`CustomJavaClientCodegen.updateModelForObject()` (line 264) unconditionally sets `additionalProperties` to `Boolean.FALSE`. In 3.1 `unevaluatedProperties` is the correct mechanism for sealing an object that uses `allOf`/`anyOf`/`oneOf` — `additionalProperties: false` does not see through those combinators. This means any 3.1 schema that uses `unevaluatedProperties: false` instead of `additionalProperties: false` will NOT be sealed by the codegen. + +**Impact:** +- `const` schemas will generate as single-value `enum` — workable but different from the intended model. +- `$defs` references will not be resolved by the preprocessing traversal in `preprocessRemoveRedundancies`, potentially causing schemas that are only referenced via `$defs` to be pruned. +- `unevaluatedProperties` is silently ignored; generated model classes will have an `additionalProperties` map even when the spec author intended to seal the object. +- `prefixItems` / tuple arrays are not mapped — they will likely generate as `List`. +- `if`/`then`/`else` schemas are not mapped — they will generate as `Object`. + +**Action required:** +- `$defs`: extend `preprocessRemoveRedundancies` traversal to follow `$defs` references. +- `const`: map to a single-element enum or a `@JsonProperty` constant in generated code; add a preprocessing step to normalise `const` to a single-item `enum` if the upstream generator does not handle it. +- `unevaluatedProperties`: do not force-set `additionalProperties: false` in `updateModelForObject`; instead inspect whether `unevaluatedProperties` is present. +- `if`/`then`/`else`, `prefixItems`, `$dynamicRef`: emit unsupported-feature warnings. + +--- + +## Gap 10 — `ValidationKeywordsPreprocessor` Assumes `paths` is Present + +**Current code:** +`ValidationKeywordsPreprocessor.execute()` (line 23) always walks `input.path("paths")`. In OAS 3.1 a document may omit `paths` entirely and provide only `webhooks` or `components`. + +When `paths` is missing, `pathsNode` is a `MissingNode`; `findValue()` returns `null` and no exception is raised — but it also means the validator silently skips validation entirely, allowing invalid `anyOf`/`oneOf` placements in a spec that does have `paths` nested inside `webhooks`. + +**Action required:** +- Guard on `pathsNode.isMissingNode()` and emit a warning when `paths` is absent. +- Extend validation to traverse `webhooks` operations for the same `anyOf`/`oneOf` placement rules. +- Consider whether the `oneOfAnyOfGenerationEnabled=false` default restriction makes sense for 3.1 specs, where `anyOf: [{$ref:...}, {type:"null"}]` is the canonical nullable pattern and must be supported. + +--- + +## Gap 11 — No OAS Version Detection or Version-Specific Routing + +**Current state:** +There is no code in the custom layers that reads `openAPI.getOpenapi()` (the version string) to branch behaviour. All processing assumes OAS 3.0.x semantics. `swagger-parser` 2.1.45 transparently parses both versions into the same `io.swagger.v3.oas.models.OpenAPI` object model, hiding the version distinction from consumers. + +**Impact:** +- The same preprocessing logic is applied regardless of whether the document declares `openapi: 3.0.3` or `openapi: 3.1.0`, leading to incorrect behaviour for `exclusiveMinimum`/`exclusiveMaximum`, `nullable`, and `$ref` sibling semantics. +- No validation that the spec version matches expected conventions. + +**Action required:** +- Read the version from `openAPI.getOpenapi()` (or from the raw `JsonNode` in preprocessing steps) and gate version-specific logic behind it. +- Add an explicit unsupported-version warning (or error) when the generator encounters a version it is not yet fully tested against. + +--- + +## Gap 12 — `info.summary` and `info.license.identifier` Not Surfaced + +**Spec change (3.1.0-rc0):** The Info Object gains a `summary` field (plain string) and the License Object gains an `identifier` field (SPDX expression): + +```yaml +info: + title: My API + summary: Short one-liner for catalog views + license: + name: Apache 2.0 + identifier: Apache-2.0 +``` + +**Current code:** +The generator does not read or surface `info.summary` or `license.identifier` anywhere. These fields exist only in documentation metadata and are not directly relevant to Java code generation. + +**Impact:** Low. These fields affect tooling that reads the spec for catalog/discovery purposes, not the generated Java client. + +**Action required:** No code change needed. Note that `DatamodelMetadataGeneratorAdapter` may wish to persist `info.summary` as part of the generated `.json` metadata file. + +--- + +## Gap 13 — `mutualTLS` Security Scheme Type Not Tested + +**Spec change (3.1.0-rc0):** A new `mutualTLS` security scheme type is added. It has no extra fields beyond `description`. + +**Current code:** +Security scheme types are not handled in the custom code; upstream `JavaClientCodegen` manages them. The upstream library maps security schemes to authentication annotations and configuration classes. + +**Impact:** Low for code generation (no extra fields to generate). Generated client code does not require special handling for `mutualTLS` at the source level — it is a transport-layer concern. + +**Action required:** +- Verify that `swagger-parser` 2.1.45 correctly parses `type: mutualTLS` without throwing an unknown-type exception. +- Add a test fixture with a `mutualTLS` security scheme. + +--- + +## Gap 14 — Server Object `summary` Field Not Surfaced + +**Spec change (3.1.0-rc0):** Server Objects gain a `summary` field (plain text label for tooling). + +**Current code:** Not used in code generation. No impact on generated Java clients. + +**Action required:** None for code generation. May be relevant for generated documentation or `DatamodelMetadataGeneratorAdapter`. + +--- + +## Gap 15 — `jsonSchemaDialect` Top-Level Field Not Handled + +**Spec change (3.1.0):** A new top-level `jsonSchemaDialect` URI field declares the default JSON Schema dialect for all Schema Objects. The OAS dialect URI is `https://spec.openapis.org/oas/3.1/dialect/base`. + +**Current code:** `swagger-parser` accepts this field without error, but neither the custom normalizer nor the preprocessing steps read or act on it. + +**Impact:** Low for the common case (spec authors rarely override the dialect). Non-standard dialects (e.g., pure JSON Schema 2020-12 without OAS extensions) may cause the upstream `JavaClientCodegen` to mishandle discriminator or `xml` objects. + +**Action required:** +- Emit a warning when `jsonSchemaDialect` is set to a non-OAS URI. +- Consider passing the dialect URI through to `swagger-parser` parse options. + +--- + +## Dependency Versions to Verify + +The following library versions determine how much OAS 3.1 support is available out-of-the-box: + +| Library | Current version | Notes | +|---|---|---| +| `openapi-generator` | 7.23.0 | 3.1 support present but has known bugs (nullable+allOf+$ref, unevaluatedProperties) | +| `io-swagger-parser-v3` | 2.1.45 | Parses 3.1 but full 2020-12 JSON Schema validation is incomplete | +| `io-swagger-core-v3` | 2.2.52 | Model classes expose both `getType()` and `getTypes()` — sufficient for dual-version handling | + +Recommend checking the upstream changelogs for any 3.1-related fixes released after these versions before implementing the gaps above. + +--- + +## Priority Summary + +| Priority | Gap | Effort | +|---|---|---| +| P0 — Breaking | Gap 1: `nullable` removed | Medium | +| P0 — Breaking | Gap 2: `exclusiveMinimum/Maximum` semantic change | Low | +| P0 — Breaking | Gap 3: `type` as array | Medium | +| P0 — Breaking | Gap 4: `$ref` sibling merging | Medium | +| P1 — Functional | Gap 5: `webhooks` / optional `paths` (NPE risk) | Medium | +| P1 — Functional | Gap 8: Binary/file upload encoding | Low | +| P1 — Functional | Gap 9: JSON Schema 2020-12 keywords (`$defs`, `const`, `unevaluatedProperties`) | High | +| P1 — Functional | Gap 10: `ValidationKeywordsPreprocessor` blocks canonical nullable pattern | Low | +| P1 — Functional | Gap 11: No OAS version detection | Low | +| P2 — Quality | Gap 6: `components.pathItems` traversal | Low | +| P2 — Quality | Gap 7: `example` deprecation warning | Low | +| P3 — Informational | Gap 12: `info.summary` / `license.identifier` | Trivial | +| P3 — Informational | Gap 13: `mutualTLS` test coverage | Trivial | +| P3 — Informational | Gap 14: Server `summary` | Trivial | +| P3 — Informational | Gap 15: `jsonSchemaDialect` field | Trivial | diff --git a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/CreatorForInterfaceSubtypesFeature.java b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/CreatorForInterfaceSubtypesFeature.java index df5a5122e2..c97da7cbde 100644 --- a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/CreatorForInterfaceSubtypesFeature.java +++ b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/CreatorForInterfaceSubtypesFeature.java @@ -34,8 +34,10 @@ void apply() final var creators = new HashSet(); for( final String candidate : Sets.union(m.anyOf, m.oneOf) ) { - final var creator = processCandidate(candidate); - creators.add(creator); + if( candidate != null ) { + final var creator = processCandidate(candidate); + creators.add(creator); + } } final var hasArray = creators.stream().anyMatch(CreatorDetails::isArray); @@ -52,7 +54,7 @@ void apply() log.warn(msg, m.name); } if( hasArray ) { - final var msg = "Field can be oneOf %d array types. Deserialization may not work as expected."; + final var msg = "Object contains oneOf with array types: {}. Deserialization may not work as expected."; log.warn(msg, m.name); } diff --git a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/CustomJavaClientCodegen.java b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/CustomJavaClientCodegen.java index 889e370923..d9442942f0 100644 --- a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/CustomJavaClientCodegen.java +++ b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/CustomJavaClientCodegen.java @@ -24,6 +24,7 @@ import org.openapitools.codegen.CodegenProperty; import org.openapitools.codegen.languages.JavaClientCodegen; import org.openapitools.codegen.model.ModelMap; +import org.openapitools.codegen.model.ModelsMap; import org.openapitools.codegen.model.OperationsMap; import com.sap.cloud.sdk.datamodel.openapi.generator.model.GenerationConfiguration; @@ -38,6 +39,8 @@ class CustomJavaClientCodegen extends JavaClientCodegen { private final GenerationConfiguration config; private static final Predicate DOUBLE_IS_PATTERN = Pattern.compile("^isIs[A-Z]").asPredicate(); + // schemaName -> (propertyName -> sibling description) captured before normalization strips $ref context + private final Map> siblingDescriptions = new java.util.HashMap<>(); public CustomJavaClientCodegen( @Nonnull final GenerationConfiguration config ) { @@ -47,6 +50,9 @@ public CustomJavaClientCodegen( @Nonnull final GenerationConfiguration config ) @Override public void preprocessOpenAPI( @Nonnull final OpenAPI openAPI ) { + // Capture sibling descriptions on $ref property schemas before normalization resolves them away. + captureSiblingDescriptions(openAPI); + if( USE_EXCLUDE_PROPERTIES.isEnabled(config) ) { final String[] exclusions = USE_EXCLUDE_PROPERTIES.getValue(config).trim().split("[,\\s]+"); for( final String exclusion : exclusions ) { @@ -55,11 +61,12 @@ public void preprocessOpenAPI( @Nonnull final OpenAPI openAPI ) } } + // OAS 3.1 documents may have no paths (webhooks-only or components-only). if( USE_EXCLUDE_PATHS.isEnabled(config) ) { final String[] exclusions = USE_EXCLUDE_PATHS.getValue(config).trim().split("[,\\s]+"); - for( final String exclusion : exclusions ) { - if( !openAPI.getPaths().keySet().remove(exclusion) ) { - log.error("Could not remove path {}", exclusion); + if( openAPI.getPaths() != null ) { + for( final String exclusion : exclusions ) { + openAPI.getPaths().remove(exclusion); } } } @@ -137,6 +144,54 @@ protected void updateModelForComposedSchema( } } + @SuppressWarnings( { "rawtypes", "RedundantSuppression" } ) + @Override + @Nonnull + public Map postProcessAllModels( @Nonnull final Map objs ) + { + final Map result = super.postProcessAllModels(objs); + + // Restore sibling descriptions lost during $ref resolution for primitive-typed properties. + for( final var schemaEntry : siblingDescriptions.entrySet() ) { + final ModelsMap modelsMap = result.get(schemaEntry.getKey()); + if( modelsMap == null ) { + continue; + } + for( final ModelMap modelMap : modelsMap.getModels() ) { + for( final CodegenProperty prop : modelMap.getModel().vars ) { + final String siblingDesc = schemaEntry.getValue().get(prop.baseName); + if( siblingDesc != null ) { + prop.description = escapeText(siblingDesc); + prop.unescapedDescription = siblingDesc; + } + } + } + } + return result; + } + + @SuppressWarnings( { "rawtypes", "unchecked" } ) + private void captureSiblingDescriptions( @Nonnull final OpenAPI openAPI ) + { + if( openAPI.getComponents() == null || openAPI.getComponents().getSchemas() == null ) { + return; + } + for( final var schemaEntry : openAPI.getComponents().getSchemas().entrySet() ) { + final Schema modelSchema = schemaEntry.getValue(); + if( modelSchema.getProperties() == null ) { + continue; + } + for( final var propEntry : ((Map) modelSchema.getProperties()).entrySet() ) { + final Schema propSchema = propEntry.getValue(); + if( propSchema.get$ref() != null && propSchema.getDescription() != null ) { + siblingDescriptions + .computeIfAbsent(schemaEntry.getKey(), k -> new java.util.HashMap<>()) + .put(propEntry.getKey(), propSchema.getDescription()); + } + } + } + } + /** * Remove property from specification. * @@ -147,7 +202,7 @@ protected void updateModelForComposedSchema( * @param propertyName * The name of the property to remove. */ - @SuppressWarnings( { "rawtypes", "unchecked", "ReplaceInefficientStreamCount" } ) + @SuppressWarnings( { "rawtypes", "unchecked" } ) private void preprocessRemoveProperty( @Nonnull final OpenAPI openAPI, @Nonnull final String schemaName, @@ -161,7 +216,7 @@ private void preprocessRemoveProperty( boolean removed = false; final Predicate remove = - s -> s != null && s.getProperties() != null && s.getProperties().remove(propertyName) != null; + s -> s.getProperties() != null && s.getProperties().remove(propertyName) != null; final var schemasQueued = new LinkedList(); final var schemasDone = new HashSet(); schemasQueued.add(schema); @@ -200,6 +255,11 @@ private void preprocessRemoveRedundancies( @Nonnull final OpenAPI openAPI ) final var refs = new LinkedHashSet(); final var pattern = Pattern.compile("\\$ref: #/components/schemas/(\\w+)"); + // OAS 3.1 documents may have no paths (webhooks-only or components-only). + if( openAPI.getPaths() == null || openAPI.getPaths().isEmpty() ) { + return; + } + // find and queue schemas nested in paths for( final var path : openAPI.getPaths().values() ) { final var m = pattern.matcher(path.toString()); @@ -211,6 +271,20 @@ private void preprocessRemoveRedundancies( @Nonnull final OpenAPI openAPI ) } } + // OAS 3.1 adds components/pathItems — traverse them for schema references too + final var pathItems = openAPI.getComponents() != null ? openAPI.getComponents().getPathItems() : null; + if( pathItems != null ) { + for( final var pathItem : pathItems.values() ) { + final var m = pattern.matcher(pathItem.toString()); + while( m.find() ) { + final var name = m.group(1); + final var schema = openAPI.getComponents().getSchemas().get(name); + queue.add(schema); + refs.add(m.group(0).split(" ")[1]); + } + } + } + while( !queue.isEmpty() ) { final var s = queue.remove(); if( s == null || !done.add(s) ) { diff --git a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/CustomOpenAPINormalizer.java b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/CustomOpenAPINormalizer.java index 9122eac603..b4dd6a3a86 100644 --- a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/CustomOpenAPINormalizer.java +++ b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/CustomOpenAPINormalizer.java @@ -1,6 +1,7 @@ package com.sap.cloud.sdk.datamodel.openapi.generator; import java.util.Map; +import java.util.Set; import javax.annotation.Nonnull; @@ -11,10 +12,13 @@ import io.swagger.v3.oas.models.media.Schema; /** - * Fix Api client methods with oneOf primitive param to stay simplified from OpenAPI generator 7.22.0 + * Fix Api client methods with oneOf primitive param to stay simplified from OpenAPI generator 7.22.0. Also adds OAS + * 3.1-aware normalisation: nullable warnings, example deprecation warnings, and contentEncoding/contentMediaType → + * format mapping for binary file uploads. */ public class CustomOpenAPINormalizer extends OpenAPINormalizer { + private final boolean isOas31; /** * Initializes OpenAPI Normalizer with a set of rules @@ -27,10 +31,12 @@ public class CustomOpenAPINormalizer extends OpenAPINormalizer public CustomOpenAPINormalizer( final @Nonnull OpenAPI openAPI, final @Nonnull Map inputRules ) { super(openAPI, inputRules); + this.isOas31 = OasVersionUtil.isOas31(openAPI); } /** - * Normalize reference schema with allOf to support sibling properties + * Normalize reference schema with allOf to support sibling properties. Also warns on OAS 3.1 deprecated keywords + * when processing a 3.1 spec. * * @param schema * Schema @@ -46,6 +52,15 @@ protected void normalizeReferenceSchema( final @Nonnull Schema schema ) LOGGER.warn("Type(s) cleared (set to null) given $ref is set to {}.", schema.get$ref()); } + // warn when deprecated nullable: true is used in an OAS 3.1 spec + if( isOas31 && schema.getNullable() != null ) { + LOGGER + .warn( + "'nullable: true' is not a valid OAS 3.1 keyword on $ref schema '{}'. " + + "Use anyOf: [{{$ref: \"...\"}}, {{type: \"null\"}}] instead.", + schema.get$ref()); + } + if( schema.getTitle() != null || schema.getDescription() != null || schema.getNullable() != null @@ -53,8 +68,12 @@ protected void normalizeReferenceSchema( final @Nonnull Schema schema ) || schema.getDeprecated() != null || schema.getMaximum() != null || schema.getMinimum() != null + // OAS 3.0 boolean exclusiveMaximum/exclusiveMinimum || schema.getExclusiveMaximum() != null || schema.getExclusiveMinimum() != null + // OAS 3.1 numeric exclusiveMaximumValue/exclusiveMinimumValue + || schema.getExclusiveMaximumValue() != null + || schema.getExclusiveMinimumValue() != null || schema.getMaxItems() != null || schema.getMinItems() != null || schema.getMaxProperties() != null @@ -65,6 +84,8 @@ protected void normalizeReferenceSchema( final @Nonnull Schema schema ) || schema.getReadOnly() != null || schema.getExample() != null || (schema.getExamples() != null && !schema.getExamples().isEmpty()) + // OAS 3.1 const keyword as $ref sibling + || schema.getConst() != null || schema.getMultipleOf() != null || schema.getPattern() != null || (schema.getExtensions() != null && !schema.getExtensions().isEmpty()) ) { @@ -87,4 +108,41 @@ protected void normalizeReferenceSchema( final @Nonnull Schema schema ) schema.set$ref(null); } } + + /** + * Normalizes any schema (not just $ref schemas). Adds OAS 3.1 specific mappings: + *
    + *
  • warn on deprecated singular {@code example} keyword in OAS 3.1 schemas
  • + *
  • map {@code contentEncoding}/{@code contentMediaType} to {@code format} for binary file uploads
  • + *
+ */ + @Override + @Nonnull + @SuppressWarnings( { "rawtypes" } ) + public Schema normalizeSchema( final @Nonnull Schema schema, final @Nonnull Set visitedSchemas ) + { + // warn on deprecated singular `example` in OAS 3.1 Schema Objects + if( isOas31 && schema.getExample() != null ) { + LOGGER + .warn( + "The 'example' keyword is deprecated in OAS 3.1 Schema Objects. " + + "Use 'examples: [...]' (array form) instead."); + } + + // map OAS 3.1 contentEncoding/contentMediaType to legacy format keyword + // so that downstream type-mapping (File -> byte[]) continues to work. + if( isOas31 && schema.getFormat() == null ) { + if( "base64".equalsIgnoreCase(schema.getContentEncoding()) ) { + schema.setFormat("byte"); + } else if( schema.getContentEncoding() != null ) { + // Any other content encoding (e.g., "binary") → treat as binary + schema.setFormat("binary"); + } else if( schema.getContentMediaType() != null ) { + // contentMediaType without contentEncoding → binary stream + schema.setFormat("binary"); + } + } + + return super.normalizeSchema(schema, visitedSchemas); + } } diff --git a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java index 100b8e9f9e..c1ba970cea 100644 --- a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java +++ b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java @@ -115,6 +115,7 @@ private static void setGlobalSettings( @Nonnull final GenerationConfiguration co log.warn("Parsing the specification yielded the following messages: {}", spec.getMessages()); } final var result = spec.getOpenAPI(); + log.info("Detected OpenAPI specification version {}.", result.getOpenapi()); preprocessSpecification(result, config); return result; } diff --git a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/OasVersionUtil.java b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/OasVersionUtil.java new file mode 100644 index 0000000000..0a44532301 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/OasVersionUtil.java @@ -0,0 +1,18 @@ +package com.sap.cloud.sdk.datamodel.openapi.generator; + +import javax.annotation.Nonnull; + +import io.swagger.v3.oas.models.OpenAPI; + +final class OasVersionUtil +{ + private OasVersionUtil() + { + } + + static boolean isOas31( @Nonnull final OpenAPI openAPI ) + { + final String version = openAPI.getOpenapi(); + return version != null && version.startsWith("3.1"); + } +} diff --git a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/ValidationKeywordsPreprocessor.java b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/ValidationKeywordsPreprocessor.java index 08af5a7179..9e04dc7e92 100644 --- a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/ValidationKeywordsPreprocessor.java +++ b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/ValidationKeywordsPreprocessor.java @@ -13,6 +13,7 @@ class ValidationKeywordsPreprocessor implements PreprocessingStep { private final List POTENTIALLY_UNSUPPORTED_VALIDATION_KEYWORDS = Arrays.asList("anyOf", "oneOf"); private final String PATHS_NODE = "paths"; + private final String WEBHOOKS_NODE = "webhooks"; private final String COMPONENTS_NODE = "components"; private final String SCHEMAS_NODE = "schemas"; @@ -21,33 +22,37 @@ class ValidationKeywordsPreprocessor implements PreprocessingStep public PreprocessingStepResult execute( @Nonnull final JsonNode input, @Nonnull final ObjectMapper objectMapper ) { final JsonNode pathsNode = input.path(PATHS_NODE); + + // OAS 3.1 documents may omit `paths` and use only `webhooks` or `components`. + // Webhook client generation is not yet supported; emit a clear error so the user knows why. + if( pathsNode.isMissingNode() ) { + final JsonNode webhooksNode = input.path(WEBHOOKS_NODE); + if( !webhooksNode.isMissingNode() ) { + throw new OpenApiGeneratorException( + "The OAS 3.1 document contains 'webhooks' but no 'paths'. " + + "Webhook client generation is not yet supported by this generator. " + + "Add at least one path to generate a client."); + } + // components-only or empty document — no paths to validate; let upstream handle it + return noChanges(input); + } + checkForValidatorsInPaths(pathsNode); final JsonNode schemasNode = input.path(COMPONENTS_NODE).path(SCHEMAS_NODE); checkForValidatorsInSchemas(schemasNode); - return new PreprocessingStepResult() - { - @Nonnull - @Override - public JsonNode getJsonNode() - { - return input; - } - - @Nonnull - @Override - public boolean changesApplied() - { - return false; - } - }; + return noChanges(input); } private void checkForValidatorsInPaths( final JsonNode pathsNode ) { for( final String field : POTENTIALLY_UNSUPPORTED_VALIDATION_KEYWORDS ) { - final boolean isUnsupported = pathsNode.findValue(field) != null; + // allow the OAS 3.1 canonical null-union pattern: + // anyOf/oneOf: [{$ref: "..."}, {type: "null"}] + // Only block occurrences that are NOT null-union patterns. + final boolean isUnsupported = + pathsNode.findValues(field).stream().anyMatch(node -> !isNullUnionPattern(node)); if( isUnsupported ) { throw new OpenApiGeneratorException( "The OpenAPI spec contains keyword " @@ -63,7 +68,9 @@ private void checkForValidatorsInSchemas( final JsonNode schemasNode ) for( final String field : POTENTIALLY_UNSUPPORTED_VALIDATION_KEYWORDS ) { for( final JsonNode schema : schemasNode ) { for( final JsonNode schemaChild : schema ) { - final boolean isUnsupported = schemaChild.findValue(field) != null; + // allow the OAS 3.1 canonical null-union pattern. + final boolean isUnsupported = + schemaChild.findValues(field).stream().anyMatch(node -> !isNullUnionPattern(node)); if( isUnsupported ) { throw new OpenApiGeneratorException( "The OpenAPI spec contains keyword " @@ -71,10 +78,58 @@ private void checkForValidatorsInSchemas( final JsonNode schemasNode ) + " inside schemas which is only supported if it is a direct child." + " Occurrences under additionalProperties and nesting inside a property is supported only if you explicitly enable it's processing using parameter in the OpenAPI generator maven plugin." + " Please regenerate your client by including parameter."); - } } } } } + + /** + * Returns {@code true} when the given JSON node represents the OAS 3.1 canonical nullable-ref pattern: + * + *
+     * anyOf/oneOf:
+     *   - $ref: "..."
+     *   - type: "null"
+     * 
+ * + * This two-element array pattern is the standard way to express a nullable $ref in OAS 3.1 and must be allowed even + * when oneOf/anyOf generation is otherwise disabled. + */ + private boolean isNullUnionPattern( final JsonNode node ) + { + if( !node.isArray() || node.size() != 2 ) { + return false; + } + boolean hasRef = false; + boolean hasNullType = false; + for( final JsonNode item : node ) { + if( item.has("$ref") && item.size() == 1 ) { + hasRef = true; + } else if( item.has("type") && "null".equals(item.path("type").asText()) && item.size() == 1 ) { + hasNullType = true; + } + } + return hasRef && hasNullType; + } + + private PreprocessingStepResult noChanges( final JsonNode input ) + { + return new PreprocessingStepResult() + { + @Nonnull + @Override + public JsonNode getJsonNode() + { + return input; + } + + @Nonnull + @Override + public boolean changesApplied() + { + return false; + } + }; + } } diff --git a/datamodel/openapi/openapi-generator/src/main/resources/openapi-generator/mustache-templates/pojo.mustache b/datamodel/openapi/openapi-generator/src/main/resources/openapi-generator/mustache-templates/pojo.mustache index b139c82a70..167cfbecbd 100644 --- a/datamodel/openapi/openapi-generator/src/main/resources/openapi-generator/mustache-templates/pojo.mustache +++ b/datamodel/openapi/openapi-generator/src/main/resources/openapi-generator/mustache-templates/pojo.mustache @@ -109,10 +109,10 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtens * * @param {{name}} {{#description}}{{description}}{{/description}}{{^description}}The {{name}} of this {@link {{classname}}}{{/description}} {{#minimum}} - * Minimum: {{minimum}} + * Minimum: {{minimum}}{{#exclusiveMinimum}} (exclusive){{/exclusiveMinimum}} {{/minimum}} {{#maximum}} - * Maximum: {{maximum}} + * Maximum: {{maximum}}{{#exclusiveMaximum}} (exclusive){{/exclusiveMaximum}} {{/maximum}} * @return The same instance of this {@link {{classname}}} class */ @@ -190,10 +190,10 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtens * Get {{name}} {{/description}} {{#minimum}} - * minimum: {{.}} + * minimum: {{.}}{{#exclusiveMinimum}} (exclusive){{/exclusiveMinimum}} {{/minimum}} {{#maximum}} - * maximum: {{.}} + * maximum: {{.}}{{#exclusiveMaximum}} (exclusive){{/exclusiveMaximum}} {{/maximum}} * @return {{name}} The {{name}} of this {@link {{classname}}} instance. {{#deprecated}} @@ -234,10 +234,10 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtens * * @param {{name}} {{#description}}{{description}}{{/description}}{{^description}}The {{name}} of this {@link {{classname}}}{{/description}} {{#minimum}} - * Minimum: {{minimum}} + * Minimum: {{minimum}}{{#exclusiveMinimum}} (exclusive){{/exclusiveMinimum}} {{/minimum}} {{#maximum}} - * Maximum: {{maximum}} + * Maximum: {{maximum}}{{#exclusiveMaximum}} (exclusive){{/exclusiveMaximum}} {{/maximum}} */ public void {{setter}}( {{#isNullable}}@Nullable{{/isNullable}}{{^isNullable}}{{#required}}@Nonnull{{/required}}{{^required}}@Nullable{{/required}}{{/isNullable}} final {{{datatypeWithEnum}}} {{name}}) { diff --git a/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/CustomOpenAPINormalizerTest.java b/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/CustomOpenAPINormalizerTest.java new file mode 100644 index 0000000000..192a9fd4b7 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/CustomOpenAPINormalizerTest.java @@ -0,0 +1,125 @@ +package com.sap.cloud.sdk.datamodel.openapi.generator; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.HashSet; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.media.Schema; + +class CustomOpenAPINormalizerTest +{ + private static OpenAPI oas30() + { + final OpenAPI openAPI = new OpenAPI(); + openAPI.setOpenapi("3.0.3"); + return openAPI; + } + + private static OpenAPI oas31() + { + final OpenAPI openAPI = new OpenAPI(); + openAPI.setOpenapi("3.1.0"); + return openAPI; + } + + private static CustomOpenAPINormalizer normalizer( final OpenAPI openAPI ) + { + return new CustomOpenAPINormalizer(openAPI, Map.of()); + } + + // --- contentEncoding / contentMediaType → format mapping --- + + @Test + void base64ContentEncodingMapsToByteFormat() + { + final Schema schema = new Schema<>(); + schema.setContentEncoding("base64"); + + normalizer(oas31()).normalizeSchema(schema, new HashSet<>()); + + assertThat(schema.getFormat()).isEqualTo("byte"); + } + + @Test + void base64ContentEncodingCaseInsensitive() + { + final Schema schema = new Schema<>(); + schema.setContentEncoding("BASE64"); + + normalizer(oas31()).normalizeSchema(schema, new HashSet<>()); + + assertThat(schema.getFormat()).isEqualTo("byte"); + } + + @Test + void binaryContentEncodingMapsToBinaryFormat() + { + final Schema schema = new Schema<>(); + schema.setContentEncoding("binary"); + + normalizer(oas31()).normalizeSchema(schema, new HashSet<>()); + + assertThat(schema.getFormat()).isEqualTo("binary"); + } + + @Test + void contentMediaTypeWithoutEncodingMapsToBinaryFormat() + { + final Schema schema = new Schema<>(); + schema.setContentMediaType("application/octet-stream"); + + normalizer(oas31()).normalizeSchema(schema, new HashSet<>()); + + assertThat(schema.getFormat()).isEqualTo("binary"); + } + + @Test + void existingFormatIsNotOverwritten() + { + final Schema schema = new Schema<>(); + schema.setFormat("uuid"); + schema.setContentEncoding("base64"); + + normalizer(oas31()).normalizeSchema(schema, new HashSet<>()); + + assertThat(schema.getFormat()).isEqualTo("uuid"); + } + + @Test + void noContentEncodingOrMediaTypeLeaveFormatNull() + { + final Schema schema = new Schema<>(); + + normalizer(oas31()).normalizeSchema(schema, new HashSet<>()); + + assertThat(schema.getFormat()).isNull(); + } + + // --- OAS 3.0: no format mapping applied --- + + @Test + void contentEncodingDoesNotMapFormatInOas30() + { + final Schema schema = new Schema<>(); + schema.setContentEncoding("base64"); + + normalizer(oas30()).normalizeSchema(schema, new HashSet<>()); + + assertThat(schema.getFormat()).isNull(); + } + + @Test + void contentMediaTypeDoesNotMapFormatInOas30() + { + final Schema schema = new Schema<>(); + schema.setContentMediaType("application/octet-stream"); + + normalizer(oas30()).normalizeSchema(schema, new HashSet<>()); + + assertThat(schema.getFormat()).isNull(); + } +} diff --git a/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorIntegrationTest.java b/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorIntegrationTest.java index 27487ab474..0a3d68b90b 100644 --- a/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorIntegrationTest.java +++ b/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorIntegrationTest.java @@ -166,6 +166,72 @@ enum TestCase 7, Map.of(), Map.of()), + OAS31_NULLABLE_TYPE_ARRAY( + "oas31-nullable-type-array", + "sodastore.yaml", + "com.sap.cloud.sdk.datamodel.rest.test.api", + "com.sap.cloud.sdk.datamodel.rest.test.model", + ApiMaturity.RELEASED, + false, + true, + 2, + Map.of(), + Map.of()), + OAS31_EXCLUSIVE_MIN_MAX( + "oas31-exclusive-min-max", + "sodastore.yaml", + "com.sap.cloud.sdk.datamodel.rest.test.api", + "com.sap.cloud.sdk.datamodel.rest.test.model", + ApiMaturity.RELEASED, + false, + true, + 2, + Map.of(), + Map.of()), + OAS31_REF_WITH_SIBLING( + "oas31-ref-with-sibling", + "sodastore.yaml", + "com.sap.cloud.sdk.datamodel.rest.test.api", + "com.sap.cloud.sdk.datamodel.rest.test.model", + ApiMaturity.RELEASED, + false, + true, + 2, + Map.of(), + Map.of()), + OAS31_NULLABLE_REF( + "oas31-nullable-ref", + "sodastore.yaml", + "com.sap.cloud.sdk.datamodel.rest.test.api", + "com.sap.cloud.sdk.datamodel.rest.test.model", + ApiMaturity.RELEASED, + false, + true, + 3, + Map.of(), + Map.of()), + OAS30_EXCLUSIVE_MIN_MAX( + "oas30-exclusive-min-max", + "sodastore.yaml", + "com.sap.cloud.sdk.datamodel.rest.test.api", + "com.sap.cloud.sdk.datamodel.rest.test.model", + ApiMaturity.RELEASED, + false, + true, + 2, + Map.of(), + Map.of()), + OAS31_COMPONENTS_PATH_ITEMS( + "oas31-components-path-items", + "sodastore.yaml", + "com.sap.cloud.sdk.datamodel.rest.test.api", + "com.sap.cloud.sdk.datamodel.rest.test.model", + ApiMaturity.RELEASED, + false, + true, + 3, + Map.of("removeUnusedComponents", "true"), + Map.of()), FILE_HANDLING( "file-handling", "file-handling.yaml", diff --git a/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorUnitTest.java b/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorUnitTest.java index 1517023d82..c841ff6430 100644 --- a/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorUnitTest.java +++ b/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorUnitTest.java @@ -389,4 +389,5 @@ void testConfigOptionsArePassedToGenerator() // assert output directory was created implicitly assertThat(outputDirectory.toFile().exists()).isTrue(); } + } diff --git a/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/ValidationKeywordsPreprocessorTest.java b/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/ValidationKeywordsPreprocessorTest.java index 362d8075ad..3f5266d051 100644 --- a/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/ValidationKeywordsPreprocessorTest.java +++ b/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/ValidationKeywordsPreprocessorTest.java @@ -116,4 +116,72 @@ void testSodastoreApiWithAllOf() assertThat(result.getJsonNode()).isEqualTo(jsonNode); } + // --- OAS 3.1 tests --- + + @Test + void testOas31NullUnionAnyOfInPaths_isAllowed() + throws IOException + { + // anyOf: [{$ref: "..."}, {type: "null"}] in a path request body is the OAS 3.1 + // canonical nullable-$ref pattern and must be allowed even when oneOf/anyOf generation + // is otherwise disabled. + final Path inputFilePath = + Paths + .get( + "src/test/resources/" + + ValidationKeywordsPreprocessorTest.class.getSimpleName() + + "/sodastore-31-nullable.json"); + + final ObjectMapper objectMapper = new ObjectMapper(); + final JsonNode jsonNode = objectMapper.readTree(inputFilePath.toFile()); + + final PreprocessingStep.PreprocessingStepResult result = + new ValidationKeywordsPreprocessor().execute(jsonNode, objectMapper); + + assertThat(result.changesApplied()).isFalse(); + assertThat(result.getJsonNode()).isEqualTo(jsonNode); + } + + @Test + void testOas31NullUnionAnyOfInSchemas_isAllowed() + throws IOException + { + // The sodastore-31-nullable.json fixture also contains null-union anyOf in component schemas. + final Path inputFilePath = + Paths + .get( + "src/test/resources/" + + ValidationKeywordsPreprocessorTest.class.getSimpleName() + + "/sodastore-31-nullable.json"); + + final ObjectMapper objectMapper = new ObjectMapper(); + final JsonNode jsonNode = objectMapper.readTree(inputFilePath.toFile()); + + // Must not throw — null-union patterns in schemas are allowed + final PreprocessingStep.PreprocessingStepResult result = + new ValidationKeywordsPreprocessor().execute(jsonNode, objectMapper); + + assertThat(result.changesApplied()).isFalse(); + } + + @Test + void testNonNullUnionOneOfInPaths_isBlocked() + throws IOException + { + // A oneOf with two $ref items (no null type) in a path must still be blocked + // when oneOf/anyOf generation is disabled. + final Path inputFilePath = + Paths + .get( + "src/test/resources/" + + ValidationKeywordsPreprocessorTest.class.getSimpleName() + + "/AggregatorInPathSchema.json"); + + final ObjectMapper objectMapper = new ObjectMapper(); + final JsonNode jsonNode = objectMapper.readTree(inputFilePath.toFile()); + + assertThatThrownBy(() -> new ValidationKeywordsPreprocessor().execute(jsonNode, objectMapper)) + .isInstanceOf(OpenApiGeneratorException.class); + } + } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas30-exclusive-min-max/input/sodastore.yaml b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas30-exclusive-min-max/input/sodastore.yaml new file mode 100644 index 0000000000..9ad45cbb3a --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas30-exclusive-min-max/input/sodastore.yaml @@ -0,0 +1,38 @@ +openapi: 3.0.3 +info: + title: OAS 3.0 Boolean exclusiveMinimum and exclusiveMaximum + version: 1.0.0 + +paths: + /sodas: + get: + operationId: getSodas + responses: + '200': + description: A soda + content: + application/json: + schema: + $ref: '#/components/schemas/Soda' + +components: + schemas: + Soda: + type: object + properties: + name: + type: string + rating: + # OAS 3.0: boolean exclusiveMinimum/exclusiveMaximum as flags alongside minimum/maximum + type: number + minimum: 0 + exclusiveMinimum: true + maximum: 5 + exclusiveMaximum: true + score: + # OAS 3.0: non-exclusive minimum/maximum (no boolean flags) + type: number + minimum: 0 + maximum: 100 + required: + - name diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas30-exclusive-min-max/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas30-exclusive-min-max/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java new file mode 100644 index 0000000000..bbd12b54a0 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas30-exclusive-min-max/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.api; + +import com.fasterxml.jackson.core.type.TypeReference; + +import com.sap.cloud.sdk.services.openapi.apache.core.OpenApiRequestException; +import com.sap.cloud.sdk.services.openapi.apache.core.OpenApiResponse; +import com.sap.cloud.sdk.services.openapi.apache.apiclient.ApiClient; +import com.sap.cloud.sdk.services.openapi.apache.apiclient.BaseApi; +import com.sap.cloud.sdk.services.openapi.apache.apiclient.Pair; + + +import com.sap.cloud.sdk.datamodel.rest.test.model.Soda; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.StringJoiner; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.sap.cloud.sdk.cloudplatform.connectivity.Destination; + + +/** + * OAS 3.0 Boolean exclusiveMinimum and exclusiveMaximum in version 1.0.0. + *

+ * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + */ +public class DefaultApi extends BaseApi { + + /** + * Instantiates this API class to invoke operations on the OAS 3.0 Boolean exclusiveMinimum and exclusiveMaximum. + * + * @param httpDestination The destination that API should be used with + */ + public DefaultApi( @Nonnull final Destination httpDestination ) + { + super(httpDestination); + } + + /** + * Instantiates this API class to invoke operations on the OAS 3.0 Boolean exclusiveMinimum and exclusiveMaximum based on a given {@link ApiClient}. + * + * @param apiClient + * ApiClient to invoke the API on + */ + public DefaultApi(@Nonnull final ApiClient apiClient) { + super(apiClient); + } + + /** + * Creates a new API instance with additional default headers. + * + * @param defaultHeaders Additional headers to include in all requests + * @return A new API instance with the combined headers + */ + public DefaultApi withDefaultHeaders(@Nonnull final Map defaultHeaders) { + final var api = new DefaultApi(apiClient); + api.defaultHeaders.putAll(this.defaultHeaders); + api.defaultHeaders.putAll(defaultHeaders); + return api; + } + + + /** + *

+ *

+ *

200 - A soda + * @return Soda + * @throws OpenApiRequestException if an error occurs while attempting to invoke the API + */ + @Nonnull + public Soda getSodas() throws OpenApiRequestException { + + // create path and map variables + final String localVarPath = "/sodas"; + + final StringJoiner localVarQueryStringJoiner = new StringJoiner("&"); + final List localVarQueryParams = new ArrayList(); + final List localVarCollectionQueryParams = new ArrayList(); + final Map localVarHeaderParams = new HashMap(defaultHeaders); + final Map localVarFormParams = new HashMap(); + + + final String[] localVarAccepts = { + "application/json" + }; + final String localVarAccept = ApiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { + + }; + final String localVarContentType = ApiClient.selectHeaderContentType(localVarContentTypes); + + final TypeReference localVarReturnType = new TypeReference() {}; + + return apiClient.invokeAPI( + localVarPath, + "GET", + localVarQueryParams, + localVarCollectionQueryParams, + localVarQueryStringJoiner.toString(), + null, + localVarHeaderParams, + localVarFormParams, + localVarAccept, + localVarContentType, + localVarReturnType + ); + } + } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas30-exclusive-min-max/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas30-exclusive-min-max/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java new file mode 100644 index 0000000000..2838b9548b --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas30-exclusive-min-max/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +/* + * OAS 3.0 Boolean exclusiveMinimum and exclusiveMaximum + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.model; + +import java.util.Objects; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.math.BigDecimal; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * Soda + */ +// CHECKSTYLE:OFF +public class Soda +// CHECKSTYLE:ON +{ + @JsonProperty("name") + private String name; + + @JsonProperty("rating") + private BigDecimal rating; + + @JsonProperty("score") + private BigDecimal score; + + @JsonAnySetter + @JsonAnyGetter + private final Map cloudSdkCustomFields = new LinkedHashMap<>(); + + /** + * Set the name of this {@link Soda} instance and return the same instance. + * + * @param name The name of this {@link Soda} + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda name( @Nonnull final String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name The name of this {@link Soda} instance. + */ + @Nonnull + public String getName() { + return name; + } + + /** + * Set the name of this {@link Soda} instance. + * + * @param name The name of this {@link Soda} + */ + public void setName( @Nonnull final String name) { + this.name = name; + } + + /** + * Set the rating of this {@link Soda} instance and return the same instance. + * + * @param rating The rating of this {@link Soda} + * Minimum: 0 (exclusive) + * Maximum: 5 (exclusive) + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda rating( @Nullable final BigDecimal rating) { + this.rating = rating; + return this; + } + + /** + * Get rating + * minimum: 0 (exclusive) + * maximum: 5 (exclusive) + * @return rating The rating of this {@link Soda} instance. + */ + @Nonnull + public BigDecimal getRating() { + return rating; + } + + /** + * Set the rating of this {@link Soda} instance. + * + * @param rating The rating of this {@link Soda} + * Minimum: 0 (exclusive) + * Maximum: 5 (exclusive) + */ + public void setRating( @Nullable final BigDecimal rating) { + this.rating = rating; + } + + /** + * Set the score of this {@link Soda} instance and return the same instance. + * + * @param score The score of this {@link Soda} + * Minimum: 0 + * Maximum: 100 + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda score( @Nullable final BigDecimal score) { + this.score = score; + return this; + } + + /** + * Get score + * minimum: 0 + * maximum: 100 + * @return score The score of this {@link Soda} instance. + */ + @Nonnull + public BigDecimal getScore() { + return score; + } + + /** + * Set the score of this {@link Soda} instance. + * + * @param score The score of this {@link Soda} + * Minimum: 0 + * Maximum: 100 + */ + public void setScore( @Nullable final BigDecimal score) { + this.score = score; + } + + /** + * Get the names of the unrecognizable properties of the {@link Soda}. + * @return The set of properties names + */ + @JsonIgnore + @Nonnull + public Set getCustomFieldNames() { + return cloudSdkCustomFields.keySet(); + } + + /** + * Get the value of an unrecognizable property of this {@link Soda} instance. + * @deprecated Use {@link #toMap()} instead. + * @param name The name of the property + * @return The value of the property + * @throws NoSuchElementException If no property with the given name could be found. + */ + @Nullable + @Deprecated + public Object getCustomField( @Nonnull final String name ) throws NoSuchElementException { + if( !cloudSdkCustomFields.containsKey(name) ) { + throw new NoSuchElementException("Soda has no field with name '" + name + "'."); + } + return cloudSdkCustomFields.get(name); + } + + /** + * Get the value of all properties of this {@link Soda} instance including unrecognized properties. + * + * @return The map of all properties + */ + @JsonIgnore + @Nonnull + public Map toMap() + { + final Map declaredFields = new LinkedHashMap<>(cloudSdkCustomFields); + if( name != null ) declaredFields.put("name", name); + if( rating != null ) declaredFields.put("rating", rating); + if( score != null ) declaredFields.put("score", score); + return declaredFields; + } + + /** + * Set an unrecognizable property of this {@link Soda} instance. If the map previously contained a mapping + * for the key, the old value is replaced by the specified value. + * @param customFieldName The name of the property + * @param customFieldValue The value of the property + */ + @JsonIgnore + public void setCustomField( @Nonnull String customFieldName, @Nullable Object customFieldValue ) + { + cloudSdkCustomFields.put(customFieldName, customFieldValue); + } + + + @Override + public boolean equals(@Nullable final java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Soda soda = (Soda) o; + return Objects.equals(this.cloudSdkCustomFields, soda.cloudSdkCustomFields) && + Objects.equals(this.name, soda.name) && + Objects.equals(this.rating, soda.rating) && + Objects.equals(this.score, soda.score); + } + + @Override + public int hashCode() { + return Objects.hash(name, rating, score, cloudSdkCustomFields); + } + + @Override + @Nonnull public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class Soda {\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" rating: ").append(toIndentedString(rating)).append("\n"); + sb.append(" score: ").append(toIndentedString(score)).append("\n"); + cloudSdkCustomFields.forEach((k,v) -> sb.append(" ").append(k).append(": ").append(toIndentedString(v)).append("\n")); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(final java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-components-path-items/input/sodastore.yaml b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-components-path-items/input/sodastore.yaml new file mode 100644 index 0000000000..0ea8f98073 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-components-path-items/input/sodastore.yaml @@ -0,0 +1,49 @@ +openapi: 3.1.0 +info: + title: OAS 3.1 components/pathItems schema references + version: 1.0.0 + +paths: + /sodas: + get: + operationId: getSodas + responses: + '200': + description: A soda + content: + application/json: + schema: + $ref: '#/components/schemas/Soda' + +components: + # OAS 3.1 adds components/pathItems — schemas referenced here must not be removed + pathItems: + sodaItem: + get: + operationId: getSodaDetail + responses: + '200': + description: success + content: + application/json: + schema: + $ref: '#/components/schemas/SodaDetail' + + schemas: + Soda: + type: object + properties: + name: + type: string + # Only referenced from components/pathItems, not from paths + SodaDetail: + type: object + properties: + description: + type: string + # Not referenced anywhere — should be removed by removeUnusedComponents + UnusedSchema: + type: object + properties: + garbage: + type: string diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-components-path-items/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-components-path-items/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java new file mode 100644 index 0000000000..4275275066 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-components-path-items/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.api; + +import com.fasterxml.jackson.core.type.TypeReference; + +import com.sap.cloud.sdk.services.openapi.apache.core.OpenApiRequestException; +import com.sap.cloud.sdk.services.openapi.apache.core.OpenApiResponse; +import com.sap.cloud.sdk.services.openapi.apache.apiclient.ApiClient; +import com.sap.cloud.sdk.services.openapi.apache.apiclient.BaseApi; +import com.sap.cloud.sdk.services.openapi.apache.apiclient.Pair; + + +import com.sap.cloud.sdk.datamodel.rest.test.model.Soda; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.StringJoiner; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.sap.cloud.sdk.cloudplatform.connectivity.Destination; + + +/** + * OAS 3.1 components/pathItems schema references in version 1.0.0. + *

+ * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + */ +public class DefaultApi extends BaseApi { + + /** + * Instantiates this API class to invoke operations on the OAS 3.1 components/pathItems schema references. + * + * @param httpDestination The destination that API should be used with + */ + public DefaultApi( @Nonnull final Destination httpDestination ) + { + super(httpDestination); + } + + /** + * Instantiates this API class to invoke operations on the OAS 3.1 components/pathItems schema references based on a given {@link ApiClient}. + * + * @param apiClient + * ApiClient to invoke the API on + */ + public DefaultApi(@Nonnull final ApiClient apiClient) { + super(apiClient); + } + + /** + * Creates a new API instance with additional default headers. + * + * @param defaultHeaders Additional headers to include in all requests + * @return A new API instance with the combined headers + */ + public DefaultApi withDefaultHeaders(@Nonnull final Map defaultHeaders) { + final var api = new DefaultApi(apiClient); + api.defaultHeaders.putAll(this.defaultHeaders); + api.defaultHeaders.putAll(defaultHeaders); + return api; + } + + + /** + *

+ *

+ *

200 - A soda + * @return Soda + * @throws OpenApiRequestException if an error occurs while attempting to invoke the API + */ + @Nonnull + public Soda getSodas() throws OpenApiRequestException { + + // create path and map variables + final String localVarPath = "/sodas"; + + final StringJoiner localVarQueryStringJoiner = new StringJoiner("&"); + final List localVarQueryParams = new ArrayList(); + final List localVarCollectionQueryParams = new ArrayList(); + final Map localVarHeaderParams = new HashMap(defaultHeaders); + final Map localVarFormParams = new HashMap(); + + + final String[] localVarAccepts = { + "application/json" + }; + final String localVarAccept = ApiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { + + }; + final String localVarContentType = ApiClient.selectHeaderContentType(localVarContentTypes); + + final TypeReference localVarReturnType = new TypeReference() {}; + + return apiClient.invokeAPI( + localVarPath, + "GET", + localVarQueryParams, + localVarCollectionQueryParams, + localVarQueryStringJoiner.toString(), + null, + localVarHeaderParams, + localVarFormParams, + localVarAccept, + localVarContentType, + localVarReturnType + ); + } + } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-components-path-items/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-components-path-items/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java new file mode 100644 index 0000000000..211258b8b9 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-components-path-items/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +/* + * OAS 3.1 components/pathItems schema references + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.model; + +import java.util.Objects; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * Soda + */ +// CHECKSTYLE:OFF +public class Soda +// CHECKSTYLE:ON +{ + @JsonProperty("name") + private String name; + + @JsonAnySetter + @JsonAnyGetter + private final Map cloudSdkCustomFields = new LinkedHashMap<>(); + + /** + * Set the name of this {@link Soda} instance and return the same instance. + * + * @param name The name of this {@link Soda} + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda name( @Nullable final String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name The name of this {@link Soda} instance. + */ + @Nullable + public String getName() { + return name; + } + + /** + * Set the name of this {@link Soda} instance. + * + * @param name The name of this {@link Soda} + */ + public void setName( @Nullable final String name) { + this.name = name; + } + + /** + * Get the names of the unrecognizable properties of the {@link Soda}. + * @return The set of properties names + */ + @JsonIgnore + @Nonnull + public Set getCustomFieldNames() { + return cloudSdkCustomFields.keySet(); + } + + /** + * Get the value of an unrecognizable property of this {@link Soda} instance. + * @deprecated Use {@link #toMap()} instead. + * @param name The name of the property + * @return The value of the property + * @throws NoSuchElementException If no property with the given name could be found. + */ + @Nullable + @Deprecated + public Object getCustomField( @Nonnull final String name ) throws NoSuchElementException { + if( !cloudSdkCustomFields.containsKey(name) ) { + throw new NoSuchElementException("Soda has no field with name '" + name + "'."); + } + return cloudSdkCustomFields.get(name); + } + + /** + * Get the value of all properties of this {@link Soda} instance including unrecognized properties. + * + * @return The map of all properties + */ + @JsonIgnore + @Nonnull + public Map toMap() + { + final Map declaredFields = new LinkedHashMap<>(cloudSdkCustomFields); + if( name != null ) declaredFields.put("name", name); + return declaredFields; + } + + /** + * Set an unrecognizable property of this {@link Soda} instance. If the map previously contained a mapping + * for the key, the old value is replaced by the specified value. + * @param customFieldName The name of the property + * @param customFieldValue The value of the property + */ + @JsonIgnore + public void setCustomField( @Nonnull String customFieldName, @Nullable Object customFieldValue ) + { + cloudSdkCustomFields.put(customFieldName, customFieldValue); + } + + + @Override + public boolean equals(@Nullable final java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Soda soda = (Soda) o; + return Objects.equals(this.cloudSdkCustomFields, soda.cloudSdkCustomFields) && + Objects.equals(this.name, soda.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, cloudSdkCustomFields); + } + + @Override + @Nonnull public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class Soda {\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + cloudSdkCustomFields.forEach((k,v) -> sb.append(" ").append(k).append(": ").append(toIndentedString(v)).append("\n")); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(final java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-components-path-items/output/com/sap/cloud/sdk/datamodel/rest/test/model/SodaDetail.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-components-path-items/output/com/sap/cloud/sdk/datamodel/rest/test/model/SodaDetail.java new file mode 100644 index 0000000000..3e2fb390ff --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-components-path-items/output/com/sap/cloud/sdk/datamodel/rest/test/model/SodaDetail.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +/* + * OAS 3.1 components/pathItems schema references + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.model; + +import java.util.Objects; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * SodaDetail + */ +// CHECKSTYLE:OFF +public class SodaDetail +// CHECKSTYLE:ON +{ + @JsonProperty("description") + private String description; + + @JsonAnySetter + @JsonAnyGetter + private final Map cloudSdkCustomFields = new LinkedHashMap<>(); + + /** + * Set the description of this {@link SodaDetail} instance and return the same instance. + * + * @param description The description of this {@link SodaDetail} + * @return The same instance of this {@link SodaDetail} class + */ + @Nonnull public SodaDetail description( @Nullable final String description) { + this.description = description; + return this; + } + + /** + * Get description + * @return description The description of this {@link SodaDetail} instance. + */ + @Nullable + public String getDescription() { + return description; + } + + /** + * Set the description of this {@link SodaDetail} instance. + * + * @param description The description of this {@link SodaDetail} + */ + public void setDescription( @Nullable final String description) { + this.description = description; + } + + /** + * Get the names of the unrecognizable properties of the {@link SodaDetail}. + * @return The set of properties names + */ + @JsonIgnore + @Nonnull + public Set getCustomFieldNames() { + return cloudSdkCustomFields.keySet(); + } + + /** + * Get the value of an unrecognizable property of this {@link SodaDetail} instance. + * @deprecated Use {@link #toMap()} instead. + * @param name The name of the property + * @return The value of the property + * @throws NoSuchElementException If no property with the given name could be found. + */ + @Nullable + @Deprecated + public Object getCustomField( @Nonnull final String name ) throws NoSuchElementException { + if( !cloudSdkCustomFields.containsKey(name) ) { + throw new NoSuchElementException("SodaDetail has no field with name '" + name + "'."); + } + return cloudSdkCustomFields.get(name); + } + + /** + * Get the value of all properties of this {@link SodaDetail} instance including unrecognized properties. + * + * @return The map of all properties + */ + @JsonIgnore + @Nonnull + public Map toMap() + { + final Map declaredFields = new LinkedHashMap<>(cloudSdkCustomFields); + if( description != null ) declaredFields.put("description", description); + return declaredFields; + } + + /** + * Set an unrecognizable property of this {@link SodaDetail} instance. If the map previously contained a mapping + * for the key, the old value is replaced by the specified value. + * @param customFieldName The name of the property + * @param customFieldValue The value of the property + */ + @JsonIgnore + public void setCustomField( @Nonnull String customFieldName, @Nullable Object customFieldValue ) + { + cloudSdkCustomFields.put(customFieldName, customFieldValue); + } + + + @Override + public boolean equals(@Nullable final java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final SodaDetail sodaDetail = (SodaDetail) o; + return Objects.equals(this.cloudSdkCustomFields, sodaDetail.cloudSdkCustomFields) && + Objects.equals(this.description, sodaDetail.description); + } + + @Override + public int hashCode() { + return Objects.hash(description, cloudSdkCustomFields); + } + + @Override + @Nonnull public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class SodaDetail {\n"); + sb.append(" description: ").append(toIndentedString(description)).append("\n"); + cloudSdkCustomFields.forEach((k,v) -> sb.append(" ").append(k).append(": ").append(toIndentedString(v)).append("\n")); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(final java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-exclusive-min-max/input/sodastore.yaml b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-exclusive-min-max/input/sodastore.yaml new file mode 100644 index 0000000000..913834b7c5 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-exclusive-min-max/input/sodastore.yaml @@ -0,0 +1,47 @@ +openapi: 3.1.0 +info: + title: OAS 3.1 Numeric exclusiveMinimum and exclusiveMaximum + version: 1.0.0 + +paths: + /sodas: + get: + operationId: getSodas + responses: + '200': + description: A soda + content: + application/json: + schema: + $ref: '#/components/schemas/Soda' + +components: + schemas: + Soda: + type: object + properties: + name: + type: string + rating: + # numeric exclusiveMinimum/exclusiveMaximum as direct values + type: number + exclusiveMinimum: 0 + exclusiveMaximum: 5 + score: + # OAS 3.1: non-exclusive minimum/maximum (plain numeric values) + type: number + minimum: 0 + maximum: 100 + temperature: + # OAS 3.1: mixed — inclusive minimum alongside exclusive maximum + type: number + minimum: 0 + exclusiveMaximum: 100 + combo: + # OAS 3.1: both minimum (inclusive) and exclusiveMinimum (exclusive numeric) present; + # exclusiveMinimum: 3 is stricter than minimum: 2, so effective constraint is > 3 + type: number + minimum: 2 + exclusiveMinimum: 3 + required: + - name diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-exclusive-min-max/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-exclusive-min-max/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java new file mode 100644 index 0000000000..a9aa17c3ff --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-exclusive-min-max/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.api; + +import com.fasterxml.jackson.core.type.TypeReference; + +import com.sap.cloud.sdk.services.openapi.apache.core.OpenApiRequestException; +import com.sap.cloud.sdk.services.openapi.apache.core.OpenApiResponse; +import com.sap.cloud.sdk.services.openapi.apache.apiclient.ApiClient; +import com.sap.cloud.sdk.services.openapi.apache.apiclient.BaseApi; +import com.sap.cloud.sdk.services.openapi.apache.apiclient.Pair; + + +import com.sap.cloud.sdk.datamodel.rest.test.model.Soda; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.StringJoiner; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.sap.cloud.sdk.cloudplatform.connectivity.Destination; + + +/** + * OAS 3.1 Numeric exclusiveMinimum and exclusiveMaximum in version 1.0.0. + *

+ * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + */ +public class DefaultApi extends BaseApi { + + /** + * Instantiates this API class to invoke operations on the OAS 3.1 Numeric exclusiveMinimum and exclusiveMaximum. + * + * @param httpDestination The destination that API should be used with + */ + public DefaultApi( @Nonnull final Destination httpDestination ) + { + super(httpDestination); + } + + /** + * Instantiates this API class to invoke operations on the OAS 3.1 Numeric exclusiveMinimum and exclusiveMaximum based on a given {@link ApiClient}. + * + * @param apiClient + * ApiClient to invoke the API on + */ + public DefaultApi(@Nonnull final ApiClient apiClient) { + super(apiClient); + } + + /** + * Creates a new API instance with additional default headers. + * + * @param defaultHeaders Additional headers to include in all requests + * @return A new API instance with the combined headers + */ + public DefaultApi withDefaultHeaders(@Nonnull final Map defaultHeaders) { + final var api = new DefaultApi(apiClient); + api.defaultHeaders.putAll(this.defaultHeaders); + api.defaultHeaders.putAll(defaultHeaders); + return api; + } + + + /** + *

+ *

+ *

200 - A soda + * @return Soda + * @throws OpenApiRequestException if an error occurs while attempting to invoke the API + */ + @Nonnull + public Soda getSodas() throws OpenApiRequestException { + + // create path and map variables + final String localVarPath = "/sodas"; + + final StringJoiner localVarQueryStringJoiner = new StringJoiner("&"); + final List localVarQueryParams = new ArrayList(); + final List localVarCollectionQueryParams = new ArrayList(); + final Map localVarHeaderParams = new HashMap(defaultHeaders); + final Map localVarFormParams = new HashMap(); + + + final String[] localVarAccepts = { + "application/json" + }; + final String localVarAccept = ApiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { + + }; + final String localVarContentType = ApiClient.selectHeaderContentType(localVarContentTypes); + + final TypeReference localVarReturnType = new TypeReference() {}; + + return apiClient.invokeAPI( + localVarPath, + "GET", + localVarQueryParams, + localVarCollectionQueryParams, + localVarQueryStringJoiner.toString(), + null, + localVarHeaderParams, + localVarFormParams, + localVarAccept, + localVarContentType, + localVarReturnType + ); + } + } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-exclusive-min-max/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-exclusive-min-max/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java new file mode 100644 index 0000000000..e071d03ae7 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-exclusive-min-max/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +/* + * OAS 3.1 Numeric exclusiveMinimum and exclusiveMaximum + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.model; + +import java.util.Objects; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.math.BigDecimal; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * Soda + */ +// CHECKSTYLE:OFF +public class Soda +// CHECKSTYLE:ON +{ + @JsonProperty("name") + private String name; + + @JsonProperty("rating") + private BigDecimal rating; + + @JsonProperty("score") + private BigDecimal score; + + @JsonProperty("temperature") + private BigDecimal temperature; + + @JsonProperty("combo") + private BigDecimal combo; + + @JsonAnySetter + @JsonAnyGetter + private final Map cloudSdkCustomFields = new LinkedHashMap<>(); + + /** + * Set the name of this {@link Soda} instance and return the same instance. + * + * @param name The name of this {@link Soda} + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda name( @Nonnull final String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name The name of this {@link Soda} instance. + */ + @Nonnull + public String getName() { + return name; + } + + /** + * Set the name of this {@link Soda} instance. + * + * @param name The name of this {@link Soda} + */ + public void setName( @Nonnull final String name) { + this.name = name; + } + + /** + * Set the rating of this {@link Soda} instance and return the same instance. + * + * @param rating The rating of this {@link Soda} + * Minimum: 0 (exclusive) + * Maximum: 5 (exclusive) + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda rating( @Nullable final BigDecimal rating) { + this.rating = rating; + return this; + } + + /** + * Get rating + * minimum: 0 (exclusive) + * maximum: 5 (exclusive) + * @return rating The rating of this {@link Soda} instance. + */ + @Nonnull + public BigDecimal getRating() { + return rating; + } + + /** + * Set the rating of this {@link Soda} instance. + * + * @param rating The rating of this {@link Soda} + * Minimum: 0 (exclusive) + * Maximum: 5 (exclusive) + */ + public void setRating( @Nullable final BigDecimal rating) { + this.rating = rating; + } + + /** + * Set the score of this {@link Soda} instance and return the same instance. + * + * @param score The score of this {@link Soda} + * Minimum: 0 + * Maximum: 100 + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda score( @Nullable final BigDecimal score) { + this.score = score; + return this; + } + + /** + * Get score + * minimum: 0 + * maximum: 100 + * @return score The score of this {@link Soda} instance. + */ + @Nonnull + public BigDecimal getScore() { + return score; + } + + /** + * Set the score of this {@link Soda} instance. + * + * @param score The score of this {@link Soda} + * Minimum: 0 + * Maximum: 100 + */ + public void setScore( @Nullable final BigDecimal score) { + this.score = score; + } + + /** + * Set the temperature of this {@link Soda} instance and return the same instance. + * + * @param temperature The temperature of this {@link Soda} + * Minimum: 0 + * Maximum: 100 (exclusive) + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda temperature( @Nullable final BigDecimal temperature) { + this.temperature = temperature; + return this; + } + + /** + * Get temperature + * minimum: 0 + * maximum: 100 (exclusive) + * @return temperature The temperature of this {@link Soda} instance. + */ + @Nonnull + public BigDecimal getTemperature() { + return temperature; + } + + /** + * Set the temperature of this {@link Soda} instance. + * + * @param temperature The temperature of this {@link Soda} + * Minimum: 0 + * Maximum: 100 (exclusive) + */ + public void setTemperature( @Nullable final BigDecimal temperature) { + this.temperature = temperature; + } + + /** + * Set the combo of this {@link Soda} instance and return the same instance. + * + * @param combo The combo of this {@link Soda} + * Minimum: 3 (exclusive) + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda combo( @Nullable final BigDecimal combo) { + this.combo = combo; + return this; + } + + /** + * Get combo + * minimum: 3 (exclusive) + * @return combo The combo of this {@link Soda} instance. + */ + @Nonnull + public BigDecimal getCombo() { + return combo; + } + + /** + * Set the combo of this {@link Soda} instance. + * + * @param combo The combo of this {@link Soda} + * Minimum: 3 (exclusive) + */ + public void setCombo( @Nullable final BigDecimal combo) { + this.combo = combo; + } + + /** + * Get the names of the unrecognizable properties of the {@link Soda}. + * @return The set of properties names + */ + @JsonIgnore + @Nonnull + public Set getCustomFieldNames() { + return cloudSdkCustomFields.keySet(); + } + + /** + * Get the value of an unrecognizable property of this {@link Soda} instance. + * @deprecated Use {@link #toMap()} instead. + * @param name The name of the property + * @return The value of the property + * @throws NoSuchElementException If no property with the given name could be found. + */ + @Nullable + @Deprecated + public Object getCustomField( @Nonnull final String name ) throws NoSuchElementException { + if( !cloudSdkCustomFields.containsKey(name) ) { + throw new NoSuchElementException("Soda has no field with name '" + name + "'."); + } + return cloudSdkCustomFields.get(name); + } + + /** + * Get the value of all properties of this {@link Soda} instance including unrecognized properties. + * + * @return The map of all properties + */ + @JsonIgnore + @Nonnull + public Map toMap() + { + final Map declaredFields = new LinkedHashMap<>(cloudSdkCustomFields); + if( name != null ) declaredFields.put("name", name); + if( rating != null ) declaredFields.put("rating", rating); + if( score != null ) declaredFields.put("score", score); + if( temperature != null ) declaredFields.put("temperature", temperature); + if( combo != null ) declaredFields.put("combo", combo); + return declaredFields; + } + + /** + * Set an unrecognizable property of this {@link Soda} instance. If the map previously contained a mapping + * for the key, the old value is replaced by the specified value. + * @param customFieldName The name of the property + * @param customFieldValue The value of the property + */ + @JsonIgnore + public void setCustomField( @Nonnull String customFieldName, @Nullable Object customFieldValue ) + { + cloudSdkCustomFields.put(customFieldName, customFieldValue); + } + + + @Override + public boolean equals(@Nullable final java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Soda soda = (Soda) o; + return Objects.equals(this.cloudSdkCustomFields, soda.cloudSdkCustomFields) && + Objects.equals(this.name, soda.name) && + Objects.equals(this.rating, soda.rating) && + Objects.equals(this.score, soda.score) && + Objects.equals(this.temperature, soda.temperature) && + Objects.equals(this.combo, soda.combo); + } + + @Override + public int hashCode() { + return Objects.hash(name, rating, score, temperature, combo, cloudSdkCustomFields); + } + + @Override + @Nonnull public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class Soda {\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" rating: ").append(toIndentedString(rating)).append("\n"); + sb.append(" score: ").append(toIndentedString(score)).append("\n"); + sb.append(" temperature: ").append(toIndentedString(temperature)).append("\n"); + sb.append(" combo: ").append(toIndentedString(combo)).append("\n"); + cloudSdkCustomFields.forEach((k,v) -> sb.append(" ").append(k).append(": ").append(toIndentedString(v)).append("\n")); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(final java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-nullable-ref/input/sodastore.yaml b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-nullable-ref/input/sodastore.yaml new file mode 100644 index 0000000000..19686b15ec --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-nullable-ref/input/sodastore.yaml @@ -0,0 +1,37 @@ +openapi: 3.1.0 +info: + title: OAS 3.1 Nullable $ref via anyOf + version: 1.0.0 + +paths: + /sodas: + get: + operationId: getSodas + responses: + '200': + description: A soda + content: + application/json: + schema: + $ref: '#/components/schemas/Soda' + +components: + schemas: + SodaCategory: + type: object + properties: + name: + type: string + + Soda: + type: object + properties: + name: + type: string + category: + # nullable $ref using anyOf with null type + anyOf: + - $ref: '#/components/schemas/SodaCategory' + - type: "null" + required: + - name diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-nullable-ref/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-nullable-ref/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java new file mode 100644 index 0000000000..030db36445 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-nullable-ref/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.api; + +import com.fasterxml.jackson.core.type.TypeReference; + +import com.sap.cloud.sdk.services.openapi.apache.core.OpenApiRequestException; +import com.sap.cloud.sdk.services.openapi.apache.core.OpenApiResponse; +import com.sap.cloud.sdk.services.openapi.apache.apiclient.ApiClient; +import com.sap.cloud.sdk.services.openapi.apache.apiclient.BaseApi; +import com.sap.cloud.sdk.services.openapi.apache.apiclient.Pair; + + +import com.sap.cloud.sdk.datamodel.rest.test.model.Soda; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.StringJoiner; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.sap.cloud.sdk.cloudplatform.connectivity.Destination; + + +/** + * OAS 3.1 Nullable $ref via anyOf in version 1.0.0. + *

+ * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + */ +public class DefaultApi extends BaseApi { + + /** + * Instantiates this API class to invoke operations on the OAS 3.1 Nullable $ref via anyOf. + * + * @param httpDestination The destination that API should be used with + */ + public DefaultApi( @Nonnull final Destination httpDestination ) + { + super(httpDestination); + } + + /** + * Instantiates this API class to invoke operations on the OAS 3.1 Nullable $ref via anyOf based on a given {@link ApiClient}. + * + * @param apiClient + * ApiClient to invoke the API on + */ + public DefaultApi(@Nonnull final ApiClient apiClient) { + super(apiClient); + } + + /** + * Creates a new API instance with additional default headers. + * + * @param defaultHeaders Additional headers to include in all requests + * @return A new API instance with the combined headers + */ + public DefaultApi withDefaultHeaders(@Nonnull final Map defaultHeaders) { + final var api = new DefaultApi(apiClient); + api.defaultHeaders.putAll(this.defaultHeaders); + api.defaultHeaders.putAll(defaultHeaders); + return api; + } + + + /** + *

+ *

+ *

200 - A soda + * @return Soda + * @throws OpenApiRequestException if an error occurs while attempting to invoke the API + */ + @Nonnull + public Soda getSodas() throws OpenApiRequestException { + + // create path and map variables + final String localVarPath = "/sodas"; + + final StringJoiner localVarQueryStringJoiner = new StringJoiner("&"); + final List localVarQueryParams = new ArrayList(); + final List localVarCollectionQueryParams = new ArrayList(); + final Map localVarHeaderParams = new HashMap(defaultHeaders); + final Map localVarFormParams = new HashMap(); + + + final String[] localVarAccepts = { + "application/json" + }; + final String localVarAccept = ApiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { + + }; + final String localVarContentType = ApiClient.selectHeaderContentType(localVarContentTypes); + + final TypeReference localVarReturnType = new TypeReference() {}; + + return apiClient.invokeAPI( + localVarPath, + "GET", + localVarQueryParams, + localVarCollectionQueryParams, + localVarQueryStringJoiner.toString(), + null, + localVarHeaderParams, + localVarFormParams, + localVarAccept, + localVarContentType, + localVarReturnType + ); + } + } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-nullable-ref/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-nullable-ref/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java new file mode 100644 index 0000000000..7468af81f2 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-nullable-ref/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +/* + * OAS 3.1 Nullable $ref via anyOf + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.model; + +import java.util.Objects; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sap.cloud.sdk.datamodel.rest.test.model.SodaCategory; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * Soda + */ +// CHECKSTYLE:OFF +public class Soda +// CHECKSTYLE:ON +{ + @JsonProperty("name") + private String name; + + @JsonProperty("category") + private SodaCategory category; + + @JsonAnySetter + @JsonAnyGetter + private final Map cloudSdkCustomFields = new LinkedHashMap<>(); + + /** + * Set the name of this {@link Soda} instance and return the same instance. + * + * @param name The name of this {@link Soda} + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda name( @Nonnull final String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name The name of this {@link Soda} instance. + */ + @Nonnull + public String getName() { + return name; + } + + /** + * Set the name of this {@link Soda} instance. + * + * @param name The name of this {@link Soda} + */ + public void setName( @Nonnull final String name) { + this.name = name; + } + + /** + * Set the category of this {@link Soda} instance and return the same instance. + * + * @param category The category of this {@link Soda} + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda category( @Nullable final SodaCategory category) { + this.category = category; + return this; + } + + /** + * Get category + * @return category The category of this {@link Soda} instance. + */ + @Nullable + public SodaCategory getCategory() { + return category; + } + + /** + * Set the category of this {@link Soda} instance. + * + * @param category The category of this {@link Soda} + */ + public void setCategory( @Nullable final SodaCategory category) { + this.category = category; + } + + /** + * Get the names of the unrecognizable properties of the {@link Soda}. + * @return The set of properties names + */ + @JsonIgnore + @Nonnull + public Set getCustomFieldNames() { + return cloudSdkCustomFields.keySet(); + } + + /** + * Get the value of an unrecognizable property of this {@link Soda} instance. + * @deprecated Use {@link #toMap()} instead. + * @param name The name of the property + * @return The value of the property + * @throws NoSuchElementException If no property with the given name could be found. + */ + @Nullable + @Deprecated + public Object getCustomField( @Nonnull final String name ) throws NoSuchElementException { + if( !cloudSdkCustomFields.containsKey(name) ) { + throw new NoSuchElementException("Soda has no field with name '" + name + "'."); + } + return cloudSdkCustomFields.get(name); + } + + /** + * Get the value of all properties of this {@link Soda} instance including unrecognized properties. + * + * @return The map of all properties + */ + @JsonIgnore + @Nonnull + public Map toMap() + { + final Map declaredFields = new LinkedHashMap<>(cloudSdkCustomFields); + if( name != null ) declaredFields.put("name", name); + if( category != null ) declaredFields.put("category", category); + return declaredFields; + } + + /** + * Set an unrecognizable property of this {@link Soda} instance. If the map previously contained a mapping + * for the key, the old value is replaced by the specified value. + * @param customFieldName The name of the property + * @param customFieldValue The value of the property + */ + @JsonIgnore + public void setCustomField( @Nonnull String customFieldName, @Nullable Object customFieldValue ) + { + cloudSdkCustomFields.put(customFieldName, customFieldValue); + } + + + @Override + public boolean equals(@Nullable final java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Soda soda = (Soda) o; + return Objects.equals(this.cloudSdkCustomFields, soda.cloudSdkCustomFields) && + Objects.equals(this.name, soda.name) && + Objects.equals(this.category, soda.category); + } + + @Override + public int hashCode() { + return Objects.hash(name, category, cloudSdkCustomFields); + } + + @Override + @Nonnull public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class Soda {\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" category: ").append(toIndentedString(category)).append("\n"); + cloudSdkCustomFields.forEach((k,v) -> sb.append(" ").append(k).append(": ").append(toIndentedString(v)).append("\n")); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(final java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-nullable-ref/output/com/sap/cloud/sdk/datamodel/rest/test/model/SodaCategory.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-nullable-ref/output/com/sap/cloud/sdk/datamodel/rest/test/model/SodaCategory.java new file mode 100644 index 0000000000..90e9cc5959 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-nullable-ref/output/com/sap/cloud/sdk/datamodel/rest/test/model/SodaCategory.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +/* + * OAS 3.1 Nullable $ref via anyOf + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.model; + +import java.util.Objects; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * SodaCategory + */ +// CHECKSTYLE:OFF +public class SodaCategory +// CHECKSTYLE:ON +{ + @JsonProperty("name") + private String name; + + @JsonAnySetter + @JsonAnyGetter + private final Map cloudSdkCustomFields = new LinkedHashMap<>(); + + /** + * Set the name of this {@link SodaCategory} instance and return the same instance. + * + * @param name The name of this {@link SodaCategory} + * @return The same instance of this {@link SodaCategory} class + */ + @Nonnull public SodaCategory name( @Nullable final String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name The name of this {@link SodaCategory} instance. + */ + @Nonnull + public String getName() { + return name; + } + + /** + * Set the name of this {@link SodaCategory} instance. + * + * @param name The name of this {@link SodaCategory} + */ + public void setName( @Nullable final String name) { + this.name = name; + } + + /** + * Get the names of the unrecognizable properties of the {@link SodaCategory}. + * @return The set of properties names + */ + @JsonIgnore + @Nonnull + public Set getCustomFieldNames() { + return cloudSdkCustomFields.keySet(); + } + + /** + * Get the value of an unrecognizable property of this {@link SodaCategory} instance. + * @deprecated Use {@link #toMap()} instead. + * @param name The name of the property + * @return The value of the property + * @throws NoSuchElementException If no property with the given name could be found. + */ + @Nullable + @Deprecated + public Object getCustomField( @Nonnull final String name ) throws NoSuchElementException { + if( !cloudSdkCustomFields.containsKey(name) ) { + throw new NoSuchElementException("SodaCategory has no field with name '" + name + "'."); + } + return cloudSdkCustomFields.get(name); + } + + /** + * Get the value of all properties of this {@link SodaCategory} instance including unrecognized properties. + * + * @return The map of all properties + */ + @JsonIgnore + @Nonnull + public Map toMap() + { + final Map declaredFields = new LinkedHashMap<>(cloudSdkCustomFields); + if( name != null ) declaredFields.put("name", name); + return declaredFields; + } + + /** + * Set an unrecognizable property of this {@link SodaCategory} instance. If the map previously contained a mapping + * for the key, the old value is replaced by the specified value. + * @param customFieldName The name of the property + * @param customFieldValue The value of the property + */ + @JsonIgnore + public void setCustomField( @Nonnull String customFieldName, @Nullable Object customFieldValue ) + { + cloudSdkCustomFields.put(customFieldName, customFieldValue); + } + + + @Override + public boolean equals(@Nullable final java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final SodaCategory sodaCategory = (SodaCategory) o; + return Objects.equals(this.cloudSdkCustomFields, sodaCategory.cloudSdkCustomFields) && + Objects.equals(this.name, sodaCategory.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, cloudSdkCustomFields); + } + + @Override + @Nonnull public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class SodaCategory {\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + cloudSdkCustomFields.forEach((k,v) -> sb.append(" ").append(k).append(": ").append(toIndentedString(v)).append("\n")); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(final java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-nullable-type-array/input/sodastore.yaml b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-nullable-type-array/input/sodastore.yaml new file mode 100644 index 0000000000..c31da5b707 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-nullable-type-array/input/sodastore.yaml @@ -0,0 +1,31 @@ +openapi: 3.1.0 +info: + title: OAS 3.1 Nullable Type Array + version: 1.0.0 + +paths: + /sodas: + get: + operationId: getSodas + responses: + '200': + description: A soda + content: + application/json: + schema: + $ref: '#/components/schemas/Soda' + +components: + schemas: + Soda: + type: object + properties: + name: + type: string + brand: + # nullable via type array instead of nullable: true + type: + - string + - "null" + required: + - name diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-nullable-type-array/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-nullable-type-array/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java new file mode 100644 index 0000000000..7c74b39ef6 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-nullable-type-array/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.api; + +import com.fasterxml.jackson.core.type.TypeReference; + +import com.sap.cloud.sdk.services.openapi.apache.core.OpenApiRequestException; +import com.sap.cloud.sdk.services.openapi.apache.core.OpenApiResponse; +import com.sap.cloud.sdk.services.openapi.apache.apiclient.ApiClient; +import com.sap.cloud.sdk.services.openapi.apache.apiclient.BaseApi; +import com.sap.cloud.sdk.services.openapi.apache.apiclient.Pair; + + +import com.sap.cloud.sdk.datamodel.rest.test.model.Soda; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.StringJoiner; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.sap.cloud.sdk.cloudplatform.connectivity.Destination; + + +/** + * OAS 3.1 Nullable Type Array in version 1.0.0. + *

+ * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + */ +public class DefaultApi extends BaseApi { + + /** + * Instantiates this API class to invoke operations on the OAS 3.1 Nullable Type Array. + * + * @param httpDestination The destination that API should be used with + */ + public DefaultApi( @Nonnull final Destination httpDestination ) + { + super(httpDestination); + } + + /** + * Instantiates this API class to invoke operations on the OAS 3.1 Nullable Type Array based on a given {@link ApiClient}. + * + * @param apiClient + * ApiClient to invoke the API on + */ + public DefaultApi(@Nonnull final ApiClient apiClient) { + super(apiClient); + } + + /** + * Creates a new API instance with additional default headers. + * + * @param defaultHeaders Additional headers to include in all requests + * @return A new API instance with the combined headers + */ + public DefaultApi withDefaultHeaders(@Nonnull final Map defaultHeaders) { + final var api = new DefaultApi(apiClient); + api.defaultHeaders.putAll(this.defaultHeaders); + api.defaultHeaders.putAll(defaultHeaders); + return api; + } + + + /** + *

+ *

+ *

200 - A soda + * @return Soda + * @throws OpenApiRequestException if an error occurs while attempting to invoke the API + */ + @Nonnull + public Soda getSodas() throws OpenApiRequestException { + + // create path and map variables + final String localVarPath = "/sodas"; + + final StringJoiner localVarQueryStringJoiner = new StringJoiner("&"); + final List localVarQueryParams = new ArrayList(); + final List localVarCollectionQueryParams = new ArrayList(); + final Map localVarHeaderParams = new HashMap(defaultHeaders); + final Map localVarFormParams = new HashMap(); + + + final String[] localVarAccepts = { + "application/json" + }; + final String localVarAccept = ApiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { + + }; + final String localVarContentType = ApiClient.selectHeaderContentType(localVarContentTypes); + + final TypeReference localVarReturnType = new TypeReference() {}; + + return apiClient.invokeAPI( + localVarPath, + "GET", + localVarQueryParams, + localVarCollectionQueryParams, + localVarQueryStringJoiner.toString(), + null, + localVarHeaderParams, + localVarFormParams, + localVarAccept, + localVarContentType, + localVarReturnType + ); + } + } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-nullable-type-array/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-nullable-type-array/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java new file mode 100644 index 0000000000..5b36050103 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-nullable-type-array/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +/* + * OAS 3.1 Nullable Type Array + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.model; + +import java.util.Objects; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * Soda + */ +// CHECKSTYLE:OFF +public class Soda +// CHECKSTYLE:ON +{ + @JsonProperty("name") + private String name; + + @JsonProperty("brand") + private String brand; + + @JsonAnySetter + @JsonAnyGetter + private final Map cloudSdkCustomFields = new LinkedHashMap<>(); + + /** + * Set the name of this {@link Soda} instance and return the same instance. + * + * @param name The name of this {@link Soda} + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda name( @Nonnull final String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name The name of this {@link Soda} instance. + */ + @Nonnull + public String getName() { + return name; + } + + /** + * Set the name of this {@link Soda} instance. + * + * @param name The name of this {@link Soda} + */ + public void setName( @Nonnull final String name) { + this.name = name; + } + + /** + * Set the brand of this {@link Soda} instance and return the same instance. + * + * @param brand The brand of this {@link Soda} + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda brand( @Nullable final String brand) { + this.brand = brand; + return this; + } + + /** + * Get brand + * @return brand The brand of this {@link Soda} instance. + */ + @Nullable + public String getBrand() { + return brand; + } + + /** + * Set the brand of this {@link Soda} instance. + * + * @param brand The brand of this {@link Soda} + */ + public void setBrand( @Nullable final String brand) { + this.brand = brand; + } + + /** + * Get the names of the unrecognizable properties of the {@link Soda}. + * @return The set of properties names + */ + @JsonIgnore + @Nonnull + public Set getCustomFieldNames() { + return cloudSdkCustomFields.keySet(); + } + + /** + * Get the value of an unrecognizable property of this {@link Soda} instance. + * @deprecated Use {@link #toMap()} instead. + * @param name The name of the property + * @return The value of the property + * @throws NoSuchElementException If no property with the given name could be found. + */ + @Nullable + @Deprecated + public Object getCustomField( @Nonnull final String name ) throws NoSuchElementException { + if( !cloudSdkCustomFields.containsKey(name) ) { + throw new NoSuchElementException("Soda has no field with name '" + name + "'."); + } + return cloudSdkCustomFields.get(name); + } + + /** + * Get the value of all properties of this {@link Soda} instance including unrecognized properties. + * + * @return The map of all properties + */ + @JsonIgnore + @Nonnull + public Map toMap() + { + final Map declaredFields = new LinkedHashMap<>(cloudSdkCustomFields); + if( name != null ) declaredFields.put("name", name); + if( brand != null ) declaredFields.put("brand", brand); + return declaredFields; + } + + /** + * Set an unrecognizable property of this {@link Soda} instance. If the map previously contained a mapping + * for the key, the old value is replaced by the specified value. + * @param customFieldName The name of the property + * @param customFieldValue The value of the property + */ + @JsonIgnore + public void setCustomField( @Nonnull String customFieldName, @Nullable Object customFieldValue ) + { + cloudSdkCustomFields.put(customFieldName, customFieldValue); + } + + + @Override + public boolean equals(@Nullable final java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Soda soda = (Soda) o; + return Objects.equals(this.cloudSdkCustomFields, soda.cloudSdkCustomFields) && + Objects.equals(this.name, soda.name) && + Objects.equals(this.brand, soda.brand); + } + + @Override + public int hashCode() { + return Objects.hash(name, brand, cloudSdkCustomFields); + } + + @Override + @Nonnull public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class Soda {\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" brand: ").append(toIndentedString(brand)).append("\n"); + cloudSdkCustomFields.forEach((k,v) -> sb.append(" ").append(k).append(": ").append(toIndentedString(v)).append("\n")); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(final java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-ref-with-sibling/input/sodastore.yaml b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-ref-with-sibling/input/sodastore.yaml new file mode 100644 index 0000000000..081c006624 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-ref-with-sibling/input/sodastore.yaml @@ -0,0 +1,34 @@ +openapi: 3.1.0 +info: + title: OAS 3.1 $ref with Sibling Properties + version: 1.0.0 + +paths: + /sodas: + get: + operationId: getSodas + responses: + '200': + description: A soda + content: + application/json: + schema: + $ref: '#/components/schemas/Soda' + +components: + schemas: + SodaDescription: + type: string + description: Soda description + + Soda: + type: object + properties: + name: + type: string + description: + # $ref with a sibling property — valid in OAS 3.1 + $ref: '#/components/schemas/SodaDescription' + description: Soda description as part of the Soda object + required: + - name diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-ref-with-sibling/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-ref-with-sibling/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java new file mode 100644 index 0000000000..fdf9fb8654 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-ref-with-sibling/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.api; + +import com.fasterxml.jackson.core.type.TypeReference; + +import com.sap.cloud.sdk.services.openapi.apache.core.OpenApiRequestException; +import com.sap.cloud.sdk.services.openapi.apache.core.OpenApiResponse; +import com.sap.cloud.sdk.services.openapi.apache.apiclient.ApiClient; +import com.sap.cloud.sdk.services.openapi.apache.apiclient.BaseApi; +import com.sap.cloud.sdk.services.openapi.apache.apiclient.Pair; + + +import com.sap.cloud.sdk.datamodel.rest.test.model.Soda; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.StringJoiner; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.sap.cloud.sdk.cloudplatform.connectivity.Destination; + + +/** + * OAS 3.1 $ref with Sibling Properties in version 1.0.0. + *

+ * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + */ +public class DefaultApi extends BaseApi { + + /** + * Instantiates this API class to invoke operations on the OAS 3.1 $ref with Sibling Properties. + * + * @param httpDestination The destination that API should be used with + */ + public DefaultApi( @Nonnull final Destination httpDestination ) + { + super(httpDestination); + } + + /** + * Instantiates this API class to invoke operations on the OAS 3.1 $ref with Sibling Properties based on a given {@link ApiClient}. + * + * @param apiClient + * ApiClient to invoke the API on + */ + public DefaultApi(@Nonnull final ApiClient apiClient) { + super(apiClient); + } + + /** + * Creates a new API instance with additional default headers. + * + * @param defaultHeaders Additional headers to include in all requests + * @return A new API instance with the combined headers + */ + public DefaultApi withDefaultHeaders(@Nonnull final Map defaultHeaders) { + final var api = new DefaultApi(apiClient); + api.defaultHeaders.putAll(this.defaultHeaders); + api.defaultHeaders.putAll(defaultHeaders); + return api; + } + + + /** + *

+ *

+ *

200 - A soda + * @return Soda + * @throws OpenApiRequestException if an error occurs while attempting to invoke the API + */ + @Nonnull + public Soda getSodas() throws OpenApiRequestException { + + // create path and map variables + final String localVarPath = "/sodas"; + + final StringJoiner localVarQueryStringJoiner = new StringJoiner("&"); + final List localVarQueryParams = new ArrayList(); + final List localVarCollectionQueryParams = new ArrayList(); + final Map localVarHeaderParams = new HashMap(defaultHeaders); + final Map localVarFormParams = new HashMap(); + + + final String[] localVarAccepts = { + "application/json" + }; + final String localVarAccept = ApiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { + + }; + final String localVarContentType = ApiClient.selectHeaderContentType(localVarContentTypes); + + final TypeReference localVarReturnType = new TypeReference() {}; + + return apiClient.invokeAPI( + localVarPath, + "GET", + localVarQueryParams, + localVarCollectionQueryParams, + localVarQueryStringJoiner.toString(), + null, + localVarHeaderParams, + localVarFormParams, + localVarAccept, + localVarContentType, + localVarReturnType + ); + } + } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-ref-with-sibling/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-ref-with-sibling/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java new file mode 100644 index 0000000000..d88df9c21b --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorApacheIntegrationTest/oas31-ref-with-sibling/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +/* + * OAS 3.1 $ref with Sibling Properties + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.model; + +import java.util.Objects; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * Soda + */ +// CHECKSTYLE:OFF +public class Soda +// CHECKSTYLE:ON +{ + @JsonProperty("name") + private String name; + + @JsonProperty("description") + private String description; + + @JsonAnySetter + @JsonAnyGetter + private final Map cloudSdkCustomFields = new LinkedHashMap<>(); + + /** + * Set the name of this {@link Soda} instance and return the same instance. + * + * @param name The name of this {@link Soda} + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda name( @Nonnull final String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name The name of this {@link Soda} instance. + */ + @Nonnull + public String getName() { + return name; + } + + /** + * Set the name of this {@link Soda} instance. + * + * @param name The name of this {@link Soda} + */ + public void setName( @Nonnull final String name) { + this.name = name; + } + + /** + * Set the description of this {@link Soda} instance and return the same instance. + * + * @param description The description of this {@link Soda} + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda description( @Nullable final String description) { + this.description = description; + return this; + } + + /** + * Get description + * @return description The description of this {@link Soda} instance. + */ + @Nonnull + public String getDescription() { + return description; + } + + /** + * Set the description of this {@link Soda} instance. + * + * @param description The description of this {@link Soda} + */ + public void setDescription( @Nullable final String description) { + this.description = description; + } + + /** + * Get the names of the unrecognizable properties of the {@link Soda}. + * @return The set of properties names + */ + @JsonIgnore + @Nonnull + public Set getCustomFieldNames() { + return cloudSdkCustomFields.keySet(); + } + + /** + * Get the value of an unrecognizable property of this {@link Soda} instance. + * @deprecated Use {@link #toMap()} instead. + * @param name The name of the property + * @return The value of the property + * @throws NoSuchElementException If no property with the given name could be found. + */ + @Nullable + @Deprecated + public Object getCustomField( @Nonnull final String name ) throws NoSuchElementException { + if( !cloudSdkCustomFields.containsKey(name) ) { + throw new NoSuchElementException("Soda has no field with name '" + name + "'."); + } + return cloudSdkCustomFields.get(name); + } + + /** + * Get the value of all properties of this {@link Soda} instance including unrecognized properties. + * + * @return The map of all properties + */ + @JsonIgnore + @Nonnull + public Map toMap() + { + final Map declaredFields = new LinkedHashMap<>(cloudSdkCustomFields); + if( name != null ) declaredFields.put("name", name); + if( description != null ) declaredFields.put("description", description); + return declaredFields; + } + + /** + * Set an unrecognizable property of this {@link Soda} instance. If the map previously contained a mapping + * for the key, the old value is replaced by the specified value. + * @param customFieldName The name of the property + * @param customFieldValue The value of the property + */ + @JsonIgnore + public void setCustomField( @Nonnull String customFieldName, @Nullable Object customFieldValue ) + { + cloudSdkCustomFields.put(customFieldName, customFieldValue); + } + + + @Override + public boolean equals(@Nullable final java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Soda soda = (Soda) o; + return Objects.equals(this.cloudSdkCustomFields, soda.cloudSdkCustomFields) && + Objects.equals(this.name, soda.name) && + Objects.equals(this.description, soda.description); + } + + @Override + public int hashCode() { + return Objects.hash(name, description, cloudSdkCustomFields); + } + + @Override + @Nonnull public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class Soda {\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" description: ").append(toIndentedString(description)).append("\n"); + cloudSdkCustomFields.forEach((k,v) -> sb.append(" ").append(k).append(": ").append(toIndentedString(v)).append("\n")); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(final java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-for-ai-sdk/output/com/sap/cloud/sdk/services/builder/model/NewSoda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-for-ai-sdk/output/com/sap/cloud/sdk/services/builder/model/NewSoda.java index 20ce285d8a..9ca1d90b0d 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-for-ai-sdk/output/com/sap/cloud/sdk/services/builder/model/NewSoda.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-for-ai-sdk/output/com/sap/cloud/sdk/services/builder/model/NewSoda.java @@ -137,7 +137,7 @@ public void setBrand( @Nonnull final String brand) { * Get zero * @return zero The zero of this {@link NewSoda} instance. */ - @Nonnull + @Nullable public Boolean isZero() { return zero; } @@ -166,7 +166,7 @@ public void setZero( @Nullable final Boolean zero) { * Get since * @return since The since of this {@link NewSoda} instance. */ - @Nonnull + @Nullable public LocalDate getSince() { return since; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-for-ai-sdk/output/com/sap/cloud/sdk/services/builder/model/Soda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-for-ai-sdk/output/com/sap/cloud/sdk/services/builder/model/Soda.java index b0cab12da7..9b0c569565 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-for-ai-sdk/output/com/sap/cloud/sdk/services/builder/model/Soda.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-for-ai-sdk/output/com/sap/cloud/sdk/services/builder/model/Soda.java @@ -147,7 +147,7 @@ public enum DietEnum { * Get id * @return id The id of this {@link Soda} instance. */ - @Nonnull + @Nullable public Long getId() { return id; } @@ -234,7 +234,7 @@ public void setBrand( @Nonnull final String brand) { * Get isAvailable * @return isAvailable The isAvailable of this {@link Soda} instance. */ - @Nonnull + @Nullable public Boolean isAvailable() { return isAvailable; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-for-ai-sdk/output/com/sap/cloud/sdk/services/builder/model/UpdateSoda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-for-ai-sdk/output/com/sap/cloud/sdk/services/builder/model/UpdateSoda.java index 85f725e6ac..ee31eee5c3 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-for-ai-sdk/output/com/sap/cloud/sdk/services/builder/model/UpdateSoda.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-for-ai-sdk/output/com/sap/cloud/sdk/services/builder/model/UpdateSoda.java @@ -79,7 +79,7 @@ public class UpdateSoda * Get name * @return name The name of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public String getName() { return name; } @@ -108,7 +108,7 @@ public void setName( @Nullable final String name) { * Get zero * @return zero The zero of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public Boolean isZero() { return zero; } @@ -137,7 +137,7 @@ public void setZero( @Nullable final Boolean zero) { * Get since * @return since The since of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public LocalDate getSince() { return since; } @@ -166,7 +166,7 @@ public void setSince( @Nullable final LocalDate since) { * Get brand * @return brand The brand of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public String getBrand() { return brand; } @@ -195,7 +195,7 @@ public void setBrand( @Nullable final String brand) { * Get flavor * @return flavor The flavor of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public String getFlavor() { return flavor; } @@ -224,7 +224,7 @@ public void setFlavor( @Nullable final String flavor) { * Get price * @return price The price of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public Float getPrice() { return price; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-vendor-extension-json/output/com/sap/cloud/sdk/services/apiclassvendorextension/model/NewSoda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-vendor-extension-json/output/com/sap/cloud/sdk/services/apiclassvendorextension/model/NewSoda.java index 6bbd8468d5..3741a02993 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-vendor-extension-json/output/com/sap/cloud/sdk/services/apiclassvendorextension/model/NewSoda.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-vendor-extension-json/output/com/sap/cloud/sdk/services/apiclassvendorextension/model/NewSoda.java @@ -137,7 +137,7 @@ public void setBrand( @Nonnull final String brand) { * Get zero * @return zero The zero of this {@link NewSoda} instance. */ - @Nonnull + @Nullable public Boolean isZero() { return zero; } @@ -166,7 +166,7 @@ public void setZero( @Nullable final Boolean zero) { * Get since * @return since The since of this {@link NewSoda} instance. */ - @Nonnull + @Nullable public LocalDate getSince() { return since; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-vendor-extension-json/output/com/sap/cloud/sdk/services/apiclassvendorextension/model/Soda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-vendor-extension-json/output/com/sap/cloud/sdk/services/apiclassvendorextension/model/Soda.java index b0159f9aa3..3a972cbd9a 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-vendor-extension-json/output/com/sap/cloud/sdk/services/apiclassvendorextension/model/Soda.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-vendor-extension-json/output/com/sap/cloud/sdk/services/apiclassvendorextension/model/Soda.java @@ -75,7 +75,7 @@ public class Soda * Get id * @return id The id of this {@link Soda} instance. */ - @Nonnull + @Nullable public Long getId() { return id; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-vendor-extension-json/output/com/sap/cloud/sdk/services/apiclassvendorextension/model/UpdateSoda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-vendor-extension-json/output/com/sap/cloud/sdk/services/apiclassvendorextension/model/UpdateSoda.java index 65139c68cf..71fed98e84 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-vendor-extension-json/output/com/sap/cloud/sdk/services/apiclassvendorextension/model/UpdateSoda.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-vendor-extension-json/output/com/sap/cloud/sdk/services/apiclassvendorextension/model/UpdateSoda.java @@ -79,7 +79,7 @@ public class UpdateSoda * Get name * @return name The name of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public String getName() { return name; } @@ -108,7 +108,7 @@ public void setName( @Nullable final String name) { * Get zero * @return zero The zero of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public Boolean isZero() { return zero; } @@ -137,7 +137,7 @@ public void setZero( @Nullable final Boolean zero) { * Get since * @return since The since of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public LocalDate getSince() { return since; } @@ -166,7 +166,7 @@ public void setSince( @Nullable final LocalDate since) { * Get brand * @return brand The brand of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public String getBrand() { return brand; } @@ -195,7 +195,7 @@ public void setBrand( @Nullable final String brand) { * Get flavor * @return flavor The flavor of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public String getFlavor() { return flavor; } @@ -224,7 +224,7 @@ public void setFlavor( @Nullable final String flavor) { * Get price * @return price The price of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public Float getPrice() { return price; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-vendor-extension-yaml/output/com/sap/cloud/sdk/services/apiclassvendorextension/model/Soda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-vendor-extension-yaml/output/com/sap/cloud/sdk/services/apiclassvendorextension/model/Soda.java index b0159f9aa3..3a972cbd9a 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-vendor-extension-yaml/output/com/sap/cloud/sdk/services/apiclassvendorextension/model/Soda.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-vendor-extension-yaml/output/com/sap/cloud/sdk/services/apiclassvendorextension/model/Soda.java @@ -75,7 +75,7 @@ public class Soda * Get id * @return id The id of this {@link Soda} instance. */ - @Nonnull + @Nullable public Long getId() { return id; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-vendor-extension-yaml/output/com/sap/cloud/sdk/services/apiclassvendorextension/model/UpdateSoda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-vendor-extension-yaml/output/com/sap/cloud/sdk/services/apiclassvendorextension/model/UpdateSoda.java index 84b275fbbc..af5a3bb907 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-vendor-extension-yaml/output/com/sap/cloud/sdk/services/apiclassvendorextension/model/UpdateSoda.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-vendor-extension-yaml/output/com/sap/cloud/sdk/services/apiclassvendorextension/model/UpdateSoda.java @@ -72,7 +72,7 @@ public class UpdateSoda * Get name * @return name The name of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public String getName() { return name; } @@ -101,7 +101,7 @@ public void setName( @Nullable final String name) { * Get brand * @return brand The brand of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public String getBrand() { return brand; } @@ -130,7 +130,7 @@ public void setBrand( @Nullable final String brand) { * Get flavor * @return flavor The flavor of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public String getFlavor() { return flavor; } @@ -159,7 +159,7 @@ public void setFlavor( @Nullable final String flavor) { * Get price * @return price The price of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public Float getPrice() { return price; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/AllOf.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/AllOf.java index 9dfaf3ea30..acb1c546e2 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/AllOf.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/AllOf.java @@ -63,7 +63,7 @@ public class AllOf * Get sodaType * @return sodaType The sodaType of this {@link AllOf} instance. */ - @Nonnull + @Nullable public String getSodaType() { return sodaType; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/AnyOf.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/AnyOf.java index 59f1e77c07..caa2a6634d 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/AnyOf.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/AnyOf.java @@ -65,7 +65,7 @@ public class AnyOf * Get sodaType * @return sodaType The sodaType of this {@link AnyOf} instance. */ - @Nonnull + @Nullable public String getSodaType() { return sodaType; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/Cola.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/Cola.java index 523e3146a8..9bb0649a9e 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/Cola.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/Cola.java @@ -63,7 +63,7 @@ public class Cola * Get sodaType * @return sodaType The sodaType of this {@link Cola} instance. */ - @Nonnull + @Nullable public String getSodaType() { return sodaType; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/Fanta.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/Fanta.java index 349aeaae22..d017ff606b 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/Fanta.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/Fanta.java @@ -63,7 +63,7 @@ public class Fanta * Get sodaType * @return sodaType The sodaType of this {@link Fanta} instance. */ - @Nonnull + @Nullable public String getSodaType() { return sodaType; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/OneOf.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/OneOf.java index e41a7b7929..2d7585849f 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/OneOf.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/OneOf.java @@ -65,7 +65,7 @@ public class OneOf * Get sodaType * @return sodaType The sodaType of this {@link OneOf} instance. */ - @Nonnull + @Nullable public String getSodaType() { return sodaType; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/OneOfWithDiscriminator.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/OneOfWithDiscriminator.java index 5e2f1fc1cb..38866718d0 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/OneOfWithDiscriminator.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/OneOfWithDiscriminator.java @@ -73,7 +73,7 @@ public class OneOfWithDiscriminator * Get sodaType * @return sodaType The sodaType of this {@link OneOfWithDiscriminator} instance. */ - @Nonnull + @Nullable public String getSodaType() { return sodaType; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/OneOfWithDiscriminatorAndMapping.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/OneOfWithDiscriminatorAndMapping.java index 0fab43fec8..0003a28685 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/OneOfWithDiscriminatorAndMapping.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/generate-apis/output/test/OneOfWithDiscriminatorAndMapping.java @@ -73,7 +73,7 @@ public class OneOfWithDiscriminatorAndMapping * Get sodaType * @return sodaType The sodaType of this {@link OneOfWithDiscriminatorAndMapping} instance. */ - @Nonnull + @Nullable public String getSodaType() { return sodaType; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/inlineobject-schemas-enabled/output/com/sap/cloud/sdk/services/inlineobject/model/NotFound.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/inlineobject-schemas-enabled/output/com/sap/cloud/sdk/services/inlineobject/model/NotFound.java index d0893c9d66..e0f7e8920d 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/inlineobject-schemas-enabled/output/com/sap/cloud/sdk/services/inlineobject/model/NotFound.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/inlineobject-schemas-enabled/output/com/sap/cloud/sdk/services/inlineobject/model/NotFound.java @@ -63,7 +63,7 @@ public class NotFound * Get message * @return message The message of this {@link NotFound} instance. */ - @Nonnull + @Nullable public String getMessage() { return message; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/inlineobject-schemas-enabled/output/com/sap/cloud/sdk/services/inlineobject/model/ServiceUnavailableApplicationJson.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/inlineobject-schemas-enabled/output/com/sap/cloud/sdk/services/inlineobject/model/ServiceUnavailableApplicationJson.java index 2945b681ef..ebef35a00f 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/inlineobject-schemas-enabled/output/com/sap/cloud/sdk/services/inlineobject/model/ServiceUnavailableApplicationJson.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/inlineobject-schemas-enabled/output/com/sap/cloud/sdk/services/inlineobject/model/ServiceUnavailableApplicationJson.java @@ -63,7 +63,7 @@ public class ServiceUnavailableApplicationJson * Get message * @return message The message of this {@link ServiceUnavailableApplicationJson} instance. */ - @Nonnull + @Nullable public String getMessage() { return message; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/inlineobject-schemas-enabled/output/com/sap/cloud/sdk/services/inlineobject/model/ServiceUnavailableApplicationXml.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/inlineobject-schemas-enabled/output/com/sap/cloud/sdk/services/inlineobject/model/ServiceUnavailableApplicationXml.java index 7afdf67a4e..668d65cefd 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/inlineobject-schemas-enabled/output/com/sap/cloud/sdk/services/inlineobject/model/ServiceUnavailableApplicationXml.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/inlineobject-schemas-enabled/output/com/sap/cloud/sdk/services/inlineobject/model/ServiceUnavailableApplicationXml.java @@ -63,7 +63,7 @@ public class ServiceUnavailableApplicationXml * Get message * @return message The message of this {@link ServiceUnavailableApplicationXml} instance. */ - @Nonnull + @Nullable public String getMessage() { return message; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/inlineobject-schemas-enabled/output/com/sap/cloud/sdk/services/inlineobject/model/Soda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/inlineobject-schemas-enabled/output/com/sap/cloud/sdk/services/inlineobject/model/Soda.java index 542eb09b31..b02b6d497e 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/inlineobject-schemas-enabled/output/com/sap/cloud/sdk/services/inlineobject/model/Soda.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/inlineobject-schemas-enabled/output/com/sap/cloud/sdk/services/inlineobject/model/Soda.java @@ -75,7 +75,7 @@ public class Soda * Get id * @return id The id of this {@link Soda} instance. */ - @Nonnull + @Nullable public Long getId() { return id; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/input-spec-with-builder/output/com/sap/cloud/sdk/services/builder/model/Soda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/input-spec-with-builder/output/com/sap/cloud/sdk/services/builder/model/Soda.java index c9f6976f59..70d3713193 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/input-spec-with-builder/output/com/sap/cloud/sdk/services/builder/model/Soda.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/input-spec-with-builder/output/com/sap/cloud/sdk/services/builder/model/Soda.java @@ -82,7 +82,7 @@ private Soda() { } * Get id * @return id The id of this {@link Soda} instance. */ - @Nonnull + @Nullable public Long getId() { return id; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/input-spec-with-builder/output/com/sap/cloud/sdk/services/builder/model/UpdateSoda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/input-spec-with-builder/output/com/sap/cloud/sdk/services/builder/model/UpdateSoda.java index 2dcad088ed..8bc477f584 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/input-spec-with-builder/output/com/sap/cloud/sdk/services/builder/model/UpdateSoda.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/input-spec-with-builder/output/com/sap/cloud/sdk/services/builder/model/UpdateSoda.java @@ -76,7 +76,7 @@ private UpdateSoda() { } * Get name * @return name The name of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public String getName() { return name; } @@ -105,7 +105,7 @@ public void setName( @Nullable final String name) { * Get brand * @return brand The brand of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public String getBrand() { return brand; } @@ -134,7 +134,7 @@ public void setBrand( @Nullable final String brand) { * Get flavor * @return flavor The flavor of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public String getFlavor() { return flavor; } @@ -163,7 +163,7 @@ public void setFlavor( @Nullable final String flavor) { * Get price * @return price The price of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public Float getPrice() { return price; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/input-spec-with-uppercase-file-extension/output/com/sap/cloud/sdk/services/uppercasefileextension/model/Soda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/input-spec-with-uppercase-file-extension/output/com/sap/cloud/sdk/services/uppercasefileextension/model/Soda.java index 2dd435030a..2ce9f75f01 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/input-spec-with-uppercase-file-extension/output/com/sap/cloud/sdk/services/uppercasefileextension/model/Soda.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/input-spec-with-uppercase-file-extension/output/com/sap/cloud/sdk/services/uppercasefileextension/model/Soda.java @@ -75,7 +75,7 @@ public class Soda * Get id * @return id The id of this {@link Soda} instance. */ - @Nonnull + @Nullable public Long getId() { return id; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/input-spec-with-uppercase-file-extension/output/com/sap/cloud/sdk/services/uppercasefileextension/model/UpdateSoda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/input-spec-with-uppercase-file-extension/output/com/sap/cloud/sdk/services/uppercasefileextension/model/UpdateSoda.java index f3a793b661..0083a0c344 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/input-spec-with-uppercase-file-extension/output/com/sap/cloud/sdk/services/uppercasefileextension/model/UpdateSoda.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/input-spec-with-uppercase-file-extension/output/com/sap/cloud/sdk/services/uppercasefileextension/model/UpdateSoda.java @@ -72,7 +72,7 @@ public class UpdateSoda * Get name * @return name The name of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public String getName() { return name; } @@ -101,7 +101,7 @@ public void setName( @Nullable final String name) { * Get brand * @return brand The brand of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public String getBrand() { return brand; } @@ -130,7 +130,7 @@ public void setBrand( @Nullable final String brand) { * Get flavor * @return flavor The flavor of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public String getFlavor() { return flavor; } @@ -159,7 +159,7 @@ public void setFlavor( @Nullable final String flavor) { * Get price * @return price The price of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public Float getPrice() { return price; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas30-exclusive-min-max/input/sodastore.yaml b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas30-exclusive-min-max/input/sodastore.yaml new file mode 100644 index 0000000000..9ad45cbb3a --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas30-exclusive-min-max/input/sodastore.yaml @@ -0,0 +1,38 @@ +openapi: 3.0.3 +info: + title: OAS 3.0 Boolean exclusiveMinimum and exclusiveMaximum + version: 1.0.0 + +paths: + /sodas: + get: + operationId: getSodas + responses: + '200': + description: A soda + content: + application/json: + schema: + $ref: '#/components/schemas/Soda' + +components: + schemas: + Soda: + type: object + properties: + name: + type: string + rating: + # OAS 3.0: boolean exclusiveMinimum/exclusiveMaximum as flags alongside minimum/maximum + type: number + minimum: 0 + exclusiveMinimum: true + maximum: 5 + exclusiveMaximum: true + score: + # OAS 3.0: non-exclusive minimum/maximum (no boolean flags) + type: number + minimum: 0 + maximum: 100 + required: + - name diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas30-exclusive-min-max/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas30-exclusive-min-max/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java new file mode 100644 index 0000000000..09d8e0ade4 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas30-exclusive-min-max/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.api; + +import com.sap.cloud.sdk.services.openapi.core.OpenApiRequestException; +import com.sap.cloud.sdk.services.openapi.core.OpenApiResponse; +import com.sap.cloud.sdk.services.openapi.core.AbstractOpenApiService; +import com.sap.cloud.sdk.services.openapi.apiclient.ApiClient; + +import com.sap.cloud.sdk.datamodel.rest.test.model.Soda; + +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.util.UriComponentsBuilder; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.core.io.FileSystemResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import com.google.common.annotations.Beta; + +import com.sap.cloud.sdk.cloudplatform.connectivity.Destination; + +/** + * OAS 3.0 Boolean exclusiveMinimum and exclusiveMaximum in version 1.0.0. + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + */ +public class DefaultApi extends AbstractOpenApiService { + /** + * Instantiates this API class to invoke operations on the OAS 3.0 Boolean exclusiveMinimum and exclusiveMaximum. + * + * @param httpDestination The destination that API should be used with + */ + public DefaultApi( @Nonnull final Destination httpDestination ) + { + super(httpDestination); + } + + /** + * Instantiates this API class to invoke operations on the OAS 3.0 Boolean exclusiveMinimum and exclusiveMaximum based on a given {@link ApiClient}. + * + * @param apiClient + * ApiClient to invoke the API on + */ + @Beta + public DefaultApi( @Nonnull final ApiClient apiClient ) + { + super(apiClient); + } + + /** + *

+ *

+ *

200 - A soda + * @return Soda + * @throws OpenApiRequestException if an error occurs while attempting to invoke the API + */ + @Nonnull + public Soda getSodas() throws OpenApiRequestException { + final Object localVarPostBody = null; + + final String localVarPath = UriComponentsBuilder.fromPath("/sodas").build().toUriString(); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap(); + final HttpHeaders localVarHeaderParams = new HttpHeaders(); + final MultiValueMap localVarFormParams = new LinkedMultiValueMap(); + + final String[] localVarAccepts = { + "application/json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + final String[] localVarAuthNames = new String[] { }; + + final ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + return apiClient.invokeAPI(localVarPath, HttpMethod.GET, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, localVarReturnType); + } +} diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas30-exclusive-min-max/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas30-exclusive-min-max/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java new file mode 100644 index 0000000000..f264eee8a8 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas30-exclusive-min-max/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +/* + * OAS 3.0 Boolean exclusiveMinimum and exclusiveMaximum + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.model; + +import java.util.Objects; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.math.BigDecimal; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * Soda + */ +// CHECKSTYLE:OFF +public class Soda +// CHECKSTYLE:ON +{ + @JsonProperty("name") + private String name; + + @JsonProperty("rating") + private BigDecimal rating; + + @JsonProperty("score") + private BigDecimal score; + + @JsonAnySetter + @JsonAnyGetter + private final Map cloudSdkCustomFields = new LinkedHashMap<>(); + + /** + * Set the name of this {@link Soda} instance and return the same instance. + * + * @param name The name of this {@link Soda} + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda name( @Nonnull final String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name The name of this {@link Soda} instance. + */ + @Nonnull + public String getName() { + return name; + } + + /** + * Set the name of this {@link Soda} instance. + * + * @param name The name of this {@link Soda} + */ + public void setName( @Nonnull final String name) { + this.name = name; + } + + /** + * Set the rating of this {@link Soda} instance and return the same instance. + * + * @param rating The rating of this {@link Soda} + * Minimum: 0 (exclusive) + * Maximum: 5 (exclusive) + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda rating( @Nullable final BigDecimal rating) { + this.rating = rating; + return this; + } + + /** + * Get rating + * minimum: 0 (exclusive) + * maximum: 5 (exclusive) + * @return rating The rating of this {@link Soda} instance. + */ + @Nullable + public BigDecimal getRating() { + return rating; + } + + /** + * Set the rating of this {@link Soda} instance. + * + * @param rating The rating of this {@link Soda} + * Minimum: 0 (exclusive) + * Maximum: 5 (exclusive) + */ + public void setRating( @Nullable final BigDecimal rating) { + this.rating = rating; + } + + /** + * Set the score of this {@link Soda} instance and return the same instance. + * + * @param score The score of this {@link Soda} + * Minimum: 0 + * Maximum: 100 + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda score( @Nullable final BigDecimal score) { + this.score = score; + return this; + } + + /** + * Get score + * minimum: 0 + * maximum: 100 + * @return score The score of this {@link Soda} instance. + */ + @Nullable + public BigDecimal getScore() { + return score; + } + + /** + * Set the score of this {@link Soda} instance. + * + * @param score The score of this {@link Soda} + * Minimum: 0 + * Maximum: 100 + */ + public void setScore( @Nullable final BigDecimal score) { + this.score = score; + } + + /** + * Get the names of the unrecognizable properties of the {@link Soda}. + * @return The set of properties names + */ + @JsonIgnore + @Nonnull + public Set getCustomFieldNames() { + return cloudSdkCustomFields.keySet(); + } + + /** + * Get the value of an unrecognizable property of this {@link Soda} instance. + * @deprecated Use {@link #toMap()} instead. + * @param name The name of the property + * @return The value of the property + * @throws NoSuchElementException If no property with the given name could be found. + */ + @Nullable + @Deprecated + public Object getCustomField( @Nonnull final String name ) throws NoSuchElementException { + if( !cloudSdkCustomFields.containsKey(name) ) { + throw new NoSuchElementException("Soda has no field with name '" + name + "'."); + } + return cloudSdkCustomFields.get(name); + } + + /** + * Get the value of all properties of this {@link Soda} instance including unrecognized properties. + * + * @return The map of all properties + */ + @JsonIgnore + @Nonnull + public Map toMap() + { + final Map declaredFields = new LinkedHashMap<>(cloudSdkCustomFields); + if( name != null ) declaredFields.put("name", name); + if( rating != null ) declaredFields.put("rating", rating); + if( score != null ) declaredFields.put("score", score); + return declaredFields; + } + + /** + * Set an unrecognizable property of this {@link Soda} instance. If the map previously contained a mapping + * for the key, the old value is replaced by the specified value. + * @param customFieldName The name of the property + * @param customFieldValue The value of the property + */ + @JsonIgnore + public void setCustomField( @Nonnull String customFieldName, @Nullable Object customFieldValue ) + { + cloudSdkCustomFields.put(customFieldName, customFieldValue); + } + + + @Override + public boolean equals(@Nullable final java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Soda soda = (Soda) o; + return Objects.equals(this.cloudSdkCustomFields, soda.cloudSdkCustomFields) && + Objects.equals(this.name, soda.name) && + Objects.equals(this.rating, soda.rating) && + Objects.equals(this.score, soda.score); + } + + @Override + public int hashCode() { + return Objects.hash(name, rating, score, cloudSdkCustomFields); + } + + @Override + @Nonnull public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class Soda {\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" rating: ").append(toIndentedString(rating)).append("\n"); + sb.append(" score: ").append(toIndentedString(score)).append("\n"); + cloudSdkCustomFields.forEach((k,v) -> sb.append(" ").append(k).append(": ").append(toIndentedString(v)).append("\n")); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(final java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-components-path-items/input/sodastore.yaml b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-components-path-items/input/sodastore.yaml new file mode 100644 index 0000000000..0ea8f98073 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-components-path-items/input/sodastore.yaml @@ -0,0 +1,49 @@ +openapi: 3.1.0 +info: + title: OAS 3.1 components/pathItems schema references + version: 1.0.0 + +paths: + /sodas: + get: + operationId: getSodas + responses: + '200': + description: A soda + content: + application/json: + schema: + $ref: '#/components/schemas/Soda' + +components: + # OAS 3.1 adds components/pathItems — schemas referenced here must not be removed + pathItems: + sodaItem: + get: + operationId: getSodaDetail + responses: + '200': + description: success + content: + application/json: + schema: + $ref: '#/components/schemas/SodaDetail' + + schemas: + Soda: + type: object + properties: + name: + type: string + # Only referenced from components/pathItems, not from paths + SodaDetail: + type: object + properties: + description: + type: string + # Not referenced anywhere — should be removed by removeUnusedComponents + UnusedSchema: + type: object + properties: + garbage: + type: string diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-components-path-items/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-components-path-items/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java new file mode 100644 index 0000000000..ea68a69fa8 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-components-path-items/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.api; + +import com.sap.cloud.sdk.services.openapi.core.OpenApiRequestException; +import com.sap.cloud.sdk.services.openapi.core.OpenApiResponse; +import com.sap.cloud.sdk.services.openapi.core.AbstractOpenApiService; +import com.sap.cloud.sdk.services.openapi.apiclient.ApiClient; + +import com.sap.cloud.sdk.datamodel.rest.test.model.Soda; + +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.util.UriComponentsBuilder; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.core.io.FileSystemResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import com.google.common.annotations.Beta; + +import com.sap.cloud.sdk.cloudplatform.connectivity.Destination; + +/** + * OAS 3.1 components/pathItems schema references in version 1.0.0. + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + */ +public class DefaultApi extends AbstractOpenApiService { + /** + * Instantiates this API class to invoke operations on the OAS 3.1 components/pathItems schema references. + * + * @param httpDestination The destination that API should be used with + */ + public DefaultApi( @Nonnull final Destination httpDestination ) + { + super(httpDestination); + } + + /** + * Instantiates this API class to invoke operations on the OAS 3.1 components/pathItems schema references based on a given {@link ApiClient}. + * + * @param apiClient + * ApiClient to invoke the API on + */ + @Beta + public DefaultApi( @Nonnull final ApiClient apiClient ) + { + super(apiClient); + } + + /** + *

+ *

+ *

200 - A soda + * @return Soda + * @throws OpenApiRequestException if an error occurs while attempting to invoke the API + */ + @Nonnull + public Soda getSodas() throws OpenApiRequestException { + final Object localVarPostBody = null; + + final String localVarPath = UriComponentsBuilder.fromPath("/sodas").build().toUriString(); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap(); + final HttpHeaders localVarHeaderParams = new HttpHeaders(); + final MultiValueMap localVarFormParams = new LinkedMultiValueMap(); + + final String[] localVarAccepts = { + "application/json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + final String[] localVarAuthNames = new String[] { }; + + final ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + return apiClient.invokeAPI(localVarPath, HttpMethod.GET, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, localVarReturnType); + } +} diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-components-path-items/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-components-path-items/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java new file mode 100644 index 0000000000..211258b8b9 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-components-path-items/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +/* + * OAS 3.1 components/pathItems schema references + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.model; + +import java.util.Objects; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * Soda + */ +// CHECKSTYLE:OFF +public class Soda +// CHECKSTYLE:ON +{ + @JsonProperty("name") + private String name; + + @JsonAnySetter + @JsonAnyGetter + private final Map cloudSdkCustomFields = new LinkedHashMap<>(); + + /** + * Set the name of this {@link Soda} instance and return the same instance. + * + * @param name The name of this {@link Soda} + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda name( @Nullable final String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name The name of this {@link Soda} instance. + */ + @Nullable + public String getName() { + return name; + } + + /** + * Set the name of this {@link Soda} instance. + * + * @param name The name of this {@link Soda} + */ + public void setName( @Nullable final String name) { + this.name = name; + } + + /** + * Get the names of the unrecognizable properties of the {@link Soda}. + * @return The set of properties names + */ + @JsonIgnore + @Nonnull + public Set getCustomFieldNames() { + return cloudSdkCustomFields.keySet(); + } + + /** + * Get the value of an unrecognizable property of this {@link Soda} instance. + * @deprecated Use {@link #toMap()} instead. + * @param name The name of the property + * @return The value of the property + * @throws NoSuchElementException If no property with the given name could be found. + */ + @Nullable + @Deprecated + public Object getCustomField( @Nonnull final String name ) throws NoSuchElementException { + if( !cloudSdkCustomFields.containsKey(name) ) { + throw new NoSuchElementException("Soda has no field with name '" + name + "'."); + } + return cloudSdkCustomFields.get(name); + } + + /** + * Get the value of all properties of this {@link Soda} instance including unrecognized properties. + * + * @return The map of all properties + */ + @JsonIgnore + @Nonnull + public Map toMap() + { + final Map declaredFields = new LinkedHashMap<>(cloudSdkCustomFields); + if( name != null ) declaredFields.put("name", name); + return declaredFields; + } + + /** + * Set an unrecognizable property of this {@link Soda} instance. If the map previously contained a mapping + * for the key, the old value is replaced by the specified value. + * @param customFieldName The name of the property + * @param customFieldValue The value of the property + */ + @JsonIgnore + public void setCustomField( @Nonnull String customFieldName, @Nullable Object customFieldValue ) + { + cloudSdkCustomFields.put(customFieldName, customFieldValue); + } + + + @Override + public boolean equals(@Nullable final java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Soda soda = (Soda) o; + return Objects.equals(this.cloudSdkCustomFields, soda.cloudSdkCustomFields) && + Objects.equals(this.name, soda.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, cloudSdkCustomFields); + } + + @Override + @Nonnull public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class Soda {\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + cloudSdkCustomFields.forEach((k,v) -> sb.append(" ").append(k).append(": ").append(toIndentedString(v)).append("\n")); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(final java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-components-path-items/output/com/sap/cloud/sdk/datamodel/rest/test/model/SodaDetail.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-components-path-items/output/com/sap/cloud/sdk/datamodel/rest/test/model/SodaDetail.java new file mode 100644 index 0000000000..3e2fb390ff --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-components-path-items/output/com/sap/cloud/sdk/datamodel/rest/test/model/SodaDetail.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +/* + * OAS 3.1 components/pathItems schema references + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.model; + +import java.util.Objects; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * SodaDetail + */ +// CHECKSTYLE:OFF +public class SodaDetail +// CHECKSTYLE:ON +{ + @JsonProperty("description") + private String description; + + @JsonAnySetter + @JsonAnyGetter + private final Map cloudSdkCustomFields = new LinkedHashMap<>(); + + /** + * Set the description of this {@link SodaDetail} instance and return the same instance. + * + * @param description The description of this {@link SodaDetail} + * @return The same instance of this {@link SodaDetail} class + */ + @Nonnull public SodaDetail description( @Nullable final String description) { + this.description = description; + return this; + } + + /** + * Get description + * @return description The description of this {@link SodaDetail} instance. + */ + @Nullable + public String getDescription() { + return description; + } + + /** + * Set the description of this {@link SodaDetail} instance. + * + * @param description The description of this {@link SodaDetail} + */ + public void setDescription( @Nullable final String description) { + this.description = description; + } + + /** + * Get the names of the unrecognizable properties of the {@link SodaDetail}. + * @return The set of properties names + */ + @JsonIgnore + @Nonnull + public Set getCustomFieldNames() { + return cloudSdkCustomFields.keySet(); + } + + /** + * Get the value of an unrecognizable property of this {@link SodaDetail} instance. + * @deprecated Use {@link #toMap()} instead. + * @param name The name of the property + * @return The value of the property + * @throws NoSuchElementException If no property with the given name could be found. + */ + @Nullable + @Deprecated + public Object getCustomField( @Nonnull final String name ) throws NoSuchElementException { + if( !cloudSdkCustomFields.containsKey(name) ) { + throw new NoSuchElementException("SodaDetail has no field with name '" + name + "'."); + } + return cloudSdkCustomFields.get(name); + } + + /** + * Get the value of all properties of this {@link SodaDetail} instance including unrecognized properties. + * + * @return The map of all properties + */ + @JsonIgnore + @Nonnull + public Map toMap() + { + final Map declaredFields = new LinkedHashMap<>(cloudSdkCustomFields); + if( description != null ) declaredFields.put("description", description); + return declaredFields; + } + + /** + * Set an unrecognizable property of this {@link SodaDetail} instance. If the map previously contained a mapping + * for the key, the old value is replaced by the specified value. + * @param customFieldName The name of the property + * @param customFieldValue The value of the property + */ + @JsonIgnore + public void setCustomField( @Nonnull String customFieldName, @Nullable Object customFieldValue ) + { + cloudSdkCustomFields.put(customFieldName, customFieldValue); + } + + + @Override + public boolean equals(@Nullable final java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final SodaDetail sodaDetail = (SodaDetail) o; + return Objects.equals(this.cloudSdkCustomFields, sodaDetail.cloudSdkCustomFields) && + Objects.equals(this.description, sodaDetail.description); + } + + @Override + public int hashCode() { + return Objects.hash(description, cloudSdkCustomFields); + } + + @Override + @Nonnull public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class SodaDetail {\n"); + sb.append(" description: ").append(toIndentedString(description)).append("\n"); + cloudSdkCustomFields.forEach((k,v) -> sb.append(" ").append(k).append(": ").append(toIndentedString(v)).append("\n")); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(final java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-exclusive-min-max/input/sodastore.yaml b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-exclusive-min-max/input/sodastore.yaml new file mode 100644 index 0000000000..913834b7c5 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-exclusive-min-max/input/sodastore.yaml @@ -0,0 +1,47 @@ +openapi: 3.1.0 +info: + title: OAS 3.1 Numeric exclusiveMinimum and exclusiveMaximum + version: 1.0.0 + +paths: + /sodas: + get: + operationId: getSodas + responses: + '200': + description: A soda + content: + application/json: + schema: + $ref: '#/components/schemas/Soda' + +components: + schemas: + Soda: + type: object + properties: + name: + type: string + rating: + # numeric exclusiveMinimum/exclusiveMaximum as direct values + type: number + exclusiveMinimum: 0 + exclusiveMaximum: 5 + score: + # OAS 3.1: non-exclusive minimum/maximum (plain numeric values) + type: number + minimum: 0 + maximum: 100 + temperature: + # OAS 3.1: mixed — inclusive minimum alongside exclusive maximum + type: number + minimum: 0 + exclusiveMaximum: 100 + combo: + # OAS 3.1: both minimum (inclusive) and exclusiveMinimum (exclusive numeric) present; + # exclusiveMinimum: 3 is stricter than minimum: 2, so effective constraint is > 3 + type: number + minimum: 2 + exclusiveMinimum: 3 + required: + - name diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-exclusive-min-max/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-exclusive-min-max/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java new file mode 100644 index 0000000000..176600d2e7 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-exclusive-min-max/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.api; + +import com.sap.cloud.sdk.services.openapi.core.OpenApiRequestException; +import com.sap.cloud.sdk.services.openapi.core.OpenApiResponse; +import com.sap.cloud.sdk.services.openapi.core.AbstractOpenApiService; +import com.sap.cloud.sdk.services.openapi.apiclient.ApiClient; + +import com.sap.cloud.sdk.datamodel.rest.test.model.Soda; + +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.util.UriComponentsBuilder; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.core.io.FileSystemResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import com.google.common.annotations.Beta; + +import com.sap.cloud.sdk.cloudplatform.connectivity.Destination; + +/** + * OAS 3.1 Numeric exclusiveMinimum and exclusiveMaximum in version 1.0.0. + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + */ +public class DefaultApi extends AbstractOpenApiService { + /** + * Instantiates this API class to invoke operations on the OAS 3.1 Numeric exclusiveMinimum and exclusiveMaximum. + * + * @param httpDestination The destination that API should be used with + */ + public DefaultApi( @Nonnull final Destination httpDestination ) + { + super(httpDestination); + } + + /** + * Instantiates this API class to invoke operations on the OAS 3.1 Numeric exclusiveMinimum and exclusiveMaximum based on a given {@link ApiClient}. + * + * @param apiClient + * ApiClient to invoke the API on + */ + @Beta + public DefaultApi( @Nonnull final ApiClient apiClient ) + { + super(apiClient); + } + + /** + *

+ *

+ *

200 - A soda + * @return Soda + * @throws OpenApiRequestException if an error occurs while attempting to invoke the API + */ + @Nonnull + public Soda getSodas() throws OpenApiRequestException { + final Object localVarPostBody = null; + + final String localVarPath = UriComponentsBuilder.fromPath("/sodas").build().toUriString(); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap(); + final HttpHeaders localVarHeaderParams = new HttpHeaders(); + final MultiValueMap localVarFormParams = new LinkedMultiValueMap(); + + final String[] localVarAccepts = { + "application/json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + final String[] localVarAuthNames = new String[] { }; + + final ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + return apiClient.invokeAPI(localVarPath, HttpMethod.GET, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, localVarReturnType); + } +} diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-exclusive-min-max/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-exclusive-min-max/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java new file mode 100644 index 0000000000..4b6196d63c --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-exclusive-min-max/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +/* + * OAS 3.1 Numeric exclusiveMinimum and exclusiveMaximum + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.model; + +import java.util.Objects; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.math.BigDecimal; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * Soda + */ +// CHECKSTYLE:OFF +public class Soda +// CHECKSTYLE:ON +{ + @JsonProperty("name") + private String name; + + @JsonProperty("rating") + private BigDecimal rating; + + @JsonProperty("score") + private BigDecimal score; + + @JsonProperty("temperature") + private BigDecimal temperature; + + @JsonProperty("combo") + private BigDecimal combo; + + @JsonAnySetter + @JsonAnyGetter + private final Map cloudSdkCustomFields = new LinkedHashMap<>(); + + /** + * Set the name of this {@link Soda} instance and return the same instance. + * + * @param name The name of this {@link Soda} + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda name( @Nonnull final String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name The name of this {@link Soda} instance. + */ + @Nonnull + public String getName() { + return name; + } + + /** + * Set the name of this {@link Soda} instance. + * + * @param name The name of this {@link Soda} + */ + public void setName( @Nonnull final String name) { + this.name = name; + } + + /** + * Set the rating of this {@link Soda} instance and return the same instance. + * + * @param rating The rating of this {@link Soda} + * Minimum: 0 (exclusive) + * Maximum: 5 (exclusive) + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda rating( @Nullable final BigDecimal rating) { + this.rating = rating; + return this; + } + + /** + * Get rating + * minimum: 0 (exclusive) + * maximum: 5 (exclusive) + * @return rating The rating of this {@link Soda} instance. + */ + @Nullable + public BigDecimal getRating() { + return rating; + } + + /** + * Set the rating of this {@link Soda} instance. + * + * @param rating The rating of this {@link Soda} + * Minimum: 0 (exclusive) + * Maximum: 5 (exclusive) + */ + public void setRating( @Nullable final BigDecimal rating) { + this.rating = rating; + } + + /** + * Set the score of this {@link Soda} instance and return the same instance. + * + * @param score The score of this {@link Soda} + * Minimum: 0 + * Maximum: 100 + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda score( @Nullable final BigDecimal score) { + this.score = score; + return this; + } + + /** + * Get score + * minimum: 0 + * maximum: 100 + * @return score The score of this {@link Soda} instance. + */ + @Nullable + public BigDecimal getScore() { + return score; + } + + /** + * Set the score of this {@link Soda} instance. + * + * @param score The score of this {@link Soda} + * Minimum: 0 + * Maximum: 100 + */ + public void setScore( @Nullable final BigDecimal score) { + this.score = score; + } + + /** + * Set the temperature of this {@link Soda} instance and return the same instance. + * + * @param temperature The temperature of this {@link Soda} + * Minimum: 0 + * Maximum: 100 (exclusive) + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda temperature( @Nullable final BigDecimal temperature) { + this.temperature = temperature; + return this; + } + + /** + * Get temperature + * minimum: 0 + * maximum: 100 (exclusive) + * @return temperature The temperature of this {@link Soda} instance. + */ + @Nullable + public BigDecimal getTemperature() { + return temperature; + } + + /** + * Set the temperature of this {@link Soda} instance. + * + * @param temperature The temperature of this {@link Soda} + * Minimum: 0 + * Maximum: 100 (exclusive) + */ + public void setTemperature( @Nullable final BigDecimal temperature) { + this.temperature = temperature; + } + + /** + * Set the combo of this {@link Soda} instance and return the same instance. + * + * @param combo The combo of this {@link Soda} + * Minimum: 3 (exclusive) + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda combo( @Nullable final BigDecimal combo) { + this.combo = combo; + return this; + } + + /** + * Get combo + * minimum: 3 (exclusive) + * @return combo The combo of this {@link Soda} instance. + */ + @Nullable + public BigDecimal getCombo() { + return combo; + } + + /** + * Set the combo of this {@link Soda} instance. + * + * @param combo The combo of this {@link Soda} + * Minimum: 3 (exclusive) + */ + public void setCombo( @Nullable final BigDecimal combo) { + this.combo = combo; + } + + /** + * Get the names of the unrecognizable properties of the {@link Soda}. + * @return The set of properties names + */ + @JsonIgnore + @Nonnull + public Set getCustomFieldNames() { + return cloudSdkCustomFields.keySet(); + } + + /** + * Get the value of an unrecognizable property of this {@link Soda} instance. + * @deprecated Use {@link #toMap()} instead. + * @param name The name of the property + * @return The value of the property + * @throws NoSuchElementException If no property with the given name could be found. + */ + @Nullable + @Deprecated + public Object getCustomField( @Nonnull final String name ) throws NoSuchElementException { + if( !cloudSdkCustomFields.containsKey(name) ) { + throw new NoSuchElementException("Soda has no field with name '" + name + "'."); + } + return cloudSdkCustomFields.get(name); + } + + /** + * Get the value of all properties of this {@link Soda} instance including unrecognized properties. + * + * @return The map of all properties + */ + @JsonIgnore + @Nonnull + public Map toMap() + { + final Map declaredFields = new LinkedHashMap<>(cloudSdkCustomFields); + if( name != null ) declaredFields.put("name", name); + if( rating != null ) declaredFields.put("rating", rating); + if( score != null ) declaredFields.put("score", score); + if( temperature != null ) declaredFields.put("temperature", temperature); + if( combo != null ) declaredFields.put("combo", combo); + return declaredFields; + } + + /** + * Set an unrecognizable property of this {@link Soda} instance. If the map previously contained a mapping + * for the key, the old value is replaced by the specified value. + * @param customFieldName The name of the property + * @param customFieldValue The value of the property + */ + @JsonIgnore + public void setCustomField( @Nonnull String customFieldName, @Nullable Object customFieldValue ) + { + cloudSdkCustomFields.put(customFieldName, customFieldValue); + } + + + @Override + public boolean equals(@Nullable final java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Soda soda = (Soda) o; + return Objects.equals(this.cloudSdkCustomFields, soda.cloudSdkCustomFields) && + Objects.equals(this.name, soda.name) && + Objects.equals(this.rating, soda.rating) && + Objects.equals(this.score, soda.score) && + Objects.equals(this.temperature, soda.temperature) && + Objects.equals(this.combo, soda.combo); + } + + @Override + public int hashCode() { + return Objects.hash(name, rating, score, temperature, combo, cloudSdkCustomFields); + } + + @Override + @Nonnull public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class Soda {\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" rating: ").append(toIndentedString(rating)).append("\n"); + sb.append(" score: ").append(toIndentedString(score)).append("\n"); + sb.append(" temperature: ").append(toIndentedString(temperature)).append("\n"); + sb.append(" combo: ").append(toIndentedString(combo)).append("\n"); + cloudSdkCustomFields.forEach((k,v) -> sb.append(" ").append(k).append(": ").append(toIndentedString(v)).append("\n")); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(final java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-nullable-ref/input/sodastore.yaml b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-nullable-ref/input/sodastore.yaml new file mode 100644 index 0000000000..19686b15ec --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-nullable-ref/input/sodastore.yaml @@ -0,0 +1,37 @@ +openapi: 3.1.0 +info: + title: OAS 3.1 Nullable $ref via anyOf + version: 1.0.0 + +paths: + /sodas: + get: + operationId: getSodas + responses: + '200': + description: A soda + content: + application/json: + schema: + $ref: '#/components/schemas/Soda' + +components: + schemas: + SodaCategory: + type: object + properties: + name: + type: string + + Soda: + type: object + properties: + name: + type: string + category: + # nullable $ref using anyOf with null type + anyOf: + - $ref: '#/components/schemas/SodaCategory' + - type: "null" + required: + - name diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-nullable-ref/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-nullable-ref/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java new file mode 100644 index 0000000000..2eeec864d2 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-nullable-ref/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.api; + +import com.sap.cloud.sdk.services.openapi.core.OpenApiRequestException; +import com.sap.cloud.sdk.services.openapi.core.OpenApiResponse; +import com.sap.cloud.sdk.services.openapi.core.AbstractOpenApiService; +import com.sap.cloud.sdk.services.openapi.apiclient.ApiClient; + +import com.sap.cloud.sdk.datamodel.rest.test.model.Soda; + +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.util.UriComponentsBuilder; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.core.io.FileSystemResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import com.google.common.annotations.Beta; + +import com.sap.cloud.sdk.cloudplatform.connectivity.Destination; + +/** + * OAS 3.1 Nullable $ref via anyOf in version 1.0.0. + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + */ +public class DefaultApi extends AbstractOpenApiService { + /** + * Instantiates this API class to invoke operations on the OAS 3.1 Nullable $ref via anyOf. + * + * @param httpDestination The destination that API should be used with + */ + public DefaultApi( @Nonnull final Destination httpDestination ) + { + super(httpDestination); + } + + /** + * Instantiates this API class to invoke operations on the OAS 3.1 Nullable $ref via anyOf based on a given {@link ApiClient}. + * + * @param apiClient + * ApiClient to invoke the API on + */ + @Beta + public DefaultApi( @Nonnull final ApiClient apiClient ) + { + super(apiClient); + } + + /** + *

+ *

+ *

200 - A soda + * @return Soda + * @throws OpenApiRequestException if an error occurs while attempting to invoke the API + */ + @Nonnull + public Soda getSodas() throws OpenApiRequestException { + final Object localVarPostBody = null; + + final String localVarPath = UriComponentsBuilder.fromPath("/sodas").build().toUriString(); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap(); + final HttpHeaders localVarHeaderParams = new HttpHeaders(); + final MultiValueMap localVarFormParams = new LinkedMultiValueMap(); + + final String[] localVarAccepts = { + "application/json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + final String[] localVarAuthNames = new String[] { }; + + final ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + return apiClient.invokeAPI(localVarPath, HttpMethod.GET, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, localVarReturnType); + } +} diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-nullable-ref/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-nullable-ref/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java new file mode 100644 index 0000000000..7468af81f2 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-nullable-ref/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +/* + * OAS 3.1 Nullable $ref via anyOf + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.model; + +import java.util.Objects; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sap.cloud.sdk.datamodel.rest.test.model.SodaCategory; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * Soda + */ +// CHECKSTYLE:OFF +public class Soda +// CHECKSTYLE:ON +{ + @JsonProperty("name") + private String name; + + @JsonProperty("category") + private SodaCategory category; + + @JsonAnySetter + @JsonAnyGetter + private final Map cloudSdkCustomFields = new LinkedHashMap<>(); + + /** + * Set the name of this {@link Soda} instance and return the same instance. + * + * @param name The name of this {@link Soda} + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda name( @Nonnull final String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name The name of this {@link Soda} instance. + */ + @Nonnull + public String getName() { + return name; + } + + /** + * Set the name of this {@link Soda} instance. + * + * @param name The name of this {@link Soda} + */ + public void setName( @Nonnull final String name) { + this.name = name; + } + + /** + * Set the category of this {@link Soda} instance and return the same instance. + * + * @param category The category of this {@link Soda} + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda category( @Nullable final SodaCategory category) { + this.category = category; + return this; + } + + /** + * Get category + * @return category The category of this {@link Soda} instance. + */ + @Nullable + public SodaCategory getCategory() { + return category; + } + + /** + * Set the category of this {@link Soda} instance. + * + * @param category The category of this {@link Soda} + */ + public void setCategory( @Nullable final SodaCategory category) { + this.category = category; + } + + /** + * Get the names of the unrecognizable properties of the {@link Soda}. + * @return The set of properties names + */ + @JsonIgnore + @Nonnull + public Set getCustomFieldNames() { + return cloudSdkCustomFields.keySet(); + } + + /** + * Get the value of an unrecognizable property of this {@link Soda} instance. + * @deprecated Use {@link #toMap()} instead. + * @param name The name of the property + * @return The value of the property + * @throws NoSuchElementException If no property with the given name could be found. + */ + @Nullable + @Deprecated + public Object getCustomField( @Nonnull final String name ) throws NoSuchElementException { + if( !cloudSdkCustomFields.containsKey(name) ) { + throw new NoSuchElementException("Soda has no field with name '" + name + "'."); + } + return cloudSdkCustomFields.get(name); + } + + /** + * Get the value of all properties of this {@link Soda} instance including unrecognized properties. + * + * @return The map of all properties + */ + @JsonIgnore + @Nonnull + public Map toMap() + { + final Map declaredFields = new LinkedHashMap<>(cloudSdkCustomFields); + if( name != null ) declaredFields.put("name", name); + if( category != null ) declaredFields.put("category", category); + return declaredFields; + } + + /** + * Set an unrecognizable property of this {@link Soda} instance. If the map previously contained a mapping + * for the key, the old value is replaced by the specified value. + * @param customFieldName The name of the property + * @param customFieldValue The value of the property + */ + @JsonIgnore + public void setCustomField( @Nonnull String customFieldName, @Nullable Object customFieldValue ) + { + cloudSdkCustomFields.put(customFieldName, customFieldValue); + } + + + @Override + public boolean equals(@Nullable final java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Soda soda = (Soda) o; + return Objects.equals(this.cloudSdkCustomFields, soda.cloudSdkCustomFields) && + Objects.equals(this.name, soda.name) && + Objects.equals(this.category, soda.category); + } + + @Override + public int hashCode() { + return Objects.hash(name, category, cloudSdkCustomFields); + } + + @Override + @Nonnull public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class Soda {\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" category: ").append(toIndentedString(category)).append("\n"); + cloudSdkCustomFields.forEach((k,v) -> sb.append(" ").append(k).append(": ").append(toIndentedString(v)).append("\n")); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(final java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-nullable-ref/output/com/sap/cloud/sdk/datamodel/rest/test/model/SodaCategory.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-nullable-ref/output/com/sap/cloud/sdk/datamodel/rest/test/model/SodaCategory.java new file mode 100644 index 0000000000..632cf7a9d2 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-nullable-ref/output/com/sap/cloud/sdk/datamodel/rest/test/model/SodaCategory.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +/* + * OAS 3.1 Nullable $ref via anyOf + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.model; + +import java.util.Objects; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * SodaCategory + */ +// CHECKSTYLE:OFF +public class SodaCategory +// CHECKSTYLE:ON +{ + @JsonProperty("name") + private String name; + + @JsonAnySetter + @JsonAnyGetter + private final Map cloudSdkCustomFields = new LinkedHashMap<>(); + + /** + * Set the name of this {@link SodaCategory} instance and return the same instance. + * + * @param name The name of this {@link SodaCategory} + * @return The same instance of this {@link SodaCategory} class + */ + @Nonnull public SodaCategory name( @Nullable final String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name The name of this {@link SodaCategory} instance. + */ + @Nullable + public String getName() { + return name; + } + + /** + * Set the name of this {@link SodaCategory} instance. + * + * @param name The name of this {@link SodaCategory} + */ + public void setName( @Nullable final String name) { + this.name = name; + } + + /** + * Get the names of the unrecognizable properties of the {@link SodaCategory}. + * @return The set of properties names + */ + @JsonIgnore + @Nonnull + public Set getCustomFieldNames() { + return cloudSdkCustomFields.keySet(); + } + + /** + * Get the value of an unrecognizable property of this {@link SodaCategory} instance. + * @deprecated Use {@link #toMap()} instead. + * @param name The name of the property + * @return The value of the property + * @throws NoSuchElementException If no property with the given name could be found. + */ + @Nullable + @Deprecated + public Object getCustomField( @Nonnull final String name ) throws NoSuchElementException { + if( !cloudSdkCustomFields.containsKey(name) ) { + throw new NoSuchElementException("SodaCategory has no field with name '" + name + "'."); + } + return cloudSdkCustomFields.get(name); + } + + /** + * Get the value of all properties of this {@link SodaCategory} instance including unrecognized properties. + * + * @return The map of all properties + */ + @JsonIgnore + @Nonnull + public Map toMap() + { + final Map declaredFields = new LinkedHashMap<>(cloudSdkCustomFields); + if( name != null ) declaredFields.put("name", name); + return declaredFields; + } + + /** + * Set an unrecognizable property of this {@link SodaCategory} instance. If the map previously contained a mapping + * for the key, the old value is replaced by the specified value. + * @param customFieldName The name of the property + * @param customFieldValue The value of the property + */ + @JsonIgnore + public void setCustomField( @Nonnull String customFieldName, @Nullable Object customFieldValue ) + { + cloudSdkCustomFields.put(customFieldName, customFieldValue); + } + + + @Override + public boolean equals(@Nullable final java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final SodaCategory sodaCategory = (SodaCategory) o; + return Objects.equals(this.cloudSdkCustomFields, sodaCategory.cloudSdkCustomFields) && + Objects.equals(this.name, sodaCategory.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, cloudSdkCustomFields); + } + + @Override + @Nonnull public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class SodaCategory {\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + cloudSdkCustomFields.forEach((k,v) -> sb.append(" ").append(k).append(": ").append(toIndentedString(v)).append("\n")); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(final java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-nullable-type-array/input/sodastore.yaml b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-nullable-type-array/input/sodastore.yaml new file mode 100644 index 0000000000..c31da5b707 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-nullable-type-array/input/sodastore.yaml @@ -0,0 +1,31 @@ +openapi: 3.1.0 +info: + title: OAS 3.1 Nullable Type Array + version: 1.0.0 + +paths: + /sodas: + get: + operationId: getSodas + responses: + '200': + description: A soda + content: + application/json: + schema: + $ref: '#/components/schemas/Soda' + +components: + schemas: + Soda: + type: object + properties: + name: + type: string + brand: + # nullable via type array instead of nullable: true + type: + - string + - "null" + required: + - name diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-nullable-type-array/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-nullable-type-array/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java new file mode 100644 index 0000000000..fbfe5d2c65 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-nullable-type-array/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.api; + +import com.sap.cloud.sdk.services.openapi.core.OpenApiRequestException; +import com.sap.cloud.sdk.services.openapi.core.OpenApiResponse; +import com.sap.cloud.sdk.services.openapi.core.AbstractOpenApiService; +import com.sap.cloud.sdk.services.openapi.apiclient.ApiClient; + +import com.sap.cloud.sdk.datamodel.rest.test.model.Soda; + +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.util.UriComponentsBuilder; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.core.io.FileSystemResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import com.google.common.annotations.Beta; + +import com.sap.cloud.sdk.cloudplatform.connectivity.Destination; + +/** + * OAS 3.1 Nullable Type Array in version 1.0.0. + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + */ +public class DefaultApi extends AbstractOpenApiService { + /** + * Instantiates this API class to invoke operations on the OAS 3.1 Nullable Type Array. + * + * @param httpDestination The destination that API should be used with + */ + public DefaultApi( @Nonnull final Destination httpDestination ) + { + super(httpDestination); + } + + /** + * Instantiates this API class to invoke operations on the OAS 3.1 Nullable Type Array based on a given {@link ApiClient}. + * + * @param apiClient + * ApiClient to invoke the API on + */ + @Beta + public DefaultApi( @Nonnull final ApiClient apiClient ) + { + super(apiClient); + } + + /** + *

+ *

+ *

200 - A soda + * @return Soda + * @throws OpenApiRequestException if an error occurs while attempting to invoke the API + */ + @Nonnull + public Soda getSodas() throws OpenApiRequestException { + final Object localVarPostBody = null; + + final String localVarPath = UriComponentsBuilder.fromPath("/sodas").build().toUriString(); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap(); + final HttpHeaders localVarHeaderParams = new HttpHeaders(); + final MultiValueMap localVarFormParams = new LinkedMultiValueMap(); + + final String[] localVarAccepts = { + "application/json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + final String[] localVarAuthNames = new String[] { }; + + final ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + return apiClient.invokeAPI(localVarPath, HttpMethod.GET, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, localVarReturnType); + } +} diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-nullable-type-array/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-nullable-type-array/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java new file mode 100644 index 0000000000..5b36050103 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-nullable-type-array/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +/* + * OAS 3.1 Nullable Type Array + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.model; + +import java.util.Objects; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * Soda + */ +// CHECKSTYLE:OFF +public class Soda +// CHECKSTYLE:ON +{ + @JsonProperty("name") + private String name; + + @JsonProperty("brand") + private String brand; + + @JsonAnySetter + @JsonAnyGetter + private final Map cloudSdkCustomFields = new LinkedHashMap<>(); + + /** + * Set the name of this {@link Soda} instance and return the same instance. + * + * @param name The name of this {@link Soda} + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda name( @Nonnull final String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name The name of this {@link Soda} instance. + */ + @Nonnull + public String getName() { + return name; + } + + /** + * Set the name of this {@link Soda} instance. + * + * @param name The name of this {@link Soda} + */ + public void setName( @Nonnull final String name) { + this.name = name; + } + + /** + * Set the brand of this {@link Soda} instance and return the same instance. + * + * @param brand The brand of this {@link Soda} + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda brand( @Nullable final String brand) { + this.brand = brand; + return this; + } + + /** + * Get brand + * @return brand The brand of this {@link Soda} instance. + */ + @Nullable + public String getBrand() { + return brand; + } + + /** + * Set the brand of this {@link Soda} instance. + * + * @param brand The brand of this {@link Soda} + */ + public void setBrand( @Nullable final String brand) { + this.brand = brand; + } + + /** + * Get the names of the unrecognizable properties of the {@link Soda}. + * @return The set of properties names + */ + @JsonIgnore + @Nonnull + public Set getCustomFieldNames() { + return cloudSdkCustomFields.keySet(); + } + + /** + * Get the value of an unrecognizable property of this {@link Soda} instance. + * @deprecated Use {@link #toMap()} instead. + * @param name The name of the property + * @return The value of the property + * @throws NoSuchElementException If no property with the given name could be found. + */ + @Nullable + @Deprecated + public Object getCustomField( @Nonnull final String name ) throws NoSuchElementException { + if( !cloudSdkCustomFields.containsKey(name) ) { + throw new NoSuchElementException("Soda has no field with name '" + name + "'."); + } + return cloudSdkCustomFields.get(name); + } + + /** + * Get the value of all properties of this {@link Soda} instance including unrecognized properties. + * + * @return The map of all properties + */ + @JsonIgnore + @Nonnull + public Map toMap() + { + final Map declaredFields = new LinkedHashMap<>(cloudSdkCustomFields); + if( name != null ) declaredFields.put("name", name); + if( brand != null ) declaredFields.put("brand", brand); + return declaredFields; + } + + /** + * Set an unrecognizable property of this {@link Soda} instance. If the map previously contained a mapping + * for the key, the old value is replaced by the specified value. + * @param customFieldName The name of the property + * @param customFieldValue The value of the property + */ + @JsonIgnore + public void setCustomField( @Nonnull String customFieldName, @Nullable Object customFieldValue ) + { + cloudSdkCustomFields.put(customFieldName, customFieldValue); + } + + + @Override + public boolean equals(@Nullable final java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Soda soda = (Soda) o; + return Objects.equals(this.cloudSdkCustomFields, soda.cloudSdkCustomFields) && + Objects.equals(this.name, soda.name) && + Objects.equals(this.brand, soda.brand); + } + + @Override + public int hashCode() { + return Objects.hash(name, brand, cloudSdkCustomFields); + } + + @Override + @Nonnull public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class Soda {\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" brand: ").append(toIndentedString(brand)).append("\n"); + cloudSdkCustomFields.forEach((k,v) -> sb.append(" ").append(k).append(": ").append(toIndentedString(v)).append("\n")); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(final java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-ref-with-sibling/input/sodastore.yaml b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-ref-with-sibling/input/sodastore.yaml new file mode 100644 index 0000000000..081c006624 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-ref-with-sibling/input/sodastore.yaml @@ -0,0 +1,34 @@ +openapi: 3.1.0 +info: + title: OAS 3.1 $ref with Sibling Properties + version: 1.0.0 + +paths: + /sodas: + get: + operationId: getSodas + responses: + '200': + description: A soda + content: + application/json: + schema: + $ref: '#/components/schemas/Soda' + +components: + schemas: + SodaDescription: + type: string + description: Soda description + + Soda: + type: object + properties: + name: + type: string + description: + # $ref with a sibling property — valid in OAS 3.1 + $ref: '#/components/schemas/SodaDescription' + description: Soda description as part of the Soda object + required: + - name diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-ref-with-sibling/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-ref-with-sibling/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java new file mode 100644 index 0000000000..cb676c93a8 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-ref-with-sibling/output/com/sap/cloud/sdk/datamodel/rest/test/api/DefaultApi.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.api; + +import com.sap.cloud.sdk.services.openapi.core.OpenApiRequestException; +import com.sap.cloud.sdk.services.openapi.core.OpenApiResponse; +import com.sap.cloud.sdk.services.openapi.core.AbstractOpenApiService; +import com.sap.cloud.sdk.services.openapi.apiclient.ApiClient; + +import com.sap.cloud.sdk.datamodel.rest.test.model.Soda; + +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.util.UriComponentsBuilder; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.core.io.FileSystemResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import com.google.common.annotations.Beta; + +import com.sap.cloud.sdk.cloudplatform.connectivity.Destination; + +/** + * OAS 3.1 $ref with Sibling Properties in version 1.0.0. + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + */ +public class DefaultApi extends AbstractOpenApiService { + /** + * Instantiates this API class to invoke operations on the OAS 3.1 $ref with Sibling Properties. + * + * @param httpDestination The destination that API should be used with + */ + public DefaultApi( @Nonnull final Destination httpDestination ) + { + super(httpDestination); + } + + /** + * Instantiates this API class to invoke operations on the OAS 3.1 $ref with Sibling Properties based on a given {@link ApiClient}. + * + * @param apiClient + * ApiClient to invoke the API on + */ + @Beta + public DefaultApi( @Nonnull final ApiClient apiClient ) + { + super(apiClient); + } + + /** + *

+ *

+ *

200 - A soda + * @return Soda + * @throws OpenApiRequestException if an error occurs while attempting to invoke the API + */ + @Nonnull + public Soda getSodas() throws OpenApiRequestException { + final Object localVarPostBody = null; + + final String localVarPath = UriComponentsBuilder.fromPath("/sodas").build().toUriString(); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap(); + final HttpHeaders localVarHeaderParams = new HttpHeaders(); + final MultiValueMap localVarFormParams = new LinkedMultiValueMap(); + + final String[] localVarAccepts = { + "application/json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + final String[] localVarAuthNames = new String[] { }; + + final ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + return apiClient.invokeAPI(localVarPath, HttpMethod.GET, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, localVarReturnType); + } +} diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-ref-with-sibling/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-ref-with-sibling/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java new file mode 100644 index 0000000000..439c9072a5 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oas31-ref-with-sibling/output/com/sap/cloud/sdk/datamodel/rest/test/model/Soda.java @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. + */ + +/* + * OAS 3.1 $ref with Sibling Properties + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.sap.cloud.sdk.datamodel.rest.test.model; + +import java.util.Objects; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * Soda + */ +// CHECKSTYLE:OFF +public class Soda +// CHECKSTYLE:ON +{ + @JsonProperty("name") + private String name; + + @JsonProperty("description") + private String description; + + @JsonAnySetter + @JsonAnyGetter + private final Map cloudSdkCustomFields = new LinkedHashMap<>(); + + /** + * Set the name of this {@link Soda} instance and return the same instance. + * + * @param name The name of this {@link Soda} + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda name( @Nonnull final String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name The name of this {@link Soda} instance. + */ + @Nonnull + public String getName() { + return name; + } + + /** + * Set the name of this {@link Soda} instance. + * + * @param name The name of this {@link Soda} + */ + public void setName( @Nonnull final String name) { + this.name = name; + } + + /** + * Set the description of this {@link Soda} instance and return the same instance. + * + * @param description Soda description as part of the Soda object + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda description( @Nullable final String description) { + this.description = description; + return this; + } + + /** + * Soda description as part of the Soda object + * @return description The description of this {@link Soda} instance. + */ + @Nullable + public String getDescription() { + return description; + } + + /** + * Set the description of this {@link Soda} instance. + * + * @param description Soda description as part of the Soda object + */ + public void setDescription( @Nullable final String description) { + this.description = description; + } + + /** + * Get the names of the unrecognizable properties of the {@link Soda}. + * @return The set of properties names + */ + @JsonIgnore + @Nonnull + public Set getCustomFieldNames() { + return cloudSdkCustomFields.keySet(); + } + + /** + * Get the value of an unrecognizable property of this {@link Soda} instance. + * @deprecated Use {@link #toMap()} instead. + * @param name The name of the property + * @return The value of the property + * @throws NoSuchElementException If no property with the given name could be found. + */ + @Nullable + @Deprecated + public Object getCustomField( @Nonnull final String name ) throws NoSuchElementException { + if( !cloudSdkCustomFields.containsKey(name) ) { + throw new NoSuchElementException("Soda has no field with name '" + name + "'."); + } + return cloudSdkCustomFields.get(name); + } + + /** + * Get the value of all properties of this {@link Soda} instance including unrecognized properties. + * + * @return The map of all properties + */ + @JsonIgnore + @Nonnull + public Map toMap() + { + final Map declaredFields = new LinkedHashMap<>(cloudSdkCustomFields); + if( name != null ) declaredFields.put("name", name); + if( description != null ) declaredFields.put("description", description); + return declaredFields; + } + + /** + * Set an unrecognizable property of this {@link Soda} instance. If the map previously contained a mapping + * for the key, the old value is replaced by the specified value. + * @param customFieldName The name of the property + * @param customFieldValue The value of the property + */ + @JsonIgnore + public void setCustomField( @Nonnull String customFieldName, @Nullable Object customFieldValue ) + { + cloudSdkCustomFields.put(customFieldName, customFieldValue); + } + + + @Override + public boolean equals(@Nullable final java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Soda soda = (Soda) o; + return Objects.equals(this.cloudSdkCustomFields, soda.cloudSdkCustomFields) && + Objects.equals(this.name, soda.name) && + Objects.equals(this.description, soda.description); + } + + @Override + public int hashCode() { + return Objects.hash(name, description, cloudSdkCustomFields); + } + + @Override + @Nonnull public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class Soda {\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" description: ").append(toIndentedString(description)).append("\n"); + cloudSdkCustomFields.forEach((k,v) -> sb.append(" ").append(k).append(": ").append(toIndentedString(v)).append("\n")); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(final java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/AllOf.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/AllOf.java index 9dfaf3ea30..acb1c546e2 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/AllOf.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/AllOf.java @@ -63,7 +63,7 @@ public class AllOf * Get sodaType * @return sodaType The sodaType of this {@link AllOf} instance. */ - @Nonnull + @Nullable public String getSodaType() { return sodaType; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/AnyOf.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/AnyOf.java index 59f1e77c07..caa2a6634d 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/AnyOf.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/AnyOf.java @@ -65,7 +65,7 @@ public class AnyOf * Get sodaType * @return sodaType The sodaType of this {@link AnyOf} instance. */ - @Nonnull + @Nullable public String getSodaType() { return sodaType; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/Cola.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/Cola.java index 523e3146a8..9bb0649a9e 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/Cola.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/Cola.java @@ -63,7 +63,7 @@ public class Cola * Get sodaType * @return sodaType The sodaType of this {@link Cola} instance. */ - @Nonnull + @Nullable public String getSodaType() { return sodaType; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/Fanta.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/Fanta.java index 349aeaae22..d017ff606b 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/Fanta.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/Fanta.java @@ -63,7 +63,7 @@ public class Fanta * Get sodaType * @return sodaType The sodaType of this {@link Fanta} instance. */ - @Nonnull + @Nullable public String getSodaType() { return sodaType; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/OneOf.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/OneOf.java index e41a7b7929..2d7585849f 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/OneOf.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/OneOf.java @@ -65,7 +65,7 @@ public class OneOf * Get sodaType * @return sodaType The sodaType of this {@link OneOf} instance. */ - @Nonnull + @Nullable public String getSodaType() { return sodaType; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/OneOfWithDiscriminator.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/OneOfWithDiscriminator.java index 5e2f1fc1cb..38866718d0 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/OneOfWithDiscriminator.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/OneOfWithDiscriminator.java @@ -73,7 +73,7 @@ public class OneOfWithDiscriminator * Get sodaType * @return sodaType The sodaType of this {@link OneOfWithDiscriminator} instance. */ - @Nonnull + @Nullable public String getSodaType() { return sodaType; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/OneOfWithDiscriminatorAndMapping.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/OneOfWithDiscriminatorAndMapping.java index 0fab43fec8..0003a28685 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/OneOfWithDiscriminatorAndMapping.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-disabled/output/test/OneOfWithDiscriminatorAndMapping.java @@ -73,7 +73,7 @@ public class OneOfWithDiscriminatorAndMapping * Get sodaType * @return sodaType The sodaType of this {@link OneOfWithDiscriminatorAndMapping} instance. */ - @Nonnull + @Nullable public String getSodaType() { return sodaType; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/AllOf.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/AllOf.java index 67c23e5780..b98dc1c9f8 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/AllOf.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/AllOf.java @@ -72,7 +72,7 @@ public class AllOf * Get sodaType * @return sodaType The sodaType of this {@link AllOf} instance. */ - @Nonnull + @Nullable public String getSodaType() { return sodaType; } @@ -101,7 +101,7 @@ public void setSodaType( @Nullable final String sodaType) { * Get barCode * @return barCode The barCode of this {@link AllOf} instance. */ - @Nonnull + @Nullable public ColaBarCode getBarCode() { return barCode; } @@ -130,7 +130,7 @@ public void setBarCode( @Nullable final ColaBarCode barCode) { * Get flavor * @return flavor The flavor of this {@link AllOf} instance. */ - @Nonnull + @Nullable public FantaFlavor getFlavor() { return flavor; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/AnyOf.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/AnyOf.java index 367a2551d9..f168f1fe8a 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/AnyOf.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/AnyOf.java @@ -74,7 +74,7 @@ public class AnyOf * Get sodaType * @return sodaType The sodaType of this {@link AnyOf} instance. */ - @Nonnull + @Nullable public String getSodaType() { return sodaType; } @@ -103,7 +103,7 @@ public void setSodaType( @Nullable final String sodaType) { * Get barCode * @return barCode The barCode of this {@link AnyOf} instance. */ - @Nonnull + @Nullable public ColaBarCode getBarCode() { return barCode; } @@ -132,7 +132,7 @@ public void setBarCode( @Nullable final ColaBarCode barCode) { * Get flavor * @return flavor The flavor of this {@link AnyOf} instance. */ - @Nonnull + @Nullable public FantaFlavor getFlavor() { return flavor; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/Cola.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/Cola.java index 5a8354f0cc..b0597db43b 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/Cola.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/Cola.java @@ -71,7 +71,7 @@ public class Cola implements OneOf, OneOfWithDiscriminator, OneOfWithDiscriminat * Get sodaType * @return sodaType The sodaType of this {@link Cola} instance. */ - @Nonnull + @Nullable public String getSodaType() { return sodaType; } @@ -100,7 +100,7 @@ public void setSodaType( @Nullable final String sodaType) { * Get barCode * @return barCode The barCode of this {@link Cola} instance. */ - @Nonnull + @Nullable public ColaBarCode getBarCode() { return barCode; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/Fanta.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/Fanta.java index 877eb424e4..5ef1720d8a 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/Fanta.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/Fanta.java @@ -71,7 +71,7 @@ public class Fanta implements OneOf, OneOfWithDiscriminator, OneOfWithDiscrimina * Get sodaType * @return sodaType The sodaType of this {@link Fanta} instance. */ - @Nonnull + @Nullable public String getSodaType() { return sodaType; } @@ -100,7 +100,7 @@ public void setSodaType( @Nullable final String sodaType) { * Get flavor * @return flavor The flavor of this {@link Fanta} instance. */ - @Nonnull + @Nullable public FantaFlavor getFlavor() { return flavor; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/output/com/sap/cloud/sdk/services/builder/model/Soda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/output/com/sap/cloud/sdk/services/builder/model/Soda.java index 45a204a0fc..8e84b6fe21 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/output/com/sap/cloud/sdk/services/builder/model/Soda.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/output/com/sap/cloud/sdk/services/builder/model/Soda.java @@ -75,7 +75,7 @@ public class Soda * Get id * @return id The id of this {@link Soda} instance. */ - @Nonnull + @Nullable public Long getId() { return id; } @@ -162,7 +162,7 @@ public void setBrand( @Nonnull final String brand) { * Get isAvailable * @return isAvailable The isAvailable of this {@link Soda} instance. */ - @Nonnull + @Nullable public Boolean isIsAvailable() { return isAvailable; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/output/com/sap/cloud/sdk/services/builder/model/SodaWithFoo.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/output/com/sap/cloud/sdk/services/builder/model/SodaWithFoo.java index edccab010d..22a7aeff5b 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/output/com/sap/cloud/sdk/services/builder/model/SodaWithFoo.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/output/com/sap/cloud/sdk/services/builder/model/SodaWithFoo.java @@ -75,7 +75,7 @@ public class SodaWithFoo * Get id * @return id The id of this {@link SodaWithFoo} instance. */ - @Nonnull + @Nullable public Long getId() { return id; } @@ -162,7 +162,7 @@ public void setBrand( @Nonnull final String brand) { * Get isAvailable * @return isAvailable The isAvailable of this {@link SodaWithFoo} instance. */ - @Nonnull + @Nullable public Boolean isIsAvailable() { return isAvailable; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/output/com/sap/cloud/sdk/services/builder/model/UpdateSoda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/output/com/sap/cloud/sdk/services/builder/model/UpdateSoda.java index 40d04555dd..564bcc1d79 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/output/com/sap/cloud/sdk/services/builder/model/UpdateSoda.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/output/com/sap/cloud/sdk/services/builder/model/UpdateSoda.java @@ -76,7 +76,7 @@ public class UpdateSoda * Get name * @return name The name of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public String getName() { return name; } @@ -105,7 +105,7 @@ public void setName( @Nullable final String name) { * Get zero * @return zero The zero of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public Boolean isZero() { return zero; } @@ -134,7 +134,7 @@ public void setZero( @Nullable final Boolean zero) { * Get since * @return since The since of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public LocalDate getSince() { return since; } @@ -163,7 +163,7 @@ public void setSince( @Nullable final LocalDate since) { * Get brand * @return brand The brand of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public String getBrand() { return brand; } @@ -192,7 +192,7 @@ public void setBrand( @Nullable final String brand) { * Get price * @return price The price of this {@link UpdateSoda} instance. */ - @Nonnull + @Nullable public Float getPrice() { return price; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/remove-operation-id-prefix/output/com/sap/cloud/sdk/services/builder/model/Order.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/remove-operation-id-prefix/output/com/sap/cloud/sdk/services/builder/model/Order.java index 30c807a7b3..44788e1d0f 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/remove-operation-id-prefix/output/com/sap/cloud/sdk/services/builder/model/Order.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/remove-operation-id-prefix/output/com/sap/cloud/sdk/services/builder/model/Order.java @@ -133,7 +133,7 @@ public void setQuantity( @Nonnull final Integer quantity) { * Get totalPrice * @return totalPrice The totalPrice of this {@link Order} instance. */ - @Nonnull + @Nullable public Float getTotalPrice() { return totalPrice; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/remove-operation-id-prefix/output/com/sap/cloud/sdk/services/builder/model/OrderWithTimestamp.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/remove-operation-id-prefix/output/com/sap/cloud/sdk/services/builder/model/OrderWithTimestamp.java index b81a924cb9..0ebaa8792f 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/remove-operation-id-prefix/output/com/sap/cloud/sdk/services/builder/model/OrderWithTimestamp.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/remove-operation-id-prefix/output/com/sap/cloud/sdk/services/builder/model/OrderWithTimestamp.java @@ -137,7 +137,7 @@ public void setQuantity( @Nonnull final Integer quantity) { * Get totalPrice * @return totalPrice The totalPrice of this {@link OrderWithTimestamp} instance. */ - @Nonnull + @Nullable public Float getTotalPrice() { return totalPrice; } @@ -224,7 +224,7 @@ public void setNullableProperty( @Nullable final String nullableProperty) { * Get timestamp * @return timestamp The timestamp of this {@link OrderWithTimestamp} instance. */ - @Nonnull + @Nullable public OffsetDateTime getTimestamp() { return timestamp; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/remove-operation-id-prefix/output/com/sap/cloud/sdk/services/builder/model/Soda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/remove-operation-id-prefix/output/com/sap/cloud/sdk/services/builder/model/Soda.java index 862a33733d..fecd099eaa 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/remove-operation-id-prefix/output/com/sap/cloud/sdk/services/builder/model/Soda.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/remove-operation-id-prefix/output/com/sap/cloud/sdk/services/builder/model/Soda.java @@ -221,7 +221,7 @@ public void setQuantity( @Nonnull final Integer quantity) { * Get packaging * @return packaging The packaging of this {@link Soda} instance. */ - @Nonnull + @Nullable public PackagingEnum getPackaging() { return packaging; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/remove-operation-id-prefix/output/com/sap/cloud/sdk/services/builder/model/SodaWithId.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/remove-operation-id-prefix/output/com/sap/cloud/sdk/services/builder/model/SodaWithId.java index 70553d4ca3..e04f94e4c6 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/remove-operation-id-prefix/output/com/sap/cloud/sdk/services/builder/model/SodaWithId.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/remove-operation-id-prefix/output/com/sap/cloud/sdk/services/builder/model/SodaWithId.java @@ -224,7 +224,7 @@ public void setQuantity( @Nonnull final Integer quantity) { * Get packaging * @return packaging The packaging of this {@link SodaWithId} instance. */ - @Nonnull + @Nullable public PackagingEnum getPackaging() { return packaging; } @@ -282,7 +282,7 @@ public void setPrice( @Nonnull final Float price) { * Get id * @return id The id of this {@link SodaWithId} instance. */ - @Nonnull + @Nullable public Long getId() { return id; } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/ValidationKeywordsPreprocessorTest/sodastore-31-nullable.json b/datamodel/openapi/openapi-generator/src/test/resources/ValidationKeywordsPreprocessorTest/sodastore-31-nullable.json new file mode 100644 index 0000000000..cdb6054207 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/ValidationKeywordsPreprocessorTest/sodastore-31-nullable.json @@ -0,0 +1,67 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "OAS 3.1 Nullable Test API", + "version": "1.0.0" + }, + "paths": { + "/sodas": { + "post": { + "operationId": "addSoda", + "summary": "Add a soda with nullable fields", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "brand": { + "anyOf": [ + { "$ref": "#/components/schemas/Brand" }, + { "type": "null" } + ] + } + } + } + } + } + }, + "responses": { + "201": { + "description": "Created" + } + } + } + } + }, + "components": { + "schemas": { + "Brand": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + }, + "NullableRef": { + "type": "object", + "properties": { + "optionalBrand": { + "anyOf": [ + { "$ref": "#/components/schemas/Brand" }, + { "type": "null" } + ] + }, + "requiredName": { + "type": "string" + } + } + } + } + } +}