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

br.com.objectos.sql.code.ColumnCode Maven / Gradle / Ivy

/*
 * 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.sql.code;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.List;

import javax.lang.model.element.Modifier;

import br.com.objectos.sql.core.ColumnInfo;
import br.com.objectos.sql.core.ColumnType;
import br.com.objectos.sql.core.GeneratedValue;
import br.com.objectos.sql.core.ReferencedColumnInfo;
import br.com.objectos.sql.core.ReferencedColumnInfoColumnInfoAnnotationSpec;
import br.com.objectos.sql.core.TableInfo;
import br.com.objectos.sql.core.TableName;
import br.com.objectos.sql.core.annotation.Column;
import br.com.objectos.sql.core.annotation.ForeignKey;
import br.com.objectos.sql.core.annotation.PrimaryKey;
import br.com.objectos.sql.core.query.ComparisonOperator;
import br.com.objectos.sql.core.query.SortOrder;
import br.com.objectos.way.core.auto.AutoFunctional;
import br.com.objectos.way.core.util.WayIterables;

import com.squareup.javapoet.AnnotationSpec;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;

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

  private final String identifier;
  private final ClassName innerClassName;
  private final ColumnInfo columnInfo;

  private ColumnCode(String identifier, ClassName innerClassName, ColumnInfo columnInfo) {
    this.identifier = identifier;
    this.innerClassName = innerClassName;
    this.columnInfo = columnInfo;
  }

  public static ColumnCode code(ClassName tableClassName, ColumnInfo columnInfo) {
    TableName tableName = columnInfo.tableName();
    String identifier = columnInfo.identifier();
    String name = tableName.name() + "_" + columnInfo.name();
    ClassName innerClassName = tableClassName.nestedClass(name);
    return new ColumnCode(identifier, innerClassName, columnInfo);
  }

  @AutoFunctional
  public TypeSpec annotation() {
    TypeSpec.Builder annotation = TypeSpec.annotationBuilder(identifier)
        .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
        .addAnnotation(retentionSource())
        .addAnnotation(targetMethodParameter())
        .addAnnotation(columnAnnotation());

    if (columnInfo.primaryKey()) {
      annotation.addAnnotation(PrimaryKey.class);
    }

    if (columnInfo.autoIncrement()) {
      annotation.addAnnotation(GeneratedValue.class);
    }

    List referencedColumnInfoList = columnInfo.referencedColumnInfoList();
    if (!referencedColumnInfoList.isEmpty()) {
      annotation.addAnnotation(foreignKeyAnnotationSpec(referencedColumnInfoList));
    }

    return annotation
        .addMethod(comparisonMethod())
        .addMethod(orderByMethod())
        .build();
  }

  @AutoFunctional
  public FieldSpec field() {
    String name = innerClassName.simpleName();
    return FieldSpec.builder(innerClassName, name)
        .addModifiers(Modifier.PRIVATE, Modifier.FINAL)
        .initializer("new $T()", innerClassName)
        .build();
  }

  @AutoFunctional
  public TypeSpec inner() {
    MethodSpec privateConstructor = MethodSpec.constructorBuilder()
        .addModifiers(Modifier.PRIVATE)
        .build();

    MethodSpec tableInfoMethod = MethodSpec.methodBuilder("tableInfo")
        .addAnnotation(Override.class)
        .addModifiers(Modifier.PROTECTED)
        .returns(TableInfo.class)
        .addStatement("return TABLE")
        .build();

    MethodSpec columnInfoMethod = MethodSpec.methodBuilder("columnInfo")
        .addAnnotation(Override.class)
        .addModifiers(Modifier.PROTECTED)
        .returns(columnInfo.columnInfoType())
        .addStatement("return COLUMN_INFO_MAP.get$L(\"$L\")", columnInfo.typeName(), columnInfo.name())
        .build();

    return TypeSpec.classBuilder(innerClassName.simpleName())
        .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
        .superclass(columnInfo.qualifiedColumnInfoType())
        .addMethod(privateConstructor)
        .addMethod(tableInfoMethod)
        .addMethod(columnInfoMethod)
        .build();
  }

  @AutoFunctional
  public MethodSpec method() {
    String name = innerClassName.simpleName();
    return MethodSpec.methodBuilder(identifier)
        .addModifiers(Modifier.PUBLIC)
        .returns(innerClassName)
        .addStatement("return $L", name)
        .build();
  }

  private AnnotationSpec columnAnnotation() {
    TableName tableName = columnInfo.tableName();
    String name = columnInfo.name();
    ColumnType columnType = columnInfo.columnType();
    return AnnotationSpec.builder(Column.class)
        .addMember("schema", "$S", tableName.schemaName())
        .addMember("table", "$S", tableName.name())
        .addMember("name", "$S", name)
        .addMember("identifier", "$S", identifier)
        .addMember("type", "$T.$L", ColumnType.class, columnType)
        .build();
  }

  private MethodSpec comparisonMethod() {
    return MethodSpec.methodBuilder("comparison")
        .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
        .returns(ComparisonOperator.class)
        .defaultValue("$T.$L", ComparisonOperator.class, ComparisonOperator.EQ)
        .build();
  }

  private AnnotationSpec foreignKeyAnnotationSpec(List referencedColumnInfoList) {
    List columnList = WayIterables.from(referencedColumnInfoList)
        .transform(ReferencedColumnInfoColumnInfoAnnotationSpec.get())
        .toImmutableList();
    AnnotationSpec.Builder foreignKey = AnnotationSpec.builder(ForeignKey.class);

    for (AnnotationSpec column : columnList) {
      foreignKey.addMember("value", "$L", column);
    }

    return foreignKey.build();
  }

  private MethodSpec orderByMethod() {
    return MethodSpec.methodBuilder("orderBy")
        .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
        .returns(SortOrder.class)
        .defaultValue("$T.$L", SortOrder.class, SortOrder.ASC)
        .build();
  }

  private AnnotationSpec retentionSource() {
    return AnnotationSpec.builder(Retention.class)
        .addMember("value", "$T.$L", RetentionPolicy.class, RetentionPolicy.SOURCE)
        .build();
  }

  private AnnotationSpec targetMethodParameter() {
    return AnnotationSpec.builder(Target.class)
        .addMember("value", "{ $T.$L, $T.$L }",
            ElementType.class, ElementType.METHOD, ElementType.class, ElementType.PARAMETER)
        .build();
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy