Skip to content
This repository was archived by the owner on Oct 22, 2020. It is now read-only.

Commit bd0064d

Browse files
committed
#24 - Auto register AttributeConverter
1 parent 691b60d commit bd0064d

6 files changed

Lines changed: 149 additions & 61 deletions

File tree

src/main/java/io/ebean/querybean/generator/Constants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ interface Constants {
1313
String INHERITANCE = "javax.persistence.Inheritance";
1414
String ENTITY = "javax.persistence.Entity";
1515
String EMBEDDABLE = "javax.persistence.Embeddable";
16+
String CONVERTER = "javax.persistence.Converter";
1617

1718
String DBARRAY = "io.ebean.annotation.DbArray";
1819
String DBJSON = "io.ebean.annotation.DbJson";
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package io.ebean.querybean.generator;
2+
3+
import java.util.List;
4+
5+
class ModuleMeta {
6+
private final List<String> entities;
7+
private final List<String> other;
8+
9+
ModuleMeta(List<String> entities, List<String> other) {
10+
this.entities = entities;
11+
this.other = other;
12+
}
13+
14+
List<String> getEntities() {
15+
return entities;
16+
}
17+
18+
List<String> getOther() {
19+
return other;
20+
}
21+
}

src/main/java/io/ebean/querybean/generator/ProcessingContext.java

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ class ProcessingContext implements Constants {
6060
*/
6161
private final Set<String> allEntityPackages = new TreeSet<>();
6262

63+
private final Set<String> otherClasses = new TreeSet<>();
64+
6365
/**
6466
* The DB name prefixed entities.
6567
*/
@@ -83,7 +85,7 @@ class ProcessingContext implements Constants {
8385
/**
8486
* For partial compile the previous list of prefixed entity classes.
8587
*/
86-
private List<String> loadedPrefixEntities;
88+
private List<String> loadedPrefixEntities = new ArrayList<>(); ;
8789

8890
/**
8991
* The package for the generated ModuleInfoLoader.
@@ -103,6 +105,18 @@ class ProcessingContext implements Constants {
103105
this.readModuleInfo = new ReadModuleInfo(this);
104106
}
105107

108+
TypeElement entityAnnotation() {
109+
return elementUtils.getTypeElement(ENTITY);
110+
}
111+
112+
TypeElement embeddableAnnotation() {
113+
return elementUtils.getTypeElement(EMBEDDABLE);
114+
}
115+
116+
TypeElement converterAnnotation() {
117+
return elementUtils.getTypeElement(CONVERTER);
118+
}
119+
106120
private String generatedAnnotation(boolean jdk8) {
107121
if (jdk8) {
108122
return isTypeAvailable(GENERATED_8) ? GENERATED_8 : null;
@@ -142,7 +156,6 @@ private String typeDef(TypeMirror typeMirror) {
142156
* Gather all the fields (properties) for the given bean element.
143157
*/
144158
List<VariableElement> allFields(Element element) {
145-
146159
List<VariableElement> list = new ArrayList<>();
147160
gatherProperties(list, element);
148161
return list;
@@ -392,7 +405,9 @@ void readModuleInfo() {
392405
TypeElement factoryType = elementUtils.getTypeElement(factory);
393406
if (factoryType != null) {
394407
// previous prefixed entities to add back for partial compile
395-
loadedPrefixEntities = readModuleInfo.read(factoryType);
408+
final ModuleMeta read = readModuleInfo.read(factoryType);
409+
loadedPrefixEntities.addAll(read.getEntities());
410+
otherClasses.addAll(read.getOther());
396411
}
397412
}
398413
}
@@ -421,25 +436,22 @@ void addEntity(String beanFullName, String dbName) {
421436
* Add back entity classes for partial compile.
422437
*/
423438
int complete() {
424-
425439
int added = 0;
426-
if (loadedPrefixEntities != null) {
427-
for (String oldPrefixEntity : loadedPrefixEntities) {
428-
// maybe split as dbName:entityClass
429-
final String[] prefixEntityClass = oldPrefixEntity.split(":");
430-
431-
String dbName = null;
432-
String entityClass;
433-
if (prefixEntityClass.length > 1) {
434-
dbName = prefixEntityClass[0];
435-
entityClass = prefixEntityClass[1];
436-
} else {
437-
entityClass = prefixEntityClass[0];
438-
}
439-
if (!loaded.contains(entityClass)) {
440-
addEntity(entityClass, dbName);
441-
added++;
442-
}
440+
for (String oldPrefixEntity : loadedPrefixEntities) {
441+
// maybe split as dbName:entityClass
442+
final String[] prefixEntityClass = oldPrefixEntity.split(":");
443+
444+
String dbName = null;
445+
String entityClass;
446+
if (prefixEntityClass.length > 1) {
447+
dbName = prefixEntityClass[0];
448+
entityClass = prefixEntityClass[1];
449+
} else {
450+
entityClass = prefixEntityClass[0];
451+
}
452+
if (!loaded.contains(entityClass)) {
453+
addEntity(entityClass, dbName);
454+
added++;
443455
}
444456
}
445457
return added;
@@ -471,6 +483,18 @@ FileObject createMetaInfWriter(String target) throws IOException {
471483
return filer.createResource(StandardLocation.CLASS_OUTPUT, "", target);
472484
}
473485

486+
boolean hasOtherClasses() {
487+
return !otherClasses.isEmpty();
488+
}
489+
490+
Set<String> getOtherClasses() {
491+
return otherClasses;
492+
}
493+
494+
void addOther(Element element) {
495+
otherClasses.add(element.toString());
496+
}
497+
474498
Set<String> getPrefixEntities() {
475499
return prefixEntities;
476500
}

src/main/java/io/ebean/querybean/generator/Processor.java

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ public synchronized void init(ProcessingEnvironment processingEnv) {
3939

4040
@Override
4141
public Set<String> getSupportedAnnotationTypes() {
42-
4342
Set<String> annotations = new LinkedHashSet<>();
4443
annotations.add(ENTITY);
4544
annotations.add(EMBEDDABLE);
45+
annotations.add(CONVERTER);
4646
annotations.add(MODULEINFO);
4747
return annotations;
4848
}
@@ -56,26 +56,38 @@ public SourceVersion getSupportedSourceVersion() {
5656
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
5757

5858
processingContext.readModuleInfo();
59-
int count = 0;
60-
for (TypeElement annotation : annotations) {
61-
for (Element element : roundEnv.getElementsAnnotatedWith(annotation)) {
62-
generateQueryBeans(element);
63-
count++;
64-
}
65-
}
59+
int count = processEntities(roundEnv);
60+
processOthers(roundEnv);
6661
final int loaded = processingContext.complete();
6762
if (roundEnv.processingOver()) {
6863
writeModuleInfoBean();
6964
}
70-
7165
if (count > 0) {
7266
String msg = "Ebean APT generated %s query beans, loaded %s others - META-INF/ebean-generated-info.mf entity-packages: %s";
7367
processingContext.logNote(msg, count, loaded, processingContext.getAllEntityPackages());
7468
}
75-
7669
return true;
7770
}
7871

72+
private int processEntities(RoundEnvironment roundEnv) {
73+
int count = 0;
74+
for (Element element : roundEnv.getElementsAnnotatedWith(processingContext.embeddableAnnotation())) {
75+
generateQueryBeans(element);
76+
count++;
77+
}
78+
for (Element element : roundEnv.getElementsAnnotatedWith(processingContext.entityAnnotation())) {
79+
generateQueryBeans(element);
80+
count++;
81+
}
82+
return count;
83+
}
84+
85+
private void processOthers(RoundEnvironment roundEnv) {
86+
for (Element element : roundEnv.getElementsAnnotatedWith(processingContext.converterAnnotation())) {
87+
processingContext.addOther(element);
88+
}
89+
}
90+
7991
private void writeModuleInfoBean() {
8092
try {
8193
SimpleModuleInfoWriter writer = new SimpleModuleInfoWriter(processingContext);

src/main/java/io/ebean/querybean/generator/ReadModuleInfo.java

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import javax.lang.model.element.Element;
66
import javax.lang.model.element.ExecutableElement;
77
import java.util.ArrayList;
8+
import java.util.Collections;
89
import java.util.List;
910
import java.util.Map;
1011
import java.util.Set;
@@ -22,44 +23,46 @@ public ReadModuleInfo(ProcessingContext ctx) {
2223
this.ctx = ctx;
2324
}
2425

25-
List<String> read(Element element) {
26-
26+
ModuleMeta read(Element element) {
2727
final List<? extends AnnotationMirror> mirrors = element.getAnnotationMirrors();
28-
2928
for (AnnotationMirror mirror : mirrors) {
3029
final String name = mirror.getAnnotationType().asElement().toString();
3130
if (Constants.MODULEINFO.equals(name)) {
32-
return readEntities(mirror);
31+
List<String> entities = readEntities("entities", mirror);
32+
List<String> other = readEntities("other", mirror);
33+
return new ModuleMeta(entities, other);
3334
}
3435
}
3536
return null;
3637
}
3738

38-
@SuppressWarnings("unchecked")
39-
private List<String> readEntities(AnnotationMirror mirror) {
40-
39+
private List<String> readEntities(String key, AnnotationMirror mirror) {
4140
final Map<? extends ExecutableElement, ? extends AnnotationValue> elementValues = mirror.getElementValues();
4241
final Set<? extends Map.Entry<? extends ExecutableElement, ? extends AnnotationValue>> entries = elementValues.entrySet();
4342

4443
for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : entries) {
45-
if ("entities".equals(entry.getKey().getSimpleName().toString())) {
46-
final Object entitiesValue = entry.getValue().getValue();
47-
if (entitiesValue != null) {
48-
try {
49-
List<String> vals = new ArrayList<>();
50-
List<AnnotationValue> coll = (List<AnnotationValue>) entitiesValue;
51-
for (AnnotationValue annotationValue : coll) {
52-
vals.add((String) annotationValue.getValue());
53-
}
54-
return vals;
55-
} catch (Exception e) {
56-
ctx.logError(null, "Error reading ModuleInfo annotation, err " + e);
57-
return null;
58-
}
59-
}
44+
if (key.equals(entry.getKey().getSimpleName().toString())) {
45+
return readAttributes(entry.getValue());
46+
}
47+
}
48+
return Collections.emptyList();
49+
}
6050

51+
@SuppressWarnings("unchecked")
52+
private List<String> readAttributes(AnnotationValue value) {
53+
final Object entitiesValue = value.getValue();
54+
if (entitiesValue != null) {
55+
try {
56+
List<String> vals = new ArrayList<>();
57+
List<AnnotationValue> coll = (List<AnnotationValue>) entitiesValue;
58+
for (AnnotationValue annotationValue : coll) {
59+
vals.add((String) annotationValue.getValue());
60+
}
61+
return vals;
62+
} catch (Exception e) {
63+
ctx.logError(null, "Error reading ModuleInfo annotation, err " + e);
6164
}
6265
}
63-
return null;
66+
return Collections.emptyList();
6467
}
65-
}
68+
}

src/main/java/io/ebean/querybean/generator/SimpleModuleInfoWriter.java

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,11 @@ class SimpleModuleInfoWriter {
2929
}
3030

3131
void write() throws IOException {
32-
3332
writer = new Append(createFileWriter());
3433
writePackage();
3534
writeStartClass();
3635
writeEndClass();
3736
writer.close();
38-
3937
writeServicesFile();
4038
writeManifestFile();
4139
}
@@ -107,13 +105,26 @@ void buildAtContextModule(Append writer) {
107105
if (processingContext.isGeneratedAvailable()) {
108106
writer.append(Constants.AT_GENERATED).eol();
109107
}
110-
writer.append("@ModuleInfo(entities={%s})", prefixEntities()).eol();
108+
writer.append("@ModuleInfo(");
109+
if (processingContext.hasOtherClasses()) {
110+
writer.append("other={%s}, ", otherClasses());
111+
}
112+
writer.append("entities={%s}", prefixEntities());
113+
writer.append(")").eol();
114+
}
115+
116+
private String otherClasses() {
117+
return quoteTypes(processingContext.getOtherClasses());
111118
}
112119

113120
private String prefixEntities() {
121+
return quoteTypes(processingContext.getPrefixEntities());
122+
}
123+
124+
private String quoteTypes(Set<String> otherClasses) {
114125
StringJoiner sb = new StringJoiner(",");
115-
for (String entity : processingContext.getPrefixEntities()) {
116-
sb.add("\"" + entity + "\"");
126+
for (String fullType : otherClasses) {
127+
sb.add("\"" + fullType + "\"");
117128
}
118129
return sb.toString();
119130
}
@@ -123,7 +134,7 @@ private void writeStartClass() {
123134
buildAtContextModule(writer);
124135

125136
writer.append("public class %s implements ModuleInfoLoader {", factoryShortName).eol().eol();
126-
137+
writeMethodOtherClasses();
127138
writeMethodEntityClasses(processingContext.getDbEntities(), null);
128139

129140
final Map<String, Set<String>> otherDbEntities = processingContext.getOtherDbEntities();
@@ -132,7 +143,20 @@ private void writeStartClass() {
132143
for (Map.Entry<String, Set<String>> otherDb : otherDbEntities.entrySet()) {
133144
writeMethodEntityClasses(otherDb.getValue(), otherDb.getKey());
134145
}
146+
}
135147

148+
private void writeMethodOtherClasses() {
149+
writer.append(" private List<Class<?>> otherClasses() {").eol();
150+
if (!processingContext.hasOtherClasses()) {
151+
writer.append(" return Collections.emptyList();").eol();
152+
} else {
153+
writer.append(" List<Class<?>> others = new ArrayList<>();").eol();
154+
for (String otherType : processingContext.getOtherClasses()) {
155+
writer.append(" others.add(%s.class);", otherType).eol();
156+
}
157+
writer.append(" return others;").eol();
158+
}
159+
writer.append(" }").eol().eol();
136160
}
137161

138162
private void writeMethodEntityClasses(Set<String> dbEntities, String dbName) {
@@ -151,6 +175,9 @@ private void writeMethodEntityClasses(Set<String> dbEntities, String dbName) {
151175
for (String dbEntity : dbEntities) {
152176
writer.append(" entities.add(%s.class);", dbEntity).eol();
153177
}
178+
if (processingContext.hasOtherClasses()) {
179+
writer.append(" entities.addAll(otherClasses());").eol();
180+
}
154181
writer.append(" return entities;").eol();
155182
writer.append(" }").eol().eol();
156183
}

0 commit comments

Comments
 (0)