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

br.com.objectos.code.pojo.LazyMethod Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 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.code.pojo;

import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

import javax.lang.model.element.Modifier;

import br.com.objectos.code.AccessInfo;
import br.com.objectos.code.MethodInfo;
import br.com.objectos.code.ModifierInfo;
import br.com.objectos.core.auto.AutoPojo;
import br.com.objectos.core.util.MoreCollectors;
import br.com.objectos.lazy.annotation.Lazy;

import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;

/**
 * @author [email protected] (Marcio Endo)
 */
@AutoPojo
abstract class LazyMethod implements CanBeInvalidated {

  abstract Naming naming();

  abstract AccessInfo accessInfo();
  abstract TypeName returnTypeName();
  abstract String name();
  @Override
  public abstract String fieldName();

  LazyMethod() {
  }

  public static List of(Naming naming, Stream methodInfoStream) {
    return methodInfoStream
        .filter(m -> m.hasAnnotation(Lazy.class))
        .map(m -> LazyMethod.of(naming, m))
        .filter(Optional::isPresent)
        .map(Optional::get)
        .collect(MoreCollectors.toImmutableList());
  }

  private static LazyMethodBuilder builder() {
    return new LazyMethodBuilderPojo();
  }

  private static Optional of(Naming naming, MethodInfo methodInfo) {
    if (methodInfo.hasModifierInfo(ModifierInfo.ABSTRACT)) {
      methodInfo.compilationError("@Lazy methods cannot be abstract.");
      return Optional.empty();
    }

    if (methodInfo.hasAccessInfo(AccessInfo.PRIVATE)) {
      methodInfo.compilationError("@Lazy methods cannot be private.");
      return Optional.empty();
    }

    if (!methodInfo.hasParameterInfoListSize(0)) {
      methodInfo.compilationError("@Lazy methods cannot have parameters.");
      return Optional.empty();
    }

    LazyMethod lazyMethod = LazyMethod.builder()
        .naming(naming)
        .accessInfo(methodInfo.accessInfo())
        .returnTypeName(methodInfo.returnTypeInfo().typeName())
        .name(methodInfo.name())
        .fieldName(methodInfo.fieldName())
        .build();
    return Optional.of(lazyMethod);
  }

  public FieldSpec pojoClassField() {
    return FieldSpec.builder(lazyTypeName(), fieldName())
        .addModifiers(Modifier.PRIVATE, Modifier.FINAL)
        .initializer("new $T()", lazyClassName())
        .build();
  }

  public TypeSpec pojoClassInnerClass() {
    return TypeSpec.classBuilder(lazyClassName().simpleName())
        .addModifiers(Modifier.PRIVATE)
        .superclass(lazyTypeName())
        .addMethod(MethodSpec.methodBuilder("compute")
            .addAnnotation(Override.class)
            .addModifiers(Modifier.PROTECTED)
            .returns(returnTypeName())
            .addStatement("return $T.super.$L()", naming().pojo(), name())
            .build())
        .build();
  }

  public MethodSpec pojoClassMethod() {
    return MethodSpec.methodBuilder(name())
        .addAnnotation(Override.class)
        .addModifiers(accessInfo().modifiers())
        .returns(returnTypeName())
        .addStatement("return $L.get()", fieldName())
        .build();
  }

  private ClassName lazyClassName() {
    return naming().lazyClassName(fieldName());
  }

  private ParameterizedTypeName lazyTypeName() {
    ClassName lazy = ClassName.get(br.com.objectos.lazy.Lazy.class);
    return ParameterizedTypeName.get(lazy, returnTypeName());
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy