21
21
package org .springdoc .core .fn ;
22
22
23
23
import java .util .ArrayList ;
24
- import java .util .Arrays ;
24
+ import java .util .HashMap ;
25
25
import java .util .LinkedHashMap ;
26
26
import java .util .List ;
27
27
import java .util .Map ;
28
28
import java .util .Set ;
29
+ import java .util .stream .Collectors ;
29
30
30
31
import org .apache .commons .lang3 .StringUtils ;
31
32
32
33
import org .springframework .http .HttpHeaders ;
33
34
import org .springframework .http .HttpMethod ;
35
+ import org .springframework .util .CollectionUtils ;
34
36
35
37
/**
36
38
* The type Abstract router function visitor.
@@ -46,50 +48,63 @@ public class AbstractRouterFunctionVisitor {
46
48
/**
47
49
* The Nested or paths.
48
50
*/
49
- protected List <String > nestedOrPaths = new ArrayList <>();
51
+ protected List <String > orPaths = new ArrayList <>();
50
52
51
53
/**
52
54
* The Nested and paths.
53
55
*/
54
- protected List <String > nestedAndPaths = new ArrayList <>();
56
+ protected Map < Integer , List <String >> nestedPaths = new LinkedHashMap <>();
55
57
56
58
/**
57
- * The Nested accept headers .
59
+ * The Is or .
58
60
*/
59
- protected List < String > nestedAcceptHeaders = new ArrayList <>() ;
61
+ protected boolean isOr ;
60
62
61
63
/**
62
- * The Nested content type headers .
64
+ * The Router function data .
63
65
*/
64
- protected List <String > nestedContentTypeHeaders = new ArrayList <>() ;
66
+ protected List <RouterFunctionData > currentRouterFunctionDatas ;
65
67
66
68
/**
67
- * The Is or .
69
+ * The Attributes .
68
70
*/
69
- protected boolean isOr ;
71
+ protected Map < String , Object > attributes = new LinkedHashMap <>() ;
70
72
71
73
/**
72
- * The Is nested .
74
+ * The Level .
73
75
*/
74
- protected boolean isNested ;
76
+ private int level ;
75
77
76
78
/**
77
- * The Router function data .
79
+ * The Methods .
78
80
*/
79
- protected RouterFunctionData routerFunctionData ;
81
+ private Set < HttpMethod > methods ;
80
82
81
83
/**
82
- * The Attributes .
84
+ * The Consumes .
83
85
*/
84
- protected Map <String ,Object > attributes = new LinkedHashMap <>();
86
+ private final List <String > consumes = new ArrayList <>();
87
+
88
+ /**
89
+ * The Produces.
90
+ */
91
+ private final List <String > produces = new ArrayList <>();
92
+
93
+ /**
94
+ * The Query params.
95
+ */
96
+ private final Map <String , String > queryParams = new LinkedHashMap <>();
85
97
86
98
/**
87
99
* Method.
88
100
*
89
101
* @param methods the methods
90
102
*/
91
103
public void method (Set <HttpMethod > methods ) {
92
- routerFunctionData .setMethods (methods );
104
+ if (CollectionUtils .isEmpty (currentRouterFunctionDatas ))
105
+ this .methods = methods ;
106
+ else
107
+ currentRouterFunctionDatas .forEach (routerFunctionData -> routerFunctionData .setMethods (methods ));
93
108
}
94
109
95
110
/**
@@ -98,12 +113,26 @@ public void method(Set<HttpMethod> methods) {
98
113
* @param pattern the pattern
99
114
*/
100
115
public void path (String pattern ) {
101
- if (routerFunctionData != null )
102
- routerFunctionData .setPath (pattern );
116
+ if (currentRouterFunctionDatas != null ) {
117
+ if (!nestedPaths .isEmpty ()) {
118
+ List <String > nestedPathsList = this .nestedPaths .values ().stream ().flatMap (List ::stream ).collect (Collectors .toList ());
119
+ if (!orPaths .isEmpty ())
120
+ orPaths .forEach (nestedOrPath -> createRouterFunctionData (String .join (StringUtils .EMPTY , nestedPathsList ) + nestedOrPath + pattern ));
121
+ else
122
+ createRouterFunctionData (String .join (StringUtils .EMPTY , nestedPathsList ) + pattern );
123
+ }
124
+ else if (!orPaths .isEmpty ())
125
+ orPaths .forEach (nestedOrPath -> createRouterFunctionData (nestedOrPath + pattern ));
126
+ else
127
+ createRouterFunctionData (pattern );
128
+ }
103
129
else if (isOr )
104
- nestedOrPaths .add (pattern );
105
- else if (isNested )
106
- nestedAndPaths .add (pattern );
130
+ orPaths .add (pattern );
131
+ else if (this .level > 0 ) {
132
+ List <String > paths = CollectionUtils .isEmpty (this .nestedPaths .get (this .level )) ? new ArrayList <>() : this .nestedPaths .get (this .level );
133
+ paths .add (pattern );
134
+ this .nestedPaths .put (this .level , paths );
135
+ }
107
136
}
108
137
109
138
/**
@@ -113,14 +142,12 @@ else if (isNested)
113
142
* @param value the value
114
143
*/
115
144
public void header (String name , String value ) {
116
- if (HttpHeaders .ACCEPT .equals (name )) {
117
- calculateAccept (value );
118
- }
119
- else if (HttpHeaders .CONTENT_TYPE .equals (name )) {
120
- calculateContentType (value );
121
- }
145
+ if (HttpHeaders .ACCEPT .equals (name ))
146
+ calculateHeader (value , this .produces , name );
147
+ else if (HttpHeaders .CONTENT_TYPE .equals (name ))
148
+ calculateHeader (value , this .consumes , name );
122
149
else
123
- routerFunctionData .addHeaders (name + "=" + value );
150
+ currentRouterFunctionDatas . forEach ( routerFunctionData -> routerFunctionData .addHeaders (name + "=" + value ) );
124
151
}
125
152
126
153
/**
@@ -139,7 +166,10 @@ public List<RouterFunctionData> getRouterFunctionDatas() {
139
166
* @param value the value
140
167
*/
141
168
public void queryParam (String name , String value ) {
142
- routerFunctionData .addQueryParams (name , value );
169
+ if (CollectionUtils .isEmpty (currentRouterFunctionDatas ))
170
+ queryParams .put (name , value );
171
+ else
172
+ currentRouterFunctionDatas .forEach (routerFunctionData -> routerFunctionData .addQueryParams (name , value ));
143
173
}
144
174
145
175
/**
@@ -200,7 +230,7 @@ public void or() {
200
230
* End or.
201
231
*/
202
232
public void endOr () {
203
- // Not yet needed
233
+ this . isOr = false ;
204
234
}
205
235
206
236
/**
@@ -217,96 +247,90 @@ public void endNegate() {
217
247
// Not yet needed
218
248
}
219
249
250
+ /**
251
+ * Attributes.
252
+ *
253
+ * @param map the map
254
+ */
255
+ public void attributes (Map <String , Object > map ) {
256
+ this .attributes = map ;
257
+ }
258
+
220
259
/**
221
260
* Compute nested.
222
261
*/
223
- protected void computeNested () {
224
- if (!nestedAndPaths .isEmpty ()) {
225
- String nestedPath = String .join (StringUtils .EMPTY , nestedAndPaths );
226
- routerFunctionDatas .forEach (existingRouterFunctionData -> existingRouterFunctionData .setPath (nestedPath + existingRouterFunctionData .getPath ()));
227
- nestedAndPaths .clear ();
228
- }
229
- if (!nestedOrPaths .isEmpty ()) {
230
- List <RouterFunctionData > routerFunctionDatasClone = new ArrayList <>();
231
- for (RouterFunctionData functionData : routerFunctionDatas ) {
232
- for (String nestedOrPath : nestedOrPaths ) {
233
- RouterFunctionData routerFunctionDataClone = new RouterFunctionData (nestedOrPath , functionData );
234
- routerFunctionDatasClone .add (routerFunctionDataClone );
235
- }
236
- }
237
- this .routerFunctionDatas = routerFunctionDatasClone ;
238
- nestedAndPaths .clear ();
239
- }
240
- if (!nestedAcceptHeaders .isEmpty ()) {
241
- routerFunctionDatas .forEach (existingRouterFunctionData -> existingRouterFunctionData .addProduces (nestedAcceptHeaders ));
242
- nestedAcceptHeaders .clear ();
243
- }
244
- if (!nestedContentTypeHeaders .isEmpty ()) {
245
- routerFunctionDatas .forEach (existingRouterFunctionData -> existingRouterFunctionData .addConsumes (nestedContentTypeHeaders ));
246
- nestedContentTypeHeaders .clear ();
247
- }
262
+ protected void commonEndNested () {
263
+ nestedPaths .remove (this .level );
264
+ this .level --;
248
265
}
249
266
250
267
/**
251
- * Calculate content type.
252
- *
253
- * @param value the value
268
+ * Common start nested.
254
269
*/
255
- private void calculateContentType (String value ) {
256
- if (value .contains ("," )) {
257
- String [] mediaTypes = value .substring (1 , value .length () - 1 ).split (", " );
258
- for (String mediaType : mediaTypes )
259
- if (routerFunctionData != null )
260
- routerFunctionData .addConsumes (mediaType );
261
- else
262
- nestedContentTypeHeaders .addAll (Arrays .asList (mediaTypes ));
263
- }
264
- else {
265
- if (routerFunctionData != null )
266
- routerFunctionData .addConsumes (value );
267
- else
268
- nestedContentTypeHeaders .add (value );
269
- }
270
+ protected void commonStartNested () {
271
+ this .level ++;
272
+ this .currentRouterFunctionDatas = null ;
273
+ }
274
+
275
+ /**
276
+ * Common route.
277
+ */
278
+ protected void commonRoute () {
279
+ this .routerFunctionDatas .addAll (currentRouterFunctionDatas );
280
+ currentRouterFunctionDatas .forEach (routerFunctionData -> routerFunctionData .addAttributes (this .attributes ));
281
+ this .attributes = new HashMap <>();
270
282
}
271
283
272
284
/**
273
- * Calculate accept .
285
+ * Calculate header .
274
286
*
275
287
* @param value the value
288
+ * @param headers the headers
289
+ * @param header the header
276
290
*/
277
- private void calculateAccept (String value ) {
291
+ private void calculateHeader (String value , List < String > headers , String header ) {
278
292
if (value .contains ("," )) {
279
293
String [] mediaTypes = value .substring (1 , value .length () - 1 ).split (", " );
280
294
for (String mediaType : mediaTypes )
281
- if (routerFunctionData != null )
282
- routerFunctionData . addProduces (mediaType );
295
+ if (CollectionUtils . isEmpty ( currentRouterFunctionDatas ) )
296
+ headers . add (mediaType );
283
297
else
284
- nestedAcceptHeaders . addAll ( Arrays . asList ( mediaTypes ));
298
+ currentRouterFunctionDatas . forEach ( routerFunctionData -> addHeader ( mediaType , header , routerFunctionData ));
285
299
}
286
300
else {
287
- if (routerFunctionData != null )
288
- routerFunctionData . addProduces (value );
301
+ if (CollectionUtils . isEmpty ( currentRouterFunctionDatas ) )
302
+ headers . add (value );
289
303
else
290
- nestedAcceptHeaders . add ( value );
304
+ currentRouterFunctionDatas . forEach ( routerFunctionData -> addHeader ( value , header , routerFunctionData ) );
291
305
}
292
306
}
293
307
294
308
/**
295
- * Route.
309
+ * Create router function data.
310
+ *
311
+ * @param path the path
296
312
*/
297
- protected void route () {
298
- this .routerFunctionData = new RouterFunctionData ();
299
- routerFunctionDatas .add (this .routerFunctionData );
300
- this .routerFunctionData .addAttributes (this .attributes );
313
+ private void createRouterFunctionData (String path ) {
314
+ RouterFunctionData routerFunctionData = new RouterFunctionData ();
315
+ routerFunctionData .setPath (path );
316
+ routerFunctionData .setMethods (methods );
317
+ routerFunctionData .addConsumes (consumes );
318
+ routerFunctionData .addProduces (produces );
319
+ this .queryParams .forEach (routerFunctionData ::addQueryParams );
320
+ this .currentRouterFunctionDatas .add (routerFunctionData );
301
321
}
302
322
303
323
/**
304
- * Attributes .
324
+ * Add header .
305
325
*
306
- * @param map the map
326
+ * @param mediaType the media type
327
+ * @param header the header
328
+ * @param routerFunctionData the router function data
307
329
*/
308
- public void attributes (Map <String , Object > map ) {
309
- this .attributes = map ;
330
+ private void addHeader (String mediaType , String header ,RouterFunctionData routerFunctionData ) {
331
+ if (HttpHeaders .CONTENT_TYPE .equals (header ))
332
+ routerFunctionData .addConsumes (mediaType );
333
+ else if (HttpHeaders .ACCEPT .equals (header ))
334
+ routerFunctionData .addProduces (mediaType );
310
335
}
311
-
312
336
}
0 commit comments