Skip to content

Commit

Permalink
generate server side builders
Browse files Browse the repository at this point in the history
  • Loading branch information
tomsontom committed Nov 21, 2024
1 parent ba28baa commit 150c6e1
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 26 deletions.
6 changes: 5 additions & 1 deletion dsl/src/cli/java-client-api/record.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ export function generateRecordContent(t: MResolvedRecordType, artifactConfig: Ja
.filter(p => p.variant === 'union' || p.variant === 'record')
.forEach(p => {
const functionType = fqn('java.util.function.Function');
builderChild.append(`public <T extends ${p.type}DTO.Builder> Builder with${toFirstUpper(p.name)}(Class<T> clazz, ${functionType}<T, ${p.type}DTO> block);`,NL)
if( p.variant === 'record' ) {
builderChild.append(`public Builder with${toFirstUpper(p.name)}(${functionType}<${p.type}DTO.Builder, ${p.type}DTO> block);`,NL)
} else {
builderChild.append(`public <T extends ${p.type}DTO.Builder> Builder with${toFirstUpper(p.name)}(Class<T> clazz, ${functionType}<T, ${p.type}DTO> block);`,NL)
}
});
builderChild.append(`public ${t.name}DTO build();`, NL)
} )
Expand Down
63 changes: 39 additions & 24 deletions dsl/src/cli/java-server-jakarta-ws/record.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { CompositeGeneratorNode, IndentNode, NL, toString } from "langium/generate";
import { Artifact } from "../artifact-generator.js";
import { builtinToJavaType, generateCompilationUnit, JavaImportsCollector, JavaServerJakartaWSGeneratorConfig, resolveObjectType, resolveType, toPath } from "../java-gen-utils.js";
import { allRecordProperties, isMKeyProperty, isMRevisionProperty, MBaseProperty, MResolvedRecordType } from "../model.js";
import { allRecordProperties, isMKeyProperty, isMProperty, isMRevisionProperty, MBaseProperty, MResolvedRecordType } from "../model.js";
import { toFirstUpper } from "../util.js";

export function generateRecord(t: MResolvedRecordType, artifactConfig: JavaServerJakartaWSGeneratorConfig): Artifact | undefined {
Expand All @@ -25,17 +25,19 @@ export function generateRecordContent(t: MResolvedRecordType, artifactConfig: Ja

const allProps = allRecordProperties(t);

const dtoInterface = fqn(`${artifactConfig.rootPackageName}.service.dto.${t.name}DTO`);

node.append(`public record ${t.name}DTOImpl(`,NL)
node.indent( param => {
allProps.forEach( (property, idx, arr) => {
const end = idx + 1 < arr.length ? ',' : `) implements ${artifactConfig.rootPackageName}.service.dto.${t.name}DTO {`
const end = idx + 1 < arr.length ? ',' : `) implements ${dtoInterface} {`
addProperty(param, property, end, artifactConfig, fqn);
});
})

node.appendNewLine();
node.indent( body => {
body.append(`public static ${t.name}DTOImpl of(${artifactConfig.rootPackageName}.service.dto.${t.name}DTO source) {`,NL)
body.append(`public static ${t.name}DTOImpl of(${dtoInterface} source) {`,NL)
body.indent( mBody => {
mBody.append(`if(source instanceof ${t.name}DTOImpl) {`,NL)
mBody.indent(inner => {
Expand Down Expand Up @@ -67,7 +69,7 @@ export function generateRecordContent(t: MResolvedRecordType, artifactConfig: Ja
body.append('}')
} )

/*node.appendNewLine();
node.appendNewLine();
node.indent( body => {
body.append(`public static class BuilderImpl implements Builder {`, NL);
body.indent( param => {
Expand All @@ -83,11 +85,20 @@ export function generateRecordContent(t: MResolvedRecordType, artifactConfig: Ja
.filter(p => p.variant === 'union' || p.variant === 'record')
.forEach(p => {
const functionType = fqn('java.util.function.Function');
param.append(`public <T extends ${p.type}DTO.Builder> Builder with${toFirstUpper(p.name)}(Class<T> clazz, ${functionType}<T, ${artifactConfig.rootPackageName}.service.dto.${p.type}DTO> block) {`,NL)
param.indent( methodBody => {
methodBody.append('return this;',NL)
})
param.append('}', NL)
const iType = fqn(`${artifactConfig.rootPackageName}.service.dto.${p.type}DTO`);
if( p.variant === 'record' ) {
param.append(`public Builder with${toFirstUpper(p.name)}(${functionType}<${iType}.Builder, ${iType}> block) {`,NL)
param.indent( methodBody => {
methodBody.append('return this;',NL)
})
param.append('}', NL)
} else {
param.append(`public <T extends ${iType}.Builder> Builder with${toFirstUpper(p.name)}(Class<T> clazz, ${functionType}<T, ${iType}> block) {`,NL)
param.indent( methodBody => {
methodBody.append('return this;',NL)
})
param.append('}', NL)
}
});

param.appendNewLine();
Expand All @@ -97,25 +108,30 @@ export function generateRecordContent(t: MResolvedRecordType, artifactConfig: Ja
})
param.append('}', NL)
});
body.append('}')
})*/
body.append('}',NL)
body.appendNewLine();
body.append('public static Builder builder() {', NL)
body.indent( mBody => {
mBody.append('return new BuilderImpl();', NL)
})
body.append('}',NL)
})

node.append('}')

return node;
}

/*
function addBuilderMethod(param: IndentNode, property: MBaseProperty, artifactConfig: JavaServerJakartaWSGeneratorConfig, fqn: (type: string) => string) {
export function addBuilderMethod(param: IndentNode, property: MBaseProperty, artifactConfig: JavaServerJakartaWSGeneratorConfig, fqn: (type: string) => string, typePrefix = '') {
if( isMKeyProperty(property) ) {
param.append(`public Builder ${property.name}(${builtinToJavaType(property.type, fqn)} ${property.name}) {`, NL)
param.append(`public ${typePrefix}Builder ${property.name}(${builtinToJavaType(property.type, fqn)} ${property.name}) {`, NL)
param.indent( body => {
body.append(`this.${property.name} = ${property.name};`,NL)
body.append('return this;',NL)
})
param.append('}', NL)
} else if( isMRevisionProperty(property) ) {
param.append(`public Builder ${property.name}(${builtinToJavaType(property.type, fqn)} ${property.name}) {`, NL)
param.append(`public ${typePrefix}Builder ${property.name}(${builtinToJavaType(property.type, fqn)} ${property.name}) {`, NL)
param.indent( body => {
body.append(`this.${property.name} = ${property.name};`,NL)
body.append('return this;',NL)
Expand All @@ -124,47 +140,46 @@ function addBuilderMethod(param: IndentNode, property: MBaseProperty, artifactCo
} else {
if( property.variant === 'union' || property.variant === 'record' ) {
if( property.array ) {
param.append(`public Builder ${property.name}(${fqn('java.util.List')}<${artifactConfig.rootPackageName}.service.dto.${property.type}DTO> ${property.name}) {`, NL)
param.append(`public ${typePrefix}Builder ${property.name}(${fqn('java.util.List')}<${artifactConfig.rootPackageName}.service.dto.${property.type}DTO> ${property.name}) {`, NL)
param.indent( body => {
body.append(`this.${property.name} = ${property.name};`,NL)
body.append(`this.${property.name} = ${property.name}.stream().map(${property.type}DTOImpl::of).toList();`,NL)
body.append('return this;',NL)
})
param.append('}', NL)
} else {
param.append(`public Builder ${property.name}(${artifactConfig.rootPackageName}.service.dto.${property.type}DTO ${property.name}) {`, NL)
param.append(`public ${typePrefix}Builder ${property.name}(${artifactConfig.rootPackageName}.service.dto.${property.type}DTO ${property.name}) {`, NL)
param.indent( body => {
body.append(`this.${property.name} = ${property.name};`,NL)
body.append(`this.${property.name} = ${property.type}DTOImpl.of(${property.name});`,NL)
body.append('return this;',NL)
})
param.append('}', NL)
}
} else if( typeof property.type === 'string' ) {
if( property.array ) {
param.append(`public Builder ${property.name}(${fqn('java.util.List')}<${resolveObjectType(property.type, artifactConfig.nativeTypeSubstitues, fqn)}> ${property.name}) {`, NL)
param.append(`public ${typePrefix}Builder ${property.name}(${fqn('java.util.List')}<${resolveObjectType(property.type, artifactConfig.nativeTypeSubstitues, fqn)}> ${property.name}) {`, NL)
param.indent( body => {
body.append(`this.${property.name} = ${property.name};`,NL)
body.append('return this;',NL)
})
param.append('}', NL)
} else {
param.append(`public Builder ${property.name}(${resolveType(property.type, artifactConfig.nativeTypeSubstitues, fqn)} ${property.name}) {`, NL)
param.append(`public ${typePrefix}Builder ${property.name}(${resolveType(property.type, artifactConfig.nativeTypeSubstitues, fqn)} ${property.name}) {`, NL)
param.indent( body => {
body.append(`this.${property.name} = ${property.name};`,NL)
body.append('return this;',NL)
})
param.append('}', NL)
}
} else {
param.append(`public Builder ${property.name}(${toFirstUpper(property.name)} ${property.name}) {`, NL)
param.append(`public ${typePrefix}Builder ${property.name}(${toFirstUpper(property.name)} ${property.name}) {`, NL)
param.indent( body => {
body.append(`this.${property.name} = ${property.name};`,NL)
body.append('return this;',NL)
})
param.append('}', NL)
}
}
}*/

}

function addProperty(param: IndentNode, property: MBaseProperty, end: string, artifactConfig: JavaServerJakartaWSGeneratorConfig, fqn: (type: string) => string) {
if( isMKeyProperty(property) ) {
Expand Down
49 changes: 48 additions & 1 deletion dsl/src/cli/java-server-jakarta-ws/union.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { Artifact } from "../artifact-generator.js";
import { builtinToJavaType, generateCompilationUnit, JavaImportsCollector, JavaServerJakartaWSGeneratorConfig, resolveObjectType, resolveType, toPath } from "../java-gen-utils.js";
import { allRecordProperties, isMKeyProperty, isMRevisionProperty, MKeyProperty, MProperty, MResolvedRecordType, MResolvedUnionType, MRevisionProperty } from "../model.js";
import { toFirstUpper } from "../util.js";
import { addBuilderMethod } from "./record.js";
import { toType } from "../java-client-api/shared.js";

export function generateUnion(t: MResolvedUnionType, artifactConfig: JavaServerJakartaWSGeneratorConfig): Artifact {
const packageName = `${artifactConfig.rootPackageName}.rest.dto`;
Expand Down Expand Up @@ -63,6 +65,14 @@ export function generateUnion(t: MResolvedUnionType, artifactConfig: JavaServerJ
mBody.append('throw new IllegalStateException();',NL);
} )
body.append('}',NL)
body.appendNewLine();
body.append(`public static abstract class BuilderImpl implements Builder {`, NL)
body.indent( mBody => {
t.resolved.sharedProps.forEach( p => generateConstructorProperty(mBody, p, ';', artifactConfig, fqn) )
mBody.appendNewLine();
t.resolved.sharedProps.forEach( p => addBuilderMethod(mBody, p, artifactConfig, fqn))
})
body.append('}',NL)
})

node.indent( child => {
Expand All @@ -83,7 +93,8 @@ export function generateUnion(t: MResolvedUnionType, artifactConfig: JavaServerJ
}

function generateUnionRecordContent(node: IndentNode, t: MResolvedRecordType, p: MResolvedUnionType, artifactConfig: JavaServerJakartaWSGeneratorConfig, fqn: (type: string) => string) {
node.append(`public static class ${t.name}DTOImpl extends ${p.name}DTOImpl implements ${artifactConfig.rootPackageName}.service.dto.${p.name}DTO.${t.name}DTO {`,NL)
const iType = fqn(`${artifactConfig.rootPackageName}.service.dto.${p.name}DTO`);
node.append(`public static class ${t.name}DTOImpl extends ${p.name}DTOImpl implements ${iType}.${t.name}DTO {`,NL)

const sharedProps = t.resolved.unions.flatMap(u => u.resolved.sharedProps);

Expand Down Expand Up @@ -142,6 +153,42 @@ function generateUnionRecordContent(node: IndentNode, t: MResolvedRecordType, p:
mbody.append(');',NL)
})
body.append('}',NL)
body.appendNewLine();
body.append(`public static class BuilderImpl extends ${p.name}DTOImpl.BuilderImpl implements ${iType}.${t.name}DTO.Builder {`, NL)
body.indent( mBody => {
allProps.filter(p => !sharedProps.includes(p)).forEach( p => generateConstructorProperty(mBody, p, ';', artifactConfig, fqn) )
sharedProps.forEach( property => {
if( isMKeyProperty(property) || isMRevisionProperty(property) ) {
mBody.append('@Override', NL)
mBody.append(`public ${t.name}DTO.Builder ${property.name}(${builtinToJavaType(property.type, fqn)} ${property.name}) {`, NL)
mBody.indent( methodBody => {
methodBody.append(`return (${t.name}DTO.Builder) super.${property.name}(${property.name});`, NL)
})
mBody.append('}', NL)
} else {
mBody.append('@Override', NL)
mBody.append(`public ${t.name}DTO.Builder ${property.name}(${toType(property, artifactConfig, fqn)} ${property.name}) {`, NL)
mBody.indent( methodBody => {
methodBody.append(`return (${t.name}DTO.Builder) super.${property.name}(${property.name});`, NL)
})
mBody.append('}', NL);
}
})
allProps.filter(p => !sharedProps.includes(p)).forEach( property => {
addBuilderMethod(mBody, property, artifactConfig, fqn, `${t.name}DTO.`)
})
mBody.append(`public ${t.name}DTO build() {`, NL)
mBody.indent( methodBody => {
methodBody.append(`return new ${t.name}DTOImpl(`, NL)
const props = [ ...sharedProps, ...allProps.filter(p => !sharedProps.includes(p))]
methodBody.indent( inner => {
props.forEach( (p, idx, arr) => inner.append(`this.${p.name}${idx + 1 < arr.length ? ',' : ''}`, NL) )
})
methodBody.append(');', NL)
})
mBody.append('}', NL)
})
body.append('}',NL)
})

node.append('}',NL)
Expand Down

0 comments on commit 150c6e1

Please sign in to comment.