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

br.com.objectos.css.PropertyMethod Maven / Gradle / Ivy

There is a newer version: 0.3.0
Show newest version
/*
 * Copyright 2016 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.css;

import java.util.List;
import java.util.Optional;

import br.com.objectos.code.MethodInfo;
import br.com.objectos.code.ParameterInfo;
import br.com.objectos.code.SimpleTypeInfo;
import br.com.objectos.core.util.ImmutableList;
import br.com.objectos.css.boot.Property;

import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.CodeBlock.Builder;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;

/**
 * @author [email protected] (Marcio Endo)
 */
abstract class PropertyMethod {

  final String property;
  final MethodInfo methodInfo;

  public PropertyMethod(MethodInfo methodInfo) {
    String property = methodInfo.annotationInfo(Property.class)
        .flatMap(ann -> ann.stringValue("name"))
        .get();
    this.property = "".equals(property)
        ? Naming.methodNameToProperty(methodInfo.name())
        : property;

    this.methodInfo = methodInfo;
  }

  public static PropertyMethod of(MethodInfo methodInfo) {
    Optional enumType = Optional.empty();

    boolean skipEnum = methodInfo.annotationInfo(Property.class)
        .get()
        .booleanValue("skipEnum", false);

    if (methodInfo.hasParameterInfoListSize(1) && !skipEnum) {
      enumType = methodInfo.parameterInfoStream()
          .map(ParameterInfo::simpleTypeInfo)
          .filter(SimpleTypeInfo::isEnum)
          .findFirst()
          .map(CssEnumType::of);
    }

    return enumType.isPresent()
        ? new Enum(methodInfo, enumType.get())
        : new Standard(methodInfo);
  }

  public void accept(TypeSpec.Builder type) {
    type.addMethod(mainMethod());
    type.addMethods(auxMethodList(Naming.RuleSetBuilder));
    type.addTypes(auxTypeList());
  }

  public abstract List auxMethodList(ClassName outer);

  public abstract List auxTypeList();

  public MethodSpec mainMethod() {
    return methodInfo.overrideWriter()
        .returns(Naming.SELF)
        .addCode(mainMethodBody())
        .write();
  }

  private CodeBlock mainMethodBody() {
    Builder body = CodeBlock.builder()
        .add("return addDeclaration($S", property);

    methodInfo.parameterInfoStream()
        .forEach(param -> {
          String name = param.name();
          SimpleTypeInfo simpleTypeInfo = param.simpleTypeInfo();
          if (simpleTypeInfo.isEnum()) {
            body.add(", $L.stringValue()", name);
          } else {
            body.add(", $L", name);
          }
        });

    return body
        .addStatement(")")
        .build();
  }

  private static class Enum extends PropertyMethod {

    private final CssEnumType enumType;

    public Enum(MethodInfo methodInfo, CssEnumType enumType) {
      super(methodInfo);
      this.enumType = enumType;
    }

    @Override
    public List auxMethodList(ClassName outer) {
      MethodSpec auxMethod = enumType.auxMethod(outer, methodInfo.name());
      return ImmutableList.of(auxMethod);
    }

    @Override
    public List auxTypeList() {
      TypeSpec auxType = enumType.auxType(methodInfo.name());
      return ImmutableList.of(auxType);
    }

  }

  private static class Standard extends PropertyMethod {

    public Standard(MethodInfo methodInfo) {
      super(methodInfo);
    }

    @Override
    public List auxMethodList(ClassName outer) {
      return ImmutableList.of();
    }

    @Override
    public List auxTypeList() {
      return ImmutableList.of();
    }

  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy