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

net.zerobuilder.compiler.generate.DtoModule Maven / Gradle / Ivy

There is a newer version: 1.603
Show newest version
package net.zerobuilder.compiler.generate;

import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.FieldSpec;
import net.zerobuilder.compiler.generate.DtoModuleOutput.ContractModuleOutput;
import net.zerobuilder.compiler.generate.DtoModuleOutput.SimpleModuleOutput;
import net.zerobuilder.compiler.generate.DtoSimpleGoal.SimpleGoal;
import net.zerobuilder.compiler.generate.DtoStep.AbstractStep;

import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Supplier;

import static javax.lang.model.element.Modifier.FINAL;
import static javax.lang.model.element.Modifier.PRIVATE;
import static net.zerobuilder.compiler.generate.DtoSimpleGoal.abstractSteps;
import static net.zerobuilder.compiler.generate.DtoSimpleGoal.context;
import static net.zerobuilder.compiler.generate.DtoSimpleGoal.name;
import static net.zerobuilder.compiler.generate.ZeroUtil.downcase;
import static net.zerobuilder.compiler.generate.ZeroUtil.memoize;
import static net.zerobuilder.compiler.generate.ZeroUtil.transform;
import static net.zerobuilder.compiler.generate.ZeroUtil.upcase;

public final class DtoModule {

  public static abstract class Module {
    protected abstract String name();
    abstract  R accept(ModuleCases cases, P p);

    public final ClassName implType(SimpleGoal goal) {
      String implName = DtoModule.implName.apply(this, goal);
      return context.apply(goal)
          .generatedType.nestedClass(implName);
    }

    public final String methodName(SimpleGoal goal) {
      return name.apply(goal) + upcase(name());
    }

    // TODO this should not need goal argument
    public final FieldSpec cacheField(SimpleGoal goal) {
      ClassName type = implType(goal);
      return FieldSpec.builder(type, downcase(type.simpleName()), PRIVATE)
          .initializer("new $T()", type)
          .build();
    }

    protected final List steps(SimpleGoal goal) {
      return abstractSteps.apply(goal);
    }
  }

  interface ModuleCases {
    R simple(SimpleModule module, P p);
    R contract(ContractModule module, P p);
  }

  public static abstract class SimpleModule extends Module {

    protected abstract SimpleModuleOutput process(SimpleGoal goal);

    @Override
    public final  R accept(ModuleCases cases, P p) {
      return cases.simple(this, p);
    }
  }

  public static abstract class ContractModule extends Module {
    protected abstract ContractModuleOutput process(SimpleGoal goal);

    protected final List stepInterfaceTypes(SimpleGoal goal) {
      return transform(steps(goal), step -> contractType(goal).nestedClass(step.thisType));
    }

    public final ClassName contractType(SimpleGoal goal) {
      String contractName = upcase(name.apply(goal)) + upcase(name());
      return context.apply(goal)
          .generatedType.nestedClass(contractName);
    }

    @Override
    public final  R accept(ModuleCases cases, P p) {
      return cases.contract(this, p);
    }
  }

  static  BiFunction asFunction(ModuleCases cases) {
    return (module, p) -> module.accept(cases, p);
  }

  static  BiFunction moduleCases(
      BiFunction simple,
      BiFunction contract) {
    return asFunction(new ModuleCases() {
      @Override
      public R simple(SimpleModule module, P p) {
        return simple.apply(module, p);
      }
      @Override
      public R contract(ContractModule module, P p) {
        return contract.apply(module, p);
      }
    });
  }

  private static final BiFunction implName =
      moduleCases(
          (simple, goal) -> upcase(name.apply(goal)) + upcase(simple.name()),
          (contract, goal) -> upcase(name.apply(goal)) + upcase(contract.name()) + "Impl");

  private DtoModule() {
    throw new UnsupportedOperationException("no instances");
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy