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

Commit 4c4e2cf

Browse files
committed
#57 - Auto register AttributeConverter
1 parent ed22301 commit 4c4e2cf

6 files changed

Lines changed: 148 additions & 58 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+
public ModuleMeta(List<String> entities, List<String> other) {
10+
this.entities = entities;
11+
this.other = other;
12+
}
13+
14+
public List<String> getEntities() {
15+
return entities;
16+
}
17+
18+
public 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
@@ -57,6 +57,8 @@ class ProcessingContext implements Constants {
5757
*/
5858
private final Set<String> allEntityPackages = new TreeSet<>();
5959

60+
private final Set<String> otherClasses = new TreeSet<>();
61+
6062
/**
6163
* The DB name prefixed entities.
6264
*/
@@ -80,7 +82,7 @@ class ProcessingContext implements Constants {
8082
/**
8183
* For partial compile the previous list of prefixed entity classes.
8284
*/
83-
private List<String> loadedPrefixEntities;
85+
private List<String> loadedPrefixEntities = new ArrayList<>();
8486

8587
/**
8688
* The package for the generated ModuleInfoLoader.
@@ -99,6 +101,18 @@ class ProcessingContext implements Constants {
99101
this.readModuleInfo = new ReadModuleInfo(this);
100102
}
101103

104+
TypeElement entityAnnotation() {
105+
return elementUtils.getTypeElement(ENTITY);
106+
}
107+
108+
TypeElement embeddableAnnotation() {
109+
return elementUtils.getTypeElement(EMBEDDABLE);
110+
}
111+
112+
TypeElement converterAnnotation() {
113+
return elementUtils.getTypeElement(CONVERTER);
114+
}
115+
102116
private String generatedAnnotation(boolean jdk8) {
103117
if (jdk8) {
104118
return isTypeAvailable(GENERATED_8) ? GENERATED_8 : null;
@@ -114,7 +128,6 @@ private boolean isTypeAvailable(String canonicalName) {
114128
* Gather all the fields (properties) for the given bean element.
115129
*/
116130
List<VariableElement> allFields(Element element) {
117-
118131
List<VariableElement> list = new ArrayList<>();
119132
gatherProperties(list, element);
120133
return list;
@@ -374,7 +387,9 @@ void readModuleInfo() {
374387
TypeElement factoryType = elementUtils.getTypeElement(factory);
375388
if (factoryType != null) {
376389
// previous prefixed entities to add back for partial compile
377-
loadedPrefixEntities = readModuleInfo.read(factoryType);
390+
final ModuleMeta read = readModuleInfo.read(factoryType);
391+
loadedPrefixEntities.addAll(read.getEntities());
392+
otherClasses.addAll(read.getOther());
378393
}
379394
}
380395
}
@@ -403,25 +418,22 @@ void addEntity(String beanFullName, String dbName) {
403418
* Add back entity classes for partial compile.
404419
*/
405420
int complete() {
406-
407421
int added = 0;
408-
if (loadedPrefixEntities != null) {
409-
for (String oldPrefixEntity : loadedPrefixEntities) {
410-
// maybe split as dbName:entityClass
411-
final String[] prefixEntityClass = oldPrefixEntity.split(":");
412-
413-
String dbName = null;
414-
String entityClass;
415-
if (prefixEntityClass.length > 1) {
416-
dbName = prefixEntityClass[0];
417-
entityClass = prefixEntityClass[1];
418-
} else {
419-
entityClass = prefixEntityClass[0];
420-
}
421-
if (!loaded.contains(entityClass)) {
422-
addEntity(entityClass, dbName);
423-
added++;
424-
}
422+
for (String oldPrefixEntity : loadedPrefixEntities) {
423+
// maybe split as dbName:entityClass
424+
final String[] prefixEntityClass = oldPrefixEntity.split(":");
425+
426+
String dbName = null;
427+
String entityClass;
428+
if (prefixEntityClass.length > 1) {
429+
dbName = prefixEntityClass[0];
430+
entityClass = prefixEntityClass[1];
431+
} else {
432+
entityClass = prefixEntityClass[0];
433+
}
434+
if (!loaded.contains(entityClass)) {
435+
addEntity(entityClass, dbName);
436+
added++;
425437
}
426438
}
427439
return added;
@@ -453,6 +465,18 @@ FileObject createMetaInfWriter(String target) throws IOException {
453465
return filer.createResource(StandardLocation.CLASS_OUTPUT, "", target);
454466
}
455467

468+
public boolean hasOtherClasses() {
469+
return !otherClasses.isEmpty();
470+
}
471+
472+
public Set<String> getOtherClasses() {
473+
return otherClasses;
474+
}
475+
476+
void addOther(Element element) {
477+
otherClasses.add(element.toString());
478+
}
479+
456480
Set<String> getPrefixEntities() {
457481
return prefixEntities;
458482
}

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

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public Set<String> getSupportedAnnotationTypes() {
3131
Set<String> annotations = new LinkedHashSet<>();
3232
annotations.add(ENTITY);
3333
annotations.add(EMBEDDABLE);
34+
annotations.add(CONVERTER);
3435
annotations.add(MODULEINFO);
3536
return annotations;
3637
}
@@ -43,26 +44,38 @@ public SourceVersion getSupportedSourceVersion() {
4344
@Override
4445
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
4546
processingContext.readModuleInfo();
46-
int count = 0;
47-
for (TypeElement annotation : annotations) {
48-
for (Element element : roundEnv.getElementsAnnotatedWith(annotation)) {
49-
generateQueryBeans(element);
50-
count++;
51-
}
52-
}
47+
int count = processEntities(roundEnv);
48+
processOthers(roundEnv);
5349
final int loaded = processingContext.complete();
5450
if (roundEnv.processingOver()) {
5551
writeModuleInfoBean();
5652
}
57-
5853
if (count > 0) {
5954
String msg = "Ebean APT generated %s query beans, loaded %s others - META-INF/ebean-generated-info.mf entity-packages: %s";
6055
processingContext.logNote(msg, count, loaded, processingContext.getAllEntityPackages());
6156
}
62-
6357
return true;
6458
}
6559

60+
private int processEntities(RoundEnvironment roundEnv) {
61+
int count = 0;
62+
for (Element element : roundEnv.getElementsAnnotatedWith(processingContext.embeddableAnnotation())) {
63+
generateQueryBeans(element);
64+
count++;
65+
}
66+
for (Element element : roundEnv.getElementsAnnotatedWith(processingContext.entityAnnotation())) {
67+
generateQueryBeans(element);
68+
count++;
69+
}
70+
return count;
71+
}
72+
73+
private void processOthers(RoundEnvironment roundEnv) {
74+
for (Element element : roundEnv.getElementsAnnotatedWith(processingContext.converterAnnotation())) {
75+
processingContext.addOther(element);
76+
}
77+
}
78+
6679
private void writeModuleInfoBean() {
6780
try {
6881
SimpleModuleInfoWriter writer = new SimpleModuleInfoWriter(processingContext);

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

Lines changed: 26 additions & 22 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,47 @@ 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

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

4444
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-
}
45+
if (key.equals(entry.getKey().getSimpleName().toString())) {
46+
return readAttributes(entry.getValue());
47+
}
48+
}
49+
return Collections.emptyList();
50+
}
6051

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

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

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ void write() throws IOException {
3434
writeStartClass();
3535
writeEndClass();
3636
writer.close();
37-
3837
writeServicesFile();
3938
writeManifestFile();
4039
}
@@ -98,20 +97,32 @@ private void writePackage() {
9897
writer.append("import io.ebean.config.ModuleInfo;").eol();
9998
writer.append("import io.ebean.config.ModuleInfoLoader;").eol();
10099
writer.eol();
101-
102100
}
103101

104102
void buildAtContextModule(Append writer) {
105103
if (processingContext.isGeneratedAvailable()) {
106104
writer.append(Constants.AT_GENERATED).eol();
107105
}
108-
writer.append("@ModuleInfo(entities={%s})", prefixEntities()).eol();
106+
writer.append("@ModuleInfo(");
107+
if (processingContext.hasOtherClasses()) {
108+
writer.append("other={%s}, ", otherClasses());
109+
}
110+
writer.append("entities={%s}", prefixEntities());
111+
writer.append(")").eol();
112+
}
113+
114+
private String otherClasses() {
115+
return quoteTypes(processingContext.getOtherClasses());
109116
}
110117

111118
private String prefixEntities() {
119+
return quoteTypes(processingContext.getPrefixEntities());
120+
}
121+
122+
private String quoteTypes(Set<String> otherClasses) {
112123
StringJoiner sb = new StringJoiner(",");
113-
for (String entity : processingContext.getPrefixEntities()) {
114-
sb.add("\"" + entity + "\"");
124+
for (String fullType : otherClasses) {
125+
sb.add("\"" + fullType + "\"");
115126
}
116127
return sb.toString();
117128
}
@@ -121,7 +132,7 @@ private void writeStartClass() {
121132
buildAtContextModule(writer);
122133

123134
writer.append("public class %s implements ModuleInfoLoader {", factoryShortName).eol().eol();
124-
135+
writeMethodOtherClasses();
125136
writeMethodEntityClasses(processingContext.getDbEntities(), null);
126137

127138
final Map<String, Set<String>> otherDbEntities = processingContext.getOtherDbEntities();
@@ -130,7 +141,20 @@ private void writeStartClass() {
130141
for (Map.Entry<String, Set<String>> otherDb : otherDbEntities.entrySet()) {
131142
writeMethodEntityClasses(otherDb.getValue(), otherDb.getKey());
132143
}
144+
}
133145

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

136160
private void writeMethodEntityClasses(Set<String> dbEntities, String dbName) {
@@ -149,6 +173,9 @@ private void writeMethodEntityClasses(Set<String> dbEntities, String dbName) {
149173
for (String dbEntity : dbEntities) {
150174
writer.append(" entities.add(%s.class);", dbEntity).eol();
151175
}
176+
if (processingContext.hasOtherClasses()) {
177+
writer.append(" entities.addAll(otherClasses());").eol();
178+
}
152179
writer.append(" return entities;").eol();
153180
writer.append(" }").eol().eol();
154181
}

0 commit comments

Comments
 (0)