Skip to content

Commit 59a4edb

Browse files
committed
Refactoring for JSON marshalling/unmarshalling, support for JSON value trait
1 parent ef85734 commit 59a4edb

File tree

56 files changed

+1624
-756
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1624
-756
lines changed

codegen/src/main/java/software/amazon/awssdk/codegen/AddShapes.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,8 @@ private MemberModel generateMemberModel(String c2jMemberName, Member c2jMemberDe
162162
.withVariable(new VariableModel(variableName, variableType, variableDeclarationType)
163163
.withDocumentation(c2jMemberDefinition.getDocumentation()))
164164
.withSetterModel(new VariableModel(variableName, variableType, variableDeclarationType))
165-
.withGetterModel(new ReturnTypeModel(variableType));
165+
.withGetterModel(new ReturnTypeModel(variableType))
166+
.withJsonValue(c2jMemberDefinition.getJsonValue());
166167
memberModel.setDocumentation(c2jMemberDefinition.getDocumentation());
167168
memberModel.setDeprecated(c2jMemberDefinition.isDeprecated());
168169
memberModel

codegen/src/main/java/software/amazon/awssdk/codegen/IntermediateModelBuilder.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ private List<IntermediateModelShapeProcessor> createShapeProcessors() {
9090
return processors;
9191
}
9292

93-
public IntermediateModel build() throws IOException {
93+
public IntermediateModel build() {
9494
// Note: This needs to come before any pre/post processing of the
9595
// models, as the transformer must have access to the original shapes,
9696
// before any customizations have been applied (which modifies them).
@@ -119,7 +119,7 @@ public IntermediateModel build() throws IOException {
119119

120120
IntermediateModel fullModel = new IntermediateModel(
121121
constructMetadata(service, codeGenConfig, customConfig), operations, shapes,
122-
customConfig, examples, authorizers, paginators.getPaginators());
122+
customConfig, examples, authorizers, paginators.getPaginators(), namingStrategy);
123123

124124
customization.postprocess(fullModel);
125125

@@ -135,7 +135,8 @@ public IntermediateModel build() throws IOException {
135135
fullModel.getCustomizationConfig(),
136136
fullModel.getExamples(),
137137
fullModel.getCustomAuthorizers(),
138-
fullModel.getPaginators());
138+
fullModel.getPaginators(),
139+
namingStrategy);
139140

140141
linkMembersToShapes(trimmedModel);
141142
linkOperationsToInputOutputShapes(trimmedModel);

codegen/src/main/java/software/amazon/awssdk/codegen/emitters/tasks/MarshallerGeneratorTasks.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import software.amazon.awssdk.codegen.model.intermediate.Metadata;
3131
import software.amazon.awssdk.codegen.model.intermediate.ShapeModel;
3232
import software.amazon.awssdk.codegen.model.intermediate.ShapeType;
33-
import software.amazon.awssdk.codegen.poet.transform.JsonModelMarshallerSpec;
3433
import software.amazon.awssdk.codegen.poet.transform.MarshallerSpec;
3534
import software.amazon.awssdk.utils.ImmutableMap;
3635

@@ -48,7 +47,7 @@ public MarshallerGeneratorTasks(GeneratorTaskParams dependencies) {
4847
}
4948

5049
@Override
51-
protected List<GeneratorTask> createTasks() throws Exception {
50+
protected List<GeneratorTask> createTasks() {
5251
info("Emitting marshaller classes");
5352
return model.getShapes().entrySet().stream()
5453
.filter(e -> shouldGenerate(e.getValue()))
@@ -70,9 +69,8 @@ private boolean shouldGenerate(ShapeModel shapeModel) {
7069
private Stream<GeneratorTask> createTask(String javaShapeName, ShapeModel shapeModel) throws Exception {
7170
if (metadata.isJsonProtocol()) {
7271
return ShapeType.Request == shapeModel.getShapeType() ?
73-
Stream.of(createPoetGeneratorTask(new JsonModelMarshallerSpec(model, shapeModel, "ModelMarshaller")),
74-
createPoetGeneratorTask(new MarshallerSpec(model, shapeModel))) :
75-
Stream.of(createPoetGeneratorTask(new JsonModelMarshallerSpec(model, shapeModel, "Marshaller")));
72+
Stream.of(createPoetGeneratorTask(new MarshallerSpec(model, shapeModel))) :
73+
Stream.empty();
7674
}
7775

7876
return Stream.of(

codegen/src/main/java/software/amazon/awssdk/codegen/emitters/tasks/UnmarshallerGeneratorTasks.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import static software.amazon.awssdk.utils.FunctionalUtils.safeFunction;
1919

2020
import freemarker.template.Template;
21+
import java.util.Collections;
2122
import java.util.List;
2223
import java.util.Map;
2324
import java.util.stream.Collectors;
@@ -43,6 +44,9 @@ public UnmarshallerGeneratorTasks(GeneratorTaskParams dependencies) {
4344
@Override
4445
protected List<GeneratorTask> createTasks() throws Exception {
4546
info("Emitting unmarshaller classes");
47+
if (metadata.isJsonProtocol()) {
48+
return Collections.emptyList();
49+
}
4650
return model.getShapes().entrySet().stream()
4751
.filter(e -> shouldGenerate(e.getValue()))
4852
.map(safeFunction(e -> createTask(e.getKey(), e.getValue())))

codegen/src/main/java/software/amazon/awssdk/codegen/model/intermediate/IntermediateModel.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import software.amazon.awssdk.codegen.internal.Utils;
3232
import software.amazon.awssdk.codegen.model.config.customization.CustomizationConfig;
3333
import software.amazon.awssdk.codegen.model.service.PaginatorDefinition;
34+
import software.amazon.awssdk.codegen.naming.DefaultNamingStrategy;
35+
import software.amazon.awssdk.codegen.naming.NamingStrategy;
3436
import software.amazon.awssdk.core.SdkResponseMetadata;
3537
import software.amazon.awssdk.utils.IoUtils;
3638

@@ -56,6 +58,9 @@ public final class IntermediateModel {
5658
@JsonIgnore
5759
private final Map<String, PaginatorDefinition> paginators;
5860

61+
@JsonIgnore
62+
private final NamingStrategy namingStrategy;
63+
5964
@JsonCreator
6065
public IntermediateModel(
6166
@JsonProperty("metadata") Metadata metadata,
@@ -64,7 +69,7 @@ public IntermediateModel(
6469
@JsonProperty("customizationConfig") CustomizationConfig customizationConfig,
6570
@JsonProperty("serviceExamples") ServiceExamples examples) {
6671

67-
this(metadata, operations, shapes, customizationConfig, examples, Collections.emptyMap(), Collections.emptyMap());
72+
this(metadata, operations, shapes, customizationConfig, examples, Collections.emptyMap(), Collections.emptyMap(), null);
6873
}
6974

7075
public IntermediateModel(
@@ -74,14 +79,16 @@ public IntermediateModel(
7479
CustomizationConfig customizationConfig,
7580
ServiceExamples examples,
7681
Map<String, AuthorizerModel> customAuthorizers,
77-
Map<String, PaginatorDefinition> paginators) {
82+
Map<String, PaginatorDefinition> paginators,
83+
NamingStrategy namingStrategy) {
7884
this.metadata = metadata;
7985
this.operations = operations;
8086
this.shapes = shapes;
8187
this.customizationConfig = customizationConfig;
8288
this.examples = examples;
8389
this.customAuthorizers = customAuthorizers;
8490
this.paginators = paginators;
91+
this.namingStrategy = namingStrategy;
8592
}
8693

8794
public Metadata getMetadata() {
@@ -116,6 +123,10 @@ public Map<String, PaginatorDefinition> getPaginators() {
116123
return paginators;
117124
}
118125

126+
public NamingStrategy getNamingStrategy() {
127+
return namingStrategy;
128+
}
129+
119130
/**
120131
* @return Exception unmarshaller implementation to use. Currently only needed by XML based
121132
* protocols.

codegen/src/main/java/software/amazon/awssdk/codegen/model/intermediate/MemberModel.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ public class MemberModel extends DocumentationModel {
7474

7575
private String beanStyleSetterName;
7676

77+
private boolean isJsonValue;
78+
7779
public String getName() {
7880
return name;
7981
}
@@ -451,6 +453,19 @@ public boolean getIsBinary() {
451453
return http.getIsStreaming() || (http.getIsPayload() && isSdkBytesType());
452454
}
453455

456+
public boolean isJsonValue() {
457+
return isJsonValue;
458+
}
459+
460+
public void setJsonValue(boolean jsonValue) {
461+
isJsonValue = jsonValue;
462+
}
463+
464+
public MemberModel withJsonValue(boolean jsonValue) {
465+
setJsonValue(jsonValue);
466+
return this;
467+
}
468+
454469
/**
455470
* @return Implementation of {@link PathMarshaller} to use if this member is bound the the URI.
456471
* @throws IllegalStateException If this member is not bound to the URI. Templates should first check
@@ -508,7 +523,7 @@ public String getMarshallingType() {
508523
} else if (isMap()) {
509524
return "MAP";
510525
} else if (!isSimple()) {
511-
return "STRUCTURED";
526+
return "SDK_POJO";
512527
} else {
513528
return TypeUtils.getMarshallingType(variable.getSimpleType());
514529
}
@@ -525,7 +540,7 @@ public String getMarshallingTargetClass() {
525540
} else if (isMap()) {
526541
return "Map";
527542
} else if (!isSimple()) {
528-
return "StructuredPojo";
543+
return "SdkPojo";
529544
} else {
530545
return variable.getVariableType();
531546
}

codegen/src/main/java/software/amazon/awssdk/codegen/model/service/Member.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
package software.amazon.awssdk.codegen.model.service;
1717

18+
import com.fasterxml.jackson.annotation.JsonProperty;
19+
1820
public class Member {
1921

2022
private String shape;
@@ -39,6 +41,9 @@ public class Member {
3941

4042
private boolean deprecated;
4143

44+
@JsonProperty("jsonvalue")
45+
private boolean jsonValue;
46+
4247
public String getShape() {
4348
return shape;
4449
}
@@ -126,4 +131,12 @@ public boolean isDeprecated() {
126131
public void setDeprecated(boolean deprecated) {
127132
this.deprecated = deprecated;
128133
}
134+
135+
public boolean getJsonValue() {
136+
return jsonValue;
137+
}
138+
139+
public void setJsonValue(boolean jsonValue) {
140+
this.jsonValue = jsonValue;
141+
}
129142
}

codegen/src/main/java/software/amazon/awssdk/codegen/naming/DefaultNamingStrategy.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@
2222
import static software.amazon.awssdk.codegen.internal.Constant.REQUEST_CLASS_SUFFIX;
2323
import static software.amazon.awssdk.codegen.internal.Constant.RESPONSE_CLASS_SUFFIX;
2424
import static software.amazon.awssdk.codegen.internal.Constant.VARIABLE_NAME_SUFFIX;
25+
import static software.amazon.awssdk.codegen.internal.Utils.capitalize;
2526
import static software.amazon.awssdk.codegen.internal.Utils.unCapitalize;
2627

2728
import java.util.Arrays;
2829
import java.util.Collections;
2930
import java.util.HashSet;
31+
import java.util.Locale;
3032
import java.util.Objects;
3133
import java.util.Optional;
3234
import java.util.Set;
@@ -35,6 +37,7 @@
3537
import software.amazon.awssdk.codegen.internal.Constant;
3638
import software.amazon.awssdk.codegen.internal.Utils;
3739
import software.amazon.awssdk.codegen.model.config.customization.CustomizationConfig;
40+
import software.amazon.awssdk.codegen.model.intermediate.MemberModel;
3841
import software.amazon.awssdk.codegen.model.service.ServiceModel;
3942
import software.amazon.awssdk.codegen.model.service.Shape;
4043
import software.amazon.awssdk.utils.Logger;
@@ -153,6 +156,10 @@ private String concatServiceNameIfShareModel(String serviceName) {
153156
return serviceName;
154157
}
155158

159+
private String screamCase(String word) {
160+
return Stream.of(splitOnWordBoundaries(word)).map(s -> s.toUpperCase(Locale.US)).collect(joining("_"));
161+
}
162+
156163
private String pascalCase(String word) {
157164
return Stream.of(splitOnWordBoundaries(word)).map(StringUtils::lowerCase).map(Utils::capitalize).collect(joining());
158165
}
@@ -292,6 +299,11 @@ public String getFluentEnumSetterMethodName(String memberName, Shape shape) {
292299
return Utils.unCapitalize(memberName);
293300
}
294301

302+
@Override
303+
public String getSdkFieldFieldName(MemberModel memberModel) {
304+
return screamCase(memberModel.getName()) + "_FIELD";
305+
}
306+
295307
private String[] splitOnWordBoundaries(String toSplit) {
296308
String result = toSplit;
297309

codegen/src/main/java/software/amazon/awssdk/codegen/naming/NamingStrategy.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515

1616
package software.amazon.awssdk.codegen.naming;
1717

18+
import software.amazon.awssdk.codegen.model.intermediate.MemberModel;
1819
import software.amazon.awssdk.codegen.model.service.Shape;
20+
import software.amazon.awssdk.core.protocol.SdkField;
1921

2022
/**
2123
* Strategy to name various Java constructs based on the naming in the model and potentially customizations.
@@ -143,4 +145,12 @@ public interface NamingStrategy {
143145
* @return Name of the getter method for an enum model class member.
144146
*/
145147
String getFluentEnumSetterMethodName(String memberName, Shape shape);
148+
149+
/**
150+
* Stuttering is intentional, returns the name of the {@link SdkField} field.
151+
*
152+
* @param memberModel Member to generate field name for.
153+
* @return Name of field for {@link SdkField} pojo.
154+
*/
155+
String getSdkFieldFieldName(MemberModel memberModel);
146156
}

codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/JsonProtocolSpec.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ public MethodSpec initProtocolFactory(IntermediateModel model) {
104104

105105
@Override
106106
public CodeBlock responseHandler(IntermediateModel model, OperationModel opModel) {
107-
ClassName unmarshaller = getUnmarshallerType(opModel);
108107
// TODO for rest-json we need to use the real response handler since response members will be bound to headers, for
109108
// aws-json we need to have a dummy response handler since the response members will be in the initial-response
110109
// event message
@@ -116,14 +115,14 @@ public CodeBlock responseHandler(IntermediateModel model, OperationModel opModel
116115
.builder()
117116
.add("\n\n$T<$T> responseHandler = $L.createResponseHandler(new $T()" +
118117
" .withPayloadJson($L)" +
119-
" .withHasStreamingSuccessResponse($L), new $T());",
118+
" .withHasStreamingSuccessResponse($L), $T::builder);",
120119
HttpResponseHandler.class,
121120
pojoResponseType,
122121
protocolFactory,
123122
JsonOperationMetadata.class,
124123
!opModel.getHasBlobMemberAsPayload(),
125124
opModel.hasStreamingOutput(),
126-
unmarshaller);
125+
pojoResponseType);
127126
if (opModel.hasEventStreamOutput()) {
128127
builder.add("\n\n$T<$T> voidResponseHandler = $L.createResponseHandler(new $T()" +
129128
" .withPayloadJson(false)" +
@@ -314,10 +313,6 @@ private String eventStreamOutputWhenComplete(String responseHandlerName) {
314313
+ "})", responseHandlerName);
315314
}
316315

317-
private ClassName getUnmarshallerType(OperationModel opModel) {
318-
return poetExtensions.getTransformClass(opModel.getReturnType().getReturnType() + "Unmarshaller");
319-
}
320-
321316
/**
322317
* Gets the POJO response type for the operation.
323318
*

0 commit comments

Comments
 (0)