Skip to content

Commit 788b1f0

Browse files
committed
Refact xml marshallers/unmarshallers
1 parent fa248a8 commit 788b1f0

File tree

99 files changed

+2472
-1677
lines changed

Some content is hidden

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

99 files changed

+2472
-1677
lines changed

codegen/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,11 @@
130130
<artifactId>aws-query-protocol</artifactId>
131131
<version>${awsjavasdk.version}</version>
132132
</dependency>
133+
<dependency>
134+
<groupId>software.amazon.awssdk</groupId>
135+
<artifactId>aws-xml-protocol</artifactId>
136+
<version>${awsjavasdk.version}</version>
137+
</dependency>
133138
<dependency>
134139
<groupId>software.amazon.awssdk</groupId>
135140
<artifactId>protocol-core</artifactId>

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

Lines changed: 4 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -15,37 +15,26 @@
1515

1616
package software.amazon.awssdk.codegen.emitters.tasks;
1717

18-
import static software.amazon.awssdk.codegen.model.intermediate.Protocol.AWS_JSON;
1918
import static software.amazon.awssdk.utils.FunctionalUtils.safeFunction;
2019

21-
import freemarker.template.Template;
22-
import java.io.IOException;
2320
import java.util.List;
24-
import java.util.Map;
2521
import java.util.stream.Collectors;
2622
import java.util.stream.Stream;
27-
import software.amazon.awssdk.codegen.emitters.FreemarkerGeneratorTask;
2823
import software.amazon.awssdk.codegen.emitters.GeneratorTask;
2924
import software.amazon.awssdk.codegen.emitters.GeneratorTaskParams;
3025
import software.amazon.awssdk.codegen.model.intermediate.Metadata;
31-
import software.amazon.awssdk.codegen.model.intermediate.Protocol;
3226
import software.amazon.awssdk.codegen.model.intermediate.ShapeModel;
3327
import software.amazon.awssdk.codegen.model.intermediate.ShapeType;
3428
import software.amazon.awssdk.codegen.poet.eventstream.EventStreamUtils;
3529
import software.amazon.awssdk.codegen.poet.transform.MarshallerSpec;
36-
import software.amazon.awssdk.utils.ImmutableMap;
3730

3831
public class MarshallerGeneratorTasks extends BaseGeneratorTasks {
3932

40-
private final String transformClassDir;
4133
private final Metadata metadata;
42-
private final Map<String, ShapeModel> shapes;
4334

4435
public MarshallerGeneratorTasks(GeneratorTaskParams dependencies) {
4536
super(dependencies);
46-
this.transformClassDir = dependencies.getPathProvider().getTransformDirectory();
4737
this.metadata = model.getMetadata();
48-
this.shapes = model.getShapes();
4938
}
5039

5140
@Override
@@ -62,56 +51,18 @@ private boolean shouldGenerate(ShapeModel shapeModel) {
6251
info("Skip generating marshaller class for " + shapeModel.getShapeName());
6352
return false;
6453
}
54+
6555
ShapeType shapeType = shapeModel.getShapeType();
6656
return (ShapeType.Request == shapeType || (ShapeType.Model == shapeType && metadata.isJsonProtocol()))
6757
// The event stream shape is a container for event subtypes and isn't something that needs to ever be marshalled
6858
&& !shapeModel.isEventStream();
6959
}
7060

7161
private Stream<GeneratorTask> createTask(String javaShapeName, ShapeModel shapeModel) throws Exception {
72-
if (metadata.isJsonProtocol() || metadata.getProtocol() == Protocol.QUERY || metadata.getProtocol() == Protocol.EC2) {
73-
return ShapeType.Request == shapeModel.getShapeType() ||
74-
(ShapeType.Model == shapeModel.getShapeType() && shapeModel.isEvent()
75-
&& EventStreamUtils.isRequestEvent(model, shapeModel))
62+
return ShapeType.Request == shapeModel.getShapeType() || (ShapeType.Model == shapeModel.getShapeType()
63+
&& shapeModel.isEvent()
64+
&& EventStreamUtils.isRequestEvent(model, shapeModel))
7665
? Stream.of(createPoetGeneratorTask(new MarshallerSpec(model, shapeModel)))
7766
: Stream.empty();
78-
}
79-
80-
return Stream.of(
81-
createMarshallerTask(javaShapeName,
82-
freemarker.getModelMarshallerTemplate(),
83-
javaShapeName + "Marshaller",
84-
transformClassDir));
85-
}
86-
87-
private GeneratorTask createMarshallerTask(String javaShapeName, Template template,
88-
String marshallerClassName, String marshallerDirectory) throws IOException {
89-
Map<String, Object> marshallerDataModel = ImmutableMap.<String, Object>builder()
90-
.put("fileHeader", model.getFileHeader())
91-
.put("shapeName", javaShapeName)
92-
.put("shapes", shapes)
93-
.put("metadata", metadata)
94-
.put("transformPackage", model.getMetadata().getFullTransformPackageName())
95-
.put("requestTransformPackage", model.getMetadata().getFullRequestTransformPackageName())
96-
.put("customConfig", model.getCustomizationConfig())
97-
.put("className", marshallerClassName)
98-
.put("protocolEnum", getProtocolEnumName())
99-
.build();
100-
101-
return new FreemarkerGeneratorTask(marshallerDirectory,
102-
marshallerClassName,
103-
template,
104-
marshallerDataModel);
105-
}
106-
107-
private String getProtocolEnumName() {
108-
switch (metadata.getProtocol()) {
109-
case CBOR:
110-
case ION:
111-
case AWS_JSON:
112-
return AWS_JSON.name();
113-
default:
114-
return metadata.getProtocol().name();
115-
}
11667
}
11768
}

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

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
import static software.amazon.awssdk.utils.FunctionalUtils.safeFunction;
1919

20-
import freemarker.template.Template;
2120
import java.util.Collections;
2221
import java.util.List;
2322
import java.util.Map;
@@ -54,7 +53,6 @@ protected List<GeneratorTask> createTasks() throws Exception {
5453
}
5554

5655
private GeneratorTask createTask(String javaShapeName, ShapeModel shapeModel) throws Exception {
57-
Template template = freemarker.getModelUnmarshallerTemplate();
5856
ShapeType shapeType = shapeModel.getShapeType();
5957
Map<String, Object> dataModel = ImmutableMap.<String, Object>builder()
6058
.put("fileHeader", model.getFileHeader())
@@ -65,16 +63,9 @@ private GeneratorTask createTask(String javaShapeName, ShapeModel shapeModel) th
6563
.build();
6664

6765
switch (shapeType) {
68-
case Response:
69-
case Model: {
70-
return new FreemarkerGeneratorTask(transformClassDir,
71-
javaShapeName + "Unmarshaller",
72-
template,
73-
dataModel);
74-
}
7566
case Exception: {
7667
return new FreemarkerGeneratorTask(transformClassDir,
77-
javaShapeName + "Unmarshaller",
68+
javaShapeName + "Unmarshaller",
7869
freemarker.getExceptionUnmarshallerTemplate(),
7970
dataModel);
8071
}
@@ -90,10 +81,6 @@ private boolean shouldGenerate(ShapeModel shapeModel) {
9081
return false;
9182
}
9283
switch (shapeModel.getShapeType()) {
93-
case Response:
94-
case Model:
95-
// The event stream shape is a container for event subtypes and isn't something that needs to ever be unmarshalled
96-
return !shapeModel.isEventStream();
9784
case Exception:
9885
// Generating Exception Unmarshallers is not required for the JSON protocol
9986
return !metadata.isJsonProtocol();

codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/CustomizationConfig.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@ public class CustomizationConfig {
140140

141141
private boolean skipSyncClientGeneration;
142142

143+
/**
144+
* List of output shapes for which the root xml element should be used while unmarshalling the response
145+
*/
146+
private List<String> useRootXmlElementForResult = new ArrayList<>();
147+
143148
/**
144149
* Custom Response metadata
145150
*/
@@ -389,6 +394,14 @@ public void setSkipSyncClientGeneration(boolean skipSyncClientGeneration) {
389394
this.skipSyncClientGeneration = skipSyncClientGeneration;
390395
}
391396

397+
public List<String> getUseRootXmlElementForResult() {
398+
return useRootXmlElementForResult;
399+
}
400+
401+
public void setUseRootXmlElementForResult(List<String> useRootXmlElementForResult) {
402+
this.useRootXmlElementForResult = useRootXmlElementForResult;
403+
}
404+
392405
public Map<String, String> getCustomResponseMetadata() {
393406
return customResponseMetadata;
394407
}

codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientClass.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
import software.amazon.awssdk.codegen.poet.client.specs.Ec2ProtocolSpec;
4343
import software.amazon.awssdk.codegen.poet.client.specs.JsonProtocolSpec;
4444
import software.amazon.awssdk.codegen.poet.client.specs.ProtocolSpec;
45-
import software.amazon.awssdk.codegen.poet.client.specs.QueryXmlProtocolSpec;
45+
import software.amazon.awssdk.codegen.poet.client.specs.QueryProtocolSpec;
4646
import software.amazon.awssdk.codegen.poet.client.specs.XmlProtocolSpec;
4747
import software.amazon.awssdk.codegen.utils.PaginatorUtils;
4848
import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
@@ -191,7 +191,7 @@ static ProtocolSpec getProtocolSpecs(PoetExtensions poetExtensions, Intermediate
191191
Protocol protocol = model.getMetadata().getProtocol();
192192
switch (protocol) {
193193
case QUERY:
194-
return new QueryXmlProtocolSpec(poetExtensions);
194+
return new QueryProtocolSpec(poetExtensions);
195195
case REST_XML:
196196
return new XmlProtocolSpec(poetExtensions);
197197
case EC2:

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import software.amazon.awssdk.codegen.poet.PoetExtensions;
2222
import software.amazon.awssdk.protocols.query.AwsEc2ProtocolFactory;
2323

24-
public class Ec2ProtocolSpec extends QueryXmlProtocolSpec {
24+
public class Ec2ProtocolSpec extends QueryProtocolSpec {
2525

2626
public Ec2ProtocolSpec(PoetExtensions poetExtensions) {
2727
super(poetExtensions);
@@ -90,4 +90,4 @@ private MethodSpec dryRunMethod() {
9090
9191
}
9292
*/
93-
}
93+
}

codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/QueryXmlProtocolSpec.java renamed to codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/QueryProtocolSpec.java

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,16 @@
4444
import software.amazon.awssdk.protocols.query.AwsQueryProtocolFactory;
4545
import software.amazon.awssdk.utils.StringUtils;
4646

47-
public class QueryXmlProtocolSpec implements ProtocolSpec {
47+
public class QueryProtocolSpec implements ProtocolSpec {
4848

49-
private final PoetExtensions poetExtensions;
49+
protected final PoetExtensions poetExtensions;
5050
private final TypeName unmarshallerType = ParameterizedTypeName.get(Unmarshaller.class,
5151
AwsServiceException.class,
5252
Node.class);
5353
private final TypeName listOfUnmarshallersType = ParameterizedTypeName.get(ClassName.get("java.util", "List"),
5454
unmarshallerType);
5555

56-
public QueryXmlProtocolSpec(PoetExtensions poetExtensions) {
56+
public QueryProtocolSpec(PoetExtensions poetExtensions) {
5757
this.poetExtensions = poetExtensions;
5858
}
5959

@@ -63,6 +63,10 @@ public FieldSpec protocolFactory(IntermediateModel model) {
6363
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build();
6464
}
6565

66+
protected Class<?> protocolFactoryClass() {
67+
return AwsQueryProtocolFactory.class;
68+
}
69+
6670
@Override
6771
public List<FieldSpec> additionalFields() {
6872
return singletonList(FieldSpec.builder(listOfUnmarshallersType, "exceptionUnmarshallers")
@@ -83,15 +87,11 @@ public MethodSpec initProtocolFactory(IntermediateModel model) {
8387
poetExtensions.getModelClass(model.getSdkModeledExceptionBaseClassName()))
8488
.build());
8589
methodSpec.addStatement("this.exceptionUnmarshallers = unmarshallers");
86-
methodSpec.addStatement("return new $T()", protocolFactoryClass());
90+
methodSpec.addStatement("return $T.builder().build()", protocolFactoryClass());
8791

8892
return methodSpec.build();
8993
}
9094

91-
protected Class<?> protocolFactoryClass() {
92-
return AwsQueryProtocolFactory.class;
93-
}
94-
9595
private ClassName getErrorUnmarshallerClass(IntermediateModel model) {
9696
return StringUtils.isNotBlank(model.getExceptionUnmarshallerImpl()) ?
9797
PoetUtils.classNameFromFqcn(model.getExceptionUnmarshallerImpl()) :
@@ -126,17 +126,17 @@ public CodeBlock executionHandler(OperationModel opModel) {
126126
ClassName requestType = poetExtensions.getModelClass(opModel.getInput().getVariableType());
127127
ClassName marshaller = poetExtensions.getTransformClass(opModel.getInputShape().getShapeName() + "Marshaller");
128128
CodeBlock.Builder codeBlock = CodeBlock
129-
.builder()
130-
.add("\n\nreturn clientHandler.execute(new $T<$T, $T>()" +
131-
".withResponseHandler($N)" +
132-
".withErrorResponseHandler($N)" +
133-
".withInput($L)",
134-
ClientExecutionParams.class,
135-
requestType,
136-
responseType,
137-
"responseHandler",
138-
"errorResponseHandler",
139-
opModel.getInput().getVariableName());
129+
.builder()
130+
.add("\n\nreturn clientHandler.execute(new $T<$T, $T>()" +
131+
".withResponseHandler($N)" +
132+
".withErrorResponseHandler($N)" +
133+
".withInput($L)",
134+
ClientExecutionParams.class,
135+
requestType,
136+
responseType,
137+
"responseHandler",
138+
"errorResponseHandler",
139+
opModel.getInput().getVariableName());
140140
if (opModel.hasStreamingInput()) {
141141
return codeBlock.add(".withMarshaller(new $T(new $T(protocolFactory), requestBody)));",
142142
ParameterizedTypeName.get(ClassName.get(StreamingRequestMarshaller.class), requestType),
@@ -154,7 +154,7 @@ public CodeBlock asyncExecutionHandler(IntermediateModel intermediateModel, Oper
154154
ClassName marshaller = poetExtensions.getRequestTransformClass(opModel.getInputShape().getShapeName() + "Marshaller");
155155

156156
String asyncRequestBody = opModel.hasStreamingInput() ? ".withAsyncRequestBody(requestBody)"
157-
: "";
157+
: "";
158158
return CodeBlock.builder().add("\n\nreturn clientHandler.execute(new $T<$T, $T>()\n" +
159159
".withMarshaller(new $T(protocolFactory))" +
160160
".withResponseHandler(responseHandler)" +
@@ -190,4 +190,4 @@ public List<CodeBlock> errorUnmarshallers(IntermediateModel model) {
190190
.add("unmarshallers.add(new $T());", exceptionClass).build();
191191
}).collect(Collectors.toList());
192192
}
193-
}
193+
}

0 commit comments

Comments
 (0)