summaryrefslogtreecommitdiff
path: root/src/main/java/com/amazon
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/amazon')
-rw-r--r--src/main/java/com/amazon/carbonado/gen/StorableGenerator.java46
-rw-r--r--src/main/java/com/amazon/carbonado/info/StorableIntrospector.java25
2 files changed, 59 insertions, 12 deletions
diff --git a/src/main/java/com/amazon/carbonado/gen/StorableGenerator.java b/src/main/java/com/amazon/carbonado/gen/StorableGenerator.java
index bb06708..3319d5c 100644
--- a/src/main/java/com/amazon/carbonado/gen/StorableGenerator.java
+++ b/src/main/java/com/amazon/carbonado/gen/StorableGenerator.java
@@ -21,7 +21,9 @@ package com.amazon.carbonado.gen;
import java.lang.annotation.Annotation;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
+import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
@@ -449,8 +451,8 @@ public final class StorableGenerator<S extends Storable> {
final int supportParam = 0;
MethodInfo mi = mClassFile.addConstructor(Modifiers.PROTECTED, params);
CodeBuilder b = new CodeBuilder(mi);
- b.loadThis();
- b.invokeSuperConstructor(null);
+
+ addInvokeSuperConstructor(b, supportParam);
//// this.support = support
b.loadThis();
@@ -466,8 +468,8 @@ public final class StorableGenerator<S extends Storable> {
final int wrappedStorableParam = 1;
MethodInfo mi = mClassFile.addConstructor(Modifiers.PUBLIC, params);
CodeBuilder b = new CodeBuilder(mi);
- b.loadThis();
- b.invokeSuperConstructor(null);
+
+ addInvokeSuperConstructor(b, wrappedSupportParam);
//// this.wrappedSupport = wrappedSupport
b.loadThis();
@@ -1960,6 +1962,42 @@ public final class StorableGenerator<S extends Storable> {
}
/**
+ * Generates code to invoke super class constructor with no arguments or a
+ * Repository.
+ */
+ private void addInvokeSuperConstructor(CodeBuilder b, final int supportParam) {
+ // Look for constructor that accepts a Repository.
+
+ boolean passRepo = false;
+ {
+ for (Constructor c : mStorableType.getDeclaredConstructors()) {
+ int modifiers = c.getModifiers();
+ if (!Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers)) {
+ continue;
+ }
+ if (c.getParameterTypes().length == 1) {
+ if (c.getParameterTypes()[0] == Repository.class) {
+ passRepo = true;
+ break;
+ }
+ }
+ }
+ }
+
+ b.loadThis();
+
+ if (passRepo) {
+ b.loadLocal(b.getParameter(supportParam));
+ b.invokeInterface(StorableSupport.class.getName(), "getRootRepository",
+ TypeDesc.forClass(Repository.class), null);
+ b.invokeSuperConstructor(new TypeDesc[] {TypeDesc.forClass(Repository.class)});
+ } else {
+ // Assume no-arg constructor.
+ b.invokeSuperConstructor(null);
+ }
+ }
+
+ /**
* If GEN_WRAPPED, generates a method implementation which delgates to the
* WrappedSupport. Also clears join property state if called method
* returns normally.
diff --git a/src/main/java/com/amazon/carbonado/info/StorableIntrospector.java b/src/main/java/com/amazon/carbonado/info/StorableIntrospector.java
index ce704e3..133e175 100644
--- a/src/main/java/com/amazon/carbonado/info/StorableIntrospector.java
+++ b/src/main/java/com/amazon/carbonado/info/StorableIntrospector.java
@@ -62,6 +62,7 @@ import com.amazon.carbonado.Nullable;
import com.amazon.carbonado.Independent;
import com.amazon.carbonado.PrimaryKey;
import com.amazon.carbonado.Query;
+import com.amazon.carbonado.Repository;
import com.amazon.carbonado.Sequence;
import com.amazon.carbonado.Storable;
import com.amazon.carbonado.Version;
@@ -490,27 +491,35 @@ public class StorableIntrospector {
checkTypeParameter(errorMessages, type);
- // If type is a class, it must have a public or protected no-arg
- // constructor.
+ // If type is a class, it must have a public/protected constructor that
+ // takes no arguments or a Repository. If overloaded, the constructor
+ // with the Repository parameter is preferred by the code generator.
if (!type.isInterface()) {
Constructor[] ctors = type.getDeclaredConstructors();
findCtor: {
for (Constructor c : ctors) {
+ modifiers = c.getModifiers();
+ if (!Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers)) {
+ continue;
+ }
if (c.getParameterTypes().length == 0) {
- modifiers = c.getModifiers();
- if (!Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers)) {
- errorMessages.add("Cannot call constructor: " + c);
- }
break findCtor;
}
+ if (c.getParameterTypes().length == 1) {
+ if (c.getParameterTypes()[0] == Repository.class) {
+ break findCtor;
+ }
+ }
}
if (type.getEnclosingClass() == null) {
errorMessages.add
- ("Class must have an accesible no-arg constructor");
+ ("Class must have a public or protected constructor " +
+ "that takes no arguments or a Repository");
} else {
errorMessages.add
- ("Inner class must be static and have an accesible no-arg constructor");
+ ("Inner class must have a public or protected constructor " +
+ "that takes no arguments or a Repository");
}
}
}