-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
263 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { CompositeGeneratorNode, NL, toString } from "langium/generate"; | ||
|
||
import { Artifact } from "../artifact-generator.js"; | ||
import { JavaServerJakartaWSConfig, toPath } from "../java-gen-utils.js"; | ||
import { MEnumType, MInlineEnumType } from "../model.js"; | ||
|
||
export function generateEnum(t: MEnumType, artifactConfig: JavaServerJakartaWSConfig): Artifact { | ||
const packageName = `${artifactConfig.rootPackageName}.dto`; | ||
|
||
const node = new CompositeGeneratorNode() | ||
node.append('// Generated by RSD - Do not modify',NL) | ||
node.append(`package ${packageName};`, NL, NL) | ||
node.append(`public enum ${t.name} {`, NL) | ||
node.indent( child => { | ||
t.entries.forEach( e => child.append(e.name, ',', NL) ) | ||
} ) | ||
node.append('}',NL) | ||
|
||
return { | ||
name: `${t.name}.java`, | ||
content: toString(node), | ||
path: toPath(artifactConfig.targetFolder, packageName) | ||
}; | ||
} | ||
|
||
export function generateInlineEnum(t: MInlineEnumType, name: string, node: CompositeGeneratorNode) { | ||
node.indent( child => { | ||
child.append(`public enum ${name} {`, NL); | ||
child.indent( enumBody => { | ||
t.entries.forEach( e => { | ||
enumBody.append(`${e.name},`, NL); | ||
}) | ||
} ) | ||
child.append('}', NL, NL) | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import chalk from "chalk"; | ||
import { isMEnumType, isMRecordType, isMUnionType, MResolvedRSDModel, MResolvedUserType } from "../model.js"; | ||
import { Artifact, ArtifactGenerationConfig, ArtifactGeneratorConfig } from "../artifact-generator.js"; | ||
import { isJavaServerJakartaWSConfig, JavaServerJakartaWSConfig } from "../java-gen-utils.js"; | ||
import { isDefined } from "../util.js"; | ||
import { generateRecord } from "./record.js"; | ||
import { generateUnion } from "./union.js"; | ||
|
||
export function generate(model: MResolvedRSDModel, generatorConfig: ArtifactGenerationConfig, artifactConfig: ArtifactGeneratorConfig): readonly Artifact [] { | ||
console.log(chalk.cyan('Generating Java-Server-Jakarta-WS')); | ||
|
||
if( ! isJavaServerJakartaWSConfig(artifactConfig) ) { | ||
console.log(chalk.red(' Invalid configuration passed aborted artifact generation')); | ||
return []; | ||
} | ||
|
||
const result = model.elements.map( e => generateType(e, artifactConfig) ).filter(isDefined) | ||
|
||
return result; | ||
} | ||
|
||
function generateType(t: MResolvedUserType, artifactConfig: JavaServerJakartaWSConfig): Artifact | undefined { | ||
if( isMEnumType(t) ) { | ||
|
||
} else if( isMRecordType(t) ) { | ||
return generateRecord(t, artifactConfig); | ||
} else if( isMUnionType(t) ) { | ||
return generateUnion(t, artifactConfig) | ||
} | ||
return undefined; | ||
} | ||
|
||
export default { | ||
name: 'java-server-jakarta-ws', | ||
generate | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import { CompositeGeneratorNode, NL, toString } from "langium/generate"; | ||
import { Artifact } from "../artifact-generator.js"; | ||
import { builtinToJavaType, generateCompilationUnit, JavaImportsCollector, JavaServerJakartaWSConfig, resolveObjectType, resolveType, toPath } from "../java-gen-utils.js"; | ||
import { allRecordProperties, isMInlineEnumType, isMKeyProperty, isMProperty, isMRevisionProperty, MResolvedRecordType } from "../model.js"; | ||
import { toFirstUpper } from "../util.js"; | ||
import { generateInlineEnum } from "./enum.js"; | ||
|
||
export function generateRecord(t: MResolvedRecordType, artifactConfig: JavaServerJakartaWSConfig): Artifact | undefined { | ||
if( t.resolved.unions.length === 1 ) { | ||
return undefined; | ||
} | ||
const packageName = `${artifactConfig.rootPackageName}.dto`; | ||
|
||
const importCollector = new JavaImportsCollector(packageName); | ||
const fqn = importCollector.importType.bind(importCollector); | ||
|
||
return { | ||
name: `${t.name}DTO.java`, | ||
content: toString(generateCompilationUnit(packageName, importCollector, generateRecordContent(t, artifactConfig, fqn))), | ||
path: toPath(artifactConfig.targetFolder, packageName) | ||
}; | ||
} | ||
|
||
export function generateRecordContent(t: MResolvedRecordType, artifactConfig: JavaServerJakartaWSConfig, fqn: (type: string) => string): CompositeGeneratorNode { | ||
const node = new CompositeGeneratorNode(); | ||
|
||
const allProps = allRecordProperties(t); | ||
|
||
node.append(`public record ${t.name}DTO(`,NL) | ||
node.indent( param => { | ||
allProps.forEach( (property, idx, arr) => { | ||
const end = idx + 1 < arr.length ? ',' : ') {' | ||
if( isMKeyProperty(property) ) { | ||
param.append(`${builtinToJavaType(property.type, fqn)} ${property.name}`, end, NL) | ||
} else if( isMRevisionProperty(property) ) { | ||
param.append(`${builtinToJavaType(property.type, fqn)} ${property.name}`, end, NL) | ||
} else { | ||
if( property.variant === 'union' || property.variant === 'record' ) { | ||
if( property.array ) { | ||
param.append(`${fqn('java.util.List')}<${property.type}DTO> ${property.name}`, end, NL) | ||
} else { | ||
param.append(`${property.type}DTO ${property.name}`, end, NL) | ||
} | ||
} else if( typeof property.type === 'string' ) { | ||
if( property.array ) { | ||
param.append(`${fqn('java.util.List')}<${resolveObjectType(property.type, artifactConfig.nativeTypeSubstitues, fqn)}> ${property.name}`, end, NL) | ||
} else { | ||
param.append(`${resolveType(property.type, artifactConfig.nativeTypeSubstitues, fqn)} ${property.name}`, end, NL) | ||
} | ||
} else { | ||
param.append(`${toFirstUpper(property.name)} ${property.name}`, end, NL) | ||
} | ||
} | ||
}); | ||
}) | ||
|
||
allProps | ||
.filter(isMProperty) | ||
.filter(p => p.variant === 'inline-enum') | ||
.forEach( p => { | ||
const inlineEnum = p.type; | ||
if( isMInlineEnumType(inlineEnum) ) { | ||
generateInlineEnum(inlineEnum, toFirstUpper(p.name), node) | ||
} | ||
}); | ||
|
||
node.append('}') | ||
|
||
return node; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import { CompositeGeneratorNode, IndentNode, NL, toString } from "langium/generate"; | ||
import { Artifact } from "../artifact-generator.js"; | ||
import { builtinToJavaType, generateCompilationUnit, JavaImportsCollector, JavaServerJakartaWSConfig, resolveObjectType, resolveType, toPath } from "../java-gen-utils.js"; | ||
import { allRecordProperties, isMInlineEnumType, isMKeyProperty, isMProperty, isMRevisionProperty, MKeyProperty, MProperty, MResolvedRecordType, MResolvedUnionType, MRevisionProperty } from "../model.js"; | ||
import { generateInlineEnum } from "./enum.js"; | ||
import { toFirstUpper } from "../util.js"; | ||
|
||
export function generateUnion(t: MResolvedUnionType, artifactConfig: JavaServerJakartaWSConfig): Artifact { | ||
const packageName = `${artifactConfig.rootPackageName}.dto`; | ||
|
||
const importCollector = new JavaImportsCollector(packageName); | ||
const fqn = importCollector.importType.bind(importCollector); | ||
|
||
const JsonbTypeInfo = fqn('jakarta.json.bind.annotation.JsonbTypeInfo'); | ||
const JsonbSubtype = fqn('jakarta.json.bind.annotation.JsonbSubtype'); | ||
|
||
const childRecords = t.resolved.records.filter(r => r.resolved.unions.length === 1); | ||
const node = new CompositeGeneratorNode(); | ||
node.append(`@${JsonbTypeInfo}({`,NL) | ||
node.indent( child => { | ||
childRecords.forEach( r => { | ||
const desc = (t.descriminatorAliases ?? {})[r.name] ?? r.name; | ||
child.append(`@${JsonbSubtype}(alias = "${desc}", type = ${t.name}DTO.${r.name}DTO.class),`,NL); | ||
} ) | ||
} ); | ||
|
||
node.append('})',NL) | ||
node.append(`public abstract class ${t.name}DTO {`,NL) | ||
t.resolved.sharedProps | ||
.filter(isMProperty) | ||
.filter(p => p.variant === 'inline-enum') | ||
.forEach( p => { | ||
const inlineEnum = p.type; | ||
if( isMInlineEnumType(inlineEnum) ) { | ||
generateInlineEnum(inlineEnum, toFirstUpper(p.name), node) | ||
} | ||
}); | ||
|
||
|
||
node.indent( child => { | ||
t.resolved.sharedProps.forEach( p => generateProperty(child, p, artifactConfig, fqn) ) | ||
}) | ||
|
||
|
||
node.indent( child => { | ||
childRecords.forEach( r => { | ||
child.appendNewLine() | ||
generateUnionRecordContent(child, r, t, artifactConfig, fqn); | ||
} ) | ||
}) | ||
|
||
|
||
node.append('}'); | ||
|
||
return { | ||
name: `${t.name}DTO.java`, | ||
content: toString(generateCompilationUnit(packageName, importCollector, node)), | ||
path: toPath(artifactConfig.targetFolder, packageName) | ||
}; | ||
} | ||
|
||
function generateUnionRecordContent(node: IndentNode, t: MResolvedRecordType, p: MResolvedUnionType, artifactConfig: JavaServerJakartaWSConfig, fqn: (type: string) => string) { | ||
node.append(`public static class ${t.name}DTO extends ${p.name}DTO {`,NL) | ||
|
||
const sharedProps = t.resolved.unions.flatMap(u => u.resolved.sharedProps); | ||
|
||
const allProps = allRecordProperties(t); | ||
allProps | ||
.filter(isMProperty) | ||
.filter(p => p.variant === 'inline-enum') | ||
.filter(p => !sharedProps.includes(p)) | ||
.forEach( p => { | ||
const inlineEnum = p.type; | ||
if( isMInlineEnumType(inlineEnum) ) { | ||
generateInlineEnum(inlineEnum, toFirstUpper(p.name), node) | ||
} | ||
}); | ||
|
||
node.indent( child => { | ||
allProps.filter(p => !sharedProps.includes(p)).forEach( p => generateProperty(child, p, artifactConfig, fqn)) | ||
}) | ||
|
||
node.append('}',NL) | ||
} | ||
|
||
function generateProperty(node: IndentNode, property: MKeyProperty | MRevisionProperty | MProperty, artifactConfig: JavaServerJakartaWSConfig, fqn: (type: string) => string) { | ||
if( isMKeyProperty(property) ) { | ||
node.append(`public ${builtinToJavaType(property.type, fqn)} ${property.name};`,NL) | ||
} else if( isMRevisionProperty(property) ) { | ||
node.append(`public ${builtinToJavaType(property.type, fqn)} ${property.name};`,NL) | ||
} else { | ||
if( property.variant === 'union' || property.variant === 'record' ) { | ||
if( property.array ) { | ||
node.append(`public ${fqn('java.util.List')}<${property.type}DTO> ${property.name};`,NL) | ||
} else { | ||
node.append(`public ${property.type}DTO ${property.name};`,NL) | ||
} | ||
} else if( typeof property.type === 'string' ) { | ||
if( property.array ) { | ||
node.append(`public ${fqn('java.util.List')}<${resolveObjectType(property.type, artifactConfig.nativeTypeSubstitues, fqn)}> ${property.name};`,NL) | ||
} else { | ||
node.append(`public ${resolveType(property.type, artifactConfig.nativeTypeSubstitues, fqn)} ${property.name};`,NL) | ||
} | ||
} else { | ||
node.append(`public ${toFirstUpper(property.name)} ${property.name};`,NL) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters