28
28
import com .squareup .javapoet .WildcardTypeName ;
29
29
import java .io .Serializable ;
30
30
import java .util .ArrayList ;
31
+ import java .util .Collection ;
31
32
import java .util .Collections ;
32
33
import java .util .List ;
33
34
import java .util .Optional ;
@@ -84,46 +85,40 @@ public AwsServiceModel(IntermediateModel intermediateModel, ShapeModel shapeMode
84
85
@ Override
85
86
public TypeSpec poetSpec () {
86
87
if (shapeModel .isEventStream ()) {
87
- OperationModel opModel = EventStreamUtils .findOperationWithEventStream (intermediateModel ,
88
- shapeModel );
89
- String apiName = poetExtensions .getApiName (opModel );
90
- ClassName modelClass = poetExtensions .getModelClassFromShape (shapeModel );
88
+ Collection <OperationModel > opModels = EventStreamUtils .findOperationsWithEventStream (intermediateModel ,
89
+ shapeModel );
91
90
92
- if (EventStreamUtils .doesShapeContainsEventStream (opModel .getOutputShape (), shapeModel )) {
93
- ClassName responseHandlerClass = poetExtensions .eventStreamResponseHandlerType (opModel );
94
- return PoetUtils .createInterfaceBuilder (modelClass )
95
- .addAnnotation (SdkPublicApi .class )
96
- .addSuperinterface (ClassName .get (SdkPojo .class ))
97
- .addJavadoc ("Base interface for all event types of the $L API." , apiName )
98
- .addField (FieldSpec .builder (modelClass , "UNKNOWN" )
99
- .addModifiers (PUBLIC , Modifier .STATIC , Modifier .FINAL )
100
- .initializer (CodeBlock .builder ()
101
- .add ("new $T() {\n "
102
- + " @Override\n "
103
- + " public $T<$T<?>> sdkFields() {\n "
104
- + " return $T.emptyList();\n "
105
- + " }\n "
106
- + " @Override\n "
107
- + " public void accept($T.Visitor visitor) {"
108
- + " \n visitor.visitDefault(this);\n "
109
- + " }\n "
110
- + " };\n " ,
111
- modelClass , List .class , SdkField .class ,
112
- Collections .class , responseHandlerClass
113
- )
114
- .build ())
115
- .addJavadoc ("Special type of {@link $T} for unknown types of events that this "
116
- + "version of the SDK does not know about" , modelClass )
117
- .build ())
118
- .addMethod (acceptMethodSpec (modelClass , responseHandlerClass )
119
- .addModifiers (Modifier .ABSTRACT )
120
- .build ())
121
- .build ();
91
+ Collection <OperationModel > outputOperations = findOutputEventStreamOperations (opModels , shapeModel );
122
92
123
- } else if (EventStreamUtils .doesShapeContainsEventStream (opModel .getInputShape (), shapeModel )) {
93
+ ClassName modelClass = poetExtensions .getModelClassFromShape (shapeModel );
94
+
95
+ if (!outputOperations .isEmpty ()) {
96
+ CodeBlock unknownInitializer = buildUnknownEventStreamInitializer (outputOperations ,
97
+ modelClass );
98
+
99
+ TypeSpec .Builder builder =
100
+ PoetUtils .createInterfaceBuilder (modelClass )
101
+ .addAnnotation (SdkPublicApi .class )
102
+ .addSuperinterface (ClassName .get (SdkPojo .class ))
103
+ .addJavadoc ("Base interface for all event types in $L." , shapeModel .getShapeName ())
104
+ .addField (FieldSpec .builder (modelClass , "UNKNOWN" )
105
+ .addModifiers (PUBLIC , Modifier .STATIC , Modifier .FINAL )
106
+ .initializer (unknownInitializer )
107
+ .addJavadoc ("Special type of {@link $T} for unknown types of events that this "
108
+ + "version of the SDK does not know about" , modelClass )
109
+ .build ());
110
+
111
+ for (OperationModel opModel : outputOperations ) {
112
+ ClassName responseHandlerClass = poetExtensions .eventStreamResponseHandlerType (opModel );
113
+ builder .addMethod (acceptMethodSpec (modelClass , responseHandlerClass )
114
+ .addModifiers (Modifier .ABSTRACT )
115
+ .build ());
116
+ }
117
+ return builder .build ();
118
+ } else if (hasInputStreamOperations (opModels , shapeModel )) {
124
119
return PoetUtils .createInterfaceBuilder (modelClass )
125
120
.addAnnotation (SdkPublicApi .class )
126
- .addJavadoc ("Base interface for all event types of the $L API ." , apiName )
121
+ .addJavadoc ("Base interface for all event types in $L ." , shapeModel . getShapeName () )
127
122
.build ();
128
123
}
129
124
@@ -160,21 +155,25 @@ public TypeSpec poetSpec() {
160
155
if (this .shapeModel .isEvent ()) {
161
156
ShapeModel eventStream = EventStreamUtils .getBaseEventStreamShape (intermediateModel , shapeModel );
162
157
ClassName eventStreamClassName = poetExtensions .getModelClassFromShape (eventStream );
163
- OperationModel opModel = EventStreamUtils .findOperationWithEventStream (intermediateModel ,
158
+ Collection < OperationModel > opModels = EventStreamUtils .findOperationsWithEventStream (intermediateModel ,
164
159
eventStream );
165
160
166
- if (EventStreamUtils .doesShapeContainsEventStream (opModel .getOutputShape (), eventStream )) {
161
+ Collection <OperationModel > outputOperations = findOutputEventStreamOperations (opModels , eventStream );
162
+
163
+ if (!outputOperations .isEmpty ()) {
167
164
ClassName modelClass = poetExtensions .getModelClass (shapeModel .getShapeName ());
168
- ClassName responseHandlerClass = poetExtensions .eventStreamResponseHandlerType (opModel );
169
165
specBuilder .addSuperinterface (eventStreamClassName );
170
- specBuilder .addMethod (acceptMethodSpec (modelClass , responseHandlerClass )
171
- .addAnnotation (Override .class )
172
- .addCode (CodeBlock .builder ()
173
- .addStatement ("visitor.visit(this)" )
174
- .build ())
175
- .build ());
176
-
177
- } else if (EventStreamUtils .doesShapeContainsEventStream (opModel .getInputShape (), eventStream )) {
166
+ for (OperationModel opModel : outputOperations ) {
167
+ ClassName responseHandlerClass = poetExtensions .eventStreamResponseHandlerType (opModel );
168
+ specBuilder .addMethod (acceptMethodSpec (modelClass , responseHandlerClass )
169
+ .addAnnotation (Override .class )
170
+ .addCode (CodeBlock .builder ()
171
+ .addStatement ("visitor.visit(this)" )
172
+ .build ())
173
+ .build ());
174
+ }
175
+
176
+ } else if (hasInputStreamOperations (opModels , eventStream )) {
178
177
specBuilder .addSuperinterface (eventStreamClassName );
179
178
} else {
180
179
throw new IllegalArgumentException (shapeModel .getC2jName () + " event shape is not a member in any "
@@ -190,6 +189,44 @@ public TypeSpec poetSpec() {
190
189
}
191
190
}
192
191
192
+ private boolean hasInputStreamOperations (Collection <OperationModel > opModels , ShapeModel eventStream ) {
193
+ return opModels .stream ()
194
+ .anyMatch (op -> EventStreamUtils .doesShapeContainsEventStream (op .getInputShape (), eventStream ));
195
+ }
196
+
197
+ private List <OperationModel > findOutputEventStreamOperations (Collection <OperationModel > opModels ,
198
+ ShapeModel eventStream ) {
199
+ return opModels
200
+ .stream ()
201
+ .filter (opModel -> EventStreamUtils .doesShapeContainsEventStream (opModel .getOutputShape (), eventStream ))
202
+ .collect (Collectors .toList ());
203
+ }
204
+
205
+ private CodeBlock buildUnknownEventStreamInitializer (Collection <OperationModel > outputOperations ,
206
+ ClassName eventStreamModelClass ) {
207
+ CodeBlock .Builder builder = CodeBlock .builder ()
208
+ .add ("new $T() {\n "
209
+ + " @Override\n "
210
+ + " public $T<$T<?>> sdkFields() {\n "
211
+ + " return $T.emptyList();\n "
212
+ + " }\n " ,
213
+ eventStreamModelClass , List .class , SdkField .class ,
214
+ Collections .class
215
+ );
216
+
217
+ for (OperationModel opModel : outputOperations ) {
218
+ ClassName responseHandlerClass = poetExtensions .eventStreamResponseHandlerType (opModel );
219
+ builder .add (" @Override\n "
220
+ + " public void accept($T.Visitor visitor) {"
221
+ + " \n visitor.visitDefault(this);\n "
222
+ + " }\n " , responseHandlerClass );
223
+ }
224
+
225
+ builder .add (" }\n " );
226
+
227
+ return builder .build ();
228
+ }
229
+
193
230
private MethodSpec sdkFieldsMethod () {
194
231
ParameterizedTypeName sdkFieldType = ParameterizedTypeName .get (ClassName .get (SdkField .class ),
195
232
WildcardTypeName .subtypeOf (ClassName .get (Object .class )));
0 commit comments