• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Dagger Authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package dagger.grpc.server.processor;
18 
19 import static com.google.common.base.CaseFormat.LOWER_CAMEL;
20 import static com.google.common.base.CaseFormat.UPPER_CAMEL;
21 import static com.squareup.javapoet.MethodSpec.constructorBuilder;
22 import static com.squareup.javapoet.TypeSpec.classBuilder;
23 import static javax.lang.model.element.Modifier.ABSTRACT;
24 import static javax.lang.model.element.Modifier.FINAL;
25 import static javax.lang.model.element.Modifier.PRIVATE;
26 import static javax.lang.model.element.Modifier.PUBLIC;
27 import static javax.lang.model.element.Modifier.STATIC;
28 
29 import com.squareup.javapoet.ClassName;
30 import com.squareup.javapoet.MethodSpec;
31 import com.squareup.javapoet.TypeSpec;
32 import dagger.grpc.server.GrpcService;
33 
34 /**
35  * An object that generates the unscoped-proxying service definition module for a {@link
36  * GrpcService}-annotated service implementation.
37  */
38 final class UnscopedGrpcServiceModuleGenerator extends SourceGenerator {
39 
40   private final GrpcServiceModel grpcServiceModel;
41 
UnscopedGrpcServiceModuleGenerator(GrpcServiceModel grpcServiceModel)42   UnscopedGrpcServiceModuleGenerator(GrpcServiceModel grpcServiceModel) {
43     super(grpcServiceModel.packageName());
44     this.grpcServiceModel = grpcServiceModel;
45   }
46 
47   @Override
createType()48   protected TypeSpec createType() {
49     ClassName unscopedComponentFactory =
50         grpcServiceModel.unscopedServiceModuleName.nestedClass(
51             grpcServiceModel.serviceImplementationClassName.simpleName() + "ComponentFactory");
52     TypeSpec.Builder unscopedServiceModule =
53         classBuilder(grpcServiceModel.unscopedServiceModuleName)
54             .addJavadoc(
55                 "Install this module in the {@link $T @Singleton} server component\n",
56                 JavaxInject.singleton().type)
57             .addJavadoc(
58                 "if it implements {@link $T}.\n", grpcServiceModel.serviceDefinitionTypeName);
59     grpcServiceModel.generatedAnnotation().ifPresent(unscopedServiceModule::addAnnotation);
60     return unscopedServiceModule
61         .addAnnotation(
62             Dagger.module(grpcServiceModel.proxyModuleName, grpcServiceModel.serviceModuleName))
63         .addModifiers(PUBLIC, ABSTRACT)
64         .addType(unscopedComponentFactory(unscopedComponentFactory.simpleName()))
65         .addMethod(bindSubcomponentFactory(unscopedComponentFactory))
66         .addMethod(constructorBuilder().addModifiers(PRIVATE).build())
67         .build();
68   }
69 
70   /**
71    * Returns the class that implements the component factory type by returning the singleton
72    * component itself.
73    */
unscopedComponentFactory(String simpleName)74   private TypeSpec unscopedComponentFactory(String simpleName) {
75     return TypeSpec.classBuilder(simpleName)
76         .addModifiers(STATIC, FINAL)
77         .addSuperinterface(grpcServiceModel.serviceDefinitionTypeFactoryName)
78         .addField(grpcServiceModel.serviceDefinitionTypeName, "component", PRIVATE, FINAL)
79         .addMethod(
80             MethodSpec.constructorBuilder()
81                 .addAnnotation(JavaxInject.inject())
82                 .addParameter(grpcServiceModel.serviceDefinitionTypeName, "component")
83                 .addStatement("this.component = component")
84                 .build())
85         .addMethod(
86             MethodSpec.methodBuilder("grpcService")
87                 .addAnnotation(Override.class)
88                 .addModifiers(PUBLIC)
89                 .returns(grpcServiceModel.serviceDefinitionTypeName)
90                 .addParameter(Dagger.GrpcServer.GRPC_CALL_METADATA_MODULE, "grpcCallMetadataModule")
91                 .addStatement("return component")
92                 .build())
93         .build();
94   }
95 
96   /**
97    * Returns the {@link dagger.Binds @Binds} method that binds the component factory type to the
98    * {@linkplain #unscopedComponentFactory(String) unscoped component factory implementation class}.
99    */
bindSubcomponentFactory(ClassName unscopedComponentFactory)100   private MethodSpec bindSubcomponentFactory(ClassName unscopedComponentFactory) {
101     return MethodSpec.methodBuilder(
102             UPPER_CAMEL.to(
103                 LOWER_CAMEL, grpcServiceModel.serviceDefinitionTypeFactoryName.simpleName()))
104         .addAnnotation(Dagger.binds())
105         .addModifiers(ABSTRACT)
106         .returns(grpcServiceModel.serviceDefinitionTypeFactoryName)
107         .addParameter(unscopedComponentFactory, "factory")
108         .build();
109   }
110 }
111