Skip to content

Commit

Permalink
basic java emitting
Browse files Browse the repository at this point in the history
  • Loading branch information
stephengoldbaum committed Jun 13, 2024
1 parent 98218c5 commit 1d7e75f
Show file tree
Hide file tree
Showing 9 changed files with 286 additions and 24 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
.vscode/
package-lock.json
node_modules/
tsp-output/
8 changes: 4 additions & 4 deletions DataThread/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'org.jsonschema2pojo:jsonschema2pojo-gradle-plugin:1.1.1'
classpath 'org.jsonschema2pojo:jsonschema2pojo-gradle-plugin:1.2.1'
}
}

plugins {
id 'java'
}

apply plugin: 'jsonschema2pojo'

group 'com.example'
version '1.0-SNAPSHOT'

Expand All @@ -37,7 +39,7 @@ generateJava{

dependencies {
implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.3'
implementation 'org.jsonschema2pojo:jsonschema2pojo-gradle-plugin:1.1.1'
implementation 'org.jsonschema2pojo:jsonschema2pojo-gradle-plugin:1.2.1'
implementation 'com.squareup:javapoet:1.13.0'
// implementation "com.netflix.graphql.dgs:graphql-dgs-spring-graphql-starter"

Expand All @@ -48,8 +50,6 @@ test {
useJUnitPlatform()
}

apply plugin: 'jsonschema2pojo'

jsonSchema2Pojo {
source = files("$projectDir/generated/tsp-output")
targetPackage = 'org.datathread.grammar'
Expand Down
17 changes: 0 additions & 17 deletions DataThread/example/metastore/person/users.dataset.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,6 @@
"key": false,
"optional": false
},
{
"name": "foo",
"element": {
"id": "element:person:users#foo",
"name": "Foo",
"description": "Foo",
"element_type": { "Text": {} },
"info": {
"description": "What is a Foo?",
"display_name": "Fooooo",
"short_display_name": "Foo"
}
},
"description": "Foo",
"key": false,
"optional": false
},
{
"name": "savingsAmount",
"element": "element:person:savings_amount",
Expand Down
2 changes: 1 addition & 1 deletion DataThread/example/test.foo.dataset.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"fields": [
{
"name": "foo",
"element": "element:/Foo/Bah:foo",
"element": "element:Foo:foo",
"key": false,
"optional": false
}
Expand Down
9 changes: 9 additions & 0 deletions DataThread/foo.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
query {
elements {
element_type {
__typename
}
id
name
}
}
4 changes: 2 additions & 2 deletions DataThread/src/main/java/Main.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.squareup.javapoet.TypeSpec;
import datathread.metastore.Element;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.io.File;

import org.datathread.grammar._typespec.json_schema.Element;
import javax.lang.model.element.Modifier;

public class Main {
public static void main(String[] args) {
String json = null;
try {
System.out.println(new File(".").getAbsolutePath());
File baseDir = new File("DataThread/example/metastore");
File baseDir = new File("sharing/example/metastore");
String id = "element:person:active";
File file = new File(baseDir, resolveForID(id).getPath());

Expand Down
169 changes: 169 additions & 0 deletions DataThread/src/main/java/datathread/backends/JavaEmitter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
package datathread.backends;

import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.TypeSpec;
import datathread.metastore.*;

import javax.lang.model.element.Modifier;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class JavaEmitter {
public static interface Context {
public Optional<Element> getElement(String elementId);
}

private final Context context;

public JavaEmitter(Context context) {
this.context = context;
}

public TypeSpec handleDataset(Dataset dataset) {
String name = nameToJavaClassName(dataset.getName());
List<FieldSpec> fields =
dataset.getFields().stream()
.map(f -> handleField(this.context, f))
.collect(Collectors.toList());

TypeSpec javaClass = TypeSpec.classBuilder(name)
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addFields(fields)
.build();

return javaClass;
}

public FieldSpec handleField(Context context, Field field) {
String name = field.getName();
Optional<Element> element = context.getElement(field.getElement());
ClassName className = element
.map( e -> handleElementType(e.getElementType()))
.orElse(ClassName.get(Object.class));

return FieldSpec.builder(className, name)
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.build();
}

public ClassName handleElementType(ElementType elementType) {
String tipe = elementType.getAdditionalProperties().keySet().toArray()[0].toString();

// TODO
switch(tipe) {
case "Boolean":
return ClassName.get(Boolean.class);
case "Date":
return ClassName.get(java.time.LocalDate.class);
case "DateTime":
return ClassName.get(java.time.LocalDateTime.class);
case "Enum":
String name = ("" + elementType.getAdditionalProperties().get("name"))
.replaceAll("\\{", "").replaceAll("\\}", "");
return resolveReference(name);
case "Number":
return ClassName.get(Double.class);
case "Reference":
String ref = ("" + elementType.getAdditionalProperties().get("Reference"))
.replaceAll("\\{", "").replaceAll("\\}", "");
return resolveReference(ref);
case "Text":
return ClassName.get(String.class);
default:
return ClassName.get(Object.class);
}

// if(cls == Enum.class)
// return String.class;
// else if(cls == Text.class)
// return String.class;
// else if(cls == Number.class)
// return Double.class;
//// else if(cls == Record.class)
//// else if(cls == Reference.class)
//// return String.class;
// else if(cls == Text.class)
// return String.class;
// else
// return Object.class;
}

public TypeSpec handleEnum(ElementType e) {
String name = e.getAdditionalProperties().getOrDefault("name", "Enum").toString();

TypeSpec java = TypeSpec.enumBuilder(name)
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.build();

return java;
}

public TypeSpec handleElement(Element element) {
TypeSpec java = TypeSpec.classBuilder(element.getName())
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.build();

return java;
}

//// Utils ////
public static ClassName resolveReference(String id) {
ClassName className = idToClassName(id);
ClassName result = className;

switch (className.canonicalName()) {
case "core.Integer":
result = ClassName.get(Integer.class);
break;
}

return result;
}

public static ClassName idToClassName(String id) {
String[] split = id.split(":");

String pkg = escape(split[1]);
String name = nameToJavaClassName(split[2]);

return ClassName.get(pkg, name);
}

public static String escape(String s) {
return s.replaceAll("\\W", "_");
}

public static String nameToJavaClassName(String name) {
return Arrays.stream(name.split("\\s+"))
.map(JavaEmitter::capitalize)
.collect(Collectors.joining("_"));
}

public static String capitalize(String s) {
return s.substring(0,1).toUpperCase() + s.substring(1);
}

public static void main(String[] args) {
final File baseDir = new File("sharing/example/metastore");
final Context context = new Context() {
public Optional<Element> getElement(String elementId) {
Optional<Element> e = FileStore.read(baseDir, elementId, Element.class);
return e;
}
};

JavaEmitter emitter = new JavaEmitter(context);

Dataset dataset = FileStore.read(baseDir, "dataset:/person:users", Dataset.class).get();

System.out.println(emitter.handleDataset(dataset));

// FileStore.readAllDatasets(baseDir).stream()
// .map(emitter::handleDataset)
// .forEach(System.out::println);
}
}
99 changes: 99 additions & 0 deletions DataThread/src/main/java/datathread/metastore/FileStore.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package datathread.metastore;

import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Stream;

public class FileStore {
File baseDir;

public FileStore(File baseDir) {
this.baseDir = baseDir;
}

public Optional<Element> readElement(String elementId) {
return read(baseDir, elementId, Element.class);
}

public static File resolveForID(String id) {
String[] parts = id.split(":");
return resolveFile(parts[0], parts[1], parts[2]);
}

public static File resolveFile(String schemaType, String domain, String name) {
return new File(domain, name + "." + schemaType + ".json");
}

public static <T> List<T> readAll(File baseDir, String metaType, Class<T> type) {
List<T> items = new ArrayList<>();
String pattern = metaType + ".json";

try (Stream<Path> paths = Files.walk(Paths.get(baseDir.getPath()))) {
paths
.filter(Files::isRegularFile)
.filter(path -> path.getFileName().toString().endsWith(pattern))
.forEach(path -> {
try {
String json = new String(Files.readAllBytes(path));
ObjectMapper mapper = new ObjectMapper();
T item = mapper.readValue(json, type);
items.add(item);
} catch (IOException e) {
e.printStackTrace();
}
});
} catch (IOException e) {
e.printStackTrace();
}

return items;
}

public static List<Element> readAllElements(File baseDir) {
return readAll(baseDir, "element", Element.class);
}

public static List<Dataset> readAllDatasets(File baseDir) {
return readAll(baseDir, "dataset", Dataset.class);
}

public static <T> Optional<T> read(File baseDir, String id, Class<T> cls) {
File elementFile = resolveForID(id);
File absPath = new File(baseDir, elementFile.getPath());

try {
String json = new String(Files.readAllBytes(Paths.get(absPath.getAbsolutePath())));
ObjectMapper mapper = new ObjectMapper();
T item = mapper.readValue(json, cls);
return Optional.of(item);
} catch (IOException e) {
e.printStackTrace();
return Optional.empty();
}
}

public static void main(String[] args) {
File baseDir = new File("sharing/example/metastore");


System.out.println("==== Elements ====");
List<Element> elements = readAllElements(baseDir);
for (Element element : elements) {
System.out.println(element.getElementType());
}

System.out.println("==== Datasets ====");
List<Dataset> datasets = readAllDatasets(baseDir);
for (Dataset dataset : datasets) {
System.out.println(dataset.getId());
}


}
}
1 change: 1 addition & 0 deletions DataThread/src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

0 comments on commit 1d7e75f

Please sign in to comment.