diff --git a/src/main/java/io/vlingo/xoom/schemata/codegen/DomainEventArguments.java b/src/main/java/io/vlingo/xoom/schemata/codegen/DomainEventArguments.java new file mode 100644 index 00000000..6a8d4441 --- /dev/null +++ b/src/main/java/io/vlingo/xoom/schemata/codegen/DomainEventArguments.java @@ -0,0 +1,50 @@ +package io.vlingo.xoom.schemata.codegen; + +import io.vlingo.xoom.schemata.codegen.ast.FieldDefinition; +import io.vlingo.xoom.schemata.codegen.ast.types.TypeDefinition; +import io.vlingo.xoom.schemata.codegen.ast.values.Value; + +import java.util.List; +import java.util.stream.Collectors; + +public class DomainEventArguments { + + public final String namespace; + public final String version; + public final List properties; + public final String typeName; + + public DomainEventArguments(String language, String fqdn, String version, TypeDefinition node) { + this.namespace = extractNamespace(fqdn); + this.typeName = node.typeName; + this.version = version; + this.properties = extractProperties(language, node); + } + + public static class Property { + public final String type; + public final String name; + public final Object value; + + public Property(String type, String name, Object value) { + this.type = type; + this.name = name; + this.value = value; + } + } + + private String extractNamespace(String fqdn) { + int i = fqdn.indexOf(':', fqdn.indexOf(':') + 1) + 1; + int j = fqdn.indexOf(':', i); + return fqdn.substring(i, j) + ".model"; + } + + private List extractProperties(String language, TypeDefinition root) { + TypeMap typeMap = TypeMap.valueOf(language); + return root.children.stream() + .map(node -> (FieldDefinition) node) + .map(node -> new Property(typeMap.typeOf(node.type.name()), node.name, + node.defaultValue.map(Value::value).orElse(null))) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/io/vlingo/xoom/schemata/codegen/TypeDefinitionCompiler.java b/src/main/java/io/vlingo/xoom/schemata/codegen/TypeDefinitionCompiler.java index 87752146..8915b41c 100644 --- a/src/main/java/io/vlingo/xoom/schemata/codegen/TypeDefinitionCompiler.java +++ b/src/main/java/io/vlingo/xoom/schemata/codegen/TypeDefinitionCompiler.java @@ -10,8 +10,6 @@ import io.vlingo.xoom.actors.Stage; import io.vlingo.xoom.common.Completes; import io.vlingo.xoom.common.Outcome; -import io.vlingo.xoom.schemata.codegen.backend.Backend; -import io.vlingo.xoom.schemata.codegen.backend.java.JavaBackend; import io.vlingo.xoom.schemata.codegen.parser.AntlrTypeParser; import io.vlingo.xoom.schemata.codegen.parser.TypeParser; import io.vlingo.xoom.schemata.codegen.processor.Processor; @@ -50,21 +48,19 @@ public static TypeDefinitionCompiler compilerFor(final Stage stage, final String * @return TypeDefinitionCompiler */ public static TypeDefinitionCompiler newCompilerFor(final Stage stage, final String language) { - switch (language) { - case "java": - return forBackend(stage, new JavaBackend()); - default: + if (!language.equals("java") && !language.equals("csharp")){ throw new IllegalArgumentException("Unsupported language: " + language); } + return forBackend(stage, language); } /** * Answer a new {@code TypeDefinitionCompiler} for a given language {@code backendType}. * @param stage the Stage in which to create the compiler actor - * @param backend the language backend + * @param language the backend language * @return TypeDefinitionCompiler */ - static TypeDefinitionCompiler forBackend(final Stage stage, Backend backend) { + static TypeDefinitionCompiler forBackend(final Stage stage, String language) { final TypeParser typeParser = new AntlrTypeParser(); final TypeResolver typeResolver = StorageProvider.instance().typeResolverQueries; @@ -72,7 +68,7 @@ static TypeDefinitionCompiler forBackend(final Stage stage, Backend backend) { Arrays.asList( stage.actorFor(Processor.class, ComputableTypeProcessor.class), stage.actorFor(Processor.class, TypeResolverProcessor.class, typeResolver) - ), backend); + ), language); } /** diff --git a/src/main/java/io/vlingo/xoom/schemata/codegen/TypeDefinitionCompilerActor.java b/src/main/java/io/vlingo/xoom/schemata/codegen/TypeDefinitionCompilerActor.java index 30f18cde..7bb97235 100644 --- a/src/main/java/io/vlingo/xoom/schemata/codegen/TypeDefinitionCompilerActor.java +++ b/src/main/java/io/vlingo/xoom/schemata/codegen/TypeDefinitionCompilerActor.java @@ -10,7 +10,8 @@ import io.vlingo.xoom.common.Completes; import io.vlingo.xoom.common.Outcome; import io.vlingo.xoom.schemata.codegen.ast.Node; -import io.vlingo.xoom.schemata.codegen.backend.Backend; +import io.vlingo.xoom.schemata.codegen.ast.types.TypeDefinition; +import io.vlingo.xoom.schemata.codegen.backend.CodeGenerator; import io.vlingo.xoom.schemata.codegen.parser.TypeParser; import io.vlingo.xoom.schemata.codegen.processor.Processor; import io.vlingo.xoom.schemata.errors.SchemataBusinessException; @@ -22,12 +23,13 @@ public class TypeDefinitionCompilerActor implements TypeDefinitionCompiler, TypeDefinitionMiddleware { private final TypeParser parser; private final List processors; - private final Backend backend; + private final String language; + private final CodeGenerator codeGenerator = new CodeGenerator(); - public TypeDefinitionCompilerActor(final TypeParser parser, final List processors, final Backend backend) { + public TypeDefinitionCompilerActor(final TypeParser parser, final List processors, final String language) { this.parser = parser; this.processors = processors; - this.backend = backend; + this.language = language; } @Override @@ -35,7 +37,7 @@ public Completes> compile(final Input return Completes.withSuccess( parser.parseTypeDefinition(typeDefinition, fullyQualifiedTypeName) .andThen(node -> this.process(fullyQualifiedTypeName).apply(node)) - .andThenTo(node -> backend.generateOutput(node, version)) + .andThenTo(node -> codeGenerator.generateWith(language, "DomainEvent", new DomainEventArguments(language, fullyQualifiedTypeName, version, (TypeDefinition) node))) .otherwiseFail(ex -> ex) ); } diff --git a/src/main/java/io/vlingo/xoom/schemata/codegen/TypeMap.java b/src/main/java/io/vlingo/xoom/schemata/codegen/TypeMap.java new file mode 100644 index 00000000..efc6bcf2 --- /dev/null +++ b/src/main/java/io/vlingo/xoom/schemata/codegen/TypeMap.java @@ -0,0 +1,59 @@ +package io.vlingo.xoom.schemata.codegen; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public enum TypeMap { + + java(ofMapEntries( + "boolean", "boolean", + "byte", "byte", + "char", "char", + "short", "short", + "int", "int", + "long", "long", + "float", "float", + "double", "double", + "string", "String", + "type", "String", + "version", "int", + "timestamp", "long" + )), + csharp(ofMapEntries( + "boolean", "bool", + "byte", "byte", + "char", "char", + "short", "short", + "int", "int", + "long", "long", + "float", "float", + "double", "double", + "type", "string", + "version", "int", + "timestamp", "long" + )); + + final Map types; + + TypeMap(Map types) { + this.types = Collections.unmodifiableMap(types); + } + + public String typeOf(String type){ + return types.getOrDefault(type, type); + } + + private static Map ofMapEntries(String ... entries) { + if (entries.length % 2 != 0){ + throw new IllegalArgumentException("parameters must even"); + } + Map result = new HashMap<>(); + for (int i=0; i generateOutput(Node node, String version); } +*/ diff --git a/src/main/java/io/vlingo/xoom/schemata/codegen/backend/CodeGenerator.java b/src/main/java/io/vlingo/xoom/schemata/codegen/backend/CodeGenerator.java index 35de39c3..8507f425 100644 --- a/src/main/java/io/vlingo/xoom/schemata/codegen/backend/CodeGenerator.java +++ b/src/main/java/io/vlingo/xoom/schemata/codegen/backend/CodeGenerator.java @@ -1,8 +1,13 @@ package io.vlingo.xoom.schemata.codegen.backend; import freemarker.template.*; +import io.vlingo.xoom.common.Outcome; +import io.vlingo.xoom.common.Success; +import io.vlingo.xoom.schemata.errors.SchemataBusinessException; +import io.vlingo.xoom.turbo.codegen.CodeGenerationException; import java.io.IOException; +import java.io.StringWriter; import java.io.Writer; import java.util.Locale; @@ -27,4 +32,14 @@ public void generateWith(String language, String templateName, Object templateAr Template template = configuration.getTemplate("/codegen/" + language + "/" + templateName + ".ftl"); template.process(templateArgs, output); } + + public Outcome generateWith(String language, String templateName, Object templateArgs) { + StringWriter result = new StringWriter(); + try{ + generateWith(language, templateName, templateArgs, result); + }catch (IOException | TemplateException e) { + throw new CodeGenerationException(e); + } + return Success.of(result.toString()); + } } diff --git a/src/main/java/io/vlingo/xoom/schemata/codegen/backend/java/JavaBackend.java b/src/main/java/io/vlingo/xoom/schemata/codegen/backend/java/JavaBackend.java index 39a7edc9..d3bb355c 100644 --- a/src/main/java/io/vlingo/xoom/schemata/codegen/backend/java/JavaBackend.java +++ b/src/main/java/io/vlingo/xoom/schemata/codegen/backend/java/JavaBackend.java @@ -1,3 +1,4 @@ +/* // Copyright © 2012-2021 VLINGO LABS. All rights reserved. // // This Source Code Form is subject to the terms of the @@ -292,3 +293,4 @@ private Class baseClassOf(TypeDefinition type) { } } } +*/ diff --git a/src/main/resources/codegen/csharp/DomainEvent.ftl b/src/main/resources/codegen/csharp/DomainEvent.ftl index 7833f44c..1de3b9ff 100644 --- a/src/main/resources/codegen/csharp/DomainEvent.ftl +++ b/src/main/resources/codegen/csharp/DomainEvent.ftl @@ -1,20 +1,20 @@ using Vlingo.Lattice.Model; using Vlingo.Xoom.Common.Version; -namespace ${package} +namespace ${namespace} { public sealed class ${typeName} : DomainEvent { - public readonly int semanticVersion; + public readonly int eventVersion; - <#list children as p> - public readonly ${p.type.name()} ${p.name}; + <#list properties as p> + public readonly ${p.type} ${p.name}; - public ${typeName}(<#list children as p>${p.type.name()} ${p.name}<#if p?has_next>, ) + public ${typeName}(<#list properties as p>${p.type} ${p.name}<#if p?has_next>, ) { - this.semanticVersion = SemanticVersion.toValue("1.0.0"); - <#list children as p> + this.eventVersion = SemanticVersion.toValue("${version}"); + <#list properties as p> this.${p.name} = ${p.name}; } diff --git a/src/main/resources/codegen/java/DomainEvent.ftl b/src/main/resources/codegen/java/DomainEvent.ftl index a39208e1..4ebe01ea 100644 --- a/src/main/resources/codegen/java/DomainEvent.ftl +++ b/src/main/resources/codegen/java/DomainEvent.ftl @@ -1,20 +1,21 @@ -package ${package}; +package ${namespace}; import io.vlingo.xoom.common.version.SemanticVersion; import io.vlingo.xoom.lattice.model.DomainEvent; public final class ${typeName} extends DomainEvent { - public final int semanticVersion; - - <#list children as p> - public final ${p.type.name()} ${p.name}; + <#list properties as p> + public <#if !p.value??>final ${p.type} ${p.name}<#if p.value??> = ${p.value}; - public ${typeName}(<#list children as p>final ${p.type.name()} ${p.name}<#if p?has_next>, ) { - this.semanticVersion = SemanticVersion.toValue("1.0.0"); - <#list children as p> + public ${typeName}(<#list properties as p><#if p.name != 'eventVersion'>final ${p.type} ${p.name}<#if p?has_next>, ) { + <#list properties as p> + <#if p.name = 'eventVersion'> + this.${p.name} = SemanticVersion.toValue("${version}"); + <#else> this.${p.name} = ${p.name}; + } } diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index 3865b14e..f2f696e6 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -8,4 +8,4 @@ - \ No newline at end of file + diff --git a/src/test/java/io/vlingo/xoom/schemata/codegen/CodeGenTests.java b/src/test/java/io/vlingo/xoom/schemata/codegen/CodeGenTests.java index d7b450fa..30dc32c1 100644 --- a/src/test/java/io/vlingo/xoom/schemata/codegen/CodeGenTests.java +++ b/src/test/java/io/vlingo/xoom/schemata/codegen/CodeGenTests.java @@ -12,7 +12,6 @@ import io.vlingo.xoom.common.Outcome; import io.vlingo.xoom.schemata.codegen.ast.Node; import io.vlingo.xoom.schemata.codegen.ast.types.TypeDefinition; -import io.vlingo.xoom.schemata.codegen.backend.java.JavaBackend; import io.vlingo.xoom.schemata.codegen.parser.AntlrTypeParser; import io.vlingo.xoom.schemata.codegen.parser.TypeParser; import io.vlingo.xoom.schemata.codegen.processor.Processor; @@ -52,7 +51,7 @@ protected final TypeDefinitionCompiler compilerWithJavaBackend() { world.actorFor(Processor.class, ComputableTypeProcessor.class), world.actorFor(Processor.class, TypeResolverProcessor.class, typeResolver) ), - new JavaBackend() + "java" ); } diff --git a/src/test/java/io/vlingo/xoom/schemata/codegen/JavaCodeGenSchemaVersionResolverTests.java b/src/test/java/io/vlingo/xoom/schemata/codegen/JavaCodeGenSchemaVersionResolverTests.java index 44d0b2e6..7d882bd6 100644 --- a/src/test/java/io/vlingo/xoom/schemata/codegen/JavaCodeGenSchemaVersionResolverTests.java +++ b/src/test/java/io/vlingo/xoom/schemata/codegen/JavaCodeGenSchemaVersionResolverTests.java @@ -22,7 +22,6 @@ // import io.vlingo.xoom.lattice.model.object.ObjectTypeRegistry; // import io.vlingo.xoom.schemata.NoopDispatcher; // import io.vlingo.xoom.schemata.SchemataConfig; -import io.vlingo.xoom.schemata.codegen.backend.java.JavaBackend; import io.vlingo.xoom.schemata.codegen.parser.AntlrTypeParser; import io.vlingo.xoom.schemata.codegen.parser.TypeParser; import io.vlingo.xoom.schemata.codegen.processor.Processor; @@ -57,7 +56,7 @@ public void testThatSpecificationsContainingBasicTypesCanBeCompiledWithSchemaVer world.actorFor(Processor.class, ComputableTypeProcessor.class), world.actorFor(Processor.class, TypeResolverProcessor.class, typeResolver) ), - new JavaBackend() + "java" ); String spec = "event Foo {\n" + " type eventType\n" + diff --git a/src/test/java/io/vlingo/xoom/schemata/model/SchemaVersionTest.java b/src/test/java/io/vlingo/xoom/schemata/model/SchemaVersionTest.java index 551b342f..0161020a 100644 --- a/src/test/java/io/vlingo/xoom/schemata/model/SchemaVersionTest.java +++ b/src/test/java/io/vlingo/xoom/schemata/model/SchemaVersionTest.java @@ -16,7 +16,6 @@ import io.vlingo.xoom.schemata.NoopDispatcher; import io.vlingo.xoom.schemata.codegen.TypeDefinitionCompilerActor; import io.vlingo.xoom.schemata.codegen.TypeDefinitionMiddleware; -import io.vlingo.xoom.schemata.codegen.backend.java.JavaBackend; import io.vlingo.xoom.schemata.codegen.parser.AntlrTypeParser; import io.vlingo.xoom.schemata.codegen.parser.TypeParser; import io.vlingo.xoom.schemata.codegen.processor.Processor; @@ -69,7 +68,7 @@ public void setUp() throws Exception { Arrays.asList( world.actorFor(Processor.class, ComputableTypeProcessor.class), world.actorFor(Processor.class, TypeResolverProcessor.class, typeResolver)), - new JavaBackend()); + "java"); simpleSchemaVersionId = SchemaVersionId.uniqueFor(SchemaId.uniqueFor(ContextId.uniqueFor(UnitId.uniqueFor(OrganizationId.unique())))); simpleSchemaVersion = world.actorFor(SchemaVersion.class, SchemaVersionEntity.class, simpleSchemaVersionId); @@ -321,7 +320,7 @@ private static void assertCompatible(String message, SpecificationDiff diff) { private static void assertIncompatible(String message, SpecificationDiff diff) { assertFalse(message, diff.isCompatible()); } - + @SuppressWarnings("unchecked") private SpecificationDiff unwrap(Completes> outcome) throws SchemataBusinessException { return ((Outcome)outcome.await()).get();