info.archinnov.achilles.internals.codegen.meta.EntityMetaCodeGen.java Source code

Java tutorial

Introduction

Here is the source code for info.archinnov.achilles.internals.codegen.meta.EntityMetaCodeGen.java

Source

/*
 * Copyright (C) 2012-2016 DuyHai DOAN
 *
 * 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 info.archinnov.achilles.internals.codegen.meta;

import static com.squareup.javapoet.TypeName.BOOLEAN;
import static com.squareup.javapoet.TypeName.INT;
import static info.archinnov.achilles.internals.parser.TypeUtils.getRawType;
import static info.archinnov.achilles.internals.metamodel.columns.ColumnType.*;
import static info.archinnov.achilles.internals.parser.TypeUtils.*;
import static info.archinnov.achilles.internals.parser.validator.BeanValidator.*;
import static info.archinnov.achilles.internals.parser.validator.FieldValidator.validateCorrectKeysOrder;
import static info.archinnov.achilles.internals.strategy.naming.InternalNamingStrategy.inferNamingStrategy;
import static info.archinnov.achilles.internals.utils.NamingHelper.upperCaseFirst;
import static java.util.stream.Collectors.toList;
import static org.apache.commons.lang3.StringUtils.isBlank;

import java.util.*;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;

import org.apache.commons.lang3.StringUtils;

import com.datastax.driver.core.ConsistencyLevel;
import com.datastax.driver.core.Row;
import com.squareup.javapoet.*;

import info.archinnov.achilles.annotations.*;
import info.archinnov.achilles.internals.apt.AptUtils;
import info.archinnov.achilles.internals.metamodel.AbstractEntityProperty.EntityType;
import info.archinnov.achilles.internals.metamodel.columns.*;
import info.archinnov.achilles.internals.parser.AnnotationTree;
import info.archinnov.achilles.internals.parser.FieldParser.FieldMetaSignature;
import info.archinnov.achilles.internals.parser.context.GlobalParsingContext;
import info.archinnov.achilles.internals.parser.validator.BeanValidator;
import info.archinnov.achilles.internals.strategy.naming.InternalNamingStrategy;
import info.archinnov.achilles.type.tuples.Tuple2;

public class EntityMetaCodeGen extends AbstractBeanMetaCodeGen {

    public static final Comparator<Tuple2<String, PartitionKeyInfo>> PARTITION_KEY_SORTER = (o1,
            o2) -> o1._2().order.compareTo(o2._2().order);
    public static final Comparator<Tuple2<String, ClusteringColumnInfo>> CLUSTERING_COLUMN_SORTER = (o1,
            o2) -> o1._2().order.compareTo(o2._2().order);
    public static final Comparator<Tuple2<String, String>> BY_CQL_NAME_COLUMN_SORTER = (o1, o2) -> o1._1()
            .compareTo(o2._1());
    private final AptUtils aptUtils;

    public EntityMetaCodeGen(AptUtils aptUtils) {
        this.aptUtils = aptUtils;
    }

    public EntityMetaSignature buildEntityMeta(EntityType entityType, TypeElement elm,
            GlobalParsingContext globalParsingContext, List<FieldMetaSignature> fieldMetaSignatures) {
        final TypeName rawClassTypeName = getRawType(TypeName.get(elm.asType()));
        final Optional<Consistency> consistency = aptUtils.getAnnotationOnClass(elm, Consistency.class);
        final Optional<TTL> ttl = aptUtils.getAnnotationOnClass(elm, TTL.class);
        final Optional<Strategy> strategy = aptUtils.getAnnotationOnClass(elm, Strategy.class);
        final Optional<Table> entityAnnot = aptUtils.getAnnotationOnClass(elm, Table.class);

        final Optional<TypeName> viewBaseClass = AnnotationTree.findOptionalViewBaseClass(aptUtils, elm);

        aptUtils.validateFalse(entityAnnot.isPresent() && viewBaseClass.isPresent(),
                "Cannot have both @Table and @MaterializedView on the class '%s'", rawClassTypeName);

        if (entityType == EntityType.VIEW) {
            aptUtils.validateTrue(viewBaseClass.isPresent(),
                    "Missing @MaterializedView annotation on entity class '%s'", rawClassTypeName);
        }

        validateIsAConcreteNonFinalClass(aptUtils, elm);
        validateHasPublicConstructor(aptUtils, rawClassTypeName, elm);
        validateNoDuplicateNames(aptUtils, rawClassTypeName, fieldMetaSignatures);
        validateHasPartitionKey(aptUtils, rawClassTypeName, fieldMetaSignatures);

        final boolean isCounter = BeanValidator.isCounterTable(aptUtils, rawClassTypeName, fieldMetaSignatures);

        if (entityType == EntityType.TABLE) {
            validateStaticColumns(aptUtils, rawClassTypeName, fieldMetaSignatures);
        } else if (entityType == EntityType.VIEW) {
            validateNoStaticColumnsForView(aptUtils, rawClassTypeName, fieldMetaSignatures);
            aptUtils.validateFalse(isCounter,
                    "The class '%s' cannot have counter columns because it is a materialized view",
                    rawClassTypeName);
        }

        validateComputed(aptUtils, rawClassTypeName, fieldMetaSignatures);
        validateCqlColumnNotReservedWords(aptUtils, rawClassTypeName, fieldMetaSignatures);

        validateCorrectKeysOrder(aptUtils, rawClassTypeName,
                fieldMetaSignatures.stream().filter(x -> x.context.columnType == ColumnType.PARTITION)
                        .map(x -> Tuple2.of(x.context.fieldName, (KeyColumnInfo) x.context.columnInfo))
                        .collect(toList()),
                "@PartitionKey");

        validateCorrectKeysOrder(aptUtils, rawClassTypeName,
                fieldMetaSignatures.stream().filter(x -> x.context.columnType == CLUSTERING)
                        .map(x -> Tuple2.of(x.context.fieldName, (KeyColumnInfo) x.context.columnInfo))
                        .collect(toList()),
                "@ClusteringColumn");

        final TypeName rawBeanType = TypeName.get(aptUtils.erasure(elm));

        final String className = elm.getSimpleName() + META_SUFFIX;
        final TypeName typeName = ClassName.get(ENTITY_META_PACKAGE, className);

        final TypeSpec.Builder builder = TypeSpec.classBuilder(className)
                .addJavadoc("Meta class of all entities of type $T<br/>\n", rawBeanType)
                .addJavadoc("The meta class is responsible for<br/>\n").addJavadoc("<ul>\n")
                .addJavadoc("   <li>determining runtime consistency levels (read/write,serial)<li/>\n");

        if (entityType == EntityType.TABLE) {
            builder.addJavadoc("   <li>determining runtime insert strategy<li/>\n");
        }

        builder.addJavadoc("   <li>trigger event interceptors (if any)<li/>\n")
                .addJavadoc("   <li>map a $T back to an instance of $T<li/>\n", ClassName.get(Row.class),
                        rawBeanType)
                .addJavadoc(
                        "   <li>determine runtime keyspace name using static annotations and runtime SchemaNameProvider (if any)<li/>\n")
                .addJavadoc(
                        "   <li>determine runtime table name using static annotations and runtime SchemaNameProvider (if any)<li/>\n")
                .addJavadoc("   <li>generate schema during bootstrap<li/>\n")
                .addJavadoc("   <li>validate schema during bootstrap<li/>\n")
                .addJavadoc(
                        "   <li>expose all property meta classes for encoding/decoding purpose on unitary columns<li/>\n")
                .addJavadoc("<ul/>\n");

        builder.addAnnotation(ACHILLES_META_ANNOT).addModifiers(Modifier.PUBLIC, Modifier.FINAL)
                .addMethod(buildEntityClass(rawClassTypeName))
                .addMethod(buildDerivedTableName(elm, globalParsingContext.namingStrategy))
                .addMethod(buildFieldNameToCqlColumn(fieldMetaSignatures))
                .addMethod(buildGetStaticReadConsistency(consistency))
                .addMethod(buildGetStaticNamingStrategy(strategy))
                .addMethod(buildPartitionKeys(fieldMetaSignatures, rawBeanType))
                .addMethod(buildClusteringColumns(fieldMetaSignatures, rawBeanType))
                .addMethod(buildNormalColumns(fieldMetaSignatures, rawBeanType))
                .addMethod(buildComputedColumns(fieldMetaSignatures, rawBeanType));

        if (entityType == EntityType.TABLE) {
            builder.superclass(genericType(ABSTRACT_ENTITY_PROPERTY, rawBeanType))
                    .addMethod(buildIsCounterTable(isCounter))
                    .addMethod(
                            buildStaticKeyspace(aptUtils.getAnnotationOnClass(elm, Table.class).get().keyspace()))
                    .addMethod(buildStaticTableOrViewName(
                            aptUtils.getAnnotationOnClass(elm, Table.class).get().table()))
                    .addMethod(buildGetStaticWriteConsistency(consistency))
                    .addMethod(buildGetStaticSerialConsistency(consistency)).addMethod(buildGetStaticTTL(ttl))
                    .addMethod(buildGetStaticInsertStrategy(strategy))
                    .addMethod(buildStaticColumns(fieldMetaSignatures, rawBeanType))
                    .addMethod(buildCounterColumns(fieldMetaSignatures, rawBeanType));
        } else if (entityType == EntityType.VIEW) {
            builder.superclass(genericType(ABSTRACT_VIEW_PROPERTY, rawBeanType))
                    .addMethod(buildStaticKeyspace(
                            aptUtils.getAnnotationOnClass(elm, MaterializedView.class).get().keyspace()))
                    .addMethod(buildStaticTableOrViewName(
                            aptUtils.getAnnotationOnClass(elm, MaterializedView.class).get().view()))
                    .addMethod(buildGetBaseEntityClass(viewBaseClass.get()));
        }

        for (FieldMetaSignature x : fieldMetaSignatures) {
            builder.addField(x.buildPropertyAsField());
        }

        // Build public static final xxx_AchillesMeta.ColumnsForFunctions COLUMNS = new xxx_AchillesMeta.ColumnsForFunctions();
        builder.addType(
                EntityMetaColumnsForFunctionsCodeGen.createColumnsClassForFunctionParam(fieldMetaSignatures))
                .addField(buildColumnsField(className));

        return new EntityMetaSignature(entityType, builder.build(), elm.getSimpleName().toString(), typeName,
                rawBeanType, viewBaseClass, fieldMetaSignatures);
    }

    private MethodSpec buildFieldNameToCqlColumn(List<FieldMetaSignature> parsingResults) {
        final MethodSpec.Builder builder = MethodSpec.methodBuilder("fieldNameToCqlColumn")
                .addAnnotation(Override.class).addModifiers(Modifier.PROTECTED)
                .returns(genericType(BIMAP, STRING, STRING)).addStatement("$T<$T,$T> map = $T.create($L)", BIMAP,
                        STRING, STRING, HASHBIMAP, parsingResults.size());

        parsingResults.stream().map(x -> Tuple2.of(x.context.fieldName, x.context.cqlColumn))
                .forEach(x -> builder.addStatement("map.put($S, $S)", x._1(), x._2()));

        builder.addStatement("return map");
        return builder.build();
    }

    private MethodSpec buildEntityClass(TypeName rawClassTypeName) {
        return MethodSpec.methodBuilder("getEntityClass").addAnnotation(Override.class)
                .addModifiers(Modifier.PROTECTED).returns(classTypeOf(rawClassTypeName))
                .addStatement("return $T.class", rawClassTypeName).build();
    }

    private MethodSpec buildStaticKeyspace(String staticValue) {

        final Optional<String> keyspace = Optional.ofNullable(isBlank(staticValue) ? null : staticValue);

        final MethodSpec.Builder builder = MethodSpec.methodBuilder("getStaticKeyspace")
                .addAnnotation(Override.class).addModifiers(Modifier.PROTECTED)
                .returns(genericType(OPTIONAL, STRING));

        if (keyspace.isPresent()) {
            return builder.addStatement("return $T.of($S)", OPTIONAL, keyspace.get()).build();
        } else {
            return emptyOption(builder);
        }
    }

    private MethodSpec buildDerivedTableName(TypeElement elm, InternalNamingStrategy defaultStrategy) {
        final Optional<Strategy> strategy = aptUtils.getAnnotationOnClass(elm, Strategy.class);

        final String tableName = inferNamingStrategy(strategy, defaultStrategy)
                .apply(elm.getSimpleName().toString());

        return MethodSpec.methodBuilder("getDerivedTableOrViewName").addAnnotation(Override.class)
                .addModifiers(Modifier.PROTECTED).returns(String.class).addStatement("return $S", tableName)
                .build();

    }

    private MethodSpec buildStaticTableOrViewName(String staticValue) {
        final MethodSpec.Builder builder = MethodSpec.methodBuilder("getStaticTableOrViewName")
                .addAnnotation(Override.class).addModifiers(Modifier.PROTECTED)
                .returns(genericType(OPTIONAL, STRING));
        final Optional<String> tableName = Optional
                .ofNullable(StringUtils.isBlank(staticValue) ? null : staticValue);

        if (tableName.isPresent()) {
            return builder.addStatement("return $T.of($S)", OPTIONAL, tableName.get()).build();
        } else {
            return emptyOption(builder);
        }
    }

    private MethodSpec buildPartitionKeys(List<FieldMetaSignature> parsingResults, TypeName rawClassType) {
        StringJoiner joiner = new StringJoiner(",");
        parsingResults.stream().filter(x -> x.context.columnType == ColumnType.PARTITION)
                .map(x -> Tuple2.of(x.context.fieldName, (PartitionKeyInfo) x.context.columnInfo))
                .sorted(PARTITION_KEY_SORTER).map(x -> x._1()).forEach(x -> joiner.add(x));

        return MethodSpec.methodBuilder("getPartitionKeys").addAnnotation(Override.class)
                .addModifiers(Modifier.PROTECTED).returns(propertyListType(rawClassType))
                .addStatement("return $T.asList($L)", ARRAYS, joiner.toString()).build();
    }

    private MethodSpec buildClusteringColumns(List<FieldMetaSignature> parsingResults, TypeName rawClassType) {
        StringJoiner joiner = new StringJoiner(",");
        parsingResults.stream().filter(x -> x.context.columnType == CLUSTERING)
                .map(x -> Tuple2.of(x.context.fieldName, (ClusteringColumnInfo) x.context.columnInfo))
                .sorted(CLUSTERING_COLUMN_SORTER).map(x -> x._1()).forEach(x -> joiner.add(x));

        return MethodSpec.methodBuilder("getClusteringColumns").addAnnotation(Override.class)
                .addModifiers(Modifier.PROTECTED).returns(propertyListType(rawClassType))
                .addStatement("return $T.asList($L)", ARRAYS, joiner.toString()).build();
    }

    private MethodSpec buildStaticColumns(List<FieldMetaSignature> parsingResults, TypeName rawClassType) {
        StringJoiner joiner = new StringJoiner(",");
        parsingResults.stream()
                .filter(x -> (x.context.columnType == ColumnType.STATIC
                        || x.context.columnType == ColumnType.STATIC_COUNTER))
                .map(x -> Tuple2.of(x.context.cqlColumn, x.context.fieldName)).sorted(BY_CQL_NAME_COLUMN_SORTER)
                .map(x -> x._2()).forEach(x -> joiner.add(x));

        return MethodSpec.methodBuilder("getStaticColumns").addAnnotation(Override.class)
                .addModifiers(Modifier.PROTECTED).returns(propertyListType(rawClassType))
                .addStatement("return $T.asList($L)", ARRAYS, joiner.toString()).build();
    }

    private MethodSpec buildComputedColumns(List<FieldMetaSignature> parsingResults, TypeName rawClassType) {
        StringJoiner joiner = new StringJoiner(",");
        parsingResults.stream().filter(x -> x.context.columnType == ColumnType.COMPUTED)
                .map(x -> Tuple2.of(((ComputedColumnInfo) x.context.columnInfo).alias, x.context.fieldName))
                .sorted(BY_CQL_NAME_COLUMN_SORTER).map(x -> x._2()).forEach(x -> joiner.add(x));

        return MethodSpec.methodBuilder("getComputedColumns").addAnnotation(Override.class)
                .addModifiers(Modifier.PROTECTED).returns(propertyListType(rawClassType))
                .addStatement("return $T.asList($L)", ARRAYS, joiner.toString()).build();
    }

    private MethodSpec buildCounterColumns(List<FieldMetaSignature> parsingResults, TypeName rawClassType) {
        StringJoiner joiner = new StringJoiner(",");
        parsingResults.stream().filter(x -> x.context.columnType == COUNTER)
                .map(x -> Tuple2.of(x.context.cqlColumn, x.context.fieldName)).sorted(BY_CQL_NAME_COLUMN_SORTER)
                .map(x -> x._2()).forEach(x -> joiner.add(x));

        return MethodSpec.methodBuilder("getCounterColumns").addAnnotation(Override.class)
                .addModifiers(Modifier.PROTECTED).returns(propertyListType(rawClassType))
                .addStatement("return $T.asList($L)", ARRAYS, joiner.toString()).build();
    }

    private MethodSpec buildNormalColumns(List<FieldMetaSignature> parsingResults, TypeName rawClassType) {
        StringJoiner joiner = new StringJoiner(",");
        parsingResults.stream().filter(x -> x.context.columnType == ColumnType.NORMAL)
                .map(x -> Tuple2.of(x.context.cqlColumn, x.context.fieldName)).sorted(BY_CQL_NAME_COLUMN_SORTER)
                .map(x -> x._2()).forEach(x -> joiner.add(x));

        return MethodSpec.methodBuilder("getNormalColumns").addAnnotation(Override.class)
                .addModifiers(Modifier.PROTECTED).returns(propertyListType(rawClassType))
                .addStatement("return $T.asList($L)", ARRAYS, joiner.toString()).build();
    }

    private MethodSpec buildIsCounterTable(boolean isCounter) {
        return MethodSpec.methodBuilder("isCounterTable").addAnnotation(Override.class)
                .addModifiers(Modifier.PROTECTED).returns(BOOLEAN).addStatement("return $L", isCounter).build();
    }

    private MethodSpec buildGetStaticReadConsistency(Optional<Consistency> consistency) {
        final MethodSpec.Builder builder = MethodSpec.methodBuilder("getStaticReadConsistency")
                .addAnnotation(Override.class).addModifiers(Modifier.PROTECTED)
                .returns(genericType(OPTIONAL, CONSISTENCY_LEVEL));

        if (consistency.isPresent()) {
            final ConsistencyLevel consistencyLevel = consistency.get().read();
            aptUtils.validateFalse(
                    consistencyLevel == ConsistencyLevel.SERIAL
                            || consistencyLevel == ConsistencyLevel.LOCAL_SERIAL,
                    "Static read consistency level cannot be SERIAL or LOCAL_SERIAL");
            return builder.addStatement("return $T.of($T.$L)", OPTIONAL, CONSISTENCY_LEVEL, consistencyLevel.name())
                    .build();
        } else {
            return emptyOption(builder);
        }
    }

    private MethodSpec buildGetStaticWriteConsistency(Optional<Consistency> consistency) {
        final MethodSpec.Builder builder = MethodSpec.methodBuilder("getStaticWriteConsistency")
                .addAnnotation(Override.class).addModifiers(Modifier.PROTECTED)
                .returns(genericType(OPTIONAL, CONSISTENCY_LEVEL));

        if (consistency.isPresent()) {
            final ConsistencyLevel consistencyLevel = consistency.get().write();
            aptUtils.validateFalse(
                    consistencyLevel == ConsistencyLevel.SERIAL
                            || consistencyLevel == ConsistencyLevel.LOCAL_SERIAL,
                    "Static write consistency level cannot be SERIAL or LOCAL_SERIAL");
            return builder.addStatement("return $T.of($T.$L)", OPTIONAL, CONSISTENCY_LEVEL, consistencyLevel.name())
                    .build();
        } else {
            return emptyOption(builder);
        }
    }

    private MethodSpec buildGetStaticSerialConsistency(Optional<Consistency> consistency) {
        final MethodSpec.Builder builder = MethodSpec.methodBuilder("getStaticSerialConsistency")
                .addAnnotation(Override.class).addModifiers(Modifier.PROTECTED)
                .returns(genericType(OPTIONAL, CONSISTENCY_LEVEL));

        if (consistency.isPresent()) {
            final ConsistencyLevel consistencyLevel = consistency.get().serial();
            aptUtils.validateTrue(
                    consistencyLevel == ConsistencyLevel.SERIAL
                            || consistencyLevel == ConsistencyLevel.LOCAL_SERIAL,
                    "Static serial consistency level should be SERIAL or LOCAL_SERIAL");
            return builder.addStatement("return $T.of($T.$L)", OPTIONAL, CONSISTENCY_LEVEL, consistencyLevel.name())
                    .build();
        } else {
            return emptyOption(builder);
        }
    }

    private MethodSpec buildGetStaticTTL(Optional<TTL> ttl) {
        final MethodSpec.Builder builder = MethodSpec.methodBuilder("getStaticTTL").addAnnotation(Override.class)
                .addModifiers(Modifier.PROTECTED).returns(genericType(OPTIONAL, INT.box()));

        if (ttl.isPresent()) {
            return builder.addStatement("return $T.of($L)", OPTIONAL, ttl.get().value()).build();
        } else {
            return emptyOption(builder);
        }
    }

    private MethodSpec buildGetStaticInsertStrategy(Optional<Strategy> strategy) {
        final MethodSpec.Builder builder = MethodSpec.methodBuilder("getStaticInsertStrategy")
                .addAnnotation(Override.class).addModifiers(Modifier.PROTECTED)
                .returns(genericType(OPTIONAL, INSERT_STRATEGY));

        if (strategy.isPresent()) {
            return builder
                    .addStatement("return $T.of($T.$L)", OPTIONAL, INSERT_STRATEGY, strategy.get().insert().name())
                    .build();
        } else {
            return emptyOption(builder);
        }
    }

    private MethodSpec buildGetBaseEntityClass(TypeName baseEntityRawType) {
        return MethodSpec.methodBuilder("getBaseEntityClass").addAnnotation(Override.class)
                .addModifiers(Modifier.PUBLIC).returns(genericType(CLASS, WILDCARD))
                .addStatement("return $T.class", baseEntityRawType).build();
    }

    private FieldSpec buildColumnsField(String parentClassName) {

        TypeName typeName = ClassName.get(ENTITY_META_PACKAGE, parentClassName + "." + COLUMNS_FOR_FUNCTIONS_CLASS);
        return FieldSpec.builder(typeName, "COLUMNS", Modifier.STATIC, Modifier.PUBLIC, Modifier.FINAL)
                .addJavadoc("Static class to expose $S fields for <strong>type-safe</strong> function calls",
                        parentClassName)
                .initializer(CodeBlock.builder().addStatement("new $T()", typeName).build()).build();
    }

    private ParameterizedTypeName propertyListType(TypeName rawClassType) {
        return genericType(LIST, genericType(ABSTRACT_PROPERTY, rawClassType, WILDCARD, WILDCARD));
    }

    public static class EntityMetaSignature {
        public final TypeSpec sourceCode;
        public final String className;
        public final TypeName typeName;
        public final TypeName entityRawClass;
        public final String fieldName;
        public final List<FieldMetaSignature> fieldMetaSignatures;
        public final EntityType entityType;
        public final Optional<TypeName> viewBaseClass;

        public EntityMetaSignature(EntityType entityType, TypeSpec sourceCode, String className, TypeName typeName,
                TypeName entityRawClass, Optional<TypeName> viewBaseClass,
                List<FieldMetaSignature> fieldMetaSignatures) {
            this.entityType = entityType;
            this.sourceCode = sourceCode;
            this.className = className;
            this.typeName = typeName;
            this.entityRawClass = entityRawClass;
            this.viewBaseClass = viewBaseClass;
            this.fieldMetaSignatures = fieldMetaSignatures;
            this.fieldName = className.substring(0, 1).toLowerCase() + className.substring(1);
        }

        public boolean hasClustering() {
            return fieldMetaSignatures.stream().filter(x -> x.context.columnType == CLUSTERING).count() > 0;
        }

        public boolean hasStatic() {
            return fieldMetaSignatures.stream()
                    .filter(x -> x.context.columnType == STATIC || x.context.columnType == STATIC_COUNTER)
                    .count() > 0;
        }

        public boolean isCounterEntity() {
            return fieldMetaSignatures.stream()
                    .filter(x -> x.context.columnType == COUNTER || x.context.columnType == STATIC_COUNTER)
                    .count() > 0;
        }

        public boolean isTable() {
            return entityType == EntityType.TABLE;
        }

        public boolean isView() {
            return entityType == EntityType.VIEW;
        }

        public String whereType(String fieldName, String suffix) {
            return className + suffix + "_" + upperCaseFirst(fieldName);
        }

        public String endClassName(String suffix) {
            return className + suffix;
        }

        public String endReturnType(String dslSuffix, String suffix) {
            return className + dslSuffix + "." + className + suffix;
        }

        public String whereReturnType(String fieldName, String dslSuffix, String suffix) {
            return className + dslSuffix + "." + className + suffix + "_" + upperCaseFirst(fieldName);
        }

        public String selectClassName() {
            return className + SELECT_DSL_SUFFIX;
        }

        public String selectFromReturnType() {
            return selectClassName() + "." + className + SELECT_FROM_DSL_SUFFIX;
        }

        public String selectColumnsReturnType() {
            return selectClassName() + "." + className + SELECT_COLUMNS_DSL_SUFFIX;
        }

        public String selectWhereReturnType(String fieldName) {
            return selectClassName() + "." + className + SELECT_WHERE_DSL_SUFFIX + "_" + upperCaseFirst(fieldName);
        }

        public String selectEndReturnType() {
            return selectClassName() + "." + className + SELECT_END_DSL_SUFFIX;
        }

        public String deleteClassName() {
            return className + DELETE_DSL_SUFFIX;
        }

        public String deleteFromReturnType() {
            return deleteClassName() + "." + className + DELETE_FROM_DSL_SUFFIX;
        }

        public String deleteColumnsReturnType() {
            return deleteClassName() + "." + className + DELETE_COLUMNS_DSL_SUFFIX;
        }

        public String deleteWhereReturnType(String fieldName) {
            return deleteClassName() + "." + className + DELETE_WHERE_DSL_SUFFIX + "_" + upperCaseFirst(fieldName);
        }

        public String deleteStaticClassName() {
            return className + DELETE_STATIC_DSL_SUFFIX;
        }

        public String deleteStaticFromReturnType() {
            return deleteStaticClassName() + "." + className + DELETE_STATIC_FROM_DSL_SUFFIX;
        }

        public String deleteStaticColumnsReturnType() {
            return deleteStaticClassName() + "." + className + DELETE_STATIC_COLUMNS_DSL_SUFFIX;
        }

        public String deleteStaticWhereReturnType(String fieldName) {
            return deleteStaticClassName() + "." + className + DELETE_STATIC_WHERE_DSL_SUFFIX + "_"
                    + upperCaseFirst(fieldName);
        }

        public String updateClassName() {
            return className + UPDATE_DSL_SUFFIX;
        }

        public String updateFromReturnType() {
            return updateClassName() + "." + className + UPDATE_FROM_DSL_SUFFIX;
        }

        public String updateColumnsReturnType() {
            return updateClassName() + "." + className + UPDATE_COLUMNS_DSL_SUFFIX;
        }

        public String updateWhereReturnType(String fieldName) {
            return updateClassName() + "." + className + UPDATE_WHERE_DSL_SUFFIX + "_" + upperCaseFirst(fieldName);
        }

        public String updateStaticClassName() {
            return className + UPDATE_STATIC_DSL_SUFFIX;
        }

        public String updateStaticFromReturnType() {
            return updateStaticClassName() + "." + className + UPDATE_STATIC_FROM_DSL_SUFFIX;
        }

        public String updateStaticColumnsReturnType() {
            return updateStaticClassName() + "." + className + UPDATE_STATIC_COLUMNS_DSL_SUFFIX;
        }

        public String updateStaticWhereReturnType(String fieldName) {
            return updateStaticClassName() + "." + className + UPDATE_STATIC_WHERE_DSL_SUFFIX + "_"
                    + upperCaseFirst(fieldName);
        }
    }
}