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

io.ebean.querybean.generator.SimpleQueryBeanWriter Maven / Gradle / Ivy

There is a newer version: 15.8.1
Show newest version
package io.ebean.querybean.generator;


import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.persistence.Entity;
import javax.tools.JavaFileObject;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import static io.ebean.querybean.generator.Constants.AT_GENERATED;
import static io.ebean.querybean.generator.Constants.AT_TYPEQUERYBEAN;
import static io.ebean.querybean.generator.Constants.EBEANSERVER;
import static io.ebean.querybean.generator.Constants.GENERATED;
import static io.ebean.querybean.generator.Constants.TQROOTBEAN;
import static io.ebean.querybean.generator.Constants.TYPEQUERYBEAN;

/**
 * A simple implementation that generates and writes query beans.
 */
class SimpleQueryBeanWriter {

  static final String NEWLINE = "\n";

  private final Set importTypes = new TreeSet<>();

  private final List properties = new ArrayList<>();

  private final TypeElement element;

  private final ProcessingContext processingContext;

  private final String beanFullName;
  private boolean writingAssocBean;

  private String destPackage;
  private String origDestPackage;

  private String shortName;
  private String origShortName;

  private Writer writer;


  SimpleQueryBeanWriter(TypeElement element, ProcessingContext processingContext) {
    this.element = element;
    this.processingContext = processingContext;

    this.beanFullName = element.getQualifiedName().toString();
    this.destPackage = derivePackage(beanFullName)+".query";
    this.shortName = deriveShortName(beanFullName);

    processingContext.addPackage(destPackage);
  }

  private void gatherPropertyDetails() {

    importTypes.add(beanFullName);
    if (processingContext.isGeneratedAvailable()) {
      importTypes.add(GENERATED);
    }
    importTypes.add(TQROOTBEAN);
    importTypes.add(TYPEQUERYBEAN);
    importTypes.add(EBEANSERVER);

    addClassProperties();
  }

  /**
   * Recursively add properties from the inheritance hierarchy.
   * 

* Includes properties from mapped super classes and usual inheritance. *

*/ private void addClassProperties() { List fields = processingContext.allFields(element); for (VariableElement field : fields) { PropertyType type = processingContext.getPropertyType(field); if (type != null) { type.addImports(importTypes); properties.add(new PropertyMeta(field.getSimpleName().toString(), type)); } } } /** * Write the type query bean (root bean). */ void writeRootBean() throws IOException { gatherPropertyDetails(); if (isEntity()) { writer = createFileWriter(); writePackage(); writeImports(); writeClass(); writeAlias(); writeFields(); writeConstructors(); writeStaticAliasClass(); writeClassEnd(); writer.flush(); writer.close(); } } private boolean isEntity() { return element.getAnnotation(Entity.class) != null; } /** * Write the type query assoc bean. */ void writeAssocBean() throws IOException { writingAssocBean = true; origDestPackage = destPackage; destPackage = destPackage+".assoc"; origShortName = shortName; shortName = "Assoc"+shortName; prepareAssocBeanImports(); writer = createFileWriter(); writePackage(); writeImports(); writeClass(); writeFields(); writeConstructors(); writeClassEnd(); writer.flush(); writer.close(); } /** * Prepare the imports for writing assoc bean. */ private void prepareAssocBeanImports() { importTypes.remove("io.ebean.typequery.TQRootBean"); importTypes.remove("io.ebean.EbeanServer"); importTypes.add("io.ebean.typequery.TQAssocBean"); if (isEntity()) { importTypes.add("io.ebean.typequery.TQProperty"); importTypes.add(origDestPackage + ".Q" + origShortName); } // remove imports for the same package Iterator importsIterator = importTypes.iterator(); String checkImportStart = destPackage + ".QAssoc"; while (importsIterator.hasNext()){ String importType = importsIterator.next(); if (importType.startsWith(checkImportStart)) { importsIterator.remove(); } } } /** * Write constructors. */ private void writeConstructors() throws IOException { if (writingAssocBean) { writeAssocBeanFetch(); writeAssocBeanConstructor(); } else { writeRootBeanConstructor(); } } /** * Write the constructors for 'root' type query bean. */ private void writeRootBeanConstructor() throws IOException { writer.append(NEWLINE); writer.append(" /**").append(NEWLINE); writer.append(" * Construct with a given EbeanServer.").append(NEWLINE); writer.append(" */").append(NEWLINE); writer.append(" public Q").append(shortName).append("(EbeanServer server) {").append(NEWLINE); writer.append(" super(").append(shortName).append(".class, server);").append(NEWLINE); writer.append(" }").append(NEWLINE); writer.append(NEWLINE); writer.append(" /**").append(NEWLINE); writer.append(" * Construct using the default EbeanServer.").append(NEWLINE); writer.append(" */").append(NEWLINE); writer.append(" public Q").append(shortName).append("() {").append(NEWLINE); writer.append(" super(").append(shortName).append(".class);").append(NEWLINE); writer.append(" }").append(NEWLINE); writer.append(NEWLINE); writer.append(" /**").append(NEWLINE); writer.append(" * Construct for Alias.").append(NEWLINE); writer.append(" */").append(NEWLINE); writer.append(" private Q").append(shortName).append("(boolean dummy) {").append(NEWLINE); writer.append(" super(dummy);").append(NEWLINE); writer.append(" }").append(NEWLINE); } private void writeAssocBeanFetch() throws IOException { if (isEntity()) { writeAssocBeanFetch("", "Eagerly fetch this association loading the specified properties."); writeAssocBeanFetch("Query", "Eagerly fetch this association using a 'query join' loading the specified properties."); writeAssocBeanFetch("Lazy", "Use lazy loading for this association loading the specified properties."); } } private void writeAssocBeanFetch(String fetchType, String comment) throws IOException { writer.append(" /**").append(NEWLINE); writer.append(" * ").append(comment).append(NEWLINE); writer.append(" */").append(NEWLINE); writer.append(" @SafeVarargs").append(NEWLINE); writer.append(" public final R fetch").append(fetchType).append("(TQProperty... properties) {").append(NEWLINE); writer.append(" return fetch").append(fetchType).append("Properties(properties);").append(NEWLINE); writer.append(" }").append(NEWLINE); writer.append(NEWLINE); } /** * Write constructor for 'assoc' type query bean. */ private void writeAssocBeanConstructor() throws IOException { // minimal constructor writer.append(" public Q").append(shortName).append("(String name, R root) {").append(NEWLINE); writer.append(" super(name, root);").append(NEWLINE); writer.append(" }").append(NEWLINE); } /** * Write all the fields. */ private void writeFields() throws IOException { for (PropertyMeta property : properties) { property.writeFieldDefn(writer, shortName, writingAssocBean); writer.append(NEWLINE); } writer.append(NEWLINE); } /** * Write the class definition. */ private void writeClass() throws IOException { if (writingAssocBean) { writer.append("/**").append(NEWLINE); writer.append(" * Association query bean for ").append(shortName).append(".").append(NEWLINE); writer.append(" * ").append(NEWLINE); writer.append(" * THIS IS A GENERATED OBJECT, DO NOT MODIFY THIS CLASS.").append(NEWLINE); writer.append(" */").append(NEWLINE); //public class QAssocContact if (processingContext.isGeneratedAvailable()) { writer.append(AT_GENERATED).append(NEWLINE); } writer.append(AT_TYPEQUERYBEAN).append(NEWLINE); writer.append("public class ").append("Q").append(shortName); writer.append(" extends TQAssocBean<").append(origShortName).append(",R> {").append(NEWLINE); } else { writer.append("/**").append(NEWLINE); writer.append(" * Query bean for ").append(shortName).append(".").append(NEWLINE); writer.append(" * ").append(NEWLINE); writer.append(" * THIS IS A GENERATED OBJECT, DO NOT MODIFY THIS CLASS.").append(NEWLINE); writer.append(" */").append(NEWLINE); // public class QContact extends TQRootBean { if (processingContext.isGeneratedAvailable()) { writer.append(AT_GENERATED).append(NEWLINE); } writer.append(AT_TYPEQUERYBEAN).append(NEWLINE); writer.append("public class ").append("Q").append(shortName) .append(" extends TQRootBean<").append(shortName).append(",Q").append(shortName).append("> {").append(NEWLINE); } writer.append(NEWLINE); } private void writeAlias() throws IOException { if (!writingAssocBean) { writer.append(" private static final Q").append(shortName).append(" _alias = new Q"); writer.append(shortName).append("(true);").append(NEWLINE); writer.append(NEWLINE); writer.append(" /**").append(NEWLINE); writer.append(" * Return the shared 'Alias' instance used to provide properties to ").append(NEWLINE); writer.append(" * select() and fetch() ").append(NEWLINE); writer.append(" */").append(NEWLINE); writer.append(" public static Q").append(shortName).append(" alias() {").append(NEWLINE); writer.append(" return _alias;").append(NEWLINE); writer.append(" }").append(NEWLINE); writer.append(NEWLINE); } } private void writeStaticAliasClass() throws IOException { writer.append(NEWLINE); writer.append(" /**").append(NEWLINE); writer.append(" * Provides static properties to use in select() and fetch() ").append(NEWLINE); writer.append(" * clauses of a query. Typically referenced via static imports. ").append(NEWLINE); writer.append(" */").append(NEWLINE); writer.append(" public static class Alias {").append(NEWLINE); for (PropertyMeta property : properties) { property.writeFieldAliasDefn(writer, shortName); writer.append(NEWLINE); } writer.append(" }").append(NEWLINE); } private void writeClassEnd() throws IOException { writer.append("}").append(NEWLINE); } /** * Write all the imports. */ private void writeImports() throws IOException { for (String importType : importTypes) { writer.append("import ").append(importType).append(";").append(NEWLINE); } writer.append(NEWLINE); } private void writePackage() throws IOException { writer.append("package ").append(destPackage).append(";").append(NEWLINE).append(NEWLINE); } private Writer createFileWriter() throws IOException { JavaFileObject jfo = processingContext.createWriter(destPackage + "." + "Q" + shortName, element); return jfo.openWriter(); } private String derivePackage(String name) { int pos = name.lastIndexOf('.'); if (pos == -1) { return ""; } return name.substring(0, pos); } private String deriveShortName(String name) { int pos = name.lastIndexOf('.'); if (pos == -1) { return name; } return name.substring(pos+1); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy