summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2013-08-03 18:00:10 +0200
committerTrygve Laugstøl <trygvis@inamo.no>2013-08-03 18:00:10 +0200
commite1cf8889628d2d31cf7067b8c002f229fc22007d (patch)
treeb6fda3f7f23f445ca0030e88368cb39e27badb96
parent054cfb131292893d100a43ea2cb20c591c17c810 (diff)
downloadcontainer-playground-e1cf8889628d2d31cf7067b8c002f229fc22007d.tar.gz
container-playground-e1cf8889628d2d31cf7067b8c002f229fc22007d.tar.bz2
container-playground-e1cf8889628d2d31cf7067b8c002f229fc22007d.tar.xz
container-playground-e1cf8889628d2d31cf7067b8c002f229fc22007d.zip
wip
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/EntityHandler.java36
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/TransactionalHandler.java2
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/Utils.java25
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/ClassG.java63
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Constructor.java2
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/TypeRef.java56
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java49
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/persistence/FieldMirror.java22
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/persistence/GeneratorSupport.java31
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/persistence/TypeHandler.java22
-rw-r--r--container-compiler-plugin/src/test/java/io/trygvis/persistence/EntityMirrorTest.java47
-rw-r--r--container-compiler-plugin/src/test/java/io/trygvis/persistence/test/PersonTypeHandler.java5
-rw-r--r--myapp/src/main/java/io/trygvis/container/myapp/AddressBook.java47
13 files changed, 295 insertions, 112 deletions
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/EntityHandler.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/EntityHandler.java
index ad36988..cf21887 100644
--- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/EntityHandler.java
+++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/EntityHandler.java
@@ -1,6 +1,7 @@
package io.trygvis.container.compiler;
import io.trygvis.container.compiler.model.ClassG;
+import io.trygvis.container.compiler.model.TypeRef;
import io.trygvis.persistence.EntityMirror;
import io.trygvis.persistence.FieldMirror;
import io.trygvis.persistence.GeneratorSupport;
@@ -14,7 +15,6 @@ import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror;
import javax.persistence.Id;
import javax.tools.JavaFileObject;
@@ -24,6 +24,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import static io.trygvis.container.compiler.Utils.toJavaString;
import static io.trygvis.persistence.FieldMirror.PrimitiveFieldMirror;
import static java.lang.Character.isUpperCase;
import static javax.lang.model.util.ElementFilter.fieldsIn;
@@ -47,7 +48,7 @@ public class EntityHandler extends AbstractHandler {
TypeHandler typeHandler = (TypeHandler) typeHandlerClass.newInstance();
String type = entity.asType().toString();
- generatorSupport.addTypeHandler(type, typeHandler);
+ generatorSupport.addTypeHandler(new TypeRef(type, type), typeHandler);
System.out.println("Loaded TypeHandler for " + type + " through " + typeHandlerClass.getCanonicalName());
break;
}
@@ -78,8 +79,8 @@ public class EntityHandler extends AbstractHandler {
}
public void processEntity(TypeElement element) throws Exception {
- DeclaredType declaredType = types.getDeclaredType(element);
- EntityMirror entityMirror = new EntityMirror(generatorSupport, declaredType, sqlName(element.getSimpleName().toString()));
+ EntityMirror entityMirror = new EntityMirror(generatorSupport, new TypeRef(types.getDeclaredType(element)),
+ sqlName(element.getSimpleName().toString()));
for (VariableElement f : fieldsIn(elements.getAllMembers(element))) {
entityMirror.add(fromElement(generatorSupport, f));
@@ -101,16 +102,14 @@ public class EntityHandler extends AbstractHandler {
String p = elements.getPackageOf(element).getQualifiedName().toString();
- ClassG g = new ClassG(p, entityMirror.daoName);
- String insertInto = entityMirror.insertIntoSql();
- g.addPublicStaticFinalField(String.class, "insertIntoSql").value("\"" + insertInto + "\"");
-// List<String> body = new ArrayList<>();
-// body.add("this.insertIntoSql = \"" + insertInto + "\";");
-// g.addConstructor(new Parameters(), body);
+ ClassG g = new ClassG(entityMirror.daoType);
+ g.addPublicStaticFinalField(String.class, "createTableSql").value(toJavaString(entityMirror.createTableSql()));
+ g.addPublicStaticFinalField(String.class, "dropTableSql").value(toJavaString(entityMirror.dropTableSql()));
+ g.addPublicStaticFinalField(String.class, "insertIntoSql").value(toJavaString(entityMirror.insertIntoSql()));
+ g.addPublicStaticFinalField(String.class, "deleteFromSql").value(toJavaString(entityMirror.deleteFromSql()));
entityMirror.insertInto(g);
- String fileName = (p.length() == 0 ? "" : p + ".") + entityMirror.daoName;
- JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(fileName, element);
+ JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(entityMirror.daoType.fqName, element);
try (PrintWriter w = new PrintWriter(sourceFile.openWriter())) {
g.write(w);
}
@@ -119,7 +118,7 @@ public class EntityHandler extends AbstractHandler {
}
public FieldMirror fromElement(GeneratorSupport generatorSupport, VariableElement var) {
- TypeMirror type = var.asType();
+ TypeRef type = new TypeRef(var.asType().toString());
// System.out.print("element = ");
// elements.printElements(new PrintWriter(System.out), var);
String javaName = var.getSimpleName().toString();
@@ -128,13 +127,13 @@ public class EntityHandler extends AbstractHandler {
FieldMirror field;
boolean id = isId(var);
if (generatorSupport.isPrimitive(type)) {
- field = new PrimitiveFieldMirror(var, javaName, sqlName, id, notNull);
+ field = new PrimitiveFieldMirror(type, javaName, sqlName, id, notNull);
} else if (generatorSupport.hasTypeHandler(type)) {
if (id) {
throw new CompilerException(var, "A @Id field has to be a primitive or embedded.");
}
- field = new FieldMirror.ReferenceFieldMirror(var, javaName, sqlName, notNull);
+ field = new FieldMirror.ReferenceFieldMirror(type, javaName, sqlName, notNull);
} else {
throw new CompilerException(var, "Missing type handler for type: " + type);
}
@@ -151,10 +150,9 @@ public class EntityHandler extends AbstractHandler {
String p = packageElement.getQualifiedName().toString();
// TODO: Support a name prefix from @SqlEntitySet
- String className = "Daos";
+ TypeRef type = new TypeRef(p + ".Daos");
- String fileName = (p.length() == 0 ? "" : p + ".") + className;
- ClassG g = new ClassG(p, className);
+ ClassG g = new ClassG(type);
/*
TypeRef conType = g.addImport(Connection.class);
@@ -170,7 +168,7 @@ public class EntityHandler extends AbstractHandler {
g.addConstructor(parameters, body);
*/
- JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(fileName, packageElement);
+ JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(type.fqName, packageElement);
try (PrintWriter w = new PrintWriter(sourceFile.openWriter())) {
g.write(w);
}
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/TransactionalHandler.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/TransactionalHandler.java
index d24a697..fbd7660 100644
--- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/TransactionalHandler.java
+++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/TransactionalHandler.java
@@ -42,7 +42,7 @@ public class TransactionalHandler extends AbstractHandler {
String p = elements.getPackageOf(element).getQualifiedName().toString();
- ClassG g = new ClassG(p, className, targetClassName.toString());
+ ClassG g = new ClassG(new TypeRef(p + "." + className), new TypeRef(targetClassName.toString()));
FieldRef transactionManager = g.addField(PlatformTransactionManager.class, "transactionManager");
for (ExecutableElement constructor : constructorsIn(elements.getAllMembers(element))) {
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/Utils.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/Utils.java
index 8bd0de3..5057968 100644
--- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/Utils.java
+++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/Utils.java
@@ -1,5 +1,9 @@
package io.trygvis.container.compiler;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
+
import static java.lang.Character.toLowerCase;
import static java.lang.Character.toUpperCase;
@@ -28,4 +32,25 @@ public class Utils {
}
return new String(chars, 0, j);
}
+
+ public static String toJavaString(String s) {
+ try {
+ BufferedReader reader = new BufferedReader(new StringReader(s));
+ String line = reader.readLine();
+ StringBuilder buffer = new StringBuilder();
+ while (line != null) {
+ buffer.append('"');
+ buffer.append(line.replace("\"", "\\\""));
+ buffer.append('"');
+ line = reader.readLine();
+ if(line != null) {
+ buffer.append(" +\n");
+ }
+ }
+
+ return buffer.toString();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
}
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/ClassG.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/ClassG.java
index 9befa36..857311d 100644
--- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/ClassG.java
+++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/ClassG.java
@@ -12,58 +12,46 @@ import static java.lang.reflect.Modifier.*;
import static org.springframework.util.StringUtils.collectionToDelimitedString;
public class ClassG {
- private final String packageName;
- public final String className;
- private final String extendsClass;
+ public final TypeRef type;
+ private final TypeRef extendsClass;
private final Set<TypeRef> imports = new TreeSet<>();
private final Set<FieldRef> fields = new TreeSet<>();
private final List<MethodRef> methods = new ArrayList<>();
private final List<Constructor> constructors = new ArrayList<>();
- public ClassG(String packageName, String className) {
- this(packageName, className, null);
+ public ClassG(TypeRef type) {
+ this(type, null);
}
- public ClassG(String packageName, String className, String extendsClass) {
- this.packageName = packageName;
- this.className = className;
+ public ClassG(TypeRef type, TypeRef extendsClass) {
+ this.type = type;
this.extendsClass = extendsClass;
}
public TypeRef addImport(final TypeMirror type) {
- if (type.getKind().isPrimitive()) {
- return TypeRef.find(type.getKind());
- }
-
- String canonicalName = type.toString();
-
- for (TypeRef i : imports) {
- if (i.canonicalName().equals(canonicalName)) {
- return i;
- }
- }
+ return addImport(new TypeRef(type));
+ }
- TypeRef ref = new TypeRef(canonicalName, canonicalName);
- imports.add(ref);
- return ref;
+ public TypeRef addImport(Class<?> c) {
+ return addImport(new TypeRef(c));
}
- public TypeRef addImport(Class<?> klass) {
- String canonicalName = klass.getCanonicalName();
- String simpleName = klass.getSimpleName();
- String name = simpleName;
+ public TypeRef addImport(TypeRef klass) {
+ String fqName = klass.fqName;
+ String name = klass.name;
for (TypeRef i : imports) {
- if (i.canonicalName().equals(canonicalName)) {
+ if (i.fqName.equals(fqName)) {
return i;
}
- if (i.name.equals(simpleName)) {
- name = canonicalName;
+ // If we've already found an import with the same name, use the fq version
+ if (i.name.equals(name)) {
+ name = fqName;
break;
}
}
- TypeRef ref = new TypeRef(name, canonicalName);
+ TypeRef ref = new TypeRef(name, fqName);
imports.add(ref);
return ref;
@@ -114,26 +102,23 @@ public class ClassG {
}
public void write(PrintWriter writer) {
- if (packageName.length() > 0) {
- writer.println("package " + packageName + ";");
+ if (!type.inUnnamedPackage()) {
+ writer.println("package " + type.packageName() + ";");
writer.println();
}
for (TypeRef i : imports) {
- if (i.isPrimitive()) {
- continue;
- }
- if (i.canonicalName().indexOf('.') == -1) {
+ if (i.isPrimitive() || i.inUnnamedPackage()) {
continue;
}
- writer.println("import " + i.canonicalName() + ";");
+ writer.println("import " + i.fqName + ";");
}
if (!imports.isEmpty()) {
writer.println();
}
- String extendsString = extendsClass == null ? "" : " extends " + extendsClass;
+ String extendsString = extendsClass == null ? "" : " extends " + extendsClass.name;
- writer.println("public class " + className + extendsString + " {");
+ writer.println("public class " + type.className + extendsString + " {");
for (FieldRef field : fields) {
writer.println();
writer.println(" " + field.toJava() + ";");
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Constructor.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Constructor.java
index 43800ce..f669273 100644
--- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Constructor.java
+++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Constructor.java
@@ -27,7 +27,7 @@ public class Constructor {
String params = collectionToDelimitedString(ps, ", ");
- body.add(" public " + g.className + "(" + params + ") {");
+ body.add(" public " + g.type.className + "(" + params + ") {");
for (String s : this.body) {
body.add(" " + s);
}
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/TypeRef.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/TypeRef.java
index aabfb45..c6f958a 100644
--- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/TypeRef.java
+++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/TypeRef.java
@@ -1,6 +1,7 @@
package io.trygvis.container.compiler.model;
import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
public class TypeRef implements Comparable<TypeRef> {
@@ -15,27 +16,56 @@ public class TypeRef implements Comparable<TypeRef> {
public static final TypeRef DOUBLE = new TypeRef("double", null);
/**
- * The name of a class used within a class file. Is either the simple name or the canonical name.
+ * The name of a class used within a class file. Is either the just the name or the fully qualified name.
*/
public final String name;
- private final String canonicalName;
+ public final String className;
- public String canonicalName() {
- if (canonicalName == null) {
- throw new RuntimeException("This type doesn't have a canonical name");
+ public final String fqName;
+ private final boolean primitive;
+
+ public TypeRef(String name, String fqName) {
+ this.name = name;
+ this.primitive = fqName == null;
+ this.fqName = fqName == null ? name : fqName;
+
+ int i = this.fqName.lastIndexOf('.');
+ if (i == -1) {
+ this.className = this.fqName;
+ } else {
+ this.className = this.fqName.substring(i + 1, this.fqName.length());
}
+ }
+
+ public TypeRef(TypeMirror type) {
+ this(type.toString());
+ }
+
+ public TypeRef(Class<?> klass) {
+ this(klass.getCanonicalName(), klass.getCanonicalName());
+ }
- return canonicalName;
+ public TypeRef(String fqName) {
+ this(fqName, fqName);
}
public boolean isPrimitive() {
- return canonicalName == null;
+ return primitive;
}
- public TypeRef(String name, String canonicalName) {
- this.name = name;
- this.canonicalName = canonicalName;
+ public boolean inUnnamedPackage() {
+ return fqName.indexOf('.') == -1;
+ }
+
+ public String packageName() {
+ int i = fqName.lastIndexOf('.');
+
+ if (i == -1) {
+ throw new RuntimeException("This type is in the unnamed package: " + name);
+ }
+
+ return fqName.substring(0, i);
}
@Override
@@ -45,17 +75,17 @@ public class TypeRef implements Comparable<TypeRef> {
TypeRef classRef = (TypeRef) o;
- return canonicalName.equals(classRef.canonicalName);
+ return fqName.equals(classRef.fqName);
}
@Override
public int hashCode() {
- return canonicalName.hashCode();
+ return fqName.hashCode();
}
@Override
public int compareTo(TypeRef o) {
- return canonicalName.compareTo(o.canonicalName);
+ return fqName.compareTo(o.fqName);
}
public static TypeRef find(TypeKind kind) {
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java
index 41ae1d4..2a4952f 100644
--- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java
+++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java
@@ -4,32 +4,56 @@ import io.trygvis.container.compiler.model.ClassG;
import io.trygvis.container.compiler.model.ParameterRef;
import io.trygvis.container.compiler.model.TypeRef;
-import javax.lang.model.type.DeclaredType;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
+import static java.lang.String.format;
import static org.apache.commons.lang.StringUtils.join;
public class EntityMirror {
public final GeneratorSupport generatorSupport;
public final List<FieldMirror> fields = new ArrayList<>();
- public final DeclaredType javaName;
+ public final List<FieldMirror> idFields = new ArrayList<>();
+ public final TypeRef type;
public final String tableName;
- public final String daoName;
+ public final TypeRef daoType;
- public EntityMirror(GeneratorSupport generatorSupport, DeclaredType javaName, String tableName) {
+ public EntityMirror(GeneratorSupport generatorSupport, TypeRef type, String tableName) {
this.generatorSupport = generatorSupport;
- this.javaName = javaName;
+ this.type = type;
this.tableName = tableName;
- this.daoName = javaName.asElement().getSimpleName() + "Dao";
+ this.daoType = new TypeRef(type.name + "Dao");
}
public void add(FieldMirror field) {
fields.add(field);
+ if(field.id) {
+ idFields.add(field);
+ }
+ }
+
+ public String createTableSql() {
+ List<String> columns = new ArrayList<>();
+ for (FieldMirror field : fields) {
+ TypeHandler typeHandler = generatorSupport.typeHandler(field.type);
+ String s = " " + field.sqlName + " " + typeHandler.sqlType(field);
+ if(field.id) {
+ s += " PRIMARY KEY";
+ }
+ columns.add(s);
+ }
+
+ return format("CREATE TABLE " + tableName + "(%n" +
+ join(columns, ",%n") +
+ "%n);");
+ }
+
+ public String dropTableSql() {
+ return "DROP TABLE " + tableName + ";";
}
public String insertIntoSql() {
@@ -44,10 +68,19 @@ public class EntityMirror {
"VALUES(" + join(placeholders, ", ") + ");";
}
+ public String deleteFromSql() {
+ List<String> ss = new ArrayList<>();
+ for (FieldMirror field : idFields) {
+ ss.add(field.sqlName + "=?");
+ }
+
+ return "DELETE FROM " + tableName + " WHERE " + join(ss, " AND ") + ";";
+ }
+
public void insertInto(ClassG g) {
TypeRef conType = g.addImport(Connection.class);
TypeRef psType = g.addImport(PreparedStatement.class);
- TypeRef objectType = g.addImport(javaName);
+ TypeRef objectType = g.addImport(type);
ParameterRef con = new ParameterRef(conType, "con");
ParameterRef object = new ParameterRef(objectType, "o");
@@ -56,7 +89,7 @@ public class EntityMirror {
body.add("try(" + psType.name + " stmt = " + con.name + ".prepareStatement(insertIntoSql)) {");
for (int i = 0; i < fields.size(); i++) {
FieldMirror field = fields.get(i);
- TypeHandler typeHandler = generatorSupport.typeHandler(field.element);
+ TypeHandler typeHandler = generatorSupport.typeHandler(field.type);
body.add(" stmt." + typeHandler.resultSetSetter(i + 1, "o", field) + ";");
}
body.add(" stmt.executeUpdate();");
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/FieldMirror.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/FieldMirror.java
index c2e5f35..bf0a0c3 100644
--- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/FieldMirror.java
+++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/FieldMirror.java
@@ -1,6 +1,6 @@
package io.trygvis.persistence;
-import javax.lang.model.element.VariableElement;
+import io.trygvis.container.compiler.model.TypeRef;
import static io.trygvis.persistence.FieldMirror.FieldType.PRIMITIVE;
import static io.trygvis.persistence.FieldMirror.FieldType.REFERENCE;
@@ -10,7 +10,7 @@ import static io.trygvis.persistence.FieldMirror.FieldType.REFERENCE;
*/
public abstract class FieldMirror {
public final FieldType fieldType;
- public final VariableElement element;
+ public final TypeRef type;
public final String javaName;
public final String sqlName;
public final boolean id;
@@ -21,9 +21,9 @@ public abstract class FieldMirror {
REFERENCE,
}
- protected FieldMirror(FieldType fieldType, VariableElement element, String javaName, String sqlName, boolean id, boolean notNull) {
+ protected FieldMirror(FieldType fieldType, TypeRef type, String javaName, String sqlName, boolean id, boolean notNull) {
this.fieldType = fieldType;
- this.element = element;
+ this.type = type;
this.javaName = javaName;
this.sqlName = sqlName;
this.id = id;
@@ -31,14 +31,15 @@ public abstract class FieldMirror {
}
public static class PrimitiveFieldMirror extends FieldMirror {
- public PrimitiveFieldMirror(VariableElement element, String javaName, String sqlName, boolean id, boolean notNull) {
- super(PRIMITIVE, element, javaName, sqlName, id, notNull);
+ public PrimitiveFieldMirror(TypeRef typeRef, String javaName, String sqlName, boolean id, boolean notNull) {
+ super(PRIMITIVE, typeRef, javaName, sqlName, id, notNull);
}
@Override
public String toString() {
return "PrimitiveFieldMirror{" +
- "javaName='" + javaName + '\'' +
+ "type='" + type + '\'' +
+ ", javaName='" + javaName + '\'' +
", sqlName='" + sqlName + '\'' +
", notNull=" + notNull +
'}';
@@ -46,14 +47,15 @@ public abstract class FieldMirror {
}
public static class ReferenceFieldMirror extends FieldMirror {
- public ReferenceFieldMirror(VariableElement element, String javaName, String sqlName, boolean notNull) {
- super(REFERENCE, element, javaName, sqlName, false, notNull);
+ public ReferenceFieldMirror(TypeRef typeRef, String javaName, String sqlName, boolean notNull) {
+ super(REFERENCE, typeRef, javaName, sqlName, false, notNull);
}
@Override
public String toString() {
return "ReferenceFieldMirror{" +
- "javaName='" + javaName + '\'' +
+ "type='" + type + '\'' +
+ ", javaName='" + javaName + '\'' +
", sqlName='" + sqlName + '\'' +
", notNull=" + notNull +
'}';
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/GeneratorSupport.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/GeneratorSupport.java
index 379f6f6..0563691 100644
--- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/GeneratorSupport.java
+++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/GeneratorSupport.java
@@ -1,42 +1,41 @@
package io.trygvis.persistence;
-import javax.lang.model.element.Element;
-import javax.lang.model.type.TypeMirror;
+import io.trygvis.container.compiler.model.TypeRef;
+
import java.util.Date;
-import java.util.HashMap;
import java.util.Map;
+import java.util.TreeMap;
public class GeneratorSupport {
- private final Map<String, TypeHandler> primitiveTypeHandlers = new HashMap<>();
- private final Map<String, TypeHandler> typeHandlers = new HashMap<>();
+ private final Map<TypeRef, TypeHandler> primitiveTypeHandlers = new TreeMap<>();
+ private final Map<TypeRef, TypeHandler> typeHandlers = new TreeMap<>();
{
- typeHandlers.put(Integer.class.getName(), new TypeHandler.IntTypeHandler());
- typeHandlers.put(Long.class.getName(), new TypeHandler.LongTypeHandler());
- typeHandlers.put(String.class.getName(), new TypeHandler.StringTypeHandler());
- typeHandlers.put(Date.class.getName(), new TypeHandler.DateTypeHandler());
+ typeHandlers.put(new TypeRef(Integer.class), new TypeHandler.IntTypeHandler());
+ typeHandlers.put(new TypeRef(Long.class), new TypeHandler.LongTypeHandler());
+ typeHandlers.put(new TypeRef(String.class), new TypeHandler.StringTypeHandler());
+ typeHandlers.put(new TypeRef(Date.class), new TypeHandler.DateTypeHandler());
primitiveTypeHandlers.putAll(typeHandlers);
}
- public void addTypeHandler(String type, TypeHandler typeHandler) {
+ public void addTypeHandler(TypeRef type, TypeHandler typeHandler) {
typeHandlers.put(type, typeHandler);
}
- public TypeHandler typeHandler(Element element) {
- String type = element.asType().toString();
+ public TypeHandler typeHandler(TypeRef type) {
TypeHandler typeHandler = typeHandlers.get(type);
if (typeHandler == null)
throw new RuntimeException("Unsupported field type: " + type);
return typeHandler;
}
- public boolean isPrimitive(TypeMirror type) {
- return primitiveTypeHandlers.containsKey(type.toString());
+ public boolean isPrimitive(TypeRef type) {
+ return primitiveTypeHandlers.containsKey(type);
}
- public boolean hasTypeHandler(TypeMirror type) {
- return typeHandlers.containsKey(type.toString());
+ public boolean hasTypeHandler(TypeRef type) {
+ return typeHandlers.containsKey(type);
}
}
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/TypeHandler.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/TypeHandler.java
index 1d7d424..ff2ad0a 100644
--- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/TypeHandler.java
+++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/TypeHandler.java
@@ -3,11 +3,18 @@ package io.trygvis.persistence;
public interface TypeHandler {
String resultSetSetter(int i, String o, FieldMirror field);
+ String sqlType(FieldMirror field);
+
public static class IntTypeHandler implements TypeHandler {
@Override
public String resultSetSetter(int i, String o, FieldMirror field) {
return "setInt(" + i + ", " + o + "." + field.javaName + ")";
}
+
+ @Override
+ public String sqlType(FieldMirror field) {
+ return "INTEGER";
+ }
}
public static class LongTypeHandler implements TypeHandler {
@@ -15,6 +22,11 @@ public interface TypeHandler {
public String resultSetSetter(int i, String o, FieldMirror field) {
return "setLong(" + i + ", " + o + "." + field.javaName + ")";
}
+
+ @Override
+ public String sqlType(FieldMirror field) {
+ return "BIGINT";
+ }
}
public static class StringTypeHandler implements TypeHandler {
@@ -22,6 +34,11 @@ public interface TypeHandler {
public String resultSetSetter(int i, String o, FieldMirror field) {
return "setString(" + i + ", " + o + "." + field.javaName + ")";
}
+
+ @Override
+ public String sqlType(FieldMirror field) {
+ return "VARCHAR(1000)";
+ }
}
public static class DateTypeHandler implements TypeHandler {
@@ -29,5 +46,10 @@ public interface TypeHandler {
public String resultSetSetter(int i, String o, FieldMirror field) {
return "setTimestamp(" + i + ", new java.sql.Timestamp(" + o + "." + field.javaName + ".getTime()))";
}
+
+ @Override
+ public String sqlType(FieldMirror field) {
+ return "TIMESTAMP";
+ }
}
}
diff --git a/container-compiler-plugin/src/test/java/io/trygvis/persistence/EntityMirrorTest.java b/container-compiler-plugin/src/test/java/io/trygvis/persistence/EntityMirrorTest.java
new file mode 100644
index 0000000..33db82b
--- /dev/null
+++ b/container-compiler-plugin/src/test/java/io/trygvis/persistence/EntityMirrorTest.java
@@ -0,0 +1,47 @@
+package io.trygvis.persistence;
+
+import io.trygvis.container.compiler.model.TypeRef;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static io.trygvis.persistence.FieldMirror.PrimitiveFieldMirror;
+import static java.lang.String.format;
+import static org.testng.Assert.assertEquals;
+
+public class EntityMirrorTest {
+
+ static FieldMirror idLong = new PrimitiveFieldMirror(new TypeRef(Long.class), "id", "id", true, false);
+ static FieldMirror idString = new PrimitiveFieldMirror(new TypeRef(String.class), "id", "id", true, false);
+
+ @DataProvider(name = "insertIntoSql", parallel = true)
+ public static Object[][] insertIntoProvider() {
+ return new Object[][]{
+ new Object[]{
+ new FieldMirror[]{idString},
+ "INSERT INTO my_table(id) VALUES(?);",
+ "DELETE FROM my_table WHERE id=?;", format(
+ "CREATE TABLE my_table(%n" +
+ " id VARCHAR(1000) PRIMARY KEY%n" +
+ ");")},
+ new Object[]{
+ new FieldMirror[]{idLong},
+ "INSERT INTO my_table(id) VALUES(?);",
+ "DELETE FROM my_table WHERE id=?;", format(
+ "CREATE TABLE my_table(%n" +
+ " id BIGINT PRIMARY KEY%n" +
+ ");")},
+ };
+ }
+
+ @Test(dataProvider = "insertIntoSql")
+ public void testInsertIntoSql(FieldMirror[] fields, String insert, String delete, String create) throws Exception {
+ EntityMirror myTable = new EntityMirror(new GeneratorSupport(), new TypeRef("Wat"), "my_table");
+ for (FieldMirror field : fields) {
+ myTable.add(field);
+ }
+
+ assertEquals(myTable.insertIntoSql(), insert);
+ assertEquals(myTable.deleteFromSql(), delete);
+ assertEquals(myTable.createTableSql(), create);
+ }
+}
diff --git a/container-compiler-plugin/src/test/java/io/trygvis/persistence/test/PersonTypeHandler.java b/container-compiler-plugin/src/test/java/io/trygvis/persistence/test/PersonTypeHandler.java
index 68e17c3..fa803da 100644
--- a/container-compiler-plugin/src/test/java/io/trygvis/persistence/test/PersonTypeHandler.java
+++ b/container-compiler-plugin/src/test/java/io/trygvis/persistence/test/PersonTypeHandler.java
@@ -8,4 +8,9 @@ public class PersonTypeHandler implements TypeHandler {
public String resultSetSetter(int i, String o, FieldMirror field) {
return "setLong(" + i + ", o." + field.javaName + ".id)";
}
+
+ @Override
+ public String sqlType(FieldMirror field) {
+ return "LONG";
+ }
}
diff --git a/myapp/src/main/java/io/trygvis/container/myapp/AddressBook.java b/myapp/src/main/java/io/trygvis/container/myapp/AddressBook.java
index 218f25f..0d05989 100644
--- a/myapp/src/main/java/io/trygvis/container/myapp/AddressBook.java
+++ b/myapp/src/main/java/io/trygvis/container/myapp/AddressBook.java
@@ -1,10 +1,16 @@
package io.trygvis.container.myapp;
+import java.io.BufferedReader;
import java.io.EOFException;
+import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
+import java.sql.Statement;
public class AddressBook {
+
+ private BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
+
public static void main(String[] args) throws Exception {
try {
new AddressBook().work();
@@ -17,6 +23,12 @@ public class AddressBook {
while (!done) {
String cmd = Character.toString(menu());
switch (cmd) {
+ case "c":
+ run(new CreateTablesCommand());
+ break;
+ case "d":
+ run(new DropTablesCommand());
+ break;
case "l":
run(new ListCommand());
break;
@@ -34,22 +46,47 @@ public class AddressBook {
}
public void run(Command command) throws Exception {
- try (Connection c = DriverManager.getConnection("jdbc:h2:mem")) {
+ try (Connection c = DriverManager.getConnection("jdbc:h2:mem:address-book;DB_CLOSE_DELAY=-1")) {
c.setAutoCommit(false);
command.run(c);
+ c.commit();
+ System.out.println("OK");
}
}
private char menu() throws Exception {
System.out.println("Menu:");
+ System.out.println("c Create");
+ System.out.println("d Drop");
System.out.println("l List");
System.out.println("a Add");
System.out.println("q Quit");
- int read = System.in.read();
- if (read == -1) {
- throw new EOFException();
+ while (true) {
+ String read = reader.readLine();
+ if (read == null) {
+ throw new EOFException();
+ }
+ read = read.trim();
+ if (read.length() != 0) {
+ return read.charAt(0);
+ }
+ }
+ }
+
+ public static class CreateTablesCommand implements Command {
+ @Override
+ public void run(Connection c) throws Exception {
+ Statement statement = c.createStatement();
+ statement.executeUpdate(PersonDao.createTableSql);
+ }
+ }
+
+ public static class DropTablesCommand implements Command {
+ @Override
+ public void run(Connection c) throws Exception {
+ Statement statement = c.createStatement();
+ statement.executeUpdate(PersonDao.dropTableSql);
}
- return (char) read;
}
public static class ListCommand implements Command {