All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.avaje.jsonb.generator.SimpleComponentWriter Maven / Gradle / Ivy

package io.avaje.jsonb.generator;

import static io.avaje.jsonb.generator.ProcessingContext.createMetaInfWriterFor;
import static io.avaje.jsonb.generator.APContext.createSourceFile;

import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import javax.tools.FileObject;
import javax.tools.JavaFileObject;

final class SimpleComponentWriter {

  private final ComponentMetaData metaData;
  private final Set importTypes = new TreeSet<>();
  private Append writer;
  private JavaFileObject fileObject;

  SimpleComponentWriter(ComponentMetaData metaData) {
    this.metaData = metaData;
  }

  void initialise() throws IOException {
    var name = metaData.fullName();
    if (fileObject == null) {
      fileObject = createSourceFile(name);
    }
    if (!metaData.isEmpty()) {
      ProcessingContext.addJsonSpi(metaData.fullName());
      ProcessingContext.validateModule();
    }
  }

  private Writer createFileWriter() throws IOException {
    return fileObject.openWriter();
  }

  void write() throws IOException {
    writer = new Append(createFileWriter());
    writePackage();
    writeImports();
    writeClassStart();
    writeRegister();
    writeClassEnd();
    writer.close();
  }

  void writeMetaInf() throws IOException {
    var services = ProcessingContext.readExistingMetaInfServices();
    final FileObject fileObject = createMetaInfWriterFor(Constants.META_INF_COMPONENT);
    if (fileObject != null) {
      final Writer writer = fileObject.openWriter();
      writer.write(String.join("\n", services));
      writer.close();
    }
  }

  private void writeRegister() {
    writer.append("  @Override").eol();
    writer.append("  public void register(Jsonb.Builder builder) {").eol();

    for (final String adapterFullName : metaData.withTypes()) {
      final String adapterShortName = Util.shortName(adapterFullName);
      writer.append("    builder.add(%s.class, %s::new);", adapterShortName, adapterShortName).eol();
    }
    for (final String adapterFullName : metaData.allFactories()) {
      final String adapterShortName = Util.shortName(adapterFullName);
      writer.append("    builder.add(%s.FACTORY);", adapterShortName).eol();
    }
    for (final String adapterFullName : metaData.all()) {
      final String adapterShortName = Util.shortName(adapterFullName);
      final String typeName = Util.shortType(Util.baseTypeOfAdapter(adapterFullName).replace("$", "."));
      writer.append("    builder.add(%s.class, %s::new);", typeName, adapterShortName).eol();
    }
    writer.append("  }").eol().eol();
  }

  private void writeClassEnd() {
    writer.append("}").eol();
  }

  private void writeClassStart() {
    final String fullName = metaData.fullName();
    final String shortName = Util.shortName(fullName);
    writer.append("@Generated(\"io.avaje.jsonb.generator\")").eol();
    final List factories = metaData.allFactories();
    if (!factories.isEmpty()) {
      writer.append("@MetaData.Factory({");
      writeMetaDataEntry(factories);
      writer.append("})").eol();
    }
    writer.append("@MetaData({");
    final List all = new ArrayList<>(metaData.all());
    all.addAll(metaData.withTypes());
    writeMetaDataEntry(all);
    writer.append("})").eol();

    writer.append("public %sclass %s implements GeneratedComponent {", Util.valhalla(), shortName).eol().eol();
  }

  private void writeMetaDataEntry(List entries) {
    for (int i = 0, size = entries.size(); i < size; i++) {
      if (i > 0) {
        writer.append(", ");
      }
      writer.append("%s.class", Util.shortName(entries.get(i)));
    }
  }


  private void writeImports() {
    importTypes.add(Constants.JSONB);
    importTypes.addAll(metaData.allImports());
    importTypes.add("io.avaje.jsonb.spi.Generated");
    importTypes.add("io.avaje.jsonb.spi.GeneratedComponent");
    importTypes.add("io.avaje.jsonb.spi.MetaData");

    for (final String importType : importTypes) {
      if (Util.validImportType(importType, metaData.packageName())) {
        writer.append("import %s;", importType).eol();
      }
    }
    writer.eol();
  }

  private void writePackage() {
    final String packageName = metaData.packageName();
    if (packageName != null && !packageName.isEmpty()) {
      writer.append("package %s;", packageName).eol().eol();
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy