info.archinnov.achilles.internals.codegen.ManagerCodeGen Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of achilles-core Show documentation
Show all versions of achilles-core Show documentation
CQL implementation for Achilles using Datastax Java driver
/*
* 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;
import static info.archinnov.achilles.internals.parser.TypeUtils.*;
import java.util.ArrayList;
import java.util.List;
import javax.lang.model.element.Modifier;
import com.squareup.javapoet.*;
import info.archinnov.achilles.internals.apt.AptUtils;
import info.archinnov.achilles.internals.codegen.meta.EntityMetaCodeGen.EntityMetaSignature;
import info.archinnov.achilles.internals.parser.TypeUtils;
import info.archinnov.achilles.internals.parser.context.GlobalParsingContext;
public class ManagerCodeGen {
static ManagerAndDSLClasses buildManager(GlobalParsingContext context, AptUtils aptUtils, EntityMetaSignature signature) {
final List classes = new ArrayList<>();
final TypeSpec.Builder builder = TypeSpec.classBuilder(signature.className + MANAGER_SUFFIX)
.superclass(genericType(ABSTRACT_MANAGER, signature.entityRawClass))
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addMethod(buildConstructor(signature))
.addMethod(buildCRUD(signature))
.addMethod(buildDSL(signature))
.addMethod(buildRawQuery(signature))
.addField(buildExactEntityMetaField(signature));
// CRUD
final TypeSpec crudClass = context.crudAPICodeGen().buildCRUDClass(signature);
// DSL
final TypeSpec.Builder dslClass = TypeSpec.classBuilder(signature.className + DSL_SUFFIX)
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addMethod(buildSelectMethod(signature, SELECT_DSL_SUFFIX));
classes.add(context.selectDSLCodeGen().buildSelectClass(context, signature));
if (signature.isTable()) {
dslClass.addMethod(buildDeleteMethod(signature))
.addMethod(buildUpdateMethod(signature));
classes.add(context.deleteDSLCodeGen().buildDeleteClass(signature, context.deleteWhereDSLCodeGen()));
classes.add(context.updateDSLCodeGen().buildUpdateClass(aptUtils, signature, context.updateWhereDSLCodeGen()));
if (signature.hasStatic()) {
classes.add(context.deleteDSLCodeGen().buildDeleteStaticClass(signature, context.deleteWhereDSLCodeGen()));
classes.add(context.updateDSLCodeGen().buildUpdateStaticClass(aptUtils, signature, context.updateWhereDSLCodeGen()));
dslClass.addMethod(buildDeleteStaticMethod(signature));
dslClass.addMethod(buildUpdateStaticMethod(signature));
}
}
// INDEX
if (signature.hasIndex() && signature.isTable()) {
builder.addMethod(buildINDEX(signature));
final TypeSpec.Builder indexClass = TypeSpec.classBuilder(signature.className + INDEX_SUFFIX)
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addMethod(buildSelectMethod(signature, INDEX_SELECT_DSL_SUFFIX));
builder.addType(indexClass.build());
classes.add(context.indexSelectDSLCodeGen().buildSelectClass(context, signature));
}
// Raw
final TypeSpec.Builder queryClass = TypeSpec.classBuilder(signature.className + RAW_QUERY_SUFFIX)
.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
buildRawQueryMethods(signature).forEach(queryClass::addMethod);
builder.addType(crudClass);
builder.addType(dslClass.build());
builder.addType(queryClass.build());
return new ManagerAndDSLClasses(builder.build(), classes);
}
private static MethodSpec buildConstructor(EntityMetaSignature signature) {
String entityMetaClassName = signature.className + META_SUFFIX;
TypeName entityMetaExactType = ClassName.get(ENTITY_META_PACKAGE, entityMetaClassName);
return MethodSpec.constructorBuilder()
.addModifiers(Modifier.PUBLIC)
.addParameter(TypeUtils.classTypeOf(signature.entityRawClass), "entityClass", Modifier.FINAL)
.addParameter(entityMetaExactType, "meta", Modifier.FINAL)
.addParameter(RUNTIME_ENGINE, "rte", Modifier.FINAL)
.addStatement("super($N, $N, $N)", "entityClass", "meta", "rte")
.addStatement("this.meta = meta")
.build();
}
private static MethodSpec buildCRUD(EntityMetaSignature signature) {
TypeName crudClass = ClassName.get(MANAGER_PACKAGE, signature.className + MANAGER_SUFFIX, signature.className + CRUD_SUFFIX);
final MethodSpec.Builder builder = MethodSpec.methodBuilder("crud")
.addJavadoc("Provide CRUD operations:
\n")
.addJavadoc("\n")
.addJavadoc(" - FIND BY ID
\n");
if (signature.isTable()) {
builder.addJavadoc(" - INSERT
\n")
.addJavadoc(" - INSERT STATIC
\n")
.addJavadoc(" - INSERT IF NOT EXISTS
\n")
.addJavadoc(" - DELETE BY ID
\n")
.addJavadoc(" - DELETE BY ID IF NOT EXISTS
\n")
.addJavadoc(" - DELETE BY PARTITION
\n");
}
builder.addJavadoc("
\n")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addStatement("return new $T()", crudClass)
.returns(crudClass);
return builder.build();
}
private static MethodSpec buildDSL(EntityMetaSignature signature) {
TypeName dslClass = ClassName.get(MANAGER_PACKAGE, signature.className + MANAGER_SUFFIX, signature.className + DSL_SUFFIX);
final MethodSpec.Builder builder = MethodSpec.methodBuilder("dsl")
.addJavadoc("Provide DSL methods:
\n")
.addJavadoc("\n")
.addJavadoc(" - SELECT
\n")
.addJavadoc(" - ITERATION ON SELECT
\n");
if (signature.isTable()) {
builder.addJavadoc(" - UPDATE
\n")
.addJavadoc(" - DELETE
\n");
}
builder.addJavadoc("
\n")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addStatement("return new $T()", dslClass)
.returns(dslClass);
return builder.build();
}
private static MethodSpec buildINDEX(EntityMetaSignature signature) {
TypeName indexDslClass = ClassName.get(MANAGER_PACKAGE, signature.className + MANAGER_SUFFIX, signature.className + INDEX_SUFFIX);
final MethodSpec.Builder builder = MethodSpec.methodBuilder("indexed")
.addJavadoc("Provide INDEX query methods:
\n")
.addJavadoc("\n")
.addJavadoc(" - SELECT
\n")
.addJavadoc(" - ITERATION ON SELECT
\n");
builder.addJavadoc("
\n")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addStatement("return new $T()", indexDslClass)
.returns(indexDslClass);
return builder.build();
}
private static MethodSpec buildRawQuery(EntityMetaSignature signature) {
TypeName dslClass = ClassName.get(MANAGER_PACKAGE, signature.className + MANAGER_SUFFIX, signature.className + RAW_QUERY_SUFFIX);
return MethodSpec.methodBuilder("raw")
.addJavadoc("Provide Raw query methods:
\n")
.addJavadoc("\n")
.addJavadoc(" - Typed Queries (for SELECT only)
\n")
.addJavadoc(" - Native Queries (for any kind of statement)
\n")
.addJavadoc("
\n")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addStatement("return new $T()", dslClass)
.returns(dslClass)
.build();
}
private static MethodSpec buildSelectMethod(EntityMetaSignature signature, String suffix) {
TypeName selectTypeName = ClassName.get(DSL_PACKAGE, signature.className + suffix);
return MethodSpec.methodBuilder("select")
.addJavadoc("Generate a SELECT statement")
.addJavadoc("@return $T", selectTypeName)
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addStatement("return new $T(rte, meta)", selectTypeName)
.returns(selectTypeName)
.build();
}
private static MethodSpec buildDeleteMethod(EntityMetaSignature signature) {
TypeName deleteTypeName = ClassName.get(DSL_PACKAGE, signature.className + DELETE_DSL_SUFFIX);
return MethodSpec.methodBuilder("delete")
.addJavadoc("Generate a DELETE statement")
.addJavadoc("@return $T", deleteTypeName)
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addStatement("return new $T(rte, meta)", deleteTypeName)
.returns(deleteTypeName)
.build();
}
private static MethodSpec buildDeleteStaticMethod(EntityMetaSignature signature) {
TypeName deleteStaticTypeName = ClassName.get(DSL_PACKAGE, signature.className + DELETE_STATIC_DSL_SUFFIX);
return MethodSpec.methodBuilder("deleteStatic")
.addJavadoc("Generate a DELETE statement for static columns only")
.addJavadoc("(requiring only partition key(s))")
.addJavadoc("@return $T", deleteStaticTypeName)
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addStatement("return new $T(rte, meta)", deleteStaticTypeName)
.returns(deleteStaticTypeName)
.build();
}
private static MethodSpec buildUpdateMethod(EntityMetaSignature signature) {
TypeName updateTypeName = ClassName.get(DSL_PACKAGE, signature.className + UPDATE_DSL_SUFFIX);
return MethodSpec.methodBuilder("update")
.addJavadoc("Generate an UPDATE statement")
.addJavadoc("@return $T", updateTypeName)
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addStatement("return new $T(rte, meta)", updateTypeName)
.returns(updateTypeName)
.build();
}
private static MethodSpec buildUpdateStaticMethod(EntityMetaSignature signature) {
TypeName updateStaticTypeName = ClassName.get(DSL_PACKAGE, signature.className + UPDATE_STATIC_DSL_SUFFIX);
return MethodSpec.methodBuilder("updateStatic")
.addJavadoc("Generate an UPDATE statement for static columns only")
.addJavadoc("(requiring only partition key(s))")
.addJavadoc("@return $T", updateStaticTypeName)
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addStatement("return new $T(rte, meta)", updateStaticTypeName)
.returns(updateStaticTypeName)
.build();
}
private static List buildRawQueryMethods(EntityMetaSignature signature) {
List methods = new ArrayList<>();
methods.add(MethodSpec.methodBuilder("typedQueryForSelect")
.addJavadoc("Execute the bound statement and map the result back into an instance of $T
\n", signature.entityRawClass)
.addJavadoc("Remark: the bound statement should be a SELECT statement")
.addJavadoc("@param boundStatement a bound statement")
.addJavadoc("@return $T", genericType(TYPED_QUERY, signature.entityRawClass))
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addParameter(BOUND_STATEMENT, "boundStatement")
.addStatement("return typedQueryForSelectInternal($N)", "boundStatement")
.returns(genericType(TYPED_QUERY, signature.entityRawClass))
.build());
methods.add(MethodSpec.methodBuilder("typedQueryForSelect")
.addJavadoc("Execute the prepared statement and map the result back into an instance of $T
\n", signature.entityRawClass)
.addJavadoc("Remark: the prepared statement should be a SELECT statement")
.addJavadoc("@param preparedStatement a prepared statement")
.addJavadoc("@return $T", genericType(TYPED_QUERY, signature.entityRawClass))
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addParameter(PREPARED_STATEMENT, "preparedStatement")
.addParameter(ArrayTypeName.of(TypeName.OBJECT), "encodedBoundValues")
.varargs()
.addStatement("return typedQueryForSelectInternal($N, $N)", "preparedStatement", "encodedBoundValues")
.returns(genericType(TYPED_QUERY, signature.entityRawClass))
.build());
methods.add(MethodSpec.methodBuilder("typedQueryForSelect")
.addJavadoc("Execute the regular statement and map the result back into an instance of $T
\n", signature.entityRawClass)
.addJavadoc("Remark: the regular statement should be a SELECT statement")
.addJavadoc("@param regularStatement a regular statement")
.addJavadoc("@return $T", genericType(TYPED_QUERY, signature.entityRawClass))
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addParameter(REGULAR_STATEMENT, "regularStatement")
.addParameter(ArrayTypeName.of(TypeName.OBJECT), "encodedBoundValues")
.varargs()
.addStatement("return typedQueryForSelectInternal($N, $N)", "regularStatement", "encodedBoundValues")
.returns(genericType(TYPED_QUERY, signature.entityRawClass))
.build());
methods.add(MethodSpec.methodBuilder("nativeQuery")
.addJavadoc("Execute the native bound statement")
.addJavadoc("@param boundStatement a bound statement")
.addJavadoc("@return $T", NATIVE_QUERY)
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addParameter(BOUND_STATEMENT, "boundStatement")
.addStatement("return nativeQueryInternal($N)", "boundStatement")
.returns(NATIVE_QUERY)
.build());
methods.add(MethodSpec.methodBuilder("nativeQuery")
.addJavadoc("Execute the native prepared statement")
.addJavadoc("@param preparedStatement a prepared statement")
.addJavadoc("@return $T", NATIVE_QUERY)
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addParameter(PREPARED_STATEMENT, "preparedStatement")
.addParameter(ArrayTypeName.of(TypeName.OBJECT), "encodedBoundValues")
.varargs()
.addStatement("return nativeQueryInternal($N, $N)", "preparedStatement", "encodedBoundValues")
.returns(NATIVE_QUERY)
.build());
methods.add(MethodSpec.methodBuilder("nativeQuery")
.addJavadoc("Execute the native regular statement")
.addJavadoc("@param regularStatement a regular statement")
.addJavadoc("@return $T", NATIVE_QUERY)
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addParameter(REGULAR_STATEMENT, "regularStatement")
.addParameter(ArrayTypeName.of(TypeName.OBJECT), "encodedBoundValues")
.varargs()
.addStatement("return nativeQueryInternal($N, $N)", "regularStatement", "encodedBoundValues")
.returns(NATIVE_QUERY)
.build());
return methods;
}
private static FieldSpec buildExactEntityMetaField(EntityMetaSignature signature) {
String entityMetaClassName = signature.className + META_SUFFIX;
TypeName entityMetaExactType = ClassName.get(ENTITY_META_PACKAGE, entityMetaClassName);
return FieldSpec.builder(entityMetaExactType, "meta", Modifier.FINAL, Modifier.PUBLIC).build();
}
public static class ManagerAndDSLClasses {
public final TypeSpec managerClass;
public final List dslClasses;
public ManagerAndDSLClasses(TypeSpec managerClass, List dslClasses) {
this.managerClass = managerClass;
this.dslClasses = dslClasses;
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy