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

net.zerobuilder.compiler.generate.DtoStep 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.CodeBlock;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.TypeName;
import net.zerobuilder.compiler.generate.DtoBeanStep.AbstractBeanStep;
import net.zerobuilder.compiler.generate.DtoParameter.AbstractParameter;
import net.zerobuilder.compiler.generate.DtoParameter.RegularParameter;
import net.zerobuilder.compiler.generate.Utilities.ClassNames;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;

import static javax.lang.model.element.Modifier.PRIVATE;
import static net.zerobuilder.compiler.generate.DtoBeanStep.validBeanParameter;
import static net.zerobuilder.compiler.generate.Utilities.ClassNames.COLLECTION;
import static net.zerobuilder.compiler.generate.Utilities.ClassNames.ITERABLE;
import static net.zerobuilder.compiler.generate.Utilities.ClassNames.SET;
import static net.zerobuilder.compiler.generate.Utilities.fieldSpec;
import static net.zerobuilder.compiler.generate.Utilities.rawClassName;
import static net.zerobuilder.compiler.generate.Utilities.upcase;

final class DtoStep {

  private static final Set LIST_HIERARCHY
      = new HashSet<>(Arrays.asList(ClassNames.LIST, COLLECTION, ITERABLE));

  static final class EmptyOption {

    /**
     * Initializer for a variable of type {@link AbstractParameter#type}.
     * It evaluates to an empty List or Set.
     */
    final CodeBlock initializer;

    /**
     * Name of the convenience method to be generated, e.g. {@code "emptyFoo"}
     */
    final String name;

    private EmptyOption(CodeBlock initializer, String name) {
      this.initializer = initializer;
      this.name = name;
    }

    static Optional create(TypeName type, String name) {
      Optional maybeClassName = rawClassName(type);
      if (!maybeClassName.isPresent()) {
        return Optional.empty();
      }
      ClassName className = maybeClassName.get();
      if (LIST_HIERARCHY.contains(className)) {
        return Optional.of(new EmptyOption(
            CodeBlock.of("$T.emptyList()", Collections.class),
            emptyOptionName(name)));
      }
      if (SET.equals(className)) {
        return Optional.of(new EmptyOption(
            CodeBlock.of("$T.emptySet()", Collections.class),
            emptyOptionName(name)));
      }
      return Optional.empty();
    }

    private static String emptyOptionName(String name) {
      return "empty" + upcase(name);
    }
  }

  static abstract class AbstractStep {
    final ClassName thisType;
    final TypeName nextType;
    AbstractStep(ClassName thisType, TypeName nextType) {
      this.thisType = thisType;
      this.nextType = nextType;
    }
    abstract  R accept(StepCases cases);
  }

  interface StepCases {
    R regularStep(RegularStep step);
    R beanStep(AbstractBeanStep step);
  }

  static  Function asFunction(final StepCases cases) {
    return abstractStep -> abstractStep.accept(cases);
  }

  static  StepCases stepCases(final Function regularFunction,
                                    final Function beanFunction) {
    return new StepCases() {
      @Override
      public R regularStep(RegularStep step) {
        return regularFunction.apply(step);
      }
      @Override
      public R beanStep(AbstractBeanStep step) {
        return beanFunction.apply(step);
      }
    };
  }

  static final class RegularStep extends AbstractStep {
    final RegularParameter validParameter;
    final List declaredExceptions;

    private RegularStep(ClassName thisType, TypeName nextType, RegularParameter validParameter,
                        List declaredExceptions) {
      super(thisType, nextType);
      this.declaredExceptions = declaredExceptions;
      this.validParameter = validParameter;
    }

    static RegularStep create(ClassName thisType, TypeName nextType, RegularParameter parameter,
                              List declaredExceptions) {
      return new RegularStep(thisType, nextType, parameter, declaredExceptions);
    }

    Optional emptyOption() {
      return EmptyOption.create(validParameter.type, validParameter.name);
    }

    FieldSpec field() {
      return fieldSpec(validParameter.type, validParameter.name, PRIVATE);
    }

    @Override
     R accept(StepCases cases) {
      return cases.regularStep(this);
    }
  }

  static final Function abstractParameter
      = asFunction(new StepCases() {
    @Override
    public AbstractParameter regularStep(RegularStep step) {
      return step.validParameter;
    }
    @Override
    public AbstractParameter beanStep(AbstractBeanStep step) {
      return step.acceptBean(validBeanParameter);
    }
  });

  static final Function> declaredExceptions
      = asFunction(new StepCases>() {
    @Override
    public List regularStep(RegularStep step) {
      return step.declaredExceptions;
    }
    @Override
    public List beanStep(AbstractBeanStep step) {
      return Collections.emptyList();
    }
  });

  static  Function always(final Function parameterFunction) {
    return asFunction(new StepCases() {
      @Override
      public R regularStep(RegularStep step) {
        return parameterFunction.apply(step);
      }
      @Override
      public R beanStep(AbstractBeanStep step) {
        return parameterFunction.apply(step);
      }
    });
  }

  static final Function> emptyOption
      = asFunction(new StepCases>() {
    @Override
    public Optional regularStep(RegularStep step) {
      return step.emptyOption();
    }
    @Override
    public Optional beanStep(AbstractBeanStep step) {
      return step.acceptBean(DtoBeanStep.emptyOption);
    }
  });

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




© 2015 - 2024 Weber Informatics LLC | Privacy Policy