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

br.com.objectos.way.pojo.plugin.MethodBuilderProperty Maven / Gradle / Ivy

There is a newer version: 0.6.0
Show newest version
/*
 * Copyright 2014-2015 Objectos, Fábrica de Software LTDA.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package br.com.objectos.way.pojo.plugin;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import javax.lang.model.element.Modifier;

import br.com.objectos.way.code.Code;
import br.com.objectos.way.code.MethodInfo;
import br.com.objectos.way.code.SimpleTypeInfo;

import com.squareup.javapoet.AnnotationSpec;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;

/**
 * @author [email protected] (Marcio Endo)
 */
class MethodBuilderProperty
    extends BuilderProperty
    implements
    BuilderPropertyMethodBuilder,
    BuilderPropertyMethodBuilder.BuilderBody,
    BuilderPropertyMethodBuilder.BuilderParameter,
    BuilderPropertyMethodBuilder.BuilderName {

  private final Property property;

  private final List annotationSpecList = new ArrayList<>();
  private final CodeBlock.Builder body = CodeBlock.builder();
  private final List parameterSpecList = new ArrayList<>();
  private String name;
  private boolean varargs;

  MethodBuilderProperty(Property property) {
    this.property = property;
  }

  @Override
  public BuilderName addAnnotation(AnnotationSpec annotation) {
    Objects.requireNonNull(annotation);
    annotationSpecList.add(annotation);
    return this;
  }

  @Override
  public BuilderName addAnnotationIf(AnnotationSpec annotation, boolean condition) {
    return condition ? addAnnotation(annotation) : this;
  }

  @Override
  public BuilderParameter addParameter() {
    return addParameter(property.typeName(), property.name());
  }

  @Override
  public BuilderParameter addParameter(TypeName typeName) {
    return addParameter(typeName, property.name());
  }

  @Override
  public BuilderParameter addParameter(TypeName typeName, String name) {
    ParameterSpec parameter = ParameterSpec.builder(typeName, name).build();
    parameterSpecList.add(parameter);
    return this;
  }

  @Override
  public BuilderBody assignment() {
    body.addStatement("this.$L = $L", property.name(), property.name());
    return this;
  }

  @Override
  public BuilderBody assignment(String template, Object... args) {
    body.add("this.$L = ", property.name());
    body.add(template, args);
    body.add(";\n");
    return this;
  }

  @Override
  public BuilderBody beginControlFlow(String template, Object... args) {
    body.beginControlFlow(template, args);
    return this;
  }

  @Override
  public BuilderProperty build() {
    return this;
  }

  @Override
  public BuilderBody code(String template, Object... args) {
    body.add(template, args);
    return this;
  }

  @Override
  public BuilderBody endControlFlow() {
    body.endControlFlow();
    return this;
  }

  @Override
  public BuilderName name() {
    name = property.name();
    return this;
  }

  @Override
  public BuilderName nameSuffix(String suffix) {
    name = property.name() + suffix;
    return this;
  }

  @Override
  public BuilderBody nullCheck() {
    return nullCheck(property.name());
  }

  @Override
  public BuilderBody nullCheck(String variableName) {
    body.add(Code.nullCheck(variableName));
    return this;
  }

  @Override
  public BuilderBody nullCheckIfNecessary() {
    return nullCheckIfNecessary(property.name());
  }

  @Override
  public BuilderBody nullCheckIfNecessary(String variableName) {
    SimpleTypeInfo returnTypeInfo = methodInfo().returnTypeInfo();
    Optional maybeNull = Code.nullCheck(returnTypeInfo.typeName(), variableName);
    if (maybeNull.isPresent()) {
      body.add(maybeNull.get());
    }
    return this;
  }

  @Override
  public BuilderBody statement(String template, Object... args) {
    body.addStatement(template, args);
    return this;
  }

  @Override
  public BuilderBody varargs() {
    varargs = true;
    return this;
  }

  @Override
  void acceptBuilder(TypeSpec.Builder type) {
    type.addMethod(builderIfaceMethod());
  }

  @Override
  void acceptBuilderClass(TypeSpec.Builder type) {
    type.addMethod(builderClassSetter());
  }

  private MethodSpec builderClassSetter() {
    MethodSpec.Builder method = MethodSpec.methodBuilder(name)
        .addAnnotation(Override.class)
        .addModifiers(Modifier.PUBLIC)
        .returns(naming().builderInnerTypeName(methodInfo()))
        .addParameters(parameterSpecList)
        .varargs(varargs)
        .addCode(body
            .addStatement("return this")
            .build());
    return methodBuild(method);
  }

  private MethodSpec builderIfaceMethod() {
    MethodSpec.Builder method = MethodSpec.methodBuilder(name)
        .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
        .returns(naming().builderInnerTypeName(methodInfo()))
        .addParameters(parameterSpecList)
        .varargs(varargs);
    return methodBuild(method);
  }

  private MethodSpec methodBuild(MethodSpec.Builder method) {
    for (AnnotationSpec annotation : annotationSpecList) {
      method.addAnnotation(annotation);
    }
    return method.build();
  }

  private MethodInfo methodInfo() {
    return property.methodInfo();
  }

  private Naming naming() {
    return property.naming();
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy