Search in sources :

Example 1 with MethodGenerator

use of com.datastax.oss.driver.internal.mapper.processor.MethodGenerator in project java-driver by datastax.

the class DaoImplementationGenerator method getContents.

@Override
protected JavaFile.Builder getContents() {
    TypeSpec.Builder classBuilder = TypeSpec.classBuilder(implementationName).addJavadoc(JAVADOC_GENERATED_WARNING).addAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "\"all\"").build()).addModifiers(Modifier.PUBLIC).addSuperinterface(ClassName.get(interfaceElement));
    boolean reactive = false;
    for (TypeMirror mirror : interfaces) {
        TypeElement parentInterfaceElement = (TypeElement) context.getTypeUtils().asElement(mirror);
        Map<Name, TypeElement> typeParameters = parseTypeParameters(mirror);
        for (Element child : parentInterfaceElement.getEnclosedElements()) {
            if (child.getKind() == ElementKind.METHOD) {
                ExecutableElement methodElement = (ExecutableElement) child;
                Set<Modifier> modifiers = methodElement.getModifiers();
                if (!modifiers.contains(Modifier.STATIC) && !modifiers.contains(Modifier.DEFAULT)) {
                    Optional<MethodGenerator> maybeGenerator = context.getCodeGeneratorFactory().newDaoImplementationMethod(methodElement, typeParameters, interfaceElement, this);
                    if (!maybeGenerator.isPresent()) {
                        context.getMessager().error(methodElement, "Unrecognized method signature: no implementation will be generated");
                    } else {
                        maybeGenerator.flatMap(MethodGenerator::generate).ifPresent(classBuilder::addMethod);
                        reactive |= maybeGenerator.get().requiresReactive();
                    }
                }
            }
        }
    }
    classBuilder = classBuilder.superclass(getDaoParentClass(reactive));
    genericTypeConstantGenerator.generate(classBuilder);
    MethodSpec.Builder initAsyncBuilder = getInitAsyncContents();
    MethodSpec.Builder initBuilder = getInitContents();
    MethodSpec.Builder constructorBuilder = MethodSpec.constructorBuilder().addModifiers(Modifier.PRIVATE).addParameter(MapperContext.class, "context").addStatement("super(context)");
    context.getLoggingGenerator().addLoggerField(classBuilder, implementationName);
    // add a constructor parameter for it (the instance gets created in initAsync).
    for (Map.Entry<ClassName, String> entry : entityHelperFields.entrySet()) {
        ClassName fieldTypeName = entry.getKey();
        String fieldName = entry.getValue();
        classBuilder.addField(FieldSpec.builder(fieldTypeName, fieldName, Modifier.PRIVATE, Modifier.FINAL).build());
        constructorBuilder.addParameter(fieldTypeName, fieldName).addStatement("this.$1L = $1L", fieldName);
    }
    // Same for prepared statements:
    for (GeneratedPreparedStatement preparedStatement : preparedStatements) {
        classBuilder.addField(FieldSpec.builder(PreparedStatement.class, preparedStatement.fieldName, Modifier.PRIVATE, Modifier.FINAL).build());
        constructorBuilder.addParameter(PreparedStatement.class, preparedStatement.fieldName).addStatement("this.$1L = $1L", preparedStatement.fieldName);
    }
    // Same for method invokers:
    for (GeneratedQueryProvider queryProvider : queryProviders) {
        TypeName providerClassName = TypeName.get(queryProvider.providerClass);
        classBuilder.addField(providerClassName, queryProvider.fieldName, Modifier.PRIVATE, Modifier.FINAL);
        constructorBuilder.addParameter(providerClassName, queryProvider.fieldName).addStatement("this.$1L = $1L", queryProvider.fieldName);
    }
    classBuilder.addMethod(initAsyncBuilder.build());
    classBuilder.addMethod(initBuilder.build());
    classBuilder.addMethod(constructorBuilder.build());
    return JavaFile.builder(implementationName.packageName(), classBuilder.build());
}
Also used : TypeName(com.squareup.javapoet.TypeName) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) ExecutableElement(javax.lang.model.element.ExecutableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) ClassName(com.squareup.javapoet.ClassName) TypeName(com.squareup.javapoet.TypeName) Name(javax.lang.model.element.Name) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) MapperContext(com.datastax.oss.driver.api.mapper.MapperContext) TypeMirror(javax.lang.model.type.TypeMirror) ClassName(com.squareup.javapoet.ClassName) Modifier(javax.lang.model.element.Modifier) MethodGenerator(com.datastax.oss.driver.internal.mapper.processor.MethodGenerator) MethodSpec(com.squareup.javapoet.MethodSpec) TypeElement(javax.lang.model.element.TypeElement) PreparedStatement(com.datastax.oss.driver.api.core.cql.PreparedStatement) Map(java.util.Map) ImmutableMap(com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap) LinkedHashMap(java.util.LinkedHashMap) TypeSpec(com.squareup.javapoet.TypeSpec)

Example 2 with MethodGenerator

use of com.datastax.oss.driver.internal.mapper.processor.MethodGenerator in project java-driver by datastax.

the class EntityHelperGenerator method getContents.

@Override
protected JavaFile.Builder getContents() {
    EntityDefinition entityDefinition = context.getEntityFactory().getDefinition(classElement);
    TypeSpec.Builder classContents = TypeSpec.classBuilder(helperName).addJavadoc(JAVADOC_GENERATED_WARNING).addAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "\"all\"").build()).addModifiers(Modifier.PUBLIC).superclass(ParameterizedTypeName.get(ClassName.get(EntityHelperBase.class), ClassName.get(classElement)));
    context.getLoggingGenerator().addLoggerField(classContents, helperName);
    classContents.addMethod(MethodSpec.methodBuilder("getEntityClass").addModifiers(Modifier.PUBLIC).addAnnotation(Override.class).returns(ParameterizedTypeName.get(ClassName.get(Class.class), entityDefinition.getClassName())).addStatement("return $T.class", entityDefinition.getClassName()).build());
    for (MethodGenerator methodGenerator : ImmutableList.of(new EntityHelperSetMethodGenerator(entityDefinition, this), new EntityHelperGetMethodGenerator(entityDefinition, this), new EntityHelperInsertMethodGenerator(entityDefinition), new EntityHelperSelectByPrimaryKeyPartsMethodGenerator(), new EntityHelperSelectByPrimaryKeyMethodGenerator(), new EntityHelperSelectStartMethodGenerator(entityDefinition), new EntityHelperDeleteStartMethodGenerator(), new EntityHelperDeleteByPrimaryKeyPartsMethodGenerator(entityDefinition), new EntityHelperDeleteByPrimaryKeyMethodGenerator(), new EntityHelperUpdateStartMethodGenerator(entityDefinition), new EntityHelperUpdateByPrimaryKeyMethodGenerator(entityDefinition), new EntityHelperSchemaValidationMethodGenerator(entityDefinition, classElement, context.getLoggingGenerator(), this))) {
        methodGenerator.generate().ifPresent(classContents::addMethod);
    }
    MethodSpec.Builder constructorContents = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC);
    constructorContents.addParameter(ClassName.get(MapperContext.class), "context");
    if (entityDefinition.getDefaultKeyspace() == null) {
        constructorContents.addStatement("super(context, $L)", entityDefinition.getCqlName());
    } else {
        constructorContents.addStatement("super(context, $S, $L)", entityDefinition.getDefaultKeyspace(), entityDefinition.getCqlName());
    }
    context.getLoggingGenerator().debug(constructorContents, String.format("[{}] Entity %s will be mapped to {}{}", entityDefinition.getClassName().simpleName()), CodeBlock.of("context.getSession().getName()"), CodeBlock.of("getKeyspaceId() == null ? \"\" : getKeyspaceId() + \".\""), CodeBlock.of("getTableId()"));
    // retain primary keys for reference in methods.
    classContents.addField(FieldSpec.builder(ParameterizedTypeName.get(List.class, String.class), "primaryKeys", Modifier.PRIVATE, Modifier.FINAL).build());
    constructorContents.addCode("$[this.primaryKeys = $1T.<$2T>builder()", ImmutableList.class, String.class);
    for (PropertyDefinition propertyDefinition : entityDefinition.getPrimaryKey()) {
        constructorContents.addCode("\n.add($1L)", propertyDefinition.getCqlName());
    }
    constructorContents.addCode("\n.build()$];\n");
    genericTypeConstantGenerator.generate(classContents);
    for (Map.Entry<ClassName, String> entry : childHelpers.entrySet()) {
        ClassName childEntityName = entry.getKey();
        String fieldName = entry.getValue();
        ClassName helperClassName = GeneratedNames.entityHelper(childEntityName);
        classContents.addField(FieldSpec.builder(helperClassName, fieldName, Modifier.PRIVATE, Modifier.FINAL).build());
        constructorContents.addStatement("this.$L = new $T(context)", fieldName, helperClassName);
    }
    classContents.addMethod(constructorContents.build());
    return JavaFile.builder(helperName.packageName(), classContents.build());
}
Also used : MapperContext(com.datastax.oss.driver.api.mapper.MapperContext) ClassName(com.squareup.javapoet.ClassName) ImmutableList(com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList) List(java.util.List) MethodGenerator(com.datastax.oss.driver.internal.mapper.processor.MethodGenerator) MethodSpec(com.squareup.javapoet.MethodSpec) HashMap(java.util.HashMap) Map(java.util.Map) TypeSpec(com.squareup.javapoet.TypeSpec)

Example 3 with MethodGenerator

use of com.datastax.oss.driver.internal.mapper.processor.MethodGenerator in project java-driver by datastax.

the class MapperImplementationGenerator method getContents.

@Override
protected JavaFile.Builder getContents() {
    TypeSpec.Builder classContents = TypeSpec.classBuilder(className).addJavadoc("Do not instantiate this class directly, use {@link $T} instead.", GeneratedNames.mapperBuilder(interfaceElement)).addJavadoc(JAVADOC_PARAGRAPH_SEPARATOR).addJavadoc(JAVADOC_GENERATED_WARNING).addAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "\"all\"").build()).addModifiers(Modifier.PUBLIC).addSuperinterface(ClassName.get(interfaceElement));
    for (Element child : interfaceElement.getEnclosedElements()) {
        if (child.getKind() == ElementKind.METHOD) {
            ExecutableElement methodElement = (ExecutableElement) child;
            Set<Modifier> modifiers = methodElement.getModifiers();
            if (!modifiers.contains(Modifier.STATIC) && !modifiers.contains(Modifier.DEFAULT)) {
                Optional<MethodGenerator> maybeGenerator = context.getCodeGeneratorFactory().newMapperImplementationMethod(methodElement, interfaceElement, this);
                if (!maybeGenerator.isPresent()) {
                    context.getMessager().error(methodElement, "Unrecognized method signature: no implementation will be generated");
                } else {
                    maybeGenerator.flatMap(MethodGenerator::generate).ifPresent(classContents::addMethod);
                }
            }
        }
    }
    MethodSpec.Builder constructorContents = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC);
    GeneratedCodePatterns.addFinalFieldAndConstructorArgument(ClassName.get(DefaultMapperContext.class), "context", classContents, constructorContents);
    // Add all the fields that were requested by DAO method generators:
    for (DaoSimpleField field : daoSimpleFields) {
        classContents.addField(FieldSpec.builder(ParameterizedTypeName.get(ClassName.get(LazyReference.class), field.type), field.name, Modifier.PRIVATE, Modifier.FINAL).build());
        constructorContents.addStatement("this.$1L = new $2T<>(() -> $3T.$4L(context))", field.name, LazyReference.class, field.daoImplementationType, field.isAsync ? "initAsync" : "init");
    }
    for (DaoMapField field : daoMapFields) {
        classContents.addField(FieldSpec.builder(ParameterizedTypeName.get(ClassName.get(ConcurrentMap.class), TypeName.get(DaoCacheKey.class), field.mapValueType), field.name, Modifier.PRIVATE, Modifier.FINAL).initializer("new $T<>()", ConcurrentHashMap.class).build());
    }
    classContents.addMethod(constructorContents.build());
    return JavaFile.builder(className.packageName(), classContents.build());
}
Also used : MethodGenerator(com.datastax.oss.driver.internal.mapper.processor.MethodGenerator) MethodSpec(com.squareup.javapoet.MethodSpec) DefaultMapperContext(com.datastax.oss.driver.internal.mapper.DefaultMapperContext) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) ExecutableElement(javax.lang.model.element.ExecutableElement) ConcurrentMap(java.util.concurrent.ConcurrentMap) DaoCacheKey(com.datastax.oss.driver.internal.mapper.DaoCacheKey) Modifier(javax.lang.model.element.Modifier) TypeSpec(com.squareup.javapoet.TypeSpec)

Aggregations

MethodGenerator (com.datastax.oss.driver.internal.mapper.processor.MethodGenerator)3 MethodSpec (com.squareup.javapoet.MethodSpec)3 TypeSpec (com.squareup.javapoet.TypeSpec)3 MapperContext (com.datastax.oss.driver.api.mapper.MapperContext)2 ClassName (com.squareup.javapoet.ClassName)2 Map (java.util.Map)2 Element (javax.lang.model.element.Element)2 ExecutableElement (javax.lang.model.element.ExecutableElement)2 Modifier (javax.lang.model.element.Modifier)2 TypeElement (javax.lang.model.element.TypeElement)2 PreparedStatement (com.datastax.oss.driver.api.core.cql.PreparedStatement)1 DaoCacheKey (com.datastax.oss.driver.internal.mapper.DaoCacheKey)1 DefaultMapperContext (com.datastax.oss.driver.internal.mapper.DefaultMapperContext)1 ImmutableList (com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList)1 ImmutableMap (com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap)1 ParameterizedTypeName (com.squareup.javapoet.ParameterizedTypeName)1 TypeName (com.squareup.javapoet.TypeName)1 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1