Skip to content

Commit a650eeb

Browse files
Apply jsonName to examples trait in OpenAPI
This updates the OpenAPI conversion to apply the jsonName trait if said trait is enabled.
1 parent 6bcf579 commit a650eeb

File tree

4 files changed

+127
-3
lines changed

4 files changed

+127
-3
lines changed

smithy-openapi/src/main/java/software/amazon/smithy/openapi/fromsmithy/protocols/AwsRestJson1Protocol.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,6 @@ private boolean hasSingleUnionMember(StructureShape shape, Model model) {
167167

168168
@Override
169169
Node transformSmithyValueToProtocolValue(Context<RestJson1Trait> context, Shape shape, Node value) {
170-
return value;
170+
return value.accept(new JsonValueNodeTransformer(context, shape));
171171
}
172172
}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
package software.amazon.smithy.openapi.fromsmithy.protocols;
6+
7+
import java.util.Map;
8+
import software.amazon.smithy.model.node.ArrayNode;
9+
import software.amazon.smithy.model.node.BooleanNode;
10+
import software.amazon.smithy.model.node.Node;
11+
import software.amazon.smithy.model.node.NodeVisitor;
12+
import software.amazon.smithy.model.node.NullNode;
13+
import software.amazon.smithy.model.node.NumberNode;
14+
import software.amazon.smithy.model.node.ObjectNode;
15+
import software.amazon.smithy.model.node.StringNode;
16+
import software.amazon.smithy.model.shapes.MapShape;
17+
import software.amazon.smithy.model.shapes.MemberShape;
18+
import software.amazon.smithy.model.shapes.Shape;
19+
import software.amazon.smithy.model.traits.JsonNameTrait;
20+
import software.amazon.smithy.openapi.fromsmithy.Context;
21+
22+
/**
23+
* Applies the jsonName trait to a node value if applicable.
24+
*/
25+
public class JsonValueNodeTransformer implements NodeVisitor<Node> {
26+
private final Context<?> context;
27+
private final Shape shape;
28+
29+
/**
30+
* Construct a JsonValueNodeTransformer.
31+
*
32+
* @param context Conversion context. Used to determine if jsonName should be used.
33+
* @param shape The shape of the node being converted.
34+
*/
35+
public JsonValueNodeTransformer(Context<?> context, Shape shape) {
36+
this.context = context;
37+
this.shape = shape;
38+
}
39+
40+
@Override
41+
public Node booleanNode(BooleanNode node) {
42+
return node;
43+
}
44+
45+
@Override
46+
public Node nullNode(NullNode node) {
47+
return node;
48+
}
49+
50+
@Override
51+
public Node numberNode(NumberNode node) {
52+
return node;
53+
}
54+
55+
@Override
56+
public Node stringNode(StringNode node) {
57+
return node;
58+
}
59+
60+
@Override
61+
public Node arrayNode(ArrayNode node) {
62+
ArrayNode.Builder resultBuilder = ArrayNode.builder();
63+
Shape listShape = shape.asMemberShape()
64+
.map(m -> context.getModel().expectShape(m.getTarget()))
65+
.orElse(shape);
66+
67+
Shape target = context.getModel().expectShape(listShape.asListShape().get().getMember().getTarget());
68+
JsonValueNodeTransformer elementTransformer = new JsonValueNodeTransformer(context, target);
69+
for (Node element : node.getElements()) {
70+
resultBuilder.withValue(element.accept(elementTransformer));
71+
}
72+
return resultBuilder.build();
73+
}
74+
75+
@Override
76+
public Node objectNode(ObjectNode node) {
77+
Shape actual = shape.asMemberShape()
78+
.map(m -> context.getModel().expectShape(m.getTarget()))
79+
.orElse(shape);
80+
81+
if (shape.isMapShape()) {
82+
return mapNode(actual.asMapShape().get(), node);
83+
}
84+
return structuredNode(actual, node);
85+
}
86+
87+
private Node structuredNode(Shape structure, ObjectNode node) {
88+
ObjectNode.Builder resultBuilder = ObjectNode.builder();
89+
for (Map.Entry<StringNode, Node> entry : node.getMembers().entrySet()) {
90+
String key = entry.getKey().getValue();
91+
if (structure.getMember(key).isPresent()) {
92+
MemberShape member = structure.getMember(key).get();
93+
Shape target = context.getModel().expectShape(member.getTarget());
94+
JsonValueNodeTransformer entryTransformer = new JsonValueNodeTransformer(context, target);
95+
resultBuilder.withMember(getKey(member), entry.getValue().accept(entryTransformer));
96+
} else {
97+
resultBuilder.withMember(key, entry.getValue());
98+
}
99+
}
100+
return resultBuilder.build();
101+
}
102+
103+
private String getKey(MemberShape member) {
104+
if (!context.getJsonSchemaConverter().getConfig().getUseJsonName()) {
105+
return member.getMemberName();
106+
}
107+
return member.getTrait(JsonNameTrait.class)
108+
.map(JsonNameTrait::getValue)
109+
.orElse(member.getMemberName());
110+
}
111+
112+
private Node mapNode(MapShape map, ObjectNode node) {
113+
ObjectNode.Builder resultBuilder = ObjectNode.builder();
114+
Shape target = context.getModel().expectShape(map.getValue().getTarget());
115+
JsonValueNodeTransformer entryTransformer = new JsonValueNodeTransformer(context, target);
116+
for (Map.Entry<StringNode, Node> entry : node.getMembers().entrySet()) {
117+
resultBuilder.withMember(entry.getKey(), entry.getValue().accept(entryTransformer));
118+
}
119+
return resultBuilder.build();
120+
}
121+
}

smithy-openapi/src/test/resources/software/amazon/smithy/openapi/fromsmithy/protocols/examples-test.openapi.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@
149149
"description": "withdrawTestDoc",
150150
"value": {
151151
"location": "Denver",
152-
"bankName": "Chase",
152+
"bank": "Chase",
153153
"atmRecording": "dGVzdHZpZGVv"
154154
}
155155
}
@@ -470,7 +470,7 @@
470470
"location": {
471471
"type": "string"
472472
},
473-
"bankName": {
473+
"bank": {
474474
"type": "string"
475475
},
476476
"atmRecording": {

smithy-openapi/src/test/resources/software/amazon/smithy/openapi/fromsmithy/protocols/examples-test.smithy

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
$version: "2"
2+
13
namespace smithy.examplestrait
24

35
use aws.protocols#restJson1
@@ -76,6 +78,7 @@ operation Withdraw {
7678

7779
location: String
7880

81+
@jsonName("bank")
7982
bankName: String
8083

8184
atmRecording: exampleVideo

0 commit comments

Comments
 (0)