-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #180 from vlingo/dev-freemarker-based-code-generation
Freemarker based code generation
- Loading branch information
Showing
16 changed files
with
576 additions
and
351 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
45 changes: 45 additions & 0 deletions
45
src/main/java/io/vlingo/xoom/schemata/codegen/CodeGenerator.java
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,45 @@ | ||
package io.vlingo.xoom.schemata.codegen; | ||
|
||
import freemarker.template.*; | ||
import io.vlingo.xoom.codegen.CodeGenerationException; | ||
import io.vlingo.xoom.common.Outcome; | ||
import io.vlingo.xoom.common.Success; | ||
import io.vlingo.xoom.schemata.errors.SchemataBusinessException; | ||
|
||
import java.io.IOException; | ||
import java.io.StringWriter; | ||
import java.io.Writer; | ||
import java.util.Locale; | ||
|
||
import static freemarker.template.Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS; | ||
|
||
public class CodeGenerator { | ||
|
||
private final Configuration configuration; | ||
|
||
public CodeGenerator() { | ||
DefaultObjectWrapper objectWrapper = new DefaultObjectWrapper(DEFAULT_INCOMPATIBLE_IMPROVEMENTS); | ||
objectWrapper.setExposeFields(true); | ||
this.configuration = new Configuration(DEFAULT_INCOMPATIBLE_IMPROVEMENTS); | ||
configuration.setClassForTemplateLoading(CodeGenerator.class, "/"); | ||
configuration.setDefaultEncoding("UTF-8"); | ||
configuration.setLocale(Locale.US); | ||
configuration.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); | ||
configuration.setObjectWrapper(objectWrapper); | ||
} | ||
|
||
public void generateWith(String language, String templateName, Object templateArgs, Writer output) throws IOException, TemplateException { | ||
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()); | ||
} | ||
} |
91 changes: 91 additions & 0 deletions
91
src/main/java/io/vlingo/xoom/schemata/codegen/SchemaTypeArguments.java
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,91 @@ | ||
package io.vlingo.xoom.schemata.codegen; | ||
|
||
import io.vlingo.xoom.schemata.codegen.ast.FieldDefinition; | ||
import io.vlingo.xoom.schemata.codegen.ast.types.BasicArrayType; | ||
import io.vlingo.xoom.schemata.codegen.ast.types.TypeDefinition; | ||
import io.vlingo.xoom.schemata.codegen.ast.values.ListValue; | ||
import io.vlingo.xoom.schemata.codegen.ast.values.SingleValue; | ||
import io.vlingo.xoom.schemata.codegen.ast.values.Value; | ||
import io.vlingo.xoom.schemata.model.Category; | ||
|
||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
public class SchemaTypeArguments { | ||
|
||
public final String namespace; | ||
public final String version; | ||
public final List<Property> properties; | ||
public final Category type; | ||
public final String typeName; | ||
public final boolean createDefaultConstructor; | ||
public final boolean createRequiredArgsConstructor; | ||
|
||
public SchemaTypeArguments(String language, String fqdn, String version, TypeDefinition node) { | ||
this.namespace = extractNamespace(fqdn); | ||
this.type = node.category; | ||
this.typeName = node.typeName; | ||
this.version = version; | ||
this.properties = extractProperties(language, node); | ||
this.createDefaultConstructor = properties.stream() | ||
.filter(property -> !property.name.equals("eventType")) | ||
.filter(property -> !property.name.equals("eventVersion")) | ||
.filter(property -> !property.name.equals("occurredOn")) | ||
.allMatch(property -> property.value != null); | ||
this.createRequiredArgsConstructor = properties.stream() | ||
.anyMatch(property -> !property.name.equals("eventType") | ||
&& !property.name.equals("eventVersion") | ||
&& !property.name.equals("occurredOn")); | ||
} | ||
|
||
public static class Property { | ||
public final String type; | ||
public final boolean array; | ||
public final String name; | ||
public final Object value; | ||
|
||
public Property(String type, boolean array, String name, Object value) { | ||
this.type = type; | ||
this.array = array; | ||
this.name = name; | ||
this.value = value; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "Property{" + | ||
"type='" + type + '\'' + | ||
", array=" + array + | ||
", name='" + name + '\'' + | ||
", 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) + ".events"; | ||
} | ||
|
||
private List<Property> extractProperties(String language, TypeDefinition root) { | ||
TypeMap typeMap = TypeMap.valueOf(language); | ||
return root.children.stream() | ||
.map(node -> (FieldDefinition) node) | ||
.map(node -> { | ||
String type = typeMap.typeOf(node.type.name()); | ||
boolean array = node.type instanceof BasicArrayType; | ||
Object defaultValue = array | ||
? node.defaultValue | ||
.filter(value -> value instanceof ListValue) | ||
.map(value -> (ListValue<List<SingleValue>>)value) | ||
.map(listValue -> listValue.value.stream() | ||
.map(Value::value) | ||
.collect(Collectors.toList())) | ||
.orElse(null) | ||
: node.defaultValue.map(Value::value).orElse(null); | ||
return new Property(type, array, node.name, defaultValue); | ||
}) | ||
.collect(Collectors.toList()); | ||
} | ||
} |
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
59 changes: 59 additions & 0 deletions
59
src/main/java/io/vlingo/xoom/schemata/codegen/TypeMap.java
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,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; | ||
} | ||
} |
16 changes: 0 additions & 16 deletions
16
src/main/java/io/vlingo/xoom/schemata/codegen/backend/Backend.java
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.