19
19
import com .squareup .javapoet .CodeBlock ;
20
20
import com .squareup .javapoet .FieldSpec ;
21
21
import com .squareup .javapoet .MethodSpec ;
22
- import com .squareup .javapoet .ParameterizedTypeName ;
23
22
import com .squareup .javapoet .TypeSpec ;
24
23
import java .io .IOException ;
25
24
import java .io .InputStream ;
26
25
import java .io .UncheckedIOException ;
26
+ import java .util .Map ;
27
27
import javax .lang .model .element .Modifier ;
28
28
import software .amazon .awssdk .annotations .SdkInternalApi ;
29
29
import software .amazon .awssdk .codegen .model .intermediate .IntermediateModel ;
30
30
import software .amazon .awssdk .codegen .poet .ClassSpec ;
31
31
import software .amazon .awssdk .codegen .poet .PoetUtils ;
32
32
import software .amazon .awssdk .protocols .jsoncore .JsonNode ;
33
33
import software .amazon .awssdk .utils .IoUtils ;
34
- import software .amazon .awssdk .utils .Lazy ;
35
34
import software .amazon .awssdk .utils .Validate ;
36
35
37
36
public class DefaultPartitionDataProviderSpec implements ClassSpec {
37
+ // partitions
38
+ private static final String VERSION = "version" ;
39
+ private static final String PARTITIONS = "partitions" ;
40
+ // partition
41
+ private static final String ID = "id" ;
42
+ private static final String REGION_REGEX = "regionRegex" ;
43
+ private static final String REGIONS = "regions" ;
44
+ private static final String OUTPUTS = "outputs" ;
45
+ // outputs
46
+ private static final String DNS_SUFFIX = "dnsSuffix" ;
47
+ private static final String DUAL_STACK_DNS_SUFFIX = "dualStackDnsSuffix" ;
48
+ private static final String SUPPORTS_FIPS = "supportsFIPS" ;
49
+ private static final String SUPPORTS_DUAL_STACK = "supportsDualStack" ;
50
+
38
51
private final IntermediateModel model ;
39
52
private final EndpointRulesSpecUtils endpointRulesSpecUtils ;
40
-
41
53
private final ClassName partitionsClass ;
54
+ private final ClassName partitionClass ;
55
+ private final ClassName regionOverrideClass ;
56
+ private final ClassName outputsClass ;
42
57
43
58
public DefaultPartitionDataProviderSpec (IntermediateModel model ) {
44
59
this .model = model ;
45
60
this .endpointRulesSpecUtils = new EndpointRulesSpecUtils (model );
46
61
this .partitionsClass = endpointRulesSpecUtils .rulesRuntimeClassName ("Partitions" );
62
+ this .partitionClass = endpointRulesSpecUtils .rulesRuntimeClassName ("Partition" );
63
+ this .regionOverrideClass = endpointRulesSpecUtils .rulesRuntimeClassName ("RegionOverride" );
64
+ this .outputsClass = endpointRulesSpecUtils .rulesRuntimeClassName ("Outputs" );
47
65
}
48
66
49
67
@ Override
@@ -54,10 +72,8 @@ public TypeSpec poetSpec() {
54
72
.addSuperinterface (
55
73
endpointRulesSpecUtils .rulesRuntimeClassName ("PartitionDataProvider" ));
56
74
57
- builder .addField (partitionDataField ());
58
- builder .addField (partitionsLazyField ());
75
+ builder .addType (lazyPartitionsContainer ());
59
76
builder .addMethod (loadPartitionsMethod ());
60
- builder .addMethod (doLoadPartitionsMethod ());
61
77
return builder .build ();
62
78
}
63
79
@@ -68,44 +84,24 @@ public ClassName className() {
68
84
69
85
private MethodSpec loadPartitionsMethod () {
70
86
MethodSpec .Builder builder = MethodSpec .methodBuilder ("loadPartitions" )
71
- .addAnnotation (Override .class )
72
- .addModifiers (Modifier .PUBLIC )
73
- .returns (partitionsClass );
74
-
75
- builder .addStatement ("return PARTITIONS.getValue()" );
76
-
77
- return builder .build ();
78
- }
79
-
80
- private FieldSpec partitionDataField () {
81
- FieldSpec .Builder builder = FieldSpec .builder (String .class , "DEFAULT_PARTITION_DATA" , Modifier .PRIVATE ,
82
- Modifier .STATIC , Modifier .FINAL );
83
- builder .initializer ("$S" , readPartitionsJson ());
84
- return builder .build ();
85
- }
86
-
87
- private FieldSpec partitionsLazyField () {
88
- ParameterizedTypeName lazyType = ParameterizedTypeName .get (ClassName .get (Lazy .class ),
89
- partitionsClass );
90
- FieldSpec .Builder builder = FieldSpec .builder (lazyType , "PARTITIONS" )
91
- .addModifiers (Modifier .PRIVATE , Modifier .STATIC , Modifier .FINAL );
92
- CodeBlock init = CodeBlock .builder ()
93
- .addStatement ("new $T<>($T::doLoadPartitions)" , Lazy .class , className ())
94
- .build ();
95
-
96
- builder .initializer (init );
87
+ .addAnnotation (Override .class )
88
+ .addModifiers (Modifier .PUBLIC )
89
+ .returns (partitionsClass );
97
90
91
+ builder .addStatement ("return LazyPartitionsContainer.PARTITIONS" );
98
92
return builder .build ();
99
93
}
100
94
101
- private MethodSpec doLoadPartitionsMethod () {
102
- MethodSpec .Builder builder = MethodSpec .methodBuilder ("doLoadPartitions" )
103
- .addModifiers (Modifier .PRIVATE , Modifier .STATIC )
104
- .returns (partitionsClass );
105
-
106
- builder .addStatement ("return $T.fromNode($T.parser().parse(DEFAULT_PARTITION_DATA))" , partitionsClass , JsonNode .class );
107
-
108
- return builder .build ();
95
+ private TypeSpec lazyPartitionsContainer () {
96
+ CodeBlock .Builder builder = CodeBlock .builder ();
97
+ JsonNode node = JsonNode .parser ().parse (readPartitionsJson ());
98
+ codegenPartitions (builder , node );
99
+ return TypeSpec .classBuilder ("LazyPartitionsContainer" )
100
+ .addModifiers (Modifier .STATIC )
101
+ .addField (FieldSpec .builder (partitionsClass , "PARTITIONS" , Modifier .STATIC , Modifier .FINAL )
102
+ .initializer (builder .build ())
103
+ .build ())
104
+ .build ();
109
105
}
110
106
111
107
private String readPartitionsJson () {
@@ -132,4 +128,104 @@ private InputStream loadResource(String name) {
132
128
Validate .notNull (resourceAsStream , "Failed to load resource from %s" , name );
133
129
return resourceAsStream ;
134
130
}
131
+
132
+ private void codegenPartitions (CodeBlock .Builder builder , JsonNode node ) {
133
+ builder .add ("$T.builder()" , partitionsClass );
134
+ Map <String , JsonNode > objNode = node .asObject ();
135
+
136
+ JsonNode version = objNode .get (VERSION );
137
+ if (version != null ) {
138
+ builder .add (".version(" );
139
+ builder .add ("$S" , version .asString ());
140
+ builder .add (")" );
141
+ }
142
+
143
+ JsonNode partitions = objNode .get (PARTITIONS );
144
+ if (partitions != null ) {
145
+ partitions .asArray ().forEach (partNode -> {
146
+ builder .add (".addPartition(" );
147
+ codegenPartition (builder , partNode );
148
+ builder .add (")" );
149
+ });
150
+ }
151
+ builder .add (".build()" );
152
+ }
153
+
154
+ private void codegenPartition (CodeBlock .Builder builder , JsonNode node ) {
155
+ builder .add ("$T.builder()" , partitionClass );
156
+ Map <String , JsonNode > objNode = node .asObject ();
157
+
158
+ JsonNode id = objNode .get (ID );
159
+ if (id != null ) {
160
+ builder .add (".id(" );
161
+ builder .add ("$S" , id .asString ());
162
+ builder .add (")" );
163
+ }
164
+
165
+ JsonNode regionRegex = objNode .get (REGION_REGEX );
166
+ if (regionRegex != null ) {
167
+ builder .add (".regionRegex(" );
168
+ builder .add ("$S" , regionRegex .asString ());
169
+ builder .add (")" );
170
+ }
171
+
172
+ JsonNode regions = objNode .get (REGIONS );
173
+ if (regions != null ) {
174
+ // At the moment `RegionOverride.fromNode` does nothing. We need to fix it here **and** if we keep the
175
+ // loading from textual JSON also fix `RegionOverride.fromNode`.
176
+ Map <String , JsonNode > regionsObj = regions .asObject ();
177
+ regionsObj .forEach ((k , v ) -> {
178
+ builder .add (".putRegion($S, " , k );
179
+ codegenRegionOverride (builder , v );
180
+ builder .add (")" );
181
+ });
182
+ }
183
+
184
+ JsonNode outputs = objNode .get (OUTPUTS );
185
+ if (outputs != null ) {
186
+ builder .add (".outputs(" );
187
+ codegenOutputs (builder , outputs );
188
+ builder .add (")" );
189
+ }
190
+ builder .add (".build()" );
191
+ }
192
+
193
+ private void codegenRegionOverride (CodeBlock .Builder builder , JsonNode node ) {
194
+ builder .add ("$T.builder().build()" , regionOverrideClass );
195
+ }
196
+
197
+ private void codegenOutputs (CodeBlock .Builder builder , JsonNode node ) {
198
+ builder .add ("$T.builder()" , outputsClass );
199
+ Map <String , JsonNode > objNode = node .asObject ();
200
+
201
+ JsonNode dnsSuffix = objNode .get (DNS_SUFFIX );
202
+ if (dnsSuffix != null ) {
203
+ builder .add (".dnsSuffix(" );
204
+ builder .add ("$S" , dnsSuffix .asString ());
205
+ builder .add (")" );
206
+ }
207
+
208
+ JsonNode dualStackDnsSuffix = objNode .get (DUAL_STACK_DNS_SUFFIX );
209
+ if (dualStackDnsSuffix != null ) {
210
+ builder .add (".dualStackDnsSuffix(" );
211
+ builder .add ("$S" , dualStackDnsSuffix .asString ());
212
+ builder .add (")" );
213
+ }
214
+
215
+ JsonNode supportsFips = objNode .get (SUPPORTS_FIPS );
216
+ if (supportsFips != null ) {
217
+ builder .add (".supportsFips(" );
218
+ builder .add ("$L" , supportsFips .asBoolean ());
219
+ builder .add (")" );
220
+ }
221
+
222
+ JsonNode supportsDualStack = objNode .get (SUPPORTS_DUAL_STACK );
223
+ if (supportsDualStack != null ) {
224
+ builder .add (".supportsDualStack(" );
225
+ builder .add ("$L" , supportsDualStack .asBoolean ());
226
+ builder .add (")" );
227
+ }
228
+ builder .add (".build()" );
229
+ }
135
230
}
231
+
0 commit comments