77
88import java .util .*;
99import java .util .concurrent .atomic .AtomicInteger ;
10+ import java .util .function .Function ;
1011import java .util .stream .Collectors ;
1112import java .util .stream .Stream ;
1213
14+ import com .google .common .base .CaseFormat ;
15+ import com .google .common .base .Predicate ;
1316import com .google .common .base .Splitter ;
1417import com .google .common .collect .*;
1518import edu .umd .cs .findbugs .annotations .NonNull ;
19+ import edu .umd .cs .findbugs .annotations .Nullable ;
1620import io .jooby .MediaType ;
1721import io .jooby .StatusCode ;
1822import io .jooby .internal .openapi .OperationExt ;
@@ -160,10 +164,26 @@ protected Object doApply(
160164 snippetContext .put ("headers" , snippetContext .get ("requestHeaders" ));
161165 return resolver .apply (id (), snippetContext );
162166 }
163-
167+ },
168+ requestFields {
164169 @ Override
165- protected String id () {
166- return "http-request" ;
170+ protected Object doApply (
171+ SnippetResolver resolver ,
172+ OperationExt operation ,
173+ Map <String , Object > snippetContext ,
174+ Map <String , Object > args ,
175+ PebbleTemplate self ,
176+ EvaluationContext context ,
177+ int lineNumber )
178+ throws Exception {
179+ /* Body */
180+ List <Map <String , String >> fields = List .of ();
181+ if (operation .getRequestBody () != null ) {
182+ var schema = schema (context , operation .getRequestBody ());
183+ fields = schemaToTable (schema );
184+ }
185+ snippetContext .put ("fields" , fields );
186+ return resolver .apply (id (), snippetContext );
167187 }
168188 },
169189 httpResponse {
@@ -180,14 +200,8 @@ protected Object doApply(
180200 /* Body */
181201 var requestBodyString = "" ;
182202 var statusCode = findStatusCode (args );
183- ResponseExt response ;
184- if (statusCode != null ) {
185- response = (ResponseExt ) operation .getResponses ().get (Integer .toString (statusCode .value ()));
186- if (response == null ) {
187- throw new IllegalArgumentException ("No response: " + statusCode .value ());
188- }
189- } else {
190- response = operation .getDefaultResponse ();
203+ var response = responseByStatusCode (operation , statusCode );
204+ if (statusCode == null ) {
191205 statusCode = StatusCode .valueOf (Integer .parseInt (response .getCode ()));
192206 }
193207 var json = InternalContext .json (context );
@@ -201,10 +215,100 @@ protected Object doApply(
201215 snippetContext .put ("headers" , snippetContext .get ("responseHeaders" ));
202216 return resolver .apply (id (), snippetContext );
203217 }
204-
218+ },
219+ responseFields {
220+ @ Override
221+ protected Object doApply (
222+ SnippetResolver resolver ,
223+ OperationExt operation ,
224+ Map <String , Object > snippetContext ,
225+ Map <String , Object > args ,
226+ PebbleTemplate self ,
227+ EvaluationContext context ,
228+ int lineNumber )
229+ throws Exception {
230+ /* Body */
231+ var statusCode = findStatusCode (args );
232+ var response = responseByStatusCode (operation , statusCode );
233+ var schema = schema (context , response );
234+ snippetContext .put ("fields" , schemaToTable (schema ));
235+ return resolver .apply (id (), snippetContext );
236+ }
237+ },
238+ formParameters {
239+ @ Override
240+ protected Object doApply (
241+ SnippetResolver resolver ,
242+ OperationExt operation ,
243+ Map <String , Object > snippetContext ,
244+ Map <String , Object > args ,
245+ PebbleTemplate self ,
246+ EvaluationContext context ,
247+ int lineNumber )
248+ throws Exception {
249+ snippetContext .put ("parameters" , parametersToTable (operation , p -> "form" .equals (p .getIn ())));
250+ return resolver .apply (id (), snippetContext );
251+ }
252+ },
253+ queryParameters {
254+ @ Override
255+ protected Object doApply (
256+ SnippetResolver resolver ,
257+ OperationExt operation ,
258+ Map <String , Object > snippetContext ,
259+ Map <String , Object > args ,
260+ PebbleTemplate self ,
261+ EvaluationContext context ,
262+ int lineNumber )
263+ throws Exception {
264+ snippetContext .put (
265+ "parameters" , parametersToTable (operation , p -> "query" .equals (p .getIn ())));
266+ return resolver .apply (id (), snippetContext );
267+ }
268+ },
269+ pathParameters {
205270 @ Override
206- protected String id () {
207- return "http-response" ;
271+ protected Object doApply (
272+ SnippetResolver resolver ,
273+ OperationExt operation ,
274+ Map <String , Object > snippetContext ,
275+ Map <String , Object > args ,
276+ PebbleTemplate self ,
277+ EvaluationContext context ,
278+ int lineNumber )
279+ throws Exception {
280+ snippetContext .put ("parameters" , parametersToTable (operation , p -> "path" .equals (p .getIn ())));
281+ return resolver .apply (id (), snippetContext );
282+ }
283+ },
284+ cookieParameters {
285+ @ Override
286+ protected Object doApply (
287+ SnippetResolver resolver ,
288+ OperationExt operation ,
289+ Map <String , Object > snippetContext ,
290+ Map <String , Object > args ,
291+ PebbleTemplate self ,
292+ EvaluationContext context ,
293+ int lineNumber )
294+ throws Exception {
295+ snippetContext .put ("cookies" , parametersToTable (operation , p -> "cookie" .equals (p .getIn ())));
296+ return resolver .apply (id (), snippetContext );
297+ }
298+ },
299+ requestParameters {
300+ @ Override
301+ protected Object doApply (
302+ SnippetResolver resolver ,
303+ OperationExt operation ,
304+ Map <String , Object > snippetContext ,
305+ Map <String , Object > args ,
306+ PebbleTemplate self ,
307+ EvaluationContext context ,
308+ int lineNumber )
309+ throws Exception {
310+ snippetContext .put ("parameters" , parametersToTable (operation , p -> true ));
311+ return resolver .apply (id (), snippetContext );
208312 }
209313 },
210314 schema {
@@ -256,7 +360,7 @@ protected Object doApply(
256360 int lineNumber )
257361 throws Exception {
258362 var statusCode = findStatusCode (args );
259- var response = operation . getResponses (). get ( Integer . toString ( statusCode . value ()) );
363+ var response = responseByStatusCode ( operation , statusCode , null );
260364 if (response == null ) {
261365 throw new IllegalArgumentException ("No response for: " + statusCode );
262366 }
@@ -285,8 +389,8 @@ protected Object doApply(
285389 }
286390 };
287391
288- protected String id () {
289- return name ();
392+ protected final String id () {
393+ return CaseFormat . LOWER_CAMEL . to ( CaseFormat . LOWER_HYPHEN , name () );
290394 }
291395
292396 @ Override
@@ -329,6 +433,25 @@ public Object apply(
329433 }
330434 }
331435
436+ protected ResponseExt responseByStatusCode (
437+ OperationExt operation , @ Nullable StatusCode statusCode ) {
438+ return responseByStatusCode (operation , statusCode , operation .getDefaultResponse ());
439+ }
440+
441+ protected ResponseExt responseByStatusCode (
442+ OperationExt operation , @ Nullable StatusCode statusCode , ResponseExt defaultResponse ) {
443+ ResponseExt response ;
444+ if (statusCode != null ) {
445+ response = (ResponseExt ) operation .getResponses ().get (Integer .toString (statusCode .value ()));
446+ if (response == null ) {
447+ throw new IllegalArgumentException ("No response: " + statusCode .value ());
448+ }
449+ } else {
450+ response = defaultResponse ;
451+ }
452+ return response ;
453+ }
454+
332455 protected Map <String , Object > newSnippetContext (String serverUrl , OperationExt operation ) {
333456 Map <String , Object > map = new HashMap <>();
334457 map .put ("pattern" , operation .getPattern ());
@@ -353,8 +476,10 @@ protected Map<String, Object> newSnippetContext(String serverUrl, OperationExt o
353476 operation .getConsumes ().forEach (value -> requestHeaders .put ("Content-Type" , value ));
354477 }
355478
356- map .put ("requestHeaders" , requestHeaders .entries ());
357- map .put ("responseHeaders" , responseHeaders .entries ());
479+ Function <Map .Entry <String , String >, Map <String , String >> mapper =
480+ e -> Map .of ("name" , e .getKey (), "value" , e .getValue ());
481+ map .put ("requestHeaders" , requestHeaders .entries ().stream ().map (mapper ).toList ());
482+ map .put ("responseHeaders" , responseHeaders .entries ().stream ().map (mapper ).toList ());
358483 return map ;
359484 }
360485
@@ -371,6 +496,44 @@ protected StatusCode findStatusCode(Map<String, Object> args) {
371496 return null ;
372497 }
373498
499+ protected List <Map <String , String >> schemaToTable (Schema <?> schema ) {
500+ List <Map <String , String >> fields = new ArrayList <>();
501+ SchemaData .from (schema )
502+ .forEach (
503+ (name , type ) -> {
504+ var field = new LinkedHashMap <String , String >();
505+ field .put ("name" , name );
506+ field .put ("type" , type .toString ());
507+ var property = schema .getProperties ().get (name );
508+ if (property != null ) {
509+ field .put ("description" , property .getDescription ());
510+ }
511+ fields .add (field );
512+ });
513+ return fields ;
514+ }
515+
516+ protected List <Map <String , String >> parametersToTable (
517+ OperationExt operation , Predicate <Parameter > predicate ) {
518+ List <Map <String , String >> fields = new ArrayList <>();
519+ var parameters =
520+ Optional .ofNullable (operation .getParameters ()).orElse (List .of ()).stream ()
521+ .filter (predicate )
522+ .sorted (Comparator .comparing (Parameter ::getName ))
523+ .toList ();
524+ parameters .forEach (
525+ it -> {
526+ var schema = it .getSchema ();
527+ var field = new LinkedHashMap <String , String >();
528+ field .put ("name" , it .getName ());
529+ field .put ("type" , SchemaData .shemaType (schema ));
530+ field .put ("description" , it .getDescription ());
531+ field .put ("in" , it .getIn ());
532+ fields .add (field );
533+ });
534+ return fields ;
535+ }
536+
374537 protected Schema <?> schema (EvaluationContext context , Object input ) {
375538 var schema =
376539 switch (input ) {
0 commit comments