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()); + } +}