1 /*
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
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  * A copy of the License is located at
7  *
8  *  http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 
16 package software.amazon.awssdk.codegen.poet.rules;
17 
18 import com.squareup.javapoet.ClassName;
19 import com.squareup.javapoet.FieldSpec;
20 import com.squareup.javapoet.MethodSpec;
21 import com.squareup.javapoet.ParameterizedTypeName;
22 import com.squareup.javapoet.TypeName;
23 import com.squareup.javapoet.TypeSpec;
24 import com.squareup.javapoet.TypeVariableName;
25 import javax.lang.model.element.Modifier;
26 import software.amazon.awssdk.annotations.SdkInternalApi;
27 import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel;
28 import software.amazon.awssdk.codegen.model.service.ClientContextParam;
29 import software.amazon.awssdk.codegen.poet.ClassSpec;
30 import software.amazon.awssdk.codegen.poet.PoetUtils;
31 import software.amazon.awssdk.utils.AttributeMap;
32 
33 public class ClientContextParamsClassSpec implements ClassSpec {
34     private final IntermediateModel model;
35     private final EndpointRulesSpecUtils endpointRulesSpecUtils;
36 
ClientContextParamsClassSpec(IntermediateModel model)37     public ClientContextParamsClassSpec(IntermediateModel model) {
38         this.model = model;
39         this.endpointRulesSpecUtils = new EndpointRulesSpecUtils(model);
40     }
41 
42     @Override
poetSpec()43     public TypeSpec poetSpec() {
44         TypeSpec.Builder b = PoetUtils.createClassBuilder(endpointRulesSpecUtils.clientContextParamsName())
45                                       .superclass(ParameterizedTypeName.get(
46                                           ClassName.get(AttributeMap.class).nestedClass("Key"), TypeVariableName.get("T")))
47                                       .addAnnotation(SdkInternalApi.class)
48                                       .addTypeVariable(TypeVariableName.get("T"))
49                                       .addModifiers(Modifier.PUBLIC, Modifier.FINAL);
50 
51         b.addMethod(ctor());
52 
53         if (model.getClientContextParams() != null) {
54             model.getClientContextParams().forEach((n, m) -> {
55                 b.addField(paramDeclaration(n, m));
56             });
57         }
58 
59         if (model.getCustomizationConfig() != null && model.getCustomizationConfig().getCustomClientContextParams() != null) {
60             model.getCustomizationConfig().getCustomClientContextParams().forEach((n, m) -> {
61                 b.addField(paramDeclaration(n, m));
62             });
63         }
64 
65         return b.build();
66     }
67 
68     @Override
className()69     public ClassName className() {
70         return endpointRulesSpecUtils.clientContextParamsName();
71     }
72 
ctor()73     private MethodSpec ctor() {
74         return MethodSpec.constructorBuilder()
75                          .addModifiers(Modifier.PRIVATE)
76                          .addParameter(ParameterizedTypeName.get(ClassName.get(Class.class), TypeVariableName.get("T")),
77                                        "valueClass")
78                          .addStatement("super(valueClass)")
79                          .build();
80     }
81 
paramDeclaration(String name, ClientContextParam param)82     private FieldSpec paramDeclaration(String name, ClientContextParam param) {
83         String fieldName = endpointRulesSpecUtils.clientContextParamName(name);
84         TypeName type = endpointRulesSpecUtils.toJavaType(param.getType());
85 
86         FieldSpec.Builder b = FieldSpec.builder(ParameterizedTypeName.get(className(), type), fieldName)
87                                        .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL);
88 
89         b.initializer("new $T<>($T.class)", className(), type);
90         PoetUtils.addJavadoc(b::addJavadoc, param.getDocumentation());
91         return b.build();
92     }
93 }
94