Skip to content

Commit 795087e

Browse files
authored
feat: add Java record support (#2220)
1 parent 9cbeda0 commit 795087e

File tree

11 files changed

+250
-3
lines changed

11 files changed

+250
-3
lines changed

examples/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ These are all specific examples only relevant to the Java generator:
118118
- [java-generate-javax-constraint-annotation](./java-generate-javax-constraint-annotation) - A basic example that shows how Java data models having `javax.validation.constraints` annotations can be generated.
119119
- [java-generate-javadoc](./java-generate-javadoc) - A basic example of how to generate Java models including JavaDocs.
120120
- [integrate-into-maven](./integrate-with-maven/) - A basic example that shows how you can integrate Modelina into the Java Maven build process.
121+
- [java-generate-records](./java-generate-records/) - A basic example that shows how to change Java model type from class to record.
121122

122123
### C#
123124
These are all specific examples only relevant to the C# generator:
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Java Generate `record`
2+
3+
A basic example on how to generate models that use Java's `record` type instead of `class`
4+
5+
## How to run this example
6+
7+
Run this example using:
8+
9+
```sh
10+
npm i && npm run start
11+
```
12+
13+
If you are on Windows, use the `start:windows` script instead:
14+
15+
```sh
16+
npm i && npm run start:windows
17+
```
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`Should be able to render a Java record instead of a class using the modelType option and should log expected output to console 1`] = `
4+
Array [
5+
"public record Root(String email, String name) {
6+
7+
}",
8+
]
9+
`;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
const spy = jest.spyOn(global.console, 'log').mockImplementation(() => {
2+
return;
3+
});
4+
import { generate } from './index';
5+
6+
describe('Should be able to render a Java record instead of a class using the modelType option', () => {
7+
afterAll(() => {
8+
jest.restoreAllMocks();
9+
});
10+
test('and should log expected output to console', async () => {
11+
await generate();
12+
expect(spy.mock.calls.length).toEqual(1);
13+
expect(spy.mock.calls[0]).toMatchSnapshot();
14+
});
15+
});
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { JavaGenerator } from '../../src';
2+
3+
const generator = new JavaGenerator({
4+
modelType: 'record'
5+
});
6+
7+
const jsonSchemaDraft7 = {
8+
$schema: 'http://json-schema.org/draft-07/schema#',
9+
type: 'object',
10+
additionalProperties: false,
11+
properties: {
12+
email: {
13+
type: 'string',
14+
format: 'email'
15+
},
16+
name: {
17+
type: 'string'
18+
}
19+
}
20+
};
21+
22+
export async function generate(): Promise<void> {
23+
const models = await generator.generate(jsonSchemaDraft7);
24+
for (const model of models) {
25+
console.log(model.result);
26+
}
27+
}
28+
if (require.main === module) {
29+
generate();
30+
}

examples/java-generate-records/package-lock.json

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"config": {
3+
"example_name": "java-generate-records"
4+
},
5+
"scripts": {
6+
"install": "cd ../.. && npm i",
7+
"start": "../../node_modules/.bin/ts-node --cwd ../../ ./examples/$npm_package_config_example_name/index.ts",
8+
"start:windows": "..\\..\\node_modules\\.bin\\ts-node --cwd ..\\..\\ .\\examples\\%npm_package_config_example_name%\\index.ts",
9+
"test": "../../node_modules/.bin/jest --config=../../jest.config.js ./examples/$npm_package_config_example_name/index.spec.ts",
10+
"test:windows": "..\\..\\node_modules\\.bin\\jest --config=..\\..\\jest.config.js examples/%npm_package_config_example_name%/index.spec.ts"
11+
}
12+
}

src/generators/java/Constants.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ export const RESERVED_JAVA_KEYWORDS = [
5050
'float',
5151
'native',
5252
'super',
53-
'while'
53+
'while',
54+
'record'
5455
];
5556

5657
export function isReservedJavaKeyword(

src/generators/java/JavaGenerator.ts

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,13 @@ import {
4646
import { DeepPartial, mergePartialAndDefault } from '../../utils/Partials';
4747
import { JavaDependencyManager } from './JavaDependencyManager';
4848
import { UnionRenderer } from './renderers/UnionRenderer';
49+
import { RecordRenderer } from './renderers/RecordRenderer';
4950

5051
export interface JavaOptions extends CommonGeneratorOptions<JavaPreset> {
5152
collectionType: 'List' | 'Array';
5253
typeMapping: TypeMapping<JavaOptions, JavaDependencyManager>;
5354
constraints: Constraints<JavaOptions>;
55+
modelType: 'class' | 'record';
5456
}
5557
export type JavaConstantConstraint = ConstantConstraint<JavaOptions>;
5658
export type JavaEnumKeyConstraint = EnumKeyConstraint<JavaOptions>;
@@ -87,7 +89,8 @@ export class JavaGenerator extends AbstractGenerator<
8789
defaultPreset: JAVA_DEFAULT_PRESET,
8890
collectionType: 'Array',
8991
typeMapping: JavaDefaultTypeMapping,
90-
constraints: JavaDefaultConstraints
92+
constraints: JavaDefaultConstraints,
93+
modelType: 'class'
9194
};
9295

9396
static defaultCompleteModelOptions: JavaRenderCompleteModelOptions = {
@@ -169,6 +172,13 @@ export class JavaGenerator extends AbstractGenerator<
169172
...args.options
170173
});
171174
if (args.constrainedModel instanceof ConstrainedObjectModel) {
175+
if (this.options.modelType === 'record') {
176+
return this.renderRecord(
177+
args.constrainedModel,
178+
args.inputModel,
179+
optionsToUse
180+
);
181+
}
172182
return this.renderClass({
173183
...args,
174184
constrainedModel: args.constrainedModel,
@@ -343,4 +353,31 @@ ${outputModel.result}`;
343353
dependencies: dependencyManagerToUse.dependencies
344354
});
345355
}
356+
357+
async renderRecord(
358+
model: ConstrainedObjectModel,
359+
inputModel: InputMetaModel,
360+
options?: Partial<JavaOptions>
361+
): Promise<RenderOutput> {
362+
const optionsToUse = JavaGenerator.getJavaOptions({
363+
...this.options,
364+
...options
365+
});
366+
const dependencyManagerToUse = this.getDependencyManager(optionsToUse);
367+
const presets = this.getPresets('record');
368+
const renderer = new RecordRenderer(
369+
this.options,
370+
this,
371+
presets,
372+
model,
373+
inputModel,
374+
dependencyManagerToUse
375+
);
376+
const result = await renderer.runSelfPreset();
377+
return RenderOutput.toRenderOutput({
378+
result,
379+
renderedName: model.name,
380+
dependencies: dependencyManagerToUse.dependencies
381+
});
382+
}
346383
}

src/generators/java/JavaPreset.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import {
77
EnumArgs,
88
ConstrainedEnumModel,
99
CommonPreset,
10-
ConstrainedUnionModel
10+
ConstrainedUnionModel,
11+
InterfacePreset
1112
} from '../../models';
1213
import { JavaOptions } from './JavaGenerator';
1314
import {
@@ -18,6 +19,10 @@ import {
1819
EnumRenderer,
1920
JAVA_DEFAULT_ENUM_PRESET
2021
} from './renderers/EnumRenderer';
22+
import {
23+
JAVA_DEFAULT_RECORD_PRESET,
24+
RecordRenderer
25+
} from './renderers/RecordRenderer';
2126
import {
2227
JAVA_DEFAULT_UNION_PRESET,
2328
UnionRenderer
@@ -45,13 +50,17 @@ export interface UnionPreset<R extends AbstractRenderer, O>
4550
) => string;
4651
}
4752

53+
export type RecordPresetType<O> = InterfacePreset<RecordRenderer, O>;
54+
4855
export type JavaPreset<O = any> = Preset<{
56+
record: RecordPresetType<O>;
4957
class: ClassPresetType<O>;
5058
enum: EnumPresetType<O>;
5159
union: UnionPresetType<O>;
5260
}>;
5361

5462
export const JAVA_DEFAULT_PRESET: JavaPreset<JavaOptions> = {
63+
record: JAVA_DEFAULT_RECORD_PRESET,
5564
class: JAVA_DEFAULT_CLASS_PRESET,
5665
enum: JAVA_DEFAULT_ENUM_PRESET,
5766
union: JAVA_DEFAULT_UNION_PRESET

0 commit comments

Comments
 (0)