Skip to content

Commit

Permalink
JavaBackend replaced with CodeGenerator
Browse files Browse the repository at this point in the history
Signed-off-by: hurelhuyag <hurelhuyag@gmail.com>
  • Loading branch information
hurelhuyag committed May 4, 2021
1 parent 6a3a748 commit b2d360b
Show file tree
Hide file tree
Showing 13 changed files with 161 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -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<Property> 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<Property> 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());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -50,29 +48,27 @@ 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;

return new TypeDefinitionCompilerActor(typeParser,
Arrays.asList(
stage.actorFor(Processor.class, ComputableTypeProcessor.class),
stage.actorFor(Processor.class, TypeResolverProcessor.class, typeResolver)
), backend);
), language);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -22,20 +23,21 @@
public class TypeDefinitionCompilerActor implements TypeDefinitionCompiler, TypeDefinitionMiddleware {
private final TypeParser parser;
private final List<Processor> processors;
private final Backend backend;
private final String language;
private final CodeGenerator codeGenerator = new CodeGenerator();

public TypeDefinitionCompilerActor(final TypeParser parser, final List<Processor> processors, final Backend backend) {
public TypeDefinitionCompilerActor(final TypeParser parser, final List<Processor> processors, final String language) {
this.parser = parser;
this.processors = processors;
this.backend = backend;
this.language = language;
}

@Override
public Completes<Outcome<SchemataBusinessException, String>> compile(final InputStream typeDefinition, final String fullyQualifiedTypeName, final String version) {
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)
);
}
Expand Down
59 changes: 59 additions & 0 deletions src/main/java/io/vlingo/xoom/schemata/codegen/TypeMap.java
Original file line number Diff line number Diff line change
@@ -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<String, String> types;

TypeMap(Map<String, String> types) {
this.types = Collections.unmodifiableMap(types);
}

public String typeOf(String type){
return types.getOrDefault(type, type);
}

private static Map<String, String> ofMapEntries(String ... entries) {
if (entries.length % 2 != 0){
throw new IllegalArgumentException("parameters must even");
}
Map<String, String> result = new HashMap<>();
for (int i=0; i<entries.length-1; i+=2){
String key = entries[i];
String val = entries[i+1];
result.put(key, val);
}
return result;
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/*
// Copyright © 2012-2021 VLINGO LABS. All rights reserved.
//
// This Source Code Form is subject to the terms of the
Expand All @@ -14,3 +15,4 @@
public interface Backend {
Outcome<SchemataBusinessException,String> generateOutput(Node node, String version);
}
*/
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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<SchemataBusinessException, String> 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());
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/*
// Copyright © 2012-2021 VLINGO LABS. All rights reserved.
//
// This Source Code Form is subject to the terms of the
Expand Down Expand Up @@ -292,3 +293,4 @@ private Class<?> baseClassOf(TypeDefinition type) {
}
}
}
*/
14 changes: 7 additions & 7 deletions src/main/resources/codegen/csharp/DomainEvent.ftl
Original file line number Diff line number Diff line change
@@ -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};
</#list>

public ${typeName}(<#list children as p>${p.type.name()} ${p.name}<#if p?has_next>, </#if></#list>)
public ${typeName}(<#list properties as p>${p.type} ${p.name}<#if p?has_next>, </#if></#list>)
{
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};
</#list>
}
Expand Down
17 changes: 9 additions & 8 deletions src/main/resources/codegen/java/DomainEvent.ftl
Original file line number Diff line number Diff line change
@@ -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 </#if>${p.type} ${p.name}<#if p.value??> = ${p.value}</#if>;
</#list>

public ${typeName}(<#list children as p>final ${p.type.name()} ${p.name}<#if p?has_next>, </#if></#list>) {
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>, </#if></#if></#list>) {
<#list properties as p>
<#if p.name = 'eventVersion'>
this.${p.name} = SemanticVersion.toValue("${version}");
<#else>
this.${p.name} = ${p.name};
</#if>
</#list>
}
}
2 changes: 1 addition & 1 deletion src/main/resources/logback.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
</configuration>
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -52,7 +51,7 @@ protected final TypeDefinitionCompiler compilerWithJavaBackend() {
world.actorFor(Processor.class, ComputableTypeProcessor.class),
world.actorFor(Processor.class, TypeResolverProcessor.class, typeResolver)
),
new JavaBackend()
"java"
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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<SchemataBusinessException, SpecificationDiff>> outcome) throws SchemataBusinessException {
return ((Outcome<SchemataBusinessException, SpecificationDiff>)outcome.await()).get();
Expand Down

0 comments on commit b2d360b

Please sign in to comment.