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

Commit d2e702d

Browse files
committed
#19 - ENH: Generate META-INF/ebean-info.mf (such that we don't need ebean.mf)
1 parent 4d4c88e commit d2e702d

3 files changed

Lines changed: 244 additions & 0 deletions

File tree

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package io.ebean.querybean.generator;
2+
3+
import javax.lang.model.element.AnnotationMirror;
4+
import javax.lang.model.element.AnnotationValue;
5+
import javax.lang.model.element.Element;
6+
import javax.lang.model.element.ExecutableElement;
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
import java.util.Map;
10+
import java.util.Set;
11+
12+
import static io.ebean.querybean.generator.Constants.MODULEINFO;
13+
14+
/**
15+
* Helper to read the current/existing prefixed entity classes.
16+
* <p>
17+
* These are added back on partial compile.
18+
*/
19+
class ReadModuleInfo {
20+
21+
private final ProcessingContext ctx;
22+
23+
public ReadModuleInfo(ProcessingContext ctx) {
24+
this.ctx = ctx;
25+
}
26+
27+
List<String> read(Element element) {
28+
29+
final List<? extends AnnotationMirror> mirrors = element.getAnnotationMirrors();
30+
31+
for (AnnotationMirror mirror : mirrors) {
32+
final String name = mirror.getAnnotationType().asElement().toString();
33+
if (MODULEINFO.equals(name)) {
34+
return readEntities(mirror);
35+
}
36+
}
37+
return null;
38+
}
39+
40+
@SuppressWarnings("unchecked")
41+
private List<String> readEntities(AnnotationMirror mirror) {
42+
43+
final Map<? extends ExecutableElement, ? extends AnnotationValue> elementValues = mirror.getElementValues();
44+
final Set<? extends Map.Entry<? extends ExecutableElement, ? extends AnnotationValue>> entries = elementValues.entrySet();
45+
46+
for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : entries) {
47+
if ("entities".equals(entry.getKey().getSimpleName().toString())) {
48+
final Object entitiesValue = entry.getValue().getValue();
49+
if (entitiesValue != null) {
50+
try {
51+
List<String> vals = new ArrayList<>();
52+
List<AnnotationValue> coll = (List<AnnotationValue>) entitiesValue;
53+
for (AnnotationValue annotationValue : coll) {
54+
vals.add((String) annotationValue.getValue());
55+
}
56+
return vals;
57+
} catch (Exception e) {
58+
ctx.logError(null, "Error reading ModuleInfo annotation, err " + e);
59+
return null;
60+
}
61+
}
62+
63+
}
64+
}
65+
return null;
66+
}
67+
}
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
package io.ebean.querybean.generator;
2+
3+
import javax.tools.FileObject;
4+
import javax.tools.JavaFileObject;
5+
import java.io.IOException;
6+
import java.io.Writer;
7+
import java.util.Map;
8+
import java.util.Set;
9+
import java.util.StringJoiner;
10+
11+
/**
12+
* Write the source code for the factory.
13+
*/
14+
class SimpleModuleInfoWriter {
15+
16+
private final ProcessingContext processingContext;
17+
18+
private final String factoryPackage;
19+
private final String factoryShortName;
20+
private final String factoryFullName;
21+
22+
private Append writer;
23+
24+
SimpleModuleInfoWriter(ProcessingContext processingContext) {
25+
this.processingContext = processingContext;
26+
this.factoryPackage = processingContext.getFactoryPackage();
27+
this.factoryShortName = "_ebean$ModuleInfo";
28+
this.factoryFullName = factoryPackage + "." + factoryShortName;
29+
}
30+
31+
void write() throws IOException {
32+
33+
writer = new Append(createFileWriter());
34+
writePackage();
35+
writeStartClass();
36+
writeEndClass();
37+
writer.close();
38+
39+
writeServicesFile();
40+
writeManifestFile();
41+
}
42+
43+
private void writeServicesFile() {
44+
45+
try {
46+
FileObject jfo = processingContext.createMetaInfServicesWriter();
47+
if (jfo != null) {
48+
Writer writer = jfo.openWriter();
49+
writer.write(factoryFullName);
50+
writer.close();
51+
}
52+
53+
} catch (IOException e) {
54+
e.printStackTrace();
55+
processingContext.logError(null, "Failed to write services file " + e.getMessage());
56+
}
57+
}
58+
59+
private void writeManifestFile() {
60+
try {
61+
final Set<String> allEntityPackages = processingContext.getAllEntityPackages();
62+
if (!allEntityPackages.isEmpty()) {
63+
FileObject jfo = processingContext.createManifestWriter();
64+
if (jfo != null) {
65+
Writer writer = jfo.openWriter();
66+
writer.write(manifestEntityPackages(allEntityPackages));
67+
writer.write("\n");
68+
writer.close();
69+
}
70+
}
71+
72+
} catch (IOException e) {
73+
e.printStackTrace();
74+
processingContext.logError(null, "Failed to write services file " + e.getMessage());
75+
}
76+
}
77+
78+
private String manifestEntityPackages(Set<String> allEntityPackages) {
79+
StringJoiner join = new StringJoiner(";");
80+
for (String pkg : allEntityPackages) {
81+
join.add(pkg);
82+
}
83+
return "entity-packages: " + join.toString() + "\n";
84+
}
85+
86+
87+
private void writePackage() {
88+
89+
writer.append("package %s;", factoryPackage).eol().eol();
90+
91+
writer.append("import java.util.ArrayList;").eol();
92+
writer.append("import java.util.Collections;").eol();
93+
writer.append("import java.util.List;").eol();
94+
final String generated = processingContext.getGeneratedAnnotation();
95+
if (generated != null) {
96+
writer.append("import %s;", generated).eol();
97+
}
98+
writer.eol();
99+
writer.append("import io.ebean.config.ModuleInfo;").eol();
100+
writer.append("import io.ebean.config.ModuleInfoLoader;").eol();
101+
writer.eol();
102+
103+
}
104+
105+
void buildAtContextModule(Append writer) {
106+
if (processingContext.isGeneratedAvailable()) {
107+
writer.append(Constants.AT_GENERATED).eol();
108+
}
109+
writer.append("@ModuleInfo(entities={%s})", prefixEntities()).eol();
110+
}
111+
112+
private String prefixEntities() {
113+
StringJoiner sb = new StringJoiner(",");
114+
for (String entity : processingContext.getPrefixEntities()) {
115+
sb.add("\"" + entity + "\"");
116+
}
117+
return sb.toString();
118+
}
119+
120+
private void writeStartClass() {
121+
122+
buildAtContextModule(writer);
123+
124+
writer.append("public class %s implements ModuleInfoLoader {", factoryShortName).eol().eol();
125+
126+
writeMethodEntityClasses(processingContext.getDbEntities(), null);
127+
128+
final Map<String, Set<String>> otherDbEntities = processingContext.getOtherDbEntities();
129+
writeMethodEntityClassesFor(otherDbEntities.keySet());
130+
131+
for (Map.Entry<String, Set<String>> otherDb : otherDbEntities.entrySet()) {
132+
writeMethodEntityClasses(otherDb.getValue(), otherDb.getKey());
133+
}
134+
135+
}
136+
137+
private void writeMethodEntityClasses(Set<String> dbEntities, String dbName) {
138+
139+
String modifier = "public";
140+
String method = "entityClasses";
141+
142+
if (dbName == null) {
143+
writer.append(" @Override").eol();
144+
} else {
145+
method = dbName + "_entities";
146+
modifier = "private";
147+
}
148+
writer.append(" %s List<Class<?>> %s() {", modifier, method).eol();
149+
writer.append(" List<Class<?>> entities = new ArrayList<>();").eol();
150+
for (String dbEntity : dbEntities) {
151+
writer.append(" entities.add(%s.class);", dbEntity).eol();
152+
}
153+
writer.append(" return entities;").eol();
154+
writer.append(" }").eol().eol();
155+
}
156+
157+
private void writeMethodEntityClassesFor(Set<String> otherDbNames) {
158+
159+
writer.append(" @Override").eol();
160+
writer.append(" public List<Class<?>> entityClassesFor(String dbName) {").eol().eol();
161+
for (String dbName : otherDbNames) {
162+
writer.append(" if (\"%s\".equals(dbName)) return %s_entities();", dbName, dbName).eol();
163+
}
164+
writer.append(" return Collections.emptyList();").eol();
165+
writer.append(" }").eol().eol();
166+
}
167+
168+
private void writeEndClass() {
169+
writer.append("}").eol();
170+
}
171+
172+
private Writer createFileWriter() throws IOException {
173+
JavaFileObject jfo = processingContext.createWriter(factoryFullName, null);
174+
return jfo.openWriter();
175+
}
176+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ void writeRootBean() throws IOException {
141141
gatherPropertyDetails();
142142

143143
if (isEntity()) {
144+
processingContext.addEntity(beanFullName, dbName);
144145
writer = new Append(createFileWriter());
145146

146147
translateKotlinImportTypes();

0 commit comments

Comments
 (0)