summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2013-08-03 23:13:32 +0200
committerTrygve Laugstøl <trygvis@inamo.no>2013-08-03 23:13:32 +0200
commit2b1c32590db960be2b5f62897e65bb10d434cae0 (patch)
tree84623e4293f59f67331a7760a700121737313c48
parentdf92538ab3d83da9839f08b28fc8a67317565463 (diff)
downloadcontainer-playground-2b1c32590db960be2b5f62897e65bb10d434cae0.tar.gz
container-playground-2b1c32590db960be2b5f62897e65bb10d434cae0.tar.bz2
container-playground-2b1c32590db960be2b5f62897e65bb10d434cae0.tar.xz
container-playground-2b1c32590db960be2b5f62897e65bb10d434cae0.zip
wip
-rw-r--r--container-compiler-plugin/pom.xml11
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/EntityHandler.java38
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/MyProcessor.java8
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/TransactionalHandler.java18
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/ClassG.java186
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Constructor.java20
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/FieldRef.java8
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/MethodRef.java4
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/ParameterRef.java11
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Parameters.java31
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/TypeRef.java69
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java104
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/persistence/TypeHandler.java40
-rw-r--r--container-compiler-plugin/src/test/java/io/trygvis/container/compiler/model/TypeRefTest.java19
-rw-r--r--container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/Person.java9
-rw-r--r--container-core/pom.xml5
-rw-r--r--myapp/src/main/java/io/trygvis/container/myapp/AddressBook.java11
-rw-r--r--myapp/src/main/java/io/trygvis/container/myapp/Person.java5
-rw-r--r--pom.xml1
-rw-r--r--sql-persistence/pom.xml19
-rw-r--r--sql-persistence/src/main/java/io/trygvis/persistence/sql/AbstractTypedQuery.java227
-rw-r--r--sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlEntityDesc.java11
22 files changed, 680 insertions, 175 deletions
diff --git a/container-compiler-plugin/pom.xml b/container-compiler-plugin/pom.xml
index 2e9fff9..d451ee3 100644
--- a/container-compiler-plugin/pom.xml
+++ b/container-compiler-plugin/pom.xml
@@ -17,7 +17,7 @@
</dependency>
<dependency>
<groupId>io.trygvis.container</groupId>
- <artifactId>persistence-compile-time</artifactId>
+ <artifactId>sql-persistence</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
@@ -31,14 +31,11 @@
<version>6.8.5</version>
<scope>test</scope>
</dependency>
- <!--
<dependency>
- <groupId>org.eclipse.tycho</groupId>
- <artifactId>org.eclipse.jdt.core</artifactId>
- <version>3.9.0.v20130604-1421</version>
- <scope>test</scope>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.6</version>
</dependency>
- -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
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 c623af7..19205b1 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
@@ -7,6 +7,7 @@ import io.trygvis.persistence.FieldMirror;
import io.trygvis.persistence.GeneratorConfiguration;
import io.trygvis.persistence.SqlEntity;
import io.trygvis.persistence.TypeHandler;
+import io.trygvis.persistence.sql.SqlEntityDesc;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
@@ -28,7 +29,9 @@ 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 java.lang.reflect.Modifier.PUBLIC;
import static javax.lang.model.util.ElementFilter.fieldsIn;
+import static org.apache.commons.lang.StringUtils.stripEnd;
public class EntityHandler extends AbstractHandler {
private GeneratorConfiguration generatorConfiguration = new GeneratorConfiguration();
@@ -49,7 +52,7 @@ public class EntityHandler extends AbstractHandler {
TypeHandler typeHandler = (TypeHandler) typeHandlerClass.newInstance();
String type = entity.asType().toString();
- generatorConfiguration.addTypeHandler(new TypeRef(type, type), typeHandler);
+ generatorConfiguration.addTypeHandler(new TypeRef(type), typeHandler);
System.out.println("Loaded TypeHandler for " + type + " through " + typeHandlerClass.getCanonicalName());
break;
}
@@ -105,18 +108,33 @@ public class EntityHandler extends AbstractHandler {
}
public void generate(EntityMirror entityMirror) throws IOException {
- ClassG g = new ClassG(entityMirror.daoType);
- g.addPublicStaticFinalField(String.class, "createTableSql").value(toJavaString(entityMirror.createTableSql(sqlUnit)));
- 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()));
+ TypeRef stringType = new TypeRef(String.class);
+ TypeRef sqlEntityDescType = new TypeRef(SqlEntityDesc.class);
+
+ ClassG g = new ClassG(PUBLIC, entityMirror.daoType);
+ g.addPublicStaticFinalField(stringType, "createTableSql").
+ value(toJavaString(entityMirror.createTableSql(sqlUnit)));
+ g.addPublicStaticFinalField(stringType, "dropTableSql").
+ value(toJavaString(entityMirror.dropTableSql()));
+ g.addPublicStaticFinalField(stringType, "insertIntoSql").
+ value(toJavaString(entityMirror.insertIntoSql()));
+ g.addPublicStaticFinalField(stringType, "deleteFromSql").
+ value(toJavaString(entityMirror.deleteFromSql()));
+ String desc = "new " + sqlEntityDescType + "(" +
+ toJavaString(entityMirror.tableName) + ", " +
+ toJavaString(entityMirror.defaultFields()) +
+ ")";
+ g.addPublicStaticFinalField(sqlEntityDescType, "desc").value(desc);
entityMirror.insertInto(sqlUnit, g);
entityMirror.delete(g);
entityMirror.deleteById(g);
+ entityMirror.query(sqlUnit, g);
JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(entityMirror.daoType.fqName, sqlUnit.elementForEntity(entityMirror));
try (PrintWriter w = new PrintWriter(sourceFile.openWriter())) {
- g.write(w);
+ for (String s : g.generate()) {
+ w.println(stripEnd(s, " "));
+ }
}
}
@@ -162,7 +180,7 @@ public class EntityHandler extends AbstractHandler {
// TODO: Support a name prefix from @SqlEntitySet
TypeRef type = new TypeRef(p + ".Session");
- ClassG g = new ClassG(type);
+ ClassG g = new ClassG(PUBLIC, type);
/*
TypeRef conType = g.addImport(Connection.class);
@@ -180,7 +198,9 @@ public class EntityHandler extends AbstractHandler {
JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(type.fqName, packageElement);
try (PrintWriter w = new PrintWriter(sourceFile.openWriter())) {
- g.write(w);
+ for (String s : g.generate()) {
+ w.println(stripEnd(s, " "));
+ }
}
}
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 297b9d8..be0b446 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
@@ -69,12 +69,12 @@ public class MyProcessor implements Processor {
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
- System.out.println("io.trygvis.container.compiler.MyProcessor.process");
- System.out.println("annotations = " + annotations);
- System.out.println("roundEnv = " + roundEnv);
+// System.out.println("io.trygvis.container.compiler.MyProcessor.process");
+// System.out.println("annotations = " + annotations);
+// System.out.println("roundEnv = " + roundEnv);
try {
boolean claimed = work(roundEnv);
- System.out.println("claimed = " + claimed);
+// System.out.println("claimed = " + claimed);
return claimed;
} catch (CompilerException e) {
e.printStackTrace(System.err);
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 fbd7660..f944b1d 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
@@ -2,7 +2,6 @@ package io.trygvis.container.compiler;
import io.trygvis.container.compiler.model.ClassG;
import io.trygvis.container.compiler.model.FieldRef;
-import io.trygvis.container.compiler.model.ParameterRef;
import io.trygvis.container.compiler.model.Parameters;
import io.trygvis.container.compiler.model.TypeRef;
import io.trygvis.container.tx.PlatformTransactionManager;
@@ -23,6 +22,7 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
+import static java.lang.reflect.Modifier.PUBLIC;
import static javax.lang.model.util.ElementFilter.constructorsIn;
import static org.springframework.util.StringUtils.collectionToDelimitedString;
@@ -42,8 +42,8 @@ public class TransactionalHandler extends AbstractHandler {
String p = elements.getPackageOf(element).getQualifiedName().toString();
- ClassG g = new ClassG(new TypeRef(p + "." + className), new TypeRef(targetClassName.toString()));
- FieldRef transactionManager = g.addField(PlatformTransactionManager.class, "transactionManager");
+ ClassG g = new ClassG(PUBLIC, new TypeRef(p + "." + className)).extendsType(new TypeRef(targetClassName.toString()));
+ FieldRef transactionManager = g.addField(new TypeRef(PlatformTransactionManager.class), "transactionManager");
for (ExecutableElement constructor : constructorsIn(elements.getAllMembers(element))) {
if (!constructor.getModifiers().contains(Modifier.PUBLIC)) {
@@ -79,12 +79,12 @@ public class TransactionalHandler extends AbstractHandler {
boolean isVoid = kind == TypeKind.VOID;
TypeRef returnType = isVoid ? TypeRef.VOID : g.addImport(returnTypeMirror);
- List<ParameterRef> parameters = new ArrayList<>();
+ Parameters parameters = new Parameters();
List<String> arguments = new ArrayList<>();
for (VariableElement ve : ee.getParameters()) {
// parameters.add("final " + ve.asType().toString() + " " + ve.getSimpleName().toString());
TypeRef k = g.addImport(ve.asType());
- parameters.add(new ParameterRef(k, ve.getSimpleName().toString()));
+ parameters.addParameter(k, ve.getSimpleName().toString());
arguments.add(ve.getSimpleName().toString());
}
@@ -107,12 +107,14 @@ public class TransactionalHandler extends AbstractHandler {
body.add(" }");
body.add(" });");
- g.addMethod(body, returnType, ee.getSimpleName().toString(), parameters.toArray(new ParameterRef[arguments.size()]));
+ g.addMethod(body, returnType, ee.getSimpleName().toString(), parameters);
}
JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile((p.length() == 0 ? "" : p + ".") + className, element);
try (PrintWriter w = new PrintWriter(sourceFile.openWriter())) {
- g.write(w);
+ for (String s : g.generate()) {
+ w.println(s);
+ }
}
}
@@ -121,7 +123,7 @@ public class TransactionalHandler extends AbstractHandler {
List<String> goesToSuper = new ArrayList<>();
TypeRef k = g.addImport(PlatformTransactionManager.class);
- ParameterRef transactionManager = parameters.addParameter(k, "transactionManager");
+ Parameters.ParameterRef transactionManager = parameters.addParameter(k, "transactionManager");
for (VariableElement p : constructor.getParameters()) {
k = g.addImport(p.asType());
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 857311d..e71bbb7 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
@@ -1,31 +1,60 @@
package io.trygvis.container.compiler.model;
+import io.trygvis.container.compiler.Utils;
+import org.apache.commons.lang.StringUtils;
+
+import javax.annotation.Generated;
import javax.lang.model.type.TypeMirror;
-import java.io.PrintWriter;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
+import static io.trygvis.container.compiler.Utils.toJavaString;
import static java.lang.reflect.Modifier.*;
+import static java.util.Arrays.asList;
+import static org.apache.commons.lang.StringUtils.join;
import static org.springframework.util.StringUtils.collectionToDelimitedString;
public class ClassG {
+ public final int modifiers;
public final TypeRef type;
- private final TypeRef extendsClass;
+ private TypeRef extendsType;
+ private List<TypeRef> implementsTypes = new ArrayList<>();
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<>();
+ private final List<InnerClassG> innerClasses = new ArrayList<>();
+
+ public static class InnerClassG extends ClassG {
+ public final ClassG parent;
- public ClassG(TypeRef type) {
- this(type, null);
+ public InnerClassG(ClassG parent, int modifiers, TypeRef type) {
+ super(modifiers, type);
+ this.parent = parent;
+ }
}
- public ClassG(TypeRef type, TypeRef extendsClass) {
+ public ClassG(int modifiers, TypeRef type) {
+ if ((Modifier.classModifiers() & modifiers) != modifiers) {
+ throw new RuntimeException("Invalid modifiers for class: " + Modifier.toString(modifiers));
+ }
+
+ this.modifiers = modifiers;
this.type = type;
- this.extendsClass = extendsClass;
+ }
+
+ public ClassG extendsType(TypeRef extendsType) {
+ this.extendsType = extendsType;
+ return this;
+ }
+
+ public ClassG implementsType(TypeRef... implementsTypes) {
+ this.implementsTypes.addAll(asList(implementsTypes));
+ return this;
}
public TypeRef addImport(final TypeMirror type) {
@@ -38,20 +67,20 @@ public class ClassG {
public TypeRef addImport(TypeRef klass) {
String fqName = klass.fqName;
- String name = klass.name;
+ String name = klass.toString();
for (TypeRef i : imports) {
if (i.fqName.equals(fqName)) {
return i;
}
// If we've already found an import with the same name, use the fq version
- if (i.name.equals(name)) {
+ if (i.plainName.equals(name)) {
name = fqName;
break;
}
}
- TypeRef ref = new TypeRef(name, fqName);
+ TypeRef ref = new TypeRef(fqName, name);
imports.add(ref);
return ref;
@@ -64,23 +93,23 @@ public class ClassG {
return ref;
}
- public FieldRef addField(int modifiers, Class<?> klass, String name) {
- TypeRef type = addImport(klass);
- FieldRef ref = new FieldRef(modifiers, type, name);
+ public FieldRef addField(int modifiers, TypeRef type, String name) {
+ TypeRef t = addImport(type);
+ FieldRef ref = new FieldRef(modifiers, t, name);
fields.add(ref);
return ref;
}
- public FieldRef addField(Class<?> klass, String name) {
- return addField(PRIVATE | FINAL, klass, name);
+ public FieldRef addField(TypeRef type, String name) {
+ return addField(PRIVATE | FINAL, type, name);
}
- public FieldRef addPublicFinalField(Class<?> klass, String name) {
- return addField(PUBLIC | FINAL, klass, name);
+ public FieldRef addPublicFinalField(TypeRef type, String name) {
+ return addField(PUBLIC | FINAL, type, name);
}
- public FieldRef addPublicStaticFinalField(Class<?> klass, String name) {
- return addField(PUBLIC | STATIC | FINAL, klass, name);
+ public FieldRef addPublicStaticFinalField(TypeRef type, String name) {
+ return addField(PUBLIC | STATIC | FINAL, type, name);
}
public Constructor addConstructor(Parameters parameters, List<String> body) {
@@ -89,92 +118,129 @@ public class ClassG {
return constructor;
}
- public MethodRef addMethod(List<String> body, TypeRef returnType, String name, ParameterRef... parameters) {
+ public MethodRef addMethod(List<String> body, TypeRef returnType, String name, Parameters parameters) {
MethodRef ref = new MethodRef(PUBLIC, returnType, name, parameters, body);
methods.add(ref);
return ref;
}
- public MethodRef addStaticMethod(List<String> body, TypeRef returnType, String name, ParameterRef... parameters) {
+ public MethodRef addStaticMethod(List<String> body, TypeRef returnType, String name, Parameters parameters) {
MethodRef ref = new MethodRef(PUBLIC | STATIC, returnType, name, parameters, body);
methods.add(ref);
return ref;
}
- public void write(PrintWriter writer) {
- if (!type.inUnnamedPackage()) {
- writer.println("package " + type.packageName() + ";");
- writer.println();
+ public InnerClassG addInnerClass(int modifiers, TypeRef type) {
+ InnerClassG inner = new InnerClassG(this, modifiers, type);
+ innerClasses.add(inner);
+ return inner;
+ }
+
+ public final List<String> generate() {
+ TypeRef generatedType = addImport(Generated.class);
+
+ List<String> body = new ArrayList<>();
+ boolean isInner = this instanceof InnerClassG;
+ if (!type.inUnnamedPackage() && !isInner) {
+ body.add("package " + type.packageName() + ";");
+ body.add("");
}
- for (TypeRef i : imports) {
- if (i.isPrimitive() || i.inUnnamedPackage()) {
- continue;
+ if (!isInner) {
+ // TODO: Add imports from inner classes
+ for (TypeRef i : getImports()) {
+ if (i.isPrimitive() || i.inUnnamedPackage()) {
+ continue;
+ }
+ body.add("import " + i.fqName + ";");
+ }
+ if (!imports.isEmpty()) {
+ body.add("");
}
- writer.println("import " + i.fqName + ";");
- }
- if (!imports.isEmpty()) {
- writer.println();
}
- String extendsString = extendsClass == null ? "" : " extends " + extendsClass.name;
+ String extendsString = extendsType == null ? "" : " extends " + extendsType;
+
+ if (!implementsTypes.isEmpty()) {
+ extendsString += " implements " + join(implementsTypes, ", ");
+ }
- writer.println("public class " + type.className + extendsString + " {");
+ body.add("@" + generatedType + "(" + toJavaString("SQL Persistence, yay!!") + ")");
+ body.add(Modifier.toString(modifiers) + " class " + type.className + extendsString + " {");
for (FieldRef field : fields) {
- writer.println();
- writer.println(" " + field.toJava() + ";");
+ body.add("");
+ body.add(" " + field.toJava() + ";");
+ }
+
+ for (InnerClassG innerClass : innerClasses) {
+ body.add("");
+ addAll(1, body, innerClass.generate());
}
for (Constructor constructor : constructors) {
- writer.println();
- for (String s : constructor.write()) {
- writer.println(s);
- }
+ body.add("");
+ addAll(1, body, constructor.write());
}
for (MethodRef method : methods) {
- writer.println();
- write(writer, method);
+ body.add("");
+ addAll(1, body, write(method));
}
- writer.println("}");
+ body.add("}");
+ return body;
}
- private void write(PrintWriter writer, MethodRef method) {
+ public static void addAll(int indent, List<String> body, List<String> innerBody) {
+ String prefix = StringUtils.leftPad("", indent * 4);
+ for (String s : innerBody) {
+ body.add(prefix + s);
+ }
+ }
+
+ protected Collection<? extends TypeRef> getImports() {
+ List<TypeRef> imports = new ArrayList<>(this.imports);
+ for (InnerClassG c : innerClasses) {
+ imports.addAll(c.getImports());
+ }
+ return imports;
+ }
+
+ private List<String> write(MethodRef method) {
+ List<String> body = new ArrayList<>();
String returnString;
if (method.returnType == TypeRef.VOID) {
returnString = "void";
} else {
- returnString = method.returnType.name;
+ returnString = method.returnType.toString();
}
List<String> parameters = new ArrayList<>();
- for (ParameterRef p : method.parameters) {
- parameters.add("final " + p.klass.name + " " + p.name);
+ for (Parameters.ParameterRef p : method.parameters) {
+ parameters.add("final " + p.klass + " " + p.name);
}
- writer.print(" " +
- Modifier.toString(method.modifiers) + " " +
+ String m = Modifier.toString(method.modifiers) + " " +
returnString + " " +
- method.name + "(" + collectionToDelimitedString(parameters, ", ") + ")");
+ method.name + "(" + collectionToDelimitedString(parameters, ", ") + ")";
if (method.exceptions.isEmpty()) {
- writer.println(" {");
+ body.add(m + " {");
} else {
- writer.println(" throws");
ArrayList<TypeRef> typeRefs = new ArrayList<>(method.exceptions);
- for (int i = 0; i < typeRefs.size(); i++) {
+ String end = typeRefs.size() == 1 ? " {" : ",";
+ body.add(m + " throws " + typeRefs.get(0).toString() + end);
+ for (int i = 1; i < typeRefs.size(); i++) {
TypeRef e = typeRefs.get(i);
- writer.print(" " + e.name);
+ String s = " " + e;
if (i < typeRefs.size() - 1) {
- writer.println(",");
+ s += ",";
} else {
- writer.println(" {");
+ s += " {";
}
+ body.add(s);
}
}
- for (String s : method.body) {
- writer.print(" ");
- writer.println(s);
- }
- writer.println(" }");
+ addAll(1, body, method.body);
+ body.add("}");
+ return body;
}
}
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 f669273..0f3ceeb 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
@@ -3,7 +3,8 @@ package io.trygvis.container.compiler.model;
import java.util.ArrayList;
import java.util.List;
-import static org.springframework.util.StringUtils.collectionToDelimitedString;
+import static io.trygvis.container.compiler.model.ClassG.addAll;
+import static org.apache.commons.lang.StringUtils.join;
public class Constructor {
@@ -18,20 +19,15 @@ public class Constructor {
}
public List<String> write() {
- List<String> body = new ArrayList<>();
-
List<String> ps = new ArrayList<>();
- for (ParameterRef p : parameters) {
- ps.add(p.klass.name + " " + p.name);
+ for (Parameters.ParameterRef p : parameters) {
+ ps.add(p.klass + " " + p.name);
}
- String params = collectionToDelimitedString(ps, ", ");
-
- body.add(" public " + g.type.className + "(" + params + ") {");
- for (String s : this.body) {
- body.add(" " + s);
- }
- body.add(" }");
+ List<String> body = new ArrayList<>();
+ body.add("public " + g.type.className + "(" + join(ps, ", ") + ") {");
+ addAll(1, body, this.body);
+ body.add("}");
return body;
}
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/FieldRef.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/FieldRef.java
index 64bf032..b6df4f2 100644
--- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/FieldRef.java
+++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/FieldRef.java
@@ -4,18 +4,18 @@ import java.lang.reflect.Modifier;
public class FieldRef implements Comparable<FieldRef> {
public final int modifiers;
- public final TypeRef klass;
+ public final TypeRef type;
public final String name;
public String value;
- public FieldRef(int modifiers, TypeRef klass, String name) {
+ public FieldRef(int modifiers, TypeRef type, String name) {
this.modifiers = modifiers;
- this.klass = klass;
+ this.type = type;
this.name = name;
}
public String toJava() {
- String s = Modifier.toString(modifiers) + " " + klass.name + " " + name;
+ String s = Modifier.toString(modifiers) + " " + type + " " + name;
if (value != null) {
s += " = " + value;
}
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/MethodRef.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/MethodRef.java
index ee83fa9..902d25a 100644
--- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/MethodRef.java
+++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/MethodRef.java
@@ -11,11 +11,11 @@ public class MethodRef {
public final TypeRef returnType;
public final String name;
public final int modifiers;
- public final ParameterRef[] parameters;
+ public final Parameters parameters;
public final Set<TypeRef> exceptions = new TreeSet<>();
public final List<String> body;
- public MethodRef(int modifiers, TypeRef returnType, String name, ParameterRef[] parameters, List<String> body) {
+ public MethodRef(int modifiers, TypeRef returnType, String name, Parameters parameters, List<String> body) {
this.modifiers = modifiers;
this.returnType = returnType;
this.name = name;
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/ParameterRef.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/ParameterRef.java
deleted file mode 100644
index fc69cb1..0000000
--- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/ParameterRef.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package io.trygvis.container.compiler.model;
-
-public class ParameterRef {
- public final TypeRef klass;
- public final String name;
-
- public ParameterRef(TypeRef klass, String name) {
- this.klass = klass;
- this.name = name;
- }
-}
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Parameters.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Parameters.java
index cfd29f9..8f76714 100644
--- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Parameters.java
+++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Parameters.java
@@ -4,13 +4,30 @@ import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
-public class Parameters implements Iterable<ParameterRef> {
+public class Parameters implements Iterable<Parameters.ParameterRef> {
public static final Parameters noParameters = new Parameters();
private final List<ParameterRef> parameters = new ArrayList<>();
- public ParameterRef addParameter(TypeRef klass, String name) {
+ public Parameters() {
+ }
+
+ public Parameters(TypeRef type, String name) {
+ addParameter(type, name);
+ }
+ public Parameters(TypeRef typeA, String nameA, TypeRef typeB, String nameB) {
+ addParameter(typeA, nameA);
+ addParameter(typeB, nameB);
+ }
+
+ public Parameters(TypeRef typeA, String nameA, TypeRef typeB, String nameB, TypeRef typeC, String nameC) {
+ addParameter(typeA, nameA);
+ addParameter(typeB, nameB);
+ addParameter(typeC, nameC);
+ }
+
+ public ParameterRef addParameter(TypeRef klass, String name) {
while (taken(name)) {
name = name + "_";
}
@@ -34,4 +51,14 @@ public class Parameters implements Iterable<ParameterRef> {
public ListIterator<ParameterRef> iterator() {
return parameters.listIterator();
}
+
+ public static class ParameterRef {
+ public final TypeRef klass;
+ public final String name;
+
+ ParameterRef(TypeRef klass, String name) {
+ this.klass = klass;
+ this.name = name;
+ }
+ }
}
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 c6f958a..9c92e73 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
@@ -2,33 +2,48 @@ package io.trygvis.container.compiler.model;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
+import java.util.Collections;
+import java.util.List;
+
+import static java.util.Arrays.asList;
+import static org.apache.commons.lang.StringUtils.join;
public class TypeRef implements Comparable<TypeRef> {
- public static final TypeRef VOID = new TypeRef("void", "void");
- public static final TypeRef BOOLEAN = new TypeRef("boolean", null);
- public static final TypeRef BYTE = new TypeRef("byte", null);
- public static final TypeRef SHORT = new TypeRef("short", null);
- public static final TypeRef CHAR = new TypeRef("char", null);
- public static final TypeRef INT = new TypeRef("int", null);
- public static final TypeRef LONG = new TypeRef("long", null);
- public static final TypeRef FLOAT = new TypeRef("float", null);
- public static final TypeRef DOUBLE = new TypeRef("double", null);
+ public static final TypeRef VOID = new TypeRef("void");
+ public static final TypeRef BOOLEAN = new PrimitiveTypeRef("boolean");
+ public static final TypeRef BYTE = new PrimitiveTypeRef("byte");
+ public static final TypeRef SHORT = new PrimitiveTypeRef("short");
+ public static final TypeRef CHAR = new PrimitiveTypeRef("char");
+ public static final TypeRef INT = new PrimitiveTypeRef("int");
+ public static final TypeRef LONG = new PrimitiveTypeRef("long");
+ public static final TypeRef FLOAT = new PrimitiveTypeRef("float");
+ public static final TypeRef DOUBLE = new PrimitiveTypeRef("double");
+
+ private static class PrimitiveTypeRef extends TypeRef {
+ private PrimitiveTypeRef(String name) {
+ super(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;
+ public final String plainName;
public final String className;
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;
+ public final List<TypeRef> args;
+
+ private TypeRef(String fqName, String name, boolean primitive, List<TypeRef> args) {
+ this.fqName = fqName;
+ this.plainName = name;
+ this.primitive = primitive;
+ this.args = args;
int i = this.fqName.lastIndexOf('.');
if (i == -1) {
@@ -43,11 +58,15 @@ public class TypeRef implements Comparable<TypeRef> {
}
public TypeRef(Class<?> klass) {
- this(klass.getCanonicalName(), klass.getCanonicalName());
+ this(klass.getCanonicalName());
}
public TypeRef(String fqName) {
- this(fqName, fqName);
+ this(fqName, fqName, false, Collections.<TypeRef>emptyList());
+ }
+
+ public TypeRef(String fqName, String name) {
+ this(fqName, name, false, Collections.<TypeRef>emptyList());
}
public boolean isPrimitive() {
@@ -62,12 +81,20 @@ public class TypeRef implements Comparable<TypeRef> {
int i = fqName.lastIndexOf('.');
if (i == -1) {
- throw new RuntimeException("This type is in the unnamed package: " + name);
+ throw new RuntimeException("This type is in the unnamed package: " + toString());
}
return fqName.substring(0, i);
}
+ public TypeRef args(List<TypeRef> args) {
+ return new TypeRef(fqName, plainName, false, args);
+ }
+
+ public TypeRef args(TypeRef... args) {
+ return args(asList(args));
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -88,6 +115,14 @@ public class TypeRef implements Comparable<TypeRef> {
return fqName.compareTo(o.fqName);
}
+ public String toString() {
+ String s = plainName;
+ if(args.isEmpty()) {
+ return s;
+ }
+ return s + "<" + join(args, ", ") + ">";
+ }
+
public static TypeRef find(TypeKind kind) {
switch (kind) {
case BOOLEAN:
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 8e1602c..74c4829 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
@@ -3,18 +3,26 @@ package io.trygvis.persistence;
import io.trygvis.container.compiler.NotImplementedException;
import io.trygvis.container.compiler.SqlUnitModel;
import io.trygvis.container.compiler.model.ClassG;
-import io.trygvis.container.compiler.model.ParameterRef;
+import io.trygvis.container.compiler.model.Parameters;
import io.trygvis.container.compiler.model.TypeRef;
+import io.trygvis.persistence.sql.AbstractTypedQuery;
+import io.trygvis.persistence.sql.SqlEntityDesc;
+import javax.persistence.TypedQuery;
import java.sql.Connection;
import java.sql.PreparedStatement;
+import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
+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 java.lang.String.format;
+import static java.lang.reflect.Modifier.PUBLIC;
+import static java.lang.reflect.Modifier.STATIC;
+import static java.util.Collections.singletonList;
import static org.apache.commons.lang.StringUtils.join;
public class EntityMirror implements Comparable<EntityMirror> {
@@ -30,7 +38,7 @@ public class EntityMirror implements Comparable<EntityMirror> {
this.type = type;
this.tableName = tableName;
- this.daoType = new TypeRef(type.name + "Dao");
+ this.daoType = new TypeRef(type.plainName + "Dao").args(type.args);
}
public void add(FieldMirror field) {
@@ -111,41 +119,51 @@ public class EntityMirror implements Comparable<EntityMirror> {
return "DELETE FROM " + tableName + " WHERE " + join(ss, " AND ") + ";";
}
+ public String defaultFields() {
+ List<String> names = new ArrayList<>();
+ for (FieldMirror field : fields) {
+ names.add(field.sqlName);
+ }
+
+ return join(names, ", ");
+ }
+
public void insertInto(SqlUnitModel unit, ClassG g) {
TypeRef conType = g.addImport(Connection.class);
TypeRef psType = g.addImport(PreparedStatement.class);
- TypeRef objectType = g.addImport(type);
- ParameterRef con = new ParameterRef(conType, "con");
- ParameterRef object = new ParameterRef(objectType, "o");
+ Parameters p = new Parameters();
+ ParameterRef con = p.addParameter(conType, "con");
+ ParameterRef o = p.addParameter(type, "o");
List<String> body = new ArrayList<>();
- body.add("try(" + psType.name + " stmt = " + con.name + ".prepareStatement(insertIntoSql)) {");
+ body.add("try(" + psType + " stmt = " + con.name + ".prepareStatement(insertIntoSql)) {");
for (int i = 0; i < fields.size(); i++) {
FieldMirror field = fields.get(i);
if(field instanceof PrimitiveFieldMirror) {
TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type);
- body.add(" stmt." + typeHandler.setter(i + 1, "o." + field.javaName) + ";");
+ body.add(" stmt." + typeHandler.setter(i + 1, o.name + "." + field.javaName) + ";");
} else if (field instanceof ReferenceFieldMirror) {
ReferenceFieldMirror ref = (ReferenceFieldMirror) field;
EntityMirror referenced = unit.get(ref.type);
FieldMirror idField = referenced.getIdField();
TypeHandler typeHandler = generatorConfiguration.typeHandler(idField.type);
- body.add(" stmt." + typeHandler.setter(i + 1, "o." + field.javaName + "." + idField.javaName) + ";");
+ body.add(" stmt." + typeHandler.setter(i + 1, o.name + "." + field.javaName + "." + idField.javaName) + ";");
}
}
body.add(" stmt.executeUpdate();");
body.add("}");
- g.addStaticMethod(body, TypeRef.VOID, "insertInto", con, object).
+ g.addStaticMethod(body, TypeRef.VOID, "insertInto", p).
exception(g.addImport(SQLException.class));
}
public void delete(ClassG g) {
TypeRef conType = g.addImport(Connection.class);
TypeRef objectType = g.addImport(type);
- ParameterRef con = new ParameterRef(conType, "con");
- ParameterRef o = new ParameterRef(objectType, "o");
+ Parameters p = new Parameters();
+ ParameterRef con = p.addParameter(conType, "con");
+ ParameterRef o = p.addParameter(objectType, "o");
List<String> arguments = new ArrayList<>();
arguments.add(con.name);
@@ -155,32 +173,76 @@ public class EntityMirror implements Comparable<EntityMirror> {
List<String> body = new ArrayList<>();
body.add("deleteById(" + join(arguments, ", ") + ");");
- g.addStaticMethod(body, TypeRef.VOID, "delete", con, o).
+ g.addStaticMethod(body, TypeRef.VOID, "delete", p).
exception(g.addImport(SQLException.class));
}
public void deleteById(ClassG g) {
TypeRef conType = g.addImport(Connection.class);
TypeRef psType = g.addImport(PreparedStatement.class);
- ParameterRef con = new ParameterRef(conType, "con");
-
- ParameterRef[] parameters = new ParameterRef[idFields.size() + 1];
- parameters[0] = con;
+ Parameters p = new Parameters();
+ ParameterRef con = p.addParameter(conType, "con");
List<String> body = new ArrayList<>();
- body.add("try(" + psType.name + " stmt = " + con.name + ".prepareStatement(deleteFromSql)) {");
+ body.add("try(" + psType + " stmt = " + con.name + ".prepareStatement(deleteFromSql)) {");
for (int i = 0; i < idFields.size(); i++) {
FieldMirror field = idFields.get(i);
+ p.addParameter(field.type, field.javaName);
TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type);
- ParameterRef p = new ParameterRef(field.type, field.javaName);
- parameters[i + 1] = p;
body.add(" stmt." + typeHandler.setter(i + 1, field.javaName) + ";");
}
body.add(" stmt.executeUpdate();");
body.add("}");
- g.addStaticMethod(body, TypeRef.VOID, "deleteById", parameters).
+ g.addStaticMethod(body, TypeRef.VOID, "deleteById", p).
+ exception(g.addImport(SQLException.class));
+ }
+
+ public void query(SqlUnitModel sqlUnit, ClassG g) {
+ TypeRef conType = g.addImport(Connection.class);
+ TypeRef abstractQueryType = g.addImport(AbstractTypedQuery.class).args(type);
+ TypeRef typedQueryType = g.addImport(TypedQuery.class).args(type);
+
+ Parameters p = new Parameters();
+ ParameterRef c = p.addParameter(conType, "c");
+
+ ClassG typedQuery = g.addInnerClass(PUBLIC | STATIC, new TypeRef(type.className + "TypedQuery")).
+ extendsType(abstractQueryType);
+ typedQuery.addConstructor(p, singletonList("super(" + c.name + ", " + daoType.className + ".desc);"));
+ fromResultSet(sqlUnit, typedQuery);
+
+ List<String> body = new ArrayList<>();
+ body.add("return new " + typedQuery.type + "(" + c.name + ");");
+ g.addStaticMethod(body, typedQueryType, "query", p);
+ }
+
+ public void fromResultSet(SqlUnitModel unit, ClassG g) {
+ TypeRef rsType = g.addImport(ResultSet.class);
+ Parameters p = new Parameters();
+ ParameterRef rs = p.addParameter(rsType, "rs");
+
+ List<String> body = new ArrayList<>();
+ List<String> names = new ArrayList<>();
+ for (int i = 0; i < fields.size(); i++) {
+ FieldMirror field = fields.get(i);
+ if(field instanceof PrimitiveFieldMirror) {
+ TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type);
+ body.add(field.type + " " + field.javaName + " = " + typeHandler.getter(rs.name, i + 1) + ";");
+ } else if (field instanceof ReferenceFieldMirror) {
+ 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(field.type + " " + field.javaName + " = null;");
+ }
+ names.add(field.javaName);
+ }
+
+ body.add("return new " + type + "(" + join(names, ", ") + ");");
+
+ g.addMethod(body, type, "fromResultSet", p).
exception(g.addImport(SQLException.class));
}
@@ -200,7 +262,7 @@ public class EntityMirror implements Comparable<EntityMirror> {
}
@Override
- public int compareTo(EntityMirror o) {
+ public int compareTo(@SuppressWarnings("NullableProblems") EntityMirror o) {
return type.compareTo(o.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 3aacd7a..0454a96 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
@@ -1,14 +1,21 @@
package io.trygvis.persistence;
public interface TypeHandler {
- String setter(int i, String ref);
+ String setter(int i, String expr);
+
+ String getter(String rs, int i);
String sqlType(FieldMirror field);
public static class IntTypeHandler implements TypeHandler {
@Override
- public String setter(int i, String ref) {
- return "setInt(" + i + ", " + ref + ")";
+ public String setter(int i, String expr) {
+ return "setInt(" + i + ", " + expr + ")";
+ }
+
+ @Override
+ public String getter(String rs, int i) {
+ return rs + ".getInt(" + i + ")";
}
@Override
@@ -19,8 +26,13 @@ public interface TypeHandler {
public static class LongTypeHandler implements TypeHandler {
@Override
- public String setter(int i, String ref) {
- return "setLong(" + i + ", " + ref + ")";
+ public String setter(int i, String expr) {
+ return "setLong(" + i + ", " + expr + ")";
+ }
+
+ @Override
+ public String getter(String rs, int i) {
+ return rs + ".getLong(" + i + ")";
}
@Override
@@ -31,8 +43,13 @@ public interface TypeHandler {
public static class StringTypeHandler implements TypeHandler {
@Override
- public String setter(int i, String ref) {
- return "setString(" + i + ", " + ref + ")";
+ public String setter(int i, String expr) {
+ return "setString(" + i + ", " + expr + ")";
+ }
+
+ @Override
+ public String getter(String rs, int i) {
+ return rs + ".getString(" + i + ")";
}
@Override
@@ -43,8 +60,13 @@ public interface TypeHandler {
public static class DateTypeHandler implements TypeHandler {
@Override
- public String setter(int i, String ref) {
- return "setTimestamp(" + i + ", new java.sql.Timestamp(" + ref + ".getTime()))";
+ public String setter(int i, String expr) {
+ return "setTimestamp(" + i + ", new java.sql.Timestamp(" + expr + ".getTime()))";
+ }
+
+ @Override
+ public String getter(String rs, int i) {
+ return "new java.util.Date(" + rs + ".getTimestamp(" + i + ").getTime())";
}
@Override
diff --git a/container-compiler-plugin/src/test/java/io/trygvis/container/compiler/model/TypeRefTest.java b/container-compiler-plugin/src/test/java/io/trygvis/container/compiler/model/TypeRefTest.java
new file mode 100644
index 0000000..94425cc
--- /dev/null
+++ b/container-compiler-plugin/src/test/java/io/trygvis/container/compiler/model/TypeRefTest.java
@@ -0,0 +1,19 @@
+package io.trygvis.container.compiler.model;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+public class TypeRefTest {
+ @Test
+ public void testBasic() {
+ TypeRef foo = new TypeRef("wat.Foo");
+ TypeRef string = new TypeRef(String.class);
+ TypeRef bar = new TypeRef("wat.Bar").args(string);
+ TypeRef baz = new TypeRef("woot.Baz").args(bar);
+ assertEquals(foo.toString(), "wat.Foo");
+ assertEquals(bar.toString(), "wat.Bar<java.lang.String>");
+ assertEquals(baz.toString(), "woot.Baz<wat.Bar<java.lang.String>>");
+ }
+}
diff --git a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/Person.java b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/Person.java
index 3f1be35..43a0c78 100644
--- a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/Person.java
+++ b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/Person.java
@@ -1,14 +1,11 @@
package io.trygvis.persistence.test;
-import io.trygvis.persistence.SqlEntity;
-
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import java.util.Date;
@Entity
-//@SqlEntity("io.trygvis.persistence.test.PersonTypeHandler")
public class Person {
@Id
public Long id;
@@ -24,4 +21,10 @@ public class Person {
// @OneToMany(mappedBy = "id")
// @OrderBy("birthDate asc")
// private List<Person> children = new ArrayList<>();
+
+ public Person(Long id, Date birthDate, Person mother) {
+ this.id = id;
+ this.birthDate = birthDate;
+ this.mother = mother;
+ }
}
diff --git a/container-core/pom.xml b/container-core/pom.xml
index d17a86a..e16c761 100644
--- a/container-core/pom.xml
+++ b/container-core/pom.xml
@@ -19,11 +19,6 @@
<version>${version.spring}</version>
</dependency>
<dependency>
- <groupId>org.hibernate.javax.persistence</groupId>
- <artifactId>hibernate-jpa-2.0-api</artifactId>
- <version>1.0.1.Final</version>
- </dependency>
- <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${version.spring}</version>
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 c8440ff..ec0bffa 100644
--- a/myapp/src/main/java/io/trygvis/container/myapp/AddressBook.java
+++ b/myapp/src/main/java/io/trygvis/container/myapp/AddressBook.java
@@ -1,11 +1,13 @@
package io.trygvis.container.myapp;
+import javax.persistence.TypedQuery;
import java.io.BufferedReader;
import java.io.EOFException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
+import java.util.List;
public class AddressBook {
@@ -109,7 +111,14 @@ public class AddressBook {
public static class ListCommand implements Command {
@Override
public void run(Connection c) throws Exception {
-// PersonDao.insertInto(c, new Person());
+ TypedQuery<Person> p = PersonDao.query(c);
+
+ List<Person> 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);
+ }
}
}
}
diff --git a/myapp/src/main/java/io/trygvis/container/myapp/Person.java b/myapp/src/main/java/io/trygvis/container/myapp/Person.java
index ab883b2..6a7a694 100644
--- a/myapp/src/main/java/io/trygvis/container/myapp/Person.java
+++ b/myapp/src/main/java/io/trygvis/container/myapp/Person.java
@@ -13,4 +13,9 @@ public class Person {
public Person(String name) {
this.name = name;
}
+
+ public Person(Long id, String name) {
+ this.id = id;
+ this.name = name;
+ }
}
diff --git a/pom.xml b/pom.xml
index e9ea30b..907c9b6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,5 +37,6 @@
<module>container-compiler-plugin</module>
<module>myapp</module>
<module>container-core</module>
+ <module>sql-persistence</module>
</modules>
</project>
diff --git a/sql-persistence/pom.xml b/sql-persistence/pom.xml
new file mode 100644
index 0000000..6d5a56d
--- /dev/null
+++ b/sql-persistence/pom.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>container-playground</artifactId>
+ <groupId>io.trygvis.container</groupId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>sql-persistence</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>org.hibernate.javax.persistence</groupId>
+ <artifactId>hibernate-jpa-2.0-api</artifactId>
+ <version>1.0.1.Final</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/sql-persistence/src/main/java/io/trygvis/persistence/sql/AbstractTypedQuery.java b/sql-persistence/src/main/java/io/trygvis/persistence/sql/AbstractTypedQuery.java
new file mode 100644
index 0000000..1cb8405
--- /dev/null
+++ b/sql-persistence/src/main/java/io/trygvis/persistence/sql/AbstractTypedQuery.java
@@ -0,0 +1,227 @@
+package io.trygvis.persistence.sql;
+
+import javax.persistence.FlushModeType;
+import javax.persistence.LockModeType;
+import javax.persistence.NoResultException;
+import javax.persistence.NonUniqueResultException;
+import javax.persistence.Parameter;
+import javax.persistence.PersistenceException;
+import javax.persistence.TemporalType;
+import javax.persistence.TypedQuery;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public abstract class AbstractTypedQuery<A> implements TypedQuery<A> {
+ private final Connection c;
+ private final SqlEntityDesc sqlEntity;
+
+ private int firstResult;
+ private int maxResults;
+
+ protected AbstractTypedQuery(Connection c, SqlEntityDesc sqlEntity) {
+ this.c = c;
+ this.sqlEntity = sqlEntity;
+ }
+
+ public abstract A fromResultSet(ResultSet rs) throws SQLException;
+
+ @Override
+ public TypedQuery<A> setMaxResults(int maxResult) {
+ this.maxResults = maxResult;
+ return this;
+ }
+
+ @Override
+ public TypedQuery<A> setFirstResult(int firstResult) {
+ this.firstResult = firstResult;
+ return this;
+ }
+
+ @Override
+ public TypedQuery<A> setHint(String hintName, Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public <T> TypedQuery<A> setParameter(Parameter<T> param, T value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public TypedQuery<A> setParameter(Parameter<Calendar> param, Calendar value, TemporalType temporalType) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public TypedQuery<A> setParameter(Parameter<Date> param, Date value, TemporalType temporalType) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public TypedQuery<A> setParameter(String name, Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public TypedQuery<A> setParameter(String name, Calendar value, TemporalType temporalType) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public TypedQuery<A> setParameter(String name, Date value, TemporalType temporalType) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public TypedQuery<A> setParameter(int position, Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public TypedQuery<A> setParameter(int position, Calendar value, TemporalType temporalType) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public TypedQuery<A> setParameter(int position, Date value, TemporalType temporalType) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public TypedQuery<A> setFlushMode(FlushModeType flushMode) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public TypedQuery<A> setLockMode(LockModeType lockMode) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int executeUpdate() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int getMaxResults() {
+ return maxResults;
+ }
+
+ @Override
+ public int getFirstResult() {
+ return firstResult;
+ }
+
+ @Override
+ public Map<String, Object> getHints() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Set<Parameter<?>> getParameters() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Parameter<?> getParameter(String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public <T> Parameter<T> getParameter(String name, Class<T> type) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Parameter<?> getParameter(int position) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public <T> Parameter<T> getParameter(int position, Class<T> type) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isBound(Parameter<?> param) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public <T> T getParameterValue(Parameter<T> param) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Object getParameterValue(String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Object getParameterValue(int position) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public FlushModeType getFlushMode() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public LockModeType getLockMode() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public <T> T unwrap(Class<T> cls) {
+ throw new UnsupportedOperationException();
+ }
+
+ public List<A> getResultList() {
+ return getResultList(null, null);
+ }
+
+ public List<A> getResultList(Integer offset, Integer limit) {
+ String sql = "SELECT " + sqlEntity.defaultFields + " FROM " + sqlEntity.tableName;
+
+ if(offset != null) {
+ sql += " OFFSET " + offset;
+ }
+ if(limit != null) {
+ sql += " LIMIT " + limit;
+ }
+
+ sql += ";";
+
+ List<A> list = new ArrayList<>();
+ try (PreparedStatement stmt = c.prepareStatement(sql)) {
+ ResultSet rs = stmt.executeQuery();
+ while (rs.next()) {
+ list.add(fromResultSet(rs));
+ }
+ return list;
+ } catch (SQLException e) {
+ throw new PersistenceException(e);
+ }
+ }
+
+ public A getSingleResult() {
+ List<A> list = getResultList(null, 2);
+ switch (list.size()) {
+ case 1:
+ return list.get(0);
+ case 0:
+ throw new NoResultException();
+ default:
+ throw new NonUniqueResultException();
+ }
+ }
+}
diff --git a/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlEntityDesc.java b/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlEntityDesc.java
new file mode 100644
index 0000000..dbbeed7
--- /dev/null
+++ b/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlEntityDesc.java
@@ -0,0 +1,11 @@
+package io.trygvis.persistence.sql;
+
+public class SqlEntityDesc {
+ public final String tableName;
+ public final String defaultFields;
+
+ public SqlEntityDesc(String tableName, String defaultFields) {
+ this.tableName = tableName;
+ this.defaultFields = defaultFields;
+ }
+}