From 381c368b8907640bdd7cd81db2294724e082a119 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Sun, 4 Aug 2013 17:17:39 +0200 Subject: wip --- .../trygvis/container/compiler/EntityHandler.java | 110 +++++++++++++--- .../io/trygvis/container/compiler/MyProcessor.java | 10 +- .../java/io/trygvis/container/compiler/Utils.java | 17 +++ .../java/io/trygvis/persistence/EntityMirror.java | 60 +++++++-- .../java/io/trygvis/persistence/FieldMirror.java | 62 ++++----- .../trygvis/container/compiler/ProcessorTest.java | 13 +- .../io/trygvis/persistence/EntityMirrorTest.java | 145 ++++++++++++++++----- .../io/trygvis/persistence/test/ChildEntity.java | 13 ++ .../io/trygvis/persistence/test/ParentEntity.java | 22 ++++ myapp/pom.xml | 5 - .../io/trygvis/container/myapp/AbstractEntity.java | 20 +++ .../io/trygvis/container/myapp/AddressBook.java | 19 +-- .../java/io/trygvis/container/myapp/Contact.java | 23 ++++ .../java/io/trygvis/container/myapp/Person.java | 23 ---- 14 files changed, 396 insertions(+), 146 deletions(-) create mode 100644 container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/ChildEntity.java create mode 100644 container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/ParentEntity.java create mode 100644 myapp/src/main/java/io/trygvis/container/myapp/AbstractEntity.java create mode 100644 myapp/src/main/java/io/trygvis/container/myapp/Contact.java delete mode 100644 myapp/src/main/java/io/trygvis/container/myapp/Person.java 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 a25c766..98090a4 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 @@ -19,6 +19,7 @@ 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.TypeKind; import javax.lang.model.type.TypeMirror; import javax.persistence.Id; import javax.persistence.SequenceGenerator; @@ -29,12 +30,19 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.TreeMap; +import static io.trygvis.container.compiler.Utils.toFieldName; import static io.trygvis.container.compiler.Utils.toJavaString; -import static io.trygvis.persistence.FieldMirror.PrimitiveFieldMirror; +import static io.trygvis.persistence.FieldMirror.AccessorType.FIELD; +import static io.trygvis.persistence.FieldMirror.AccessorType.METHOD; +import static io.trygvis.persistence.FieldMirror.FieldType.PRIMITIVE; +import static io.trygvis.persistence.FieldMirror.FieldType.REFERENCE; import static java.lang.Character.isUpperCase; +import static java.lang.String.format; import static java.lang.reflect.Modifier.PUBLIC; import static javax.lang.model.util.ElementFilter.fieldsIn; +import static javax.lang.model.util.ElementFilter.methodsIn; import static org.apache.commons.lang.StringUtils.join; import static org.apache.commons.lang.StringUtils.stripEnd; @@ -65,7 +73,6 @@ public class EntityHandler extends AbstractHandler { throw new InternalErrorException("Unknown @SqlEntity field: " + field); } } -// System.out.println("sqlEntity.getElementValues() = " + sqlEntity.getElementValues()); } if (packages.size() == 0) { @@ -85,9 +92,57 @@ public class EntityHandler extends AbstractHandler { new TypeRef(types.getDeclaredType(element)), sqlName(element.getSimpleName().toString())); + Map getters = new TreeMap<>(); + Map setters = new TreeMap<>(); + for (ExecutableElement m : methodsIn(elements.getAllMembers(element))) { + String name = m.getSimpleName().toString(); + if (name.length() < 4 || !isUpperCase(name.charAt(3))) { + continue; + } + + String declaringType = ((TypeElement) m.getEnclosingElement()).getQualifiedName().toString(); + if (declaringType.equals("java.lang.Object")) { + continue; + } + + boolean isVoid = m.getReturnType().getKind().equals(TypeKind.VOID); + + if (name.startsWith("get") && m.getParameters().size() == 0 && !isVoid) { + getters.put(toFieldName(name), m); + } + + if (name.startsWith("set") && m.getParameters().size() == 1 && isVoid) { + setters.put(toFieldName(name), m); + } + } + + // Iterate over all fields. Consume relevant getters and setters. for (VariableElement f : fieldsIn(elements.getAllMembers(element))) { - FieldMirror field = fromElement(generatorConfiguration, f); + String name = f.getSimpleName().toString(); + ExecutableElement getter = getters.remove(name); + ExecutableElement setter = setters.remove(name); + FieldMirror field = fromElement(generatorConfiguration, f, getter, setter); + if (field == null) { + continue; + } entityMirror.add(field); + System.out.println("Field: " + field); + } + + for (Map.Entry e : getters.entrySet()) { + String name = e.getKey(); + ExecutableElement getter = e.getValue(); + ExecutableElement setter = setters.remove(name); + FieldMirror field = fromElement(generatorConfiguration, null, getter, setter); + if (field == null) { + continue; + } + entityMirror.add(field); + System.out.println("Field: " + field); + } + + if (!setters.isEmpty()) { + throw new CompilerException(element, "Missing getters for setters: " + join(setters.keySet(), ", ")); } // ----------------------------------------------------------------------- @@ -164,15 +219,36 @@ public class EntityHandler extends AbstractHandler { return g; } - public FieldMirror fromElement(GeneratorConfiguration generatorConfiguration, VariableElement var) { - TypeRef type = new TypeRef(var.asType()); -// System.out.print("element = "); -// elements.printElements(new PrintWriter(System.out), var); - String javaName = var.getSimpleName().toString(); - String sqlName = sqlName(javaName); + public FieldMirror fromElement(GeneratorConfiguration generatorConfiguration, VariableElement var, + ExecutableElement getter, ExecutableElement setter) { + // TODO: check the setter for annotations too + // TODO: check for transient and @Transient + FieldMirror.AccessorType accessorType; + TypeRef type; + String javaName; + String sqlName; + boolean id; + + if (var != null) { + accessorType = FIELD; + type = new TypeRef(var.asType()); + javaName = var.getSimpleName().toString(); + id = isId(var); + } else { + accessorType = METHOD; + type = new TypeRef(getter.getReturnType()); + id = isId(getter); + // TODO: this might be relaxed, just find the common type and use that. + if (!types.isSameType(getter.getReturnType(), setter.getParameters().get(0).asType())) { + throw new CompilerException(format("The setter and getter %s/%s must access the same types.", + setter.getSimpleName(), getter.getSimpleName())); + } + javaName = toFieldName(getter.getSimpleName().toString()); + } + sqlName = sqlName(javaName); + boolean notNull = false; boolean unique = false; - boolean id = isId(var); boolean primitive = generatorConfiguration.isPrimitive(type); if (id && !primitive) { throw new CompilerException(var, "A @Id field has to be a primitive or embedded."); @@ -180,16 +256,16 @@ public class EntityHandler extends AbstractHandler { FieldMirror field; if (primitive) { - field = new PrimitiveFieldMirror(type, javaName, sqlName, id, notNull, unique); + field = new FieldMirror(PRIMITIVE, accessorType, type, javaName, sqlName, id, notNull, unique); } else if (generatorConfiguration.hasTypeHandler(type)) { throw new CompilerException(var, "Missing type handler for type: " + type.fqName); } else { - field = new FieldMirror.ReferenceFieldMirror(type, javaName, sqlName, notNull, unique); + field = new FieldMirror(REFERENCE, accessorType, type, javaName, sqlName, id, notNull, unique); } return field; } - public static boolean isId(VariableElement var) { + public static boolean isId(Element var) { return var.getAnnotation(Id.class) != null; } @@ -211,9 +287,7 @@ public class EntityHandler extends AbstractHandler { FieldRef f = g.addPublicStaticFinalField(stringType, sequence.name).value(toJavaString(value)); fields.add(f.name); } - TypeRef stringArrayType = new TypeRef(String[].class); - System.out.println("stringArrayType = " + stringArrayType); - g.addPublicStaticFinalField(stringArrayType, "sequences"). + g.addPublicStaticFinalField(new TypeRef(String[].class), "sequences"). value("new String[]{" + join(fields, ", ") + "}"); return g; } @@ -233,8 +307,6 @@ public class EntityHandler extends AbstractHandler { // TODO: Support a name prefix from @SqlEntitySet TypeRef type = new TypeRef(p + ".Session"); - ClassG g = new ClassG(PUBLIC, type); - /* TypeRef conType = g.add(Connection.class); Parameters parameters = new Parameters(); @@ -249,7 +321,7 @@ public class EntityHandler extends AbstractHandler { g.addConstructor(parameters, body); */ - return g; + return new ClassG(PUBLIC, type); } public static String sqlName(String javaName) { diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/MyProcessor.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/MyProcessor.java index be0b446..89da439 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/MyProcessor.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/MyProcessor.java @@ -77,7 +77,7 @@ public class MyProcessor implements Processor { // System.out.println("claimed = " + claimed); return claimed; } catch (CompilerException e) { - e.printStackTrace(System.err); +// e.printStackTrace(System.out); Messager messager = processingEnv.getMessager(); messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage(), e.element); return true; @@ -122,7 +122,13 @@ public class MyProcessor implements Processor { new LogHandler(processingEnv).processLog((TypeElement) element); } if (types.isSameType(entity.asType(), annotationType)) { - entityHandler.recordEntity((TypeElement) element); + try { + entityHandler.recordEntity((TypeElement) element); + } catch (CompilerException e) { +// e.printStackTrace(System.out); + Messager messager = processingEnv.getMessager(); + messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage(), e.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 5057968..8bb1b33 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 @@ -12,6 +12,13 @@ public class Utils { if (s.length() < 1) { return s.toLowerCase(); } + + if (s.startsWith("set")) { + s = s.substring(3, s.length()); + } else if (s.startsWith("get")) { + s = s.substring(3, s.length()); + } + char[] chars = s.toCharArray(); boolean toUpper = false; @@ -33,6 +40,16 @@ public class Utils { return new String(chars, 0, j); } + public static String toSetterName(String s) { + s = toFieldName(s); + return "set" + toUpperCase(s.charAt(0)) + s.substring(1, s.length()); + } + + public static String toGetterName(String s) { + s = toFieldName(s); + return "get" + toUpperCase(s.charAt(0)) + s.substring(1, s.length()); + } + public static String toJavaString(String s) { try { BufferedReader reader = new BufferedReader(new StringReader(s)); 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 48f8adc..f1970f7 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 @@ -18,9 +18,13 @@ import java.sql.Types; import java.util.ArrayList; import java.util.List; +import static io.trygvis.container.compiler.Utils.toGetterName; +import static io.trygvis.container.compiler.Utils.toSetterName; import static io.trygvis.container.compiler.model.Parameters.ParameterRef; -import static io.trygvis.persistence.FieldMirror.PrimitiveFieldMirror; -import static io.trygvis.persistence.FieldMirror.ReferenceFieldMirror; +import static io.trygvis.persistence.FieldMirror.AccessorType.FIELD; +import static io.trygvis.persistence.FieldMirror.AccessorType.METHOD; +import static io.trygvis.persistence.FieldMirror.FieldType.PRIMITIVE; +import static io.trygvis.persistence.FieldMirror.FieldType.REFERENCE; import static java.lang.String.format; import static java.lang.reflect.Modifier.PUBLIC; import static java.lang.reflect.Modifier.STATIC; @@ -61,7 +65,7 @@ public class EntityMirror implements Comparable { List columns = new ArrayList<>(); for (FieldMirror field : fields) { String s; - if (field instanceof PrimitiveFieldMirror) { + if (field.fieldType == PRIMITIVE) { TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type); s = " " + field.sqlName + " " + typeHandler.sqlType(field); if (field.id) { @@ -71,9 +75,8 @@ public class EntityMirror implements Comparable { } else if (field.unique) { s += " UNIQUE"; } - } else if (field instanceof ReferenceFieldMirror) { - ReferenceFieldMirror ref = (ReferenceFieldMirror) field; - EntityMirror referenced = unit.get(ref.type); + } else if (field.fieldType == REFERENCE) { + EntityMirror referenced = unit.get(field.type); if (referenced.idFields.size() == 1) { FieldMirror idField = referenced.idFields.get(0); TypeHandler typeHandler = generatorConfiguration.typeHandler(idField.type); @@ -157,7 +160,7 @@ public class EntityMirror implements Comparable { i++; - if (field instanceof PrimitiveFieldMirror) { + if (field.fieldType == PRIMITIVE) { TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type); String access = o.name + "." + field.javaName; String setter = " stmt." + typeHandler.setter(i, access) + ";"; @@ -172,9 +175,8 @@ public class EntityMirror implements Comparable { body.add(" " + setter); body.add(" }"); } - } else if (field instanceof ReferenceFieldMirror) { - ReferenceFieldMirror ref = (ReferenceFieldMirror) field; - EntityMirror referenced = unit.get(ref.type); + } else if (field.fieldType == REFERENCE) { + EntityMirror referenced = unit.get(field.type); FieldMirror idField = referenced.getIdField(); TypeHandler typeHandler = generatorConfiguration.typeHandler(idField.type); body.add(" stmt." + typeHandler.setter(i, o.name + "." + field.javaName + "." + idField.javaName) + ";"); @@ -195,7 +197,11 @@ public class EntityMirror implements Comparable { List arguments = new ArrayList<>(); arguments.add(con.name); for (FieldMirror field : idFields) { - arguments.add(o.name + "." + field.javaName); + if(field.accessorType == FIELD) { + arguments.add(o.name + "." + field.javaName); + } else { + arguments.add(o.name + "." + toGetterName(field.javaName) + "()"); + } } List body = new ArrayList<>(); body.add("deleteById(" + join(arguments, ", ") + ");"); @@ -262,10 +268,13 @@ public class EntityMirror implements Comparable { List names = new ArrayList<>(); for (int i = 0; i < fields.size(); i++) { FieldMirror field = fields.get(i); - if (field instanceof PrimitiveFieldMirror) { + if (field.accessorType != FIELD) { + continue; + } + if (field.fieldType == PRIMITIVE) { TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type); body.add(field.type + " " + field.javaName + " = " + typeHandler.getter(rs.name, i + 1) + ";"); - } else if (field instanceof ReferenceFieldMirror) { + } else if (field.fieldType == REFERENCE) { // ReferenceFieldMirror ref = (ReferenceFieldMirror) field; // EntityMirror referenced = unit.get(ref.type); // FieldMirror idField = referenced.getIdField(); @@ -274,9 +283,32 @@ public class EntityMirror implements Comparable { body.add(field.type + " " + field.javaName + " = null;"); } names.add(field.javaName); + i++; + } + + body.add(type + " returnValue = new " + type + "(" + join(names, ", ") + ");"); + + for (int i = 0; i < fields.size(); i++) { + FieldMirror field = fields.get(i); + if (field.accessorType != METHOD) { + continue; + } + if (field.fieldType == PRIMITIVE) { + TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type); + body.add("returnValue." + toSetterName(field.javaName) + "(" + typeHandler.getter(rs.name, i + 1) + ");"); + } else if (field.fieldType == REFERENCE) { +// ReferenceFieldMirror ref = (ReferenceFieldMirror) field; +// EntityMirror referenced = unit.get(ref.type); +// FieldMirror idField = referenced.getIdField(); +// TypeHandler typeHandler = generatorConfiguration.typeHandler(idField.type); +// body.add(field.type + " " + field.javaName + " = " + typeHandler.getter(rs.name, i + 1) + ";"); + body.add("returnValue." + toSetterName(field.javaName) + "(" + null + ");"); + } + names.add(field.javaName); + i++; } - body.add("return new " + type + "(" + join(names, ", ") + ");"); + body.add("return returnValue;"); return new MethodRef(PUBLIC, type, "fromResultSet", p, body). exception(g.add(SQLException.class)); 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 f92cc2c..07fa769 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 @@ -2,14 +2,12 @@ package io.trygvis.persistence; import io.trygvis.container.compiler.model.TypeRef; -import static io.trygvis.persistence.FieldMirror.FieldType.PRIMITIVE; -import static io.trygvis.persistence.FieldMirror.FieldType.REFERENCE; - /** * TODO: a single field might have to be mapped to multiple sql columns. */ -public abstract class FieldMirror { +public class FieldMirror { public final FieldType fieldType; + public final AccessorType accessorType; public final TypeRef type; public final String javaName; public final String sqlName; @@ -22,8 +20,15 @@ public abstract class FieldMirror { REFERENCE, } - protected FieldMirror(FieldType fieldType, TypeRef type, String javaName, String sqlName, boolean id, boolean notNull, boolean unique) { + public enum AccessorType { + FIELD, + METHOD, + } + + public FieldMirror(FieldType fieldType, AccessorType accessorType, TypeRef type, String javaName, String sqlName, + boolean id, boolean notNull, boolean unique) { this.fieldType = fieldType; + this.accessorType = accessorType; this.type = type; this.javaName = javaName; this.sqlName = sqlName; @@ -32,40 +37,17 @@ public abstract class FieldMirror { this.unique = unique; } - public static class PrimitiveFieldMirror extends FieldMirror { - public PrimitiveFieldMirror(TypeRef typeRef, String javaName, String sqlName, boolean id, boolean notNull, boolean unique) { - super(PRIMITIVE, typeRef, javaName, sqlName, id, notNull, unique); - } - - @Override - public String toString() { - return "PrimitiveFieldMirror{" + - "type='" + type + '\'' + - ", javaName='" + javaName + '\'' + - ", sqlName='" + sqlName + '\'' + - ", notNull=" + notNull + - ", unique=" + unique + - '}'; - } - } - - public static class ReferenceFieldMirror extends FieldMirror { - public ReferenceFieldMirror(TypeRef typeRef, String javaName, String sqlName, boolean notNull, boolean unique) { - super(REFERENCE, typeRef, javaName, sqlName, false, notNull, unique); - } - - @Override - public String toString() { - return "ReferenceFieldMirror{" + - "type='" + type + '\'' + - ", javaName='" + javaName + '\'' + - ", sqlName='" + sqlName + '\'' + - ", notNull=" + notNull + - ", unique=" + unique + - '}'; - } - } - @Override - public abstract String toString(); + public String toString() { + return "FieldMirror{" + + "fieldType=" + fieldType + + ", accessorType=" + accessorType + + ", type=" + type + + ", javaName='" + javaName + '\'' + + ", sqlName='" + sqlName + '\'' + + ", id=" + id + + ", notNull=" + notNull + + ", unique=" + unique + + '}'; + } } diff --git a/container-compiler-plugin/src/test/java/io/trygvis/container/compiler/ProcessorTest.java b/container-compiler-plugin/src/test/java/io/trygvis/container/compiler/ProcessorTest.java index c661f8b..c7891fc 100644 --- a/container-compiler-plugin/src/test/java/io/trygvis/container/compiler/ProcessorTest.java +++ b/container-compiler-plugin/src/test/java/io/trygvis/container/compiler/ProcessorTest.java @@ -12,6 +12,7 @@ import javax.tools.ToolProvider; import java.io.IOException; import java.net.URL; import java.nio.charset.Charset; +import java.util.List; import java.util.Locale; import java.util.Map; @@ -30,11 +31,13 @@ public class ProcessorTest { InMemoryJavaFileManager fileManager = new InMemoryJavaFileManager(standardFileManager); - JavaSourceFromString person = loadCode("io.trygvis.persistence.test.Person"); - JavaSourceFromString packageInfo = loadCode("io.trygvis.persistence.test.package-info"); + List sources = asList( + loadJava("io.trygvis.persistence.test.package-info"), + loadJava("io.trygvis.persistence.test.Person"), + loadJava("io.trygvis.persistence.test.ParentEntity"), + loadJava("io.trygvis.persistence.test.ChildEntity")); - JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, collector, null, - null, asList(person, packageInfo)); + JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, collector, null, null, sources); task.setProcessors(asList(new MyProcessor())); @@ -66,7 +69,7 @@ public class ProcessorTest { fileManager.close(); } - private JavaSourceFromString loadCode(String className) throws IOException { + private JavaSourceFromString loadJava(String className) throws IOException { String path = "/" + className.replace('.', '/') + ".java"; URL resource = getClass().getResource(path); if (resource == null) { 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 index 4eead41..52b33ca 100644 --- a/container-compiler-plugin/src/test/java/io/trygvis/persistence/EntityMirrorTest.java +++ b/container-compiler-plugin/src/test/java/io/trygvis/persistence/EntityMirrorTest.java @@ -10,18 +10,23 @@ import org.testng.annotations.Test; import java.io.CharArrayWriter; import java.io.PrintWriter; -import static io.trygvis.persistence.FieldMirror.PrimitiveFieldMirror; +import static io.trygvis.persistence.FieldMirror.AccessorType.FIELD; +import static io.trygvis.persistence.FieldMirror.AccessorType.METHOD; +import static io.trygvis.persistence.FieldMirror.FieldType.PRIMITIVE; +import static io.trygvis.persistence.FieldMirror.FieldType.REFERENCE; import static java.lang.String.format; import static org.testng.Assert.assertEquals; public class EntityMirrorTest { static TypeRef entityType = new TypeRef("Wat"); - static FieldMirror idLong = new PrimitiveFieldMirror(new TypeRef(Long.class), "id", "id", true, false, true); - static FieldMirror idString = new PrimitiveFieldMirror(new TypeRef(String.class), "id", "id", true, false, true); - static FieldMirror name = new PrimitiveFieldMirror(new TypeRef(String.class), "name", "name", false, false, false); - static FieldMirror age = new PrimitiveFieldMirror(new TypeRef(Integer.class), "age", "age", false, true, false); - static FieldMirror ref = new FieldMirror.ReferenceFieldMirror(entityType, "parent", "parent", false, false); + static FieldMirror idLong = new FieldMirror(PRIMITIVE, FIELD, new TypeRef(Long.class), "id", "id", true, false, true); + static FieldMirror idString = new FieldMirror(PRIMITIVE, FIELD, new TypeRef(String.class), "id", "id", true, false, true); + static FieldMirror idMethod = new FieldMirror(PRIMITIVE, METHOD, new TypeRef(Long.class), "id", "id", true, false, true); + static FieldMirror name = new FieldMirror(PRIMITIVE, FIELD, new TypeRef(String.class), "name", "name", false, false, false); + static FieldMirror age = new FieldMirror(PRIMITIVE, FIELD, new TypeRef(Integer.class), "age", "age", false, true, false); + static FieldMirror year = new FieldMirror(PRIMITIVE, METHOD, new TypeRef(Integer.class), "year", "year", false, true, false); + static FieldMirror ref = new FieldMirror(REFERENCE, FIELD, entityType, "parent", "parent", false, false, false); @DataProvider(name = "insertIntoSql", parallel = true) public static Object[][] insertIntoProvider() { @@ -73,31 +78,32 @@ public class EntityMirrorTest { assertEquals(myTable.createTableSql(unit), create); } - @Test - public void testInsertIntoMethod() { - eq(insertInto(name), - "try(java.sql.PreparedStatement stmt = con.prepareStatement(insertIntoSql)) {", - " java.lang.String name = o.name;", - " if(name == null) {", - " stmt.setNull(1, java.sql.Types.VARCHAR);", - " } else {", - " stmt.setString(1, o.name);", - " }", - " stmt.executeUpdate();", - "}"); - - eq(insertInto(age), - "try(java.sql.PreparedStatement stmt = con.prepareStatement(insertIntoSql)) {", - " stmt.setInt(1, o.age);", - " stmt.executeUpdate();", - "}"); + @DataProvider(name = "insertIntoMethod", parallel = true) + public static Object[][] insertIntoMethodProvider() { + return new Object[][]{ + new Object[]{new FieldMirror[]{name}, join( + "try(java.sql.PreparedStatement stmt = con.prepareStatement(insertIntoSql)) {", + " java.lang.String name = o.name;", + " if(name == null) {", + " stmt.setNull(1, java.sql.Types.VARCHAR);", + " } else {", + " stmt.setString(1, o.name);", + " }", + " stmt.executeUpdate();", + "}") + }, + new Object[]{new FieldMirror[]{age}, join( + "try(java.sql.PreparedStatement stmt = con.prepareStatement(insertIntoSql)) {", + " stmt.setInt(1, o.age);", + " stmt.executeUpdate();", + "}") + }, + }; } - @Test - public void testFromResultSet() { - eq(fromResultSet(age), - "java.lang.Integer age = rs.getInt(1);", - "return new Wat(age);"); + @Test(dataProvider = "insertIntoMethod") + public void testInsertIntoMethod(FieldMirror[] fields, String expected) { + eq(insertInto(fields), expected.trim()); } private MethodRef insertInto(FieldMirror... fields) { @@ -107,6 +113,79 @@ public class EntityMirrorTest { return myTable.insertInto(unit, new Imports()); } + @DataProvider(name = "deleteMethod", parallel = true) + public static Object[][] deleteMethodProvider() { + return new Object[][]{ + new Object[]{new FieldMirror[]{idLong}, join( + "deleteById(con, o.id);") + }, + new Object[]{new FieldMirror[]{idMethod}, join( + "deleteById(con, o.getId());") + }, + }; + } + + @Test(dataProvider = "deleteMethod") + public void testDeleteMethod(FieldMirror[] fields, String expected) { + eq(delete(fields), expected.trim()); + } + + private MethodRef delete(FieldMirror... fields) { + EntityMirror myTable = new EntityMirror(new GeneratorConfiguration(), entityType, "my_table"); + myTable.add(fields); + return myTable.delete(new Imports()); + } + + @DataProvider(name = "deleteByIdMethod", parallel = true) + public static Object[][] deleteByIdMethodProvider() { + return new Object[][]{ + new Object[]{new FieldMirror[]{idLong}, join( + "try(java.sql.PreparedStatement stmt = con.prepareStatement(deleteFromSql)) {", + " stmt.setLong(1, id);", + " stmt.executeUpdate();", + "}") + }, + new Object[]{new FieldMirror[]{idMethod}, join( + "try(java.sql.PreparedStatement stmt = con.prepareStatement(deleteFromSql)) {", + " stmt.setLong(1, id);", + " stmt.executeUpdate();", + "}") + }, + }; + } + + @Test(dataProvider = "deleteByIdMethod") + public void testDeleteByIdMethod(FieldMirror[] fields, String expected) { + eq(deleteById(fields), expected.trim()); + } + + private MethodRef deleteById(FieldMirror... fields) { + EntityMirror myTable = new EntityMirror(new GeneratorConfiguration(), entityType, "my_table"); + myTable.add(fields); + return myTable.deleteById(new Imports()); + } + + @Test + public void testFromResultSet() { + eq(fromResultSet(age), + "java.lang.Integer age = rs.getInt(1);", + "Wat returnValue = new Wat(age);", + "return returnValue;"); + + eq(fromResultSet(age, year), + "java.lang.Integer age = rs.getInt(1);", + "Wat returnValue = new Wat(age);", + "returnValue.setYear(rs.getInt(2));", + "return returnValue;"); + + eq(fromResultSet(age, year, name), + "java.lang.Integer age = rs.getInt(1);", + "java.lang.String name = rs.getString(3);", + "Wat returnValue = new Wat(age, name);", + "returnValue.setYear(rs.getInt(2));", + "return returnValue;"); + } + private MethodRef fromResultSet(FieldMirror... fields) { EntityMirror myTable = new EntityMirror(new GeneratorConfiguration(), entityType, "my_table"); myTable.add(fields); @@ -128,4 +207,12 @@ public class EntityMirrorTest { assertEquals(actual.toString(), e.toString()); } + + private static String join(String... strings) { + StringBuilder buffer = new StringBuilder(); + for (String string : strings) { + buffer.append(string).append("\n"); + } + return buffer.toString(); + } } diff --git a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/ChildEntity.java b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/ChildEntity.java new file mode 100644 index 0000000..d886fca --- /dev/null +++ b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/ChildEntity.java @@ -0,0 +1,13 @@ +package io.trygvis.persistence.test; + +import javax.persistence.Entity; + +@Entity +public class ChildEntity extends ParentEntity { + public final String name; + + public ChildEntity(Long id, String name) { + super(id); + this.name = name; + } +} diff --git a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/ParentEntity.java b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/ParentEntity.java new file mode 100644 index 0000000..4695739 --- /dev/null +++ b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/ParentEntity.java @@ -0,0 +1,22 @@ +package io.trygvis.persistence.test; + +import javax.persistence.Id; + +public class ParentEntity { + @Id + public final Long id; + + public ParentEntity(Long id) { + this.id = id; + } + + private Integer age; + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } +} diff --git a/myapp/pom.xml b/myapp/pom.xml index 8851022..8084e3e 100644 --- a/myapp/pom.xml +++ b/myapp/pom.xml @@ -31,11 +31,6 @@ maven-compiler-plugin - io.trygvis.container.compiler.MyProcessor diff --git a/myapp/src/main/java/io/trygvis/container/myapp/AbstractEntity.java b/myapp/src/main/java/io/trygvis/container/myapp/AbstractEntity.java new file mode 100644 index 0000000..40896e0 --- /dev/null +++ b/myapp/src/main/java/io/trygvis/container/myapp/AbstractEntity.java @@ -0,0 +1,20 @@ +package io.trygvis.container.myapp; + +import javax.persistence.Id; + +public abstract class AbstractEntity { + private Long id; + + protected AbstractEntity(Long id) { + this.id = id; + } + + @Id + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } +} 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 0120b6a..0101004 100644 --- a/myapp/src/main/java/io/trygvis/container/myapp/AddressBook.java +++ b/myapp/src/main/java/io/trygvis/container/myapp/AddressBook.java @@ -86,7 +86,7 @@ public class AddressBook { @Override public void run(Connection c) throws Exception { Statement statement = c.createStatement(); - statement.executeUpdate(PersonDao.createTableSql); + statement.executeUpdate(ContactDao.createTableSql); for (String sql : Sequences.sequences) { statement.executeUpdate(sql); } @@ -97,7 +97,7 @@ public class AddressBook { @Override public void run(Connection c) throws Exception { Statement statement = c.createStatement(); - statement.executeUpdate(PersonDao.dropTableSql); + statement.executeUpdate(ContactDao.dropTableSql); } } @@ -106,21 +106,22 @@ public class AddressBook { public void run(Connection c) throws Exception { System.out.print("Name: "); String name = line(); - Person o = new Person(name); - PersonDao.insertInto(c, o); + Contact o = new Contact(name); + ContactDao.insertInto(c, o); } } public static class ListCommand implements Command { @Override public void run(Connection c) throws Exception { - TypedQuery p = PersonDao.query(c); + TypedQuery p = ContactDao.query(c); - List resultList = p.getResultList(); + List resultList = p.getResultList(); for (int i = 0; i < resultList.size(); i++) { - Person person = resultList.get(i); - System.out.println("#" + i); - System.out.println("Name: " + person.name); + Contact contact = resultList.get(i); + System.out.println("Item #" + i + ":"); + System.out.println("Id: " + contact.getId()); + System.out.println("Name: " + contact.name); } } } diff --git a/myapp/src/main/java/io/trygvis/container/myapp/Contact.java b/myapp/src/main/java/io/trygvis/container/myapp/Contact.java new file mode 100644 index 0000000..87e58c5 --- /dev/null +++ b/myapp/src/main/java/io/trygvis/container/myapp/Contact.java @@ -0,0 +1,23 @@ +package io.trygvis.container.myapp; + +import javax.persistence.Entity; +import javax.persistence.SequenceGenerator; + +@Entity +@SequenceGenerator(name = "id_seq") +public class Contact extends AbstractEntity { + + public String name; + +// public Contact mother; + + public Contact(String name) { + super(null); + this.name = name; + } + + public Contact(Long id, String name) { + super(id); + this.name = name; + } +} diff --git a/myapp/src/main/java/io/trygvis/container/myapp/Person.java b/myapp/src/main/java/io/trygvis/container/myapp/Person.java deleted file mode 100644 index be9026a..0000000 --- a/myapp/src/main/java/io/trygvis/container/myapp/Person.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.trygvis.container.myapp; - -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.SequenceGenerator; - -@Entity -@SequenceGenerator(name = "id_seq") -public class Person { - @Id - public Long id; - - public String name; - - public Person(String name) { - this.name = name; - } - - public Person(Long id, String name) { - this.id = id; - this.name = name; - } -} -- cgit v1.2.3