Merge pull request #3280 from ebean-orm/feature/typequery-imports-tqrootbean

QueryBean generation - use full class names for TQRootBean, TQAssocBean
This commit is contained in:
Rob Bygrave
2023-11-29 01:21:00 +13:00
committed by GitHub
13 changed files with 113 additions and 69 deletions
@@ -0,0 +1,12 @@
package org.example.domain;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
@Entity
public class PFile {
@Id
long id;
String name;
}
@@ -0,0 +1,12 @@
package org.example.domain;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
@Entity
public class PLong {
@Id
long id;
String name;
}
@@ -0,0 +1,12 @@
package org.example.domain;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
@Entity
public class Pinstant {
@Id
long id;
String name;
}
@@ -19,11 +19,6 @@ interface Constants {
String DBJSONB = "io.ebean.annotation.DbJsonB";
String DBNAME = "io.ebean.annotation.DbName";
String TQROOTBEAN = "io.ebean.typequery.TQRootBean";
String TQASSOCBEAN = "io.ebean.typequery.TQAssocBean";
String TQASSOC = "io.ebean.typequery.TQAssoc";
String DB = "io.ebean.DB";
String MODULEINFO = "io.ebean.config.ModuleInfo";
String METAINF_MANIFEST = "META-INF/ebean-generated-info.mf";
String METAINF_SERVICES_MODULELOADER = "META-INF/services/io.ebean.config.EntityClassRegister";
@@ -547,4 +547,8 @@ class ProcessingContext implements Constants {
Element asElement(TypeMirror mirror) {
return typeUtils.asElement(mirror);
}
boolean isNameClash(String shortName) {
return propertyTypeMap.isNameClash(shortName);
}
}
@@ -26,19 +26,19 @@ class PropertyMeta {
/**
* Return the type definition given the type short name and flag indicating if it is an associated bean type.
*/
private String getTypeDefn(String shortName, boolean assoc) {
return type.getTypeDefn(shortName, assoc);
private String getTypeDefn(String shortName, boolean assoc, boolean fullyQualify) {
return type.getTypeDefn(shortName, assoc, fullyQualify);
}
void writeFieldDefn(Append writer, String shortName, boolean assoc) {
void writeFieldDefn(Append writer, String shortName, boolean assoc, boolean fullyQualify) {
writer.append(" public ");
writer.append(getTypeDefn(shortName, assoc));
writer.append(getTypeDefn(shortName, assoc, fullyQualify));
writer.append(" ").append(name).append(";");
}
void writeFieldAliasDefn(Append writer, String shortName) {
void writeFieldAliasDefn(Append writer, String shortName, boolean fullyQualify) {
writer.append(" public static ");
writer.append(getTypeDefn(shortName, false));
writer.append(getTypeDefn(shortName, false, fullyQualify));
writer.append(" ").append(name).append(" = _alias.").append(name).append(";");
}
}
@@ -11,12 +11,23 @@ class PropertyType {
* The property type className or primitive short name.
*/
final String propertyType;
final String pkg;
/**
* Construct with a className of primitive name for the type.
*/
PropertyType(String propertyType) {
this.propertyType = propertyType;
this.pkg = "io.ebean.typequery.";
}
PropertyType(String propertyType, String pkg) {
this.propertyType = propertyType;
this.pkg = pkg;
}
String propertyType() {
return propertyType;
}
@Override
@@ -27,24 +38,28 @@ class PropertyType {
/**
* Return the type definition for this property.
*
* @param shortName The short name of the property type
* @param assoc flag set to true if the property is on an association bean
* @param shortName The short name of the property type
* @param assoc flag set to true if the property is on an association bean
* @param fullyQualify flag set to fully qualify the type
*/
String getTypeDefn(String shortName, boolean assoc) {
String getTypeDefn(String shortName, boolean assoc, boolean fullyQualify) {
String q = fullyQualify ? pkg : "";
if (assoc) {
// PLong<R>
return propertyType + "<R>";
// PLong<R>
return q + propertyType + "<R>";
} else {
// PLong<QCustomer>
return propertyType + "<Q" + shortName + ">";
// PLong<QCustomer>
return q + propertyType + "<Q" + shortName + ">";
}
}
/**
* Add any required imports for this property to the allImports set.
*/
void addImports(Set<String> allImports) {
allImports.add("io.ebean.typequery." + propertyType);
void addImports(Set<String> allImports, boolean fullyQualify) {
if (!fullyQualify) {
allImports.add(pkg + propertyType);
}
}
}
@@ -19,18 +19,18 @@ class PropertyTypeArray extends PropertyType {
}
@Override
String getTypeDefn(String shortName, boolean assoc) {
String getTypeDefn(String shortName, boolean assoc, boolean fullyQualify) {
String q = fullyQualify ? pkg : "";
if (assoc) {
return "PArray<R," + elementShortName + ">";
return q + "PArray<R," + elementShortName + ">";
} else {
return "PArray<Q" + shortName + "," + elementShortName + ">";
return q + "PArray<Q" + shortName + "," + elementShortName + ">";
}
}
@Override
void addImports(Set<String> allImports) {
super.addImports(allImports);
void addImports(Set<String> allImports, boolean fullyQualify) {
super.addImports(allImports, fullyQualify);
allImports.add(elementClass);
}
@@ -16,7 +16,7 @@ class PropertyTypeAssoc extends PropertyType {
* @param importName the import for the Assoc bean.
*/
PropertyTypeAssoc(String qAssocTypeName, String importName) {
super(qAssocTypeName);
super(qAssocTypeName, "");
this.importName = importName;
}
@@ -24,7 +24,7 @@ class PropertyTypeAssoc extends PropertyType {
* All required imports to the allImports set.
*/
@Override
void addImports(Set<String> allImports) {
void addImports(Set<String> allImports, boolean fullyQualify) {
allImports.add(importName);
}
@@ -19,18 +19,18 @@ class PropertyTypeEnum extends PropertyType {
}
@Override
String getTypeDefn(String shortName, boolean assoc) {
String getTypeDefn(String shortName, boolean assoc, boolean fullyQualify) {
String q = fullyQualify ? pkg : "";
if (assoc) {
return "PEnum<R," + enumShortName + ">";
return q + "PEnum<R," + enumShortName + ">";
} else {
return "PEnum<Q" + shortName + "," + enumShortName + ">";
return q + "PEnum<Q" + shortName + "," + enumShortName + ">";
}
}
@Override
void addImports(Set<String> allImports) {
super.addImports(allImports);
void addImports(Set<String> allImports, boolean fullyQualify) {
super.addImports(allImports, fullyQualify);
allImports.add(enumClass);
}
@@ -7,13 +7,8 @@ import java.net.InetAddress;
import java.net.URI;
import java.net.URL;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Currency;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import java.util.UUID;
import java.util.*;
import java.util.stream.Collectors;
/**
* Holds the Property types and how they match to class types.
@@ -25,7 +20,9 @@ class PropertyTypeMap {
*/
private final PropertyType dbJsonType = new PropertyType("PJson");
private final Map<String,PropertyType> map = new HashMap<>();
private final Map<String, PropertyType> map = new HashMap<>();
private final Set<String> propertyNames;
PropertyTypeMap() {
map.put("boolean", new PropertyType("PBoolean"));
@@ -64,11 +61,17 @@ class PropertyTypeMap {
map.put("io.ebean.types.Cidr", new PropertyType("PCidr"));
addJava8Types();
addJodaTypes();
propertyNames = map.values().stream().map(PropertyType::propertyType).collect(Collectors.toSet());
}
boolean isNameClash(String name) {
return propertyNames.contains(name);
}
private void addType(Class<?> cls) {
String simpleName = cls.getSimpleName();
map.put(cls.getName(), new PropertyType("P"+simpleName));
map.put(cls.getName(), new PropertyType("P" + simpleName));
}
private void addJava8Types() {
@@ -24,21 +24,20 @@ class PropertyTypeScalar extends PropertyType {
protected PropertyTypeScalar(String propertyType, String attributeClass) {
super(propertyType);
final Entry<String, Set<String>> signature = Split.genericsSplit(attributeClass);
this.attributeCompleteSignature = signature.getKey();
this.assocImports = signature.getValue();
}
@Override
String getTypeDefn(String shortName, boolean assoc) {
String getTypeDefn(String shortName, boolean assoc, boolean fullyQualify) {
String q = fullyQualify ? pkg : "";
if (assoc) {
// PScalarType<R, PhoneNumber>
return propertyType + "<R, " + attributeCompleteSignature + ">";
return q + propertyType + "<R, " + attributeCompleteSignature + ">";
} else {
// PScalarType<QCustomer, PhoneNumber>
return propertyType + "<Q" + shortName + ", " + attributeCompleteSignature + ">";
return q + propertyType + "<Q" + shortName + ", " + attributeCompleteSignature + ">";
}
}
@@ -46,8 +45,8 @@ class PropertyTypeScalar extends PropertyType {
* All required imports to the allImports set.
*/
@Override
void addImports(Set<String> allImports) {
super.addImports(allImports);
void addImports(Set<String> allImports, boolean fullyQualify) {
super.addImports(allImports, fullyQualify);
allImports.addAll(assocImports);
}
}
@@ -33,6 +33,7 @@ class SimpleQueryBeanWriter {
private String shortName;
private final String shortInnerName;
private final String origShortName;
private final boolean fullyQualify;
private Append writer;
SimpleQueryBeanWriter(TypeElement element, ProcessingContext processingContext) {
@@ -49,6 +50,7 @@ class SimpleQueryBeanWriter {
this.embeddable = processingContext.isEmbeddable(element);
this.dbName = findDbName();
this.implementsInterface = initInterface(element);
this.fullyQualify = processingContext.isNameClash(shortName);
}
private TypeElement initInterface(TypeElement element) {
@@ -76,13 +78,6 @@ class SimpleQueryBeanWriter {
private void gatherPropertyDetails() {
importTypes.add(beanFullName);
if (embeddable) {
importTypes.add(Constants.TQASSOC);
} else {
importTypes.add(Constants.TQASSOCBEAN);
importTypes.add(Constants.TQROOTBEAN);
}
if (implementsInterface != null) {
implementsInterfaceFullName = implementsInterface.getQualifiedName().toString();
boolean nested = implementsInterface.getNestingKind().isNested();
@@ -92,9 +87,6 @@ class SimpleQueryBeanWriter {
importTypes.add(Constants.JAVA_COLLECTION);
importTypes.add(implementsInterfaceFullName);
}
if (dbName != null) {
importTypes.add(Constants.DB);
}
addClassProperties();
}
@@ -107,7 +99,7 @@ class SimpleQueryBeanWriter {
for (VariableElement field : processingContext.allFields(element)) {
PropertyType type = processingContext.getPropertyType(field);
if (type != null) {
type.addImports(importTypes);
type.addImports(importTypes, fullyQualify);
properties.add(new PropertyMeta(field.getSimpleName().toString(), type));
}
}
@@ -171,7 +163,7 @@ class SimpleQueryBeanWriter {
if (dbName == null) {
writer.append(" super(%s.class);", shortName).eol();
} else {
writer.append(" super(%s.class, DB.byName(\"%s\"));", shortName, dbName).eol();
writer.append(" super(%s.class, io.ebean.DB.byName(\"%s\"));", shortName, dbName).eol();
}
writer.append(" }").eol();
writer.eol();
@@ -181,7 +173,7 @@ class SimpleQueryBeanWriter {
if (dbName == null) {
writer.append(" super(%s.class, transaction);", shortName).eol();
} else {
writer.append(" super(%s.class, DB.byName(\"%s\"), transaction);", shortName, dbName).eol();
writer.append(" super(%s.class, io.ebean.DB.byName(\"%s\"), transaction);", shortName, dbName).eol();
}
writer.append(" }").eol();
@@ -216,7 +208,7 @@ class SimpleQueryBeanWriter {
*/
private void writeFields() {
for (PropertyMeta property : properties) {
property.writeFieldDefn(writer, shortName, false);
property.writeFieldDefn(writer, shortName, false, fullyQualify);
writer.eol();
}
writer.eol();
@@ -233,7 +225,7 @@ class SimpleQueryBeanWriter {
writer.append("public final class Q%s {", shortName).eol();
} else {
writer.append(Constants.AT_TYPEQUERYBEAN).eol();
writer.append("public final class Q%s extends TQRootBean<%1$s,Q%1$s> {", shortName).eol();
writer.append("public final class Q%s extends io.ebean.typequery.TQRootBean<%1$s,Q%1$s> {", shortName).eol();
}
writer.eol();
}
@@ -260,7 +252,7 @@ class SimpleQueryBeanWriter {
writer.append(" ").append(Constants.AT_GENERATED).eol();
writer.append(" public static final class Alias {").eol();
for (PropertyMeta property : properties) {
property.writeFieldAliasDefn(writer, shortName);
property.writeFieldAliasDefn(writer, shortName, fullyQualify);
writer.eol();
}
writer.append(" }").eol();
@@ -272,13 +264,13 @@ class SimpleQueryBeanWriter {
writer.append(" ").append(Constants.AT_GENERATED).eol();
writer.append(" ").append(Constants.AT_TYPEQUERYBEAN).eol();
if (embeddable) {
writer.append(" public static final class Assoc<R> extends TQAssoc<%s,R> {", shortInnerName).eol();
writer.append(" public static final class Assoc<R> extends io.ebean.typequery.TQAssoc<%s,R> {", shortInnerName).eol();
} else {
writer.append(" public static final class Assoc<R> extends TQAssocBean<%s,R,Q%s> {", shortName, shortInnerName).eol();
writer.append(" public static final class Assoc<R> extends io.ebean.typequery.TQAssocBean<%s,R,Q%s> {", shortName, shortInnerName).eol();
}
for (PropertyMeta property : properties) {
writer.append(" ");
property.writeFieldDefn(writer, shortName, true);
property.writeFieldDefn(writer, shortName, true, fullyQualify);
writer.eol();
}
writer.eol();