diff --git a/querybean-generator/src/main/java/io/ebean/querybean/generator/LookupWriter.java b/querybean-generator/src/main/java/io/ebean/querybean/generator/LookupWriter.java new file mode 100644 index 0000000000..6d9f313abd --- /dev/null +++ b/querybean-generator/src/main/java/io/ebean/querybean/generator/LookupWriter.java @@ -0,0 +1,83 @@ +package io.ebean.querybean.generator; + +import static java.util.function.Predicate.not; + +import java.io.IOException; +import java.io.Writer; +import java.util.Collection; +import java.util.Set; + +import javax.annotation.processing.RoundEnvironment; +import javax.lang.model.element.TypeElement; +import javax.lang.model.util.Elements; +import javax.tools.FileObject; + +/** Write the source code for the factory. */ +class LookupWriter { + private LookupWriter() {} + + private static final String METAINF_SERVICES_LOOKUP = + "META-INF/services/io.ebean.config.LookupProvider"; + + private static final String FILE_STRING = + "package %s;\n" + + "\n" + + "import java.lang.invoke.MethodHandles;\n" + + "\n" + + "import io.ebean.config.LookupProvider;\n" + + "\n" + + "public class EbeanMethodLookup implements LookupProvider {\n" + + "\n" + + " private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();\n" + + "\n" + + " @Override\n" + + " public MethodHandles.Lookup provideLookup() {\n" + + " return LOOKUP;\n" + + " }\n" + + "}"; + + static void write( + ProcessingContext processingContext, + Elements util, + Set annotations, + RoundEnvironment roundEnv) { + + var module = + annotations.stream() + .map(roundEnv::getElementsAnnotatedWith) + .filter(not(Collection::isEmpty)) + .findAny() + .map(s -> s.iterator().next()) + .map(util::getModuleOf) + .orElse(null); + + if (module != null && !module.isUnnamed()) { + var moduleNameString = module.getQualifiedName().toString(); + + var pkg = moduleNameString + ".lookup"; + String fqn = pkg + ".EbeanMethodLookup"; + try { + var javaFileObject = processingContext.createWriter(fqn); + + var writer = new Append(javaFileObject.openWriter()); + + writer.append(FILE_STRING, pkg); + writer.close(); + writeServicesFile(processingContext, fqn); + } catch (IOException e) { + processingContext.logError(null, "Failed to write lookup class " + e.getMessage()); + } + } + } + + private static void writeServicesFile(ProcessingContext processingContext, String fqn) + throws IOException { + + FileObject jfo = processingContext.createMetaInfWriter(METAINF_SERVICES_LOOKUP); + if (jfo != null) { + Writer writer = jfo.openWriter(); + writer.write(fqn); + writer.close(); + } + } +} diff --git a/querybean-generator/src/main/java/io/ebean/querybean/generator/Processor.java b/querybean-generator/src/main/java/io/ebean/querybean/generator/Processor.java index c32f3123d8..bc9ff08e0b 100644 --- a/querybean-generator/src/main/java/io/ebean/querybean/generator/Processor.java +++ b/querybean-generator/src/main/java/io/ebean/querybean/generator/Processor.java @@ -18,8 +18,7 @@ public class Processor extends AbstractProcessor implements Constants { private ProcessingContext processingContext; - public Processor() { - } + private boolean wroteLookup; @Override public synchronized void init(ProcessingEnvironment processingEnv) { @@ -56,6 +55,10 @@ public boolean process(Set annotations, RoundEnvironment String msg = "Ebean APT generated %s query beans, loaded %s others - META-INF/ebean-generated-info.mf entity-packages: %s"; processingContext.logNote(msg, count, loaded, processingContext.getAllEntityPackages()); } + if (!wroteLookup) { + wroteLookup = true; + LookupWriter.write(processingContext, processingEnv.getElementUtils(), annotations, roundEnv); + } return true; }