diff --git a/ebean-querybean/pom.xml b/ebean-querybean/pom.xml
index 3db43bd24..805790c47 100644
--- a/ebean-querybean/pom.xml
+++ b/ebean-querybean/pom.xml
@@ -48,14 +48,14 @@
io.ebean
ebean-ddlgen
- 12.5.0
+ ${project.version}
test
io.ebean
querybean-generator
- 12.5.0
+ ${project.version}
test
diff --git a/ebean-querybean/src/test/java/org/example/domain/Address.java b/ebean-querybean/src/test/java/org/example/domain/Address.java
index 7c46b1d90..f3b161dc8 100644
--- a/ebean-querybean/src/test/java/org/example/domain/Address.java
+++ b/ebean-querybean/src/test/java/org/example/domain/Address.java
@@ -5,6 +5,9 @@ import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.validation.constraints.Size;
+import org.example.domain.otherpackage.GenericType;
+import org.example.domain.otherpackage.GenericTypeArgument;
+
/**
* Address entity bean.
*/
@@ -24,8 +27,10 @@ public class Address extends BaseModel {
@ManyToOne
Country country;
+ GenericType metadata;
+
/**
- * Create a copy of the address. Used to provide a 'snapshot' of
+ * Create a copy of the address. Used to provide a 'snapshot' of
* the shippingAddress for a give order.
*/
public Address createCopy() {
@@ -36,7 +41,7 @@ public class Address extends BaseModel {
copy.setCountry(country);
return copy;
}
-
+
public String toString() {
return id + " " + line1 + " " + line2 + " " + city + " " + country;
}
diff --git a/ebean-querybean/src/test/java/org/example/domain/otherpackage/GenericType.java b/ebean-querybean/src/test/java/org/example/domain/otherpackage/GenericType.java
new file mode 100644
index 000000000..f2b97cd86
--- /dev/null
+++ b/ebean-querybean/src/test/java/org/example/domain/otherpackage/GenericType.java
@@ -0,0 +1,17 @@
+package org.example.domain.otherpackage;
+
+public class GenericType {
+ private T data;
+
+ public GenericType(final T data) {
+ this.data = data;
+ }
+
+ public T getData() {
+ return data;
+ }
+
+ public void setData(final T data) {
+ this.data = data;
+ }
+}
diff --git a/ebean-querybean/src/test/java/org/example/domain/otherpackage/GenericTypeArgument.java b/ebean-querybean/src/test/java/org/example/domain/otherpackage/GenericTypeArgument.java
new file mode 100644
index 000000000..79ad89b6d
--- /dev/null
+++ b/ebean-querybean/src/test/java/org/example/domain/otherpackage/GenericTypeArgument.java
@@ -0,0 +1,6 @@
+package org.example.domain.otherpackage;
+
+public enum GenericTypeArgument {
+ FOO,
+ BAR;
+}
diff --git a/ebean-querybean/src/test/java/org/example/domain/otherpackage/GenericTypeAttributeConverter.java b/ebean-querybean/src/test/java/org/example/domain/otherpackage/GenericTypeAttributeConverter.java
new file mode 100644
index 000000000..c5e574f62
--- /dev/null
+++ b/ebean-querybean/src/test/java/org/example/domain/otherpackage/GenericTypeAttributeConverter.java
@@ -0,0 +1,17 @@
+package org.example.domain.otherpackage;
+
+import javax.persistence.AttributeConverter;
+import javax.persistence.Converter;
+
+@Converter
+public class GenericTypeAttributeConverter implements AttributeConverter, String> {
+ @Override
+ public String convertToDatabaseColumn(final GenericType attribute) {
+ return attribute.getData().name();
+ }
+
+ @Override
+ public GenericType convertToEntityAttribute(final String dbData) {
+ return new GenericType<>(GenericTypeArgument.valueOf(dbData));
+ }
+}
diff --git a/kotlin-querybean-generator/pom.xml b/kotlin-querybean-generator/pom.xml
index 2a04f2144..a2eceb8a5 100644
--- a/kotlin-querybean-generator/pom.xml
+++ b/kotlin-querybean-generator/pom.xml
@@ -1,5 +1,6 @@
-
+
4.0.0
ebean-parent
@@ -9,6 +10,10 @@
kotlin-querybean-generator
+
+ 1.4.10
+
+
@@ -17,16 +22,100 @@
3.1
test
+
+ io.ebean
+ ebean-querybean
+ ${project.version}
+
+
+ io.ebean
+ ebean-core
+ ${project.version}
+ test
+
+
+ org.jetbrains.kotlin
+ kotlin-stdlib-jdk8
+ ${kotlin.version}
+ test
+
+
+ org.jetbrains.kotlin
+ kotlin-test
+ ${kotlin.version}
+ test
+
+
+ io.ebean
+ ebean-ddlgen
+ ${project.version}
+ test
+
+
+ javax.validation
+ validation-api
+ 1.1.0.Final
+ test
+
+ src/test/kotlin
+
+ org.jetbrains.kotlin
+ kotlin-maven-plugin
+ ${kotlin.version}
+
+
+ test-compile
+ test-compile
+
+ test-compile
+
+
+
+ test-kapt
+
+ test-kapt
+
+
+
+ src/test/kotlin
+
+
+
+ io.ebean
+ kotlin-querybean-generator
+ ${project.version}
+
+
+
+
+
+
+ 1.8
+
+
org.apache.maven.plugins
maven-compiler-plugin
3.2
+
+
+ default-testCompile
+ none
+
+
+ java-test-compile
+ test-compile
+
+ testCompile
+
+
+
1.8
1.8
@@ -34,6 +123,25 @@
-proc:none
+
+
+ io.ebean
+ ebean-maven-plugin
+ 12.5.0
+
+
+ test
+ process-test-classes
+
+ debug=1
+
+
+ testEnhance
+
+
+
+
+
diff --git a/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/ProcessingContext.java b/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/ProcessingContext.java
index 88242259b..f16bd5553 100644
--- a/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/ProcessingContext.java
+++ b/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/ProcessingContext.java
@@ -333,9 +333,9 @@ class ProcessingContext implements Constants {
return result;
} else {
if (typeInstanceOf(typeMirror, "java.lang.Comparable")) {
- return new PropertyTypeScalarComparable(typeDef(typeMirror));
+ return new PropertyTypeScalarComparable(typeMirror.toString());
} else {
- return new PropertyTypeScalar(typeDef(typeMirror));
+ return new PropertyTypeScalar(typeMirror.toString());
}
}
}
diff --git a/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/PropertyTypeScalar.java b/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/PropertyTypeScalar.java
index 379ca1d7d..d92e1bbe0 100644
--- a/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/PropertyTypeScalar.java
+++ b/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/PropertyTypeScalar.java
@@ -1,17 +1,18 @@
package io.ebean.querybean.generator;
+import java.util.Map.Entry;
import java.util.Set;
/**
- * Property type for associated beans (OneToMany, ManyToOne etc).
+ * Property type for fields handled by ScalarTypes
*/
class PropertyTypeScalar extends PropertyType {
/**
* The package name for this associated query bean.
*/
- private final String assocPackage;
- private final String attributeSimpleName;
+ private final Set assocImports;
+ private final String attributeCompleteSignature;
/**
* Construct given the associated bean type name and package.
@@ -19,20 +20,26 @@ class PropertyTypeScalar extends PropertyType {
* @param attributeClass the type in the database bean that will be serialized via ScalarType
*/
PropertyTypeScalar(String attributeClass) {
- super("PScalar");
- int split = attributeClass.lastIndexOf('.');
- this.assocPackage = attributeClass.substring(0, split);
- this.attributeSimpleName = attributeClass.substring(split + 1);
+ this("PScalar", attributeClass);
+ }
+
+ protected PropertyTypeScalar(String propertyType, String attributeClass) {
+ super(propertyType);
+
+ final Entry> signature = Split.genericsSplit(attributeClass);
+
+ this.attributeCompleteSignature = signature.getKey();
+ this.assocImports = signature.getValue();
}
@Override
String getTypeDefn(String shortName, boolean assoc) {
if (assoc) {
// PScalarType
- return "PScalar";
+ return propertyType + "";
} else {
// PScalarType
- return "PScalar";
+ return propertyType + "";
}
}
@@ -42,7 +49,7 @@ class PropertyTypeScalar extends PropertyType {
@Override
void addImports(Set allImports) {
super.addImports(allImports);
- allImports.add(assocPackage + "." + attributeSimpleName);
+ allImports.addAll(assocImports);
}
}
diff --git a/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/PropertyTypeScalarComparable.java b/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/PropertyTypeScalarComparable.java
index 031b150a4..8acbcc919 100644
--- a/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/PropertyTypeScalarComparable.java
+++ b/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/PropertyTypeScalarComparable.java
@@ -1,17 +1,9 @@
package io.ebean.querybean.generator;
-import java.util.Set;
-
/**
- * Property type for associated beans (OneToMany, ManyToOne etc).
+ * Property type for fields handled by ScalarTypes
*/
-class PropertyTypeScalarComparable extends PropertyType {
-
- /**
- * The package name for this associated query bean.
- */
- private final String assocPackage;
- private final String attributeSimpleName;
+class PropertyTypeScalarComparable extends PropertyTypeScalar {
/**
* Construct given the associated bean type name and package.
@@ -19,30 +11,6 @@ class PropertyTypeScalarComparable extends PropertyType {
* @param attributeClass the type in the database bean that will be serialized via ScalarType
*/
PropertyTypeScalarComparable(String attributeClass) {
- super("PScalarComparable");
- int split = attributeClass.lastIndexOf('.');
- this.assocPackage = attributeClass.substring(0, split);
- this.attributeSimpleName = attributeClass.substring(split + 1);
+ super("PScalarComparable", attributeClass);
}
-
- @Override
- String getTypeDefn(String shortName, boolean assoc) {
- if (assoc) {
- // PScalarType
- return "PScalarComparable";
- } else {
- // PScalarType
- return "PScalarComparable";
- }
- }
-
- /**
- * All required imports to the allImports set.
- */
- @Override
- void addImports(Set allImports) {
- super.addImports(allImports);
- allImports.add(assocPackage + "." + attributeSimpleName);
- }
-
}
diff --git a/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/Split.java b/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/Split.java
index 61f6f2b55..0e6d10440 100644
--- a/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/Split.java
+++ b/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/Split.java
@@ -1,5 +1,11 @@
package io.ebean.querybean.generator;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.HashSet;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.StringTokenizer;
+
/**
* Helper for splitting package and class name.
*/
@@ -41,4 +47,20 @@ class Split {
return fullType;
}
+ static Entry> genericsSplit(String signature) {
+ StringBuilder simpleSignature = new StringBuilder();
+ final StringTokenizer tokenizer = new StringTokenizer(signature, ",<> ", true);
+
+ Set assocImports = new HashSet<>();
+ while (tokenizer.hasMoreTokens()) {
+ final String token = tokenizer.nextToken();
+ if (token.length() == 1 && ",<> ".indexOf(token.charAt(0)) >= 0) {
+ simpleSignature.append(token);
+ } else {
+ simpleSignature.append(Split.shortName(token));
+ assocImports.add(token);
+ }
+ }
+ return new SimpleEntry<>(simpleSignature.toString(), assocImports);
+ }
}
diff --git a/kotlin-querybean-generator/src/test/java/io/ebean/querybean/generator/SplitTest.java b/kotlin-querybean-generator/src/test/java/io/ebean/querybean/generator/SplitTest.java
deleted file mode 100644
index c382fd7b6..000000000
--- a/kotlin-querybean-generator/src/test/java/io/ebean/querybean/generator/SplitTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package io.ebean.querybean.generator;
-
-import org.testng.annotations.Test;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNull;
-
-public class SplitTest {
-
- @Test
- public void trimType() {
- assertEquals(Split.trimType("com.foo.domain.Customer"), "com.foo.domain.Customer");
- assertEquals(Split.trimType("? extends com.foo.domain.Customer"), "com.foo.domain.Customer");
- }
-
- @Test
- public void shortName() {
- assertEquals(Split.shortName("com.foo.domain.Customer"), "Customer");
- assertEquals(Split.shortName("Customer"), "Customer");
- }
-
- @Test
- public void split_normal() {
-
- String[] split = Split.split("com.foo.domain.Customer");
-
- assertEquals(split[0], "com.foo.domain");
- assertEquals(split[1], "Customer");
- }
-
- @Test
- public void split_noPackage() {
-
- String[] split = Split.split("Customer");
-
- assertNull(split[0]);
- assertEquals(split[1], "Customer");
- }
-
-}
\ No newline at end of file
diff --git a/kotlin-querybean-generator/src/test/kotlin/io/ebean/querybean/generator/SplitTest.kt b/kotlin-querybean-generator/src/test/kotlin/io/ebean/querybean/generator/SplitTest.kt
new file mode 100644
index 000000000..8c781f7d7
--- /dev/null
+++ b/kotlin-querybean-generator/src/test/kotlin/io/ebean/querybean/generator/SplitTest.kt
@@ -0,0 +1,47 @@
+package io.ebean.querybean.generator
+
+import org.testng.Assert.assertEquals
+import org.testng.Assert.assertNull
+import org.testng.annotations.Test
+import java.lang.Exception
+import java.util.Arrays
+import java.util.HashSet
+
+class SplitTest {
+ @Test
+ fun trimType() {
+ assertEquals(Split.trimType("com.foo.domain.Customer"), "com.foo.domain.Customer")
+ assertEquals(Split.trimType("? extends com.foo.domain.Customer"), "com.foo.domain.Customer")
+ }
+
+ @Test
+ fun shortName() {
+ assertEquals(Split.shortName("com.foo.domain.Customer"), "Customer")
+ assertEquals(Split.shortName("Customer"), "Customer")
+ }
+
+ @Test
+ fun split_normal() {
+ val split = Split.split("com.foo.domain.Customer")
+ assertEquals(split[0], "com.foo.domain")
+ assertEquals(split[1], "Customer")
+ }
+
+ @Test
+ fun split_noPackage() {
+ val split = Split.split("Customer")
+ assertNull(split[0])
+ assertEquals(split[1], "Customer")
+ }
+
+ @Test
+ @Throws(Exception::class)
+ fun split_generics() {
+ assertEquals("Foo>", Split.genericsSplit("com.Foo>").key)
+ assertEquals(
+ HashSet(Arrays.asList("com.Foo", "com.Bar", "org.XFoo", "org.XBar")),
+ Split.genericsSplit("com.Foo>").value
+ )
+ assertEquals("Foo", Split.genericsSplit("com.bar.Foo").key)
+ }
+}
diff --git a/kotlin-querybean-generator/src/test/kotlin/org/example/domain/Address.kt b/kotlin-querybean-generator/src/test/kotlin/org/example/domain/Address.kt
new file mode 100644
index 000000000..1669b6e0e
--- /dev/null
+++ b/kotlin-querybean-generator/src/test/kotlin/org/example/domain/Address.kt
@@ -0,0 +1,24 @@
+package org.example.domain;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import javax.validation.constraints.Size;
+
+import org.example.otherpackage.GenericType;
+import org.example.otherpackage.GenericTypeArgument;
+
+/**
+ * Address entity bean.
+ */
+@Entity
+@Table(name = "o_address")
+class Address(
+ @Size(max = 100)
+ var line1: String,
+ @Size(max = 100)
+ var line2: String,
+ @Size(max = 100)
+ var city: String,
+ // Dummy metadata field just to test generation
+ val metadata: GenericType
+) : BaseModel()
diff --git a/kotlin-querybean-generator/src/test/kotlin/org/example/domain/BaseModel.kt b/kotlin-querybean-generator/src/test/kotlin/org/example/domain/BaseModel.kt
new file mode 100644
index 000000000..44789893f
--- /dev/null
+++ b/kotlin-querybean-generator/src/test/kotlin/org/example/domain/BaseModel.kt
@@ -0,0 +1,26 @@
+package org.example.domain;
+
+import java.time.Instant;
+
+import javax.persistence.Id;
+import javax.persistence.MappedSuperclass;
+import javax.persistence.Version;
+
+import io.ebean.Model;
+import io.ebean.annotation.WhenCreated;
+import io.ebean.annotation.WhenModified;
+
+@MappedSuperclass
+abstract class BaseModel : Model() {
+ @Id
+ val id: Long? = null
+
+ @Version
+ val version: Int = 0
+
+ @WhenCreated
+ val whenCreated: Instant? = null
+
+ @WhenModified
+ val whenModified: Instant? = null
+}
diff --git a/kotlin-querybean-generator/src/test/kotlin/org/example/otherpackage/Email.kt b/kotlin-querybean-generator/src/test/kotlin/org/example/otherpackage/Email.kt
new file mode 100644
index 000000000..4845963d4
--- /dev/null
+++ b/kotlin-querybean-generator/src/test/kotlin/org/example/otherpackage/Email.kt
@@ -0,0 +1,3 @@
+package org.example.otherpackage
+
+interface Email : Comparable
diff --git a/kotlin-querybean-generator/src/test/kotlin/org/example/otherpackage/GenericType.kt b/kotlin-querybean-generator/src/test/kotlin/org/example/otherpackage/GenericType.kt
new file mode 100644
index 000000000..6d03aeeab
--- /dev/null
+++ b/kotlin-querybean-generator/src/test/kotlin/org/example/otherpackage/GenericType.kt
@@ -0,0 +1,5 @@
+package org.example.otherpackage
+
+class GenericType(
+ val data: T
+)
diff --git a/kotlin-querybean-generator/src/test/kotlin/org/example/otherpackage/GenericTypeArgument.kt b/kotlin-querybean-generator/src/test/kotlin/org/example/otherpackage/GenericTypeArgument.kt
new file mode 100644
index 000000000..13e6dbce4
--- /dev/null
+++ b/kotlin-querybean-generator/src/test/kotlin/org/example/otherpackage/GenericTypeArgument.kt
@@ -0,0 +1,6 @@
+package org.example.otherpackage
+
+enum class GenericTypeArgument {
+ FOO,
+ BAR,
+}
diff --git a/kotlin-querybean-generator/src/test/kotlin/org/example/otherpackage/GenericTypeAttributeConverter.kt b/kotlin-querybean-generator/src/test/kotlin/org/example/otherpackage/GenericTypeAttributeConverter.kt
new file mode 100644
index 000000000..a24154449
--- /dev/null
+++ b/kotlin-querybean-generator/src/test/kotlin/org/example/otherpackage/GenericTypeAttributeConverter.kt
@@ -0,0 +1,15 @@
+package org.example.otherpackage
+
+import javax.persistence.AttributeConverter
+import javax.persistence.Converter
+
+@Converter
+class GenericTypeAttributeConverter : AttributeConverter, String> {
+ override fun convertToDatabaseColumn(attribute: GenericType): String {
+ return attribute.data.name
+ }
+
+ override fun convertToEntityAttribute(dbData: String): GenericType {
+ return GenericType(GenericTypeArgument.valueOf(dbData))
+ }
+}
diff --git a/kotlin-querybean-generator/src/test/kotlin/org/example/otherpackage/PhoneAttributeConverter.kt b/kotlin-querybean-generator/src/test/kotlin/org/example/otherpackage/PhoneAttributeConverter.kt
new file mode 100644
index 000000000..55981a0a8
--- /dev/null
+++ b/kotlin-querybean-generator/src/test/kotlin/org/example/otherpackage/PhoneAttributeConverter.kt
@@ -0,0 +1,15 @@
+package org.example.otherpackage
+
+import javax.persistence.AttributeConverter
+import javax.persistence.Converter
+
+@Converter
+class PhoneAttributeConverter : AttributeConverter {
+ override fun convertToDatabaseColumn(attribute: PhoneNumber): String {
+ return attribute.msisdn
+ }
+
+ override fun convertToEntityAttribute(dbData: String): PhoneNumber {
+ return PhoneNumber(dbData)
+ }
+}
diff --git a/kotlin-querybean-generator/src/test/kotlin/org/example/otherpackage/PhoneNumber.kt b/kotlin-querybean-generator/src/test/kotlin/org/example/otherpackage/PhoneNumber.kt
new file mode 100644
index 000000000..9c3dfef7c
--- /dev/null
+++ b/kotlin-querybean-generator/src/test/kotlin/org/example/otherpackage/PhoneNumber.kt
@@ -0,0 +1,5 @@
+package org.example.otherpackage
+
+class PhoneNumber(
+ val msisdn: String
+)
diff --git a/kotlin-querybean-generator/src/test/kotlin/org/example/otherpackage/ValidEmail.kt b/kotlin-querybean-generator/src/test/kotlin/org/example/otherpackage/ValidEmail.kt
new file mode 100644
index 000000000..b0bdd55e1
--- /dev/null
+++ b/kotlin-querybean-generator/src/test/kotlin/org/example/otherpackage/ValidEmail.kt
@@ -0,0 +1,9 @@
+package org.example.otherpackage
+
+class ValidEmail(
+ val emailAddress: String
+) : Email {
+ override fun compareTo(other: ValidEmail): Int {
+ return emailAddress.compareTo(other.emailAddress)
+ }
+}
diff --git a/kotlin-querybean-generator/src/test/kotlin/org/example/otherpackage/ValidEmailAttributeConverter.kt b/kotlin-querybean-generator/src/test/kotlin/org/example/otherpackage/ValidEmailAttributeConverter.kt
new file mode 100644
index 000000000..690978ce3
--- /dev/null
+++ b/kotlin-querybean-generator/src/test/kotlin/org/example/otherpackage/ValidEmailAttributeConverter.kt
@@ -0,0 +1,15 @@
+package org.example.otherpackage
+
+import javax.persistence.AttributeConverter
+import javax.persistence.Converter
+
+@Converter
+class ValidEmailAttributeConverter : AttributeConverter {
+ override fun convertToDatabaseColumn(attribute: ValidEmail): String {
+ return attribute.emailAddress
+ }
+
+ override fun convertToEntityAttribute(dbData: String): ValidEmail {
+ return ValidEmail(dbData)
+ }
+}
diff --git a/querybean-generator/src/main/java/io/ebean/querybean/generator/ProcessingContext.java b/querybean-generator/src/main/java/io/ebean/querybean/generator/ProcessingContext.java
index 54cb79301..1000301f6 100644
--- a/querybean-generator/src/main/java/io/ebean/querybean/generator/ProcessingContext.java
+++ b/querybean-generator/src/main/java/io/ebean/querybean/generator/ProcessingContext.java
@@ -298,9 +298,9 @@ class ProcessingContext implements Constants {
return result;
} else {
if (typeInstanceOf(typeMirror, "java.lang.Comparable")) {
- return new PropertyTypeScalarComparable(typeDef(typeMirror));
+ return new PropertyTypeScalarComparable(typeMirror.toString());
} else {
- return new PropertyTypeScalar(typeDef(typeMirror));
+ return new PropertyTypeScalar(typeMirror.toString());
}
}
}
diff --git a/querybean-generator/src/main/java/io/ebean/querybean/generator/PropertyTypeScalar.java b/querybean-generator/src/main/java/io/ebean/querybean/generator/PropertyTypeScalar.java
index 379ca1d7d..dac7ea671 100644
--- a/querybean-generator/src/main/java/io/ebean/querybean/generator/PropertyTypeScalar.java
+++ b/querybean-generator/src/main/java/io/ebean/querybean/generator/PropertyTypeScalar.java
@@ -1,17 +1,17 @@
package io.ebean.querybean.generator;
+import java.util.Map.Entry;
import java.util.Set;
/**
- * Property type for associated beans (OneToMany, ManyToOne etc).
+ * Property type for fields handled by ScalarTypes
*/
class PropertyTypeScalar extends PropertyType {
-
/**
* The package name for this associated query bean.
*/
- private final String assocPackage;
- private final String attributeSimpleName;
+ private final Set assocImports;
+ private final String attributeCompleteSignature;
/**
* Construct given the associated bean type name and package.
@@ -19,20 +19,26 @@ class PropertyTypeScalar extends PropertyType {
* @param attributeClass the type in the database bean that will be serialized via ScalarType
*/
PropertyTypeScalar(String attributeClass) {
- super("PScalar");
- int split = attributeClass.lastIndexOf('.');
- this.assocPackage = attributeClass.substring(0, split);
- this.attributeSimpleName = attributeClass.substring(split + 1);
+ this("PScalar", attributeClass);
+ }
+
+ protected PropertyTypeScalar(String propertyType, String attributeClass) {
+ super(propertyType);
+
+ final Entry> signature = Split.genericsSplit(attributeClass);
+
+ this.attributeCompleteSignature = signature.getKey();
+ this.assocImports = signature.getValue();
}
@Override
String getTypeDefn(String shortName, boolean assoc) {
if (assoc) {
// PScalarType
- return "PScalar";
+ return propertyType + "";
} else {
// PScalarType
- return "PScalar";
+ return propertyType + "";
}
}
@@ -42,7 +48,6 @@ class PropertyTypeScalar extends PropertyType {
@Override
void addImports(Set allImports) {
super.addImports(allImports);
- allImports.add(assocPackage + "." + attributeSimpleName);
+ allImports.addAll(assocImports);
}
-
}
diff --git a/querybean-generator/src/main/java/io/ebean/querybean/generator/PropertyTypeScalarComparable.java b/querybean-generator/src/main/java/io/ebean/querybean/generator/PropertyTypeScalarComparable.java
index 031b150a4..b91193395 100644
--- a/querybean-generator/src/main/java/io/ebean/querybean/generator/PropertyTypeScalarComparable.java
+++ b/querybean-generator/src/main/java/io/ebean/querybean/generator/PropertyTypeScalarComparable.java
@@ -1,17 +1,9 @@
package io.ebean.querybean.generator;
-import java.util.Set;
-
/**
* Property type for associated beans (OneToMany, ManyToOne etc).
*/
-class PropertyTypeScalarComparable extends PropertyType {
-
- /**
- * The package name for this associated query bean.
- */
- private final String assocPackage;
- private final String attributeSimpleName;
+class PropertyTypeScalarComparable extends PropertyTypeScalar {
/**
* Construct given the associated bean type name and package.
@@ -19,30 +11,6 @@ class PropertyTypeScalarComparable extends PropertyType {
* @param attributeClass the type in the database bean that will be serialized via ScalarType
*/
PropertyTypeScalarComparable(String attributeClass) {
- super("PScalarComparable");
- int split = attributeClass.lastIndexOf('.');
- this.assocPackage = attributeClass.substring(0, split);
- this.attributeSimpleName = attributeClass.substring(split + 1);
+ super("PScalarComparable", attributeClass);
}
-
- @Override
- String getTypeDefn(String shortName, boolean assoc) {
- if (assoc) {
- // PScalarType
- return "PScalarComparable";
- } else {
- // PScalarType
- return "PScalarComparable";
- }
- }
-
- /**
- * All required imports to the allImports set.
- */
- @Override
- void addImports(Set allImports) {
- super.addImports(allImports);
- allImports.add(assocPackage + "." + attributeSimpleName);
- }
-
}
diff --git a/querybean-generator/src/main/java/io/ebean/querybean/generator/Split.java b/querybean-generator/src/main/java/io/ebean/querybean/generator/Split.java
index c682344e7..70e8ad542 100644
--- a/querybean-generator/src/main/java/io/ebean/querybean/generator/Split.java
+++ b/querybean-generator/src/main/java/io/ebean/querybean/generator/Split.java
@@ -1,5 +1,11 @@
package io.ebean.querybean.generator;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.HashSet;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.StringTokenizer;
+
/**
* Helper for splitting package and class name.
*/
@@ -31,4 +37,21 @@ class Split {
return className.substring(startPos + 1);
}
+ static Entry> genericsSplit(String signature) {
+ StringBuilder simpleSignature = new StringBuilder();
+ final StringTokenizer tokenizer = new StringTokenizer(signature, ",<> ", true);
+
+ Set assocImports = new HashSet<>();
+ while (tokenizer.hasMoreTokens()) {
+ final String token = tokenizer.nextToken();
+ if (token.length() == 1 && ",<> ".indexOf(token.charAt(0)) >= 0) {
+ simpleSignature.append(token);
+ } else {
+ simpleSignature.append(Split.shortName(token));
+ assocImports.add(token);
+ }
+ }
+ return new SimpleEntry<>(simpleSignature.toString(), assocImports);
+ }
+
}
diff --git a/querybean-generator/src/test/java/io/ebean/querybean/generator/SplitTest.java b/querybean-generator/src/test/java/io/ebean/querybean/generator/SplitTest.java
index 24be4a023..3ea80d6e3 100644
--- a/querybean-generator/src/test/java/io/ebean/querybean/generator/SplitTest.java
+++ b/querybean-generator/src/test/java/io/ebean/querybean/generator/SplitTest.java
@@ -1,10 +1,13 @@
package io.ebean.querybean.generator;
-import org.testng.annotations.Test;
-
+import static java.util.Arrays.asList;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
+import java.util.HashSet;
+
+import org.testng.annotations.Test;
+
public class SplitTest {
@Test
@@ -32,4 +35,9 @@ public class SplitTest {
assertEquals(split[1], "Customer");
}
-}
\ No newline at end of file
+ @Test
+ public void split_generics() throws Exception {
+ assertEquals("Foo>", Split.genericsSplit("com.Foo>").getKey());
+ assertEquals(new HashSet<>(asList("com.Foo", "com.Bar", "org.XFoo", "org.XBar")), Split.genericsSplit("com.Foo>").getValue());
+ }
+}