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

br.com.objectos.way.sql.compiler.SqlColumn 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.way.sql.compiler;

import java.util.List;
import java.util.Set;

import br.com.objectos.way.code.AnnotationInfo;
import br.com.objectos.way.code.AnnotationInfoMap;
import br.com.objectos.way.code.AnnotationValueInfo;
import br.com.objectos.way.code.ClassInfo;
import br.com.objectos.way.code.ImportInfo;
import br.com.objectos.way.code.ImportInfoSet;
import br.com.objectos.way.code.MethodInfo;
import br.com.objectos.way.code.MethodInfoHasModifierInfo;
import br.com.objectos.way.code.MethodInfoHasParameterInfoListSize;
import br.com.objectos.way.code.MethodInfoHasReturnTypeInfo;
import br.com.objectos.way.code.ModifierInfo;
import br.com.objectos.way.code.SimpleTypeInfo;
import br.com.objectos.way.code.SimpleTypePrimitives;
import br.com.objectos.way.code.TypeInfo;
import br.com.objectos.way.code.WayCode;
import br.com.objectos.way.core.testing.Testable;
import br.com.objectos.way.core.testing.Testables;
import br.com.objectos.way.core.tmpl.mustache.IsMustacheSerializable;
import br.com.objectos.way.core.tmpl.mustache.MustacheObject;
import br.com.objectos.way.core.util.Size;
import br.com.objectos.way.core.util.WayIterable;
import br.com.objectos.way.core.util.WayIterables;
import br.com.objectos.way.sql.Column;
import br.com.objectos.way.sql.ForeignKey;
import br.com.objectos.way.sql.Generated;
import br.com.objectos.way.sql.GeneratedValue;
import br.com.objectos.way.sql.PrimaryKey;

import com.google.common.base.Function;
import com.google.common.base.Optional;

/**
 * @author [email protected] (Marcio Endo)
 */
class SqlColumn implements IsMustacheSerializable, Testable {

  private final MethodInfo methodInfo;
  private final AnnotationInfo columnAnnotation;
  private final List foreignKeyAnnotationList;

  private final int index;
  private final int size;

  SqlColumn(MethodInfo methodInfo,
            AnnotationInfo columnAnnotation,
            List foreignKeyAnnotationList,
            int index,
            int size) {
    this.methodInfo = methodInfo;
    this.columnAnnotation = columnAnnotation;
    this.foreignKeyAnnotationList = foreignKeyAnnotationList;
    this.index = index;
    this.size = size;
  }

  public static List columnListOf(ClassInfo classInfo) {
    return columnListOf(classInfo.getMethodInfoIterable());
  }

  public static List columnListOf(TypeInfo typeInfo) {
    return columnListOf(typeInfo.getMethodInfoIterable());
  }

  public static SqlColumn of(MethodInfo methodInfo, int index, int size) {
    AnnotationInfoMap annotationInfoMap = methodInfo.annotationInfoMap();
    AnnotationInfo columnAnnotation = annotationInfoMap.getFirstAnnotatedWith(Column.class).get();
    List foreignKeyAnnotationList = annotationInfoMap.getAnnotatedWith(ForeignKey.class);
    return new SqlColumn(methodInfo, columnAnnotation, foreignKeyAnnotationList, index, size);
  }

  private static List columnListOf(WayIterable methodIter) {
    final Size size = WayIterables.newSize();
    return methodIter
        .filter(MethodInfoHasModifierInfo.get(ModifierInfo.ABSTRACT))
        .filter(MethodInfoHasReturnTypeInfo.not(SimpleTypePrimitives.VOID))
        .filter(MethodInfoHasParameterInfoListSize.get(0))
        .filter(MethodInfoIsColumn.get())
        .toListAndSize(size)
        .transform(new Function() {

          int index = 0;

          @Override
          public SqlColumn apply(MethodInfo input) {
            return SqlColumn.of(input, index++, size.get());
          }

        })
        .toImmutableList();
  }

  public AnnotationInfo getAnnotationInfo() {
    return columnAnnotation;
  }

  public Optional getForeignKey() {
    SimpleTypeInfo returnTypeInfo = methodInfo.returnTypeInfo();
    Optional maybeTypeInfo = returnTypeInfo.getTypeInfo();

    if (!maybeTypeInfo.isPresent()) {
      return Optional.absent();
    }

    Optional maybeClassInfo = maybeTypeInfo.get().toClassInfo();
    if (maybeClassInfo.isPresent()) {
      Optional maybeForeignKey = toForeignKey(maybeClassInfo.get());
      return maybeForeignKey;
    }

    return Optional.absent();
  }

  public String getKeyName() {
    String keyName = methodInfo.getFieldName();

    SimpleTypeInfo returnTypeInfo = methodInfo.returnTypeInfo();
    if (returnTypeInfo.isInfoOf(Generated.class)) {
      keyName = keyName + ".get()";
    }

    return keyName;
  }

  public String getSqlParameter() {
    SimpleTypeInfo returnTypeInfo = methodInfo.returnTypeInfo();
    return SqlParameter.mustacheString(returnTypeInfo);
  }

  @Override
  public boolean isEqual(SqlColumn that) {
    return Testables.isEqualHelper()
        .equal(methodInfo, that.methodInfo)
        .equal(columnAnnotation, that.columnAnnotation)
        .equal(foreignKeyAnnotationList, that.foreignKeyAnnotationList)
        .equal(index, that.index)
        .equal(size, that.size)
        .result();
  }

  public boolean isGeneratedValue() {
    AnnotationInfoMap annotationInfoMap = methodInfo.annotationInfoMap();
    Optional maybe = annotationInfoMap.getFirstAnnotatedWith(GeneratedValue.class);
    return maybe.isPresent();
  }

  public boolean isPrimaryKey() {
    AnnotationInfoMap annotationInfoMap = methodInfo.annotationInfoMap();
    Optional maybe = annotationInfoMap.getFirstAnnotatedWith(PrimaryKey.class);
    return maybe.isPresent();
  }

  public boolean references(SqlColumn sqlColumn) {
    AnnotationInfo thatAnnotation = sqlColumn.columnAnnotation;
    AnnotationInfo thatColumn = thatAnnotation.annotationInfoMap().get(Column.class).get();
    List thatValueList = thatColumn.annotationValueInfoList();

    for (AnnotationInfo annotation : foreignKeyAnnotationList) {
      AnnotationInfo fkAnnotation = annotation.annotationInfoMap().get(ForeignKey.class).get();
      List columnList = fkAnnotation.getAnnotationArray("value").get();
      for (AnnotationInfo column : columnList) {
        List thisValueList = column.annotationValueInfoList();
        if (thisValueList.equals(thatValueList)) {
          return true;
        }
      }
    }

    return false;
  }

  public Optional toForeignKey(ClassInfo classInfo) {
    SqlColumn fk = null;

    List columnList = SqlColumn.columnListOf(classInfo);
    for (SqlColumn sqlColumn : columnList) {
      if (references(sqlColumn)) {
        fk = sqlColumn;
        break;
      }
    }

    return Optional.fromNullable(fk);
  }

  @Override
  public MustacheObject toMustache() {
    boolean first = index == 0;
    boolean last = index + 1 == size;
    boolean middle = !first && !last;

    return columnAnnotation.toMustacheHelper()
        .add("first", first)
        .add("last", last)
        .add("middle", middle)

        .add("binder", binder())
        .add("declaration", declaration())
        .add("primaryKey", columnAnnotation.hasAnnotation(PrimaryKey.class))
        .add("parameter", parameter())
        .toMustache();
  }

  public PkField toPkField() {
    SimpleTypeInfo returnTypeInfo = methodInfo.returnTypeInfo();
    return new PkField(returnTypeInfo.getDeclaredName(), methodInfo.getFieldName());
  }

  public PojoMethod toPojoMethod() {
    return PojoMethod.wrap(this);
  }

  public QueryColumn toQueryColumn(ClassInfo classInfo) {
    return new QueryColumn(this, classInfo);
  }

  public void addTo(ImportInfoSet importInfoSet) {
    Set thisSet = methodInfo.toImportInfoSet();
    importInfoSet.addAll(thisSet);
  }

  String binder() {
    return binder(methodInfo.getFieldName());
  }

  String binder(String varName) {
    SimpleTypeInfo returnTypeInfo = methodInfo.returnTypeInfo();
    SimpleTypeInfo autobox = returnTypeInfo.autobox();
    return WayCode.lowerCaseFirstChar(autobox.getSimpleName()) + "(" + varName + ")";
  }

  MethodInfo methodInfo() {
    return methodInfo;
  }

  private String declaration() {
    SimpleTypeInfo returnTypeInfo = methodInfo.returnTypeInfo();
    return returnTypeInfo.getSimpleName() + " " + methodInfo.getFieldName();
  }

  private String parameter() {
    SimpleTypeInfo returnTypeInfo = methodInfo.returnTypeInfo();
    return SqlParameter.mustacheString(returnTypeInfo);
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy