2121package org .springdoc .core .fn ;
2222
2323import java .util .ArrayList ;
24- import java .util .Arrays ;
24+ import java .util .HashMap ;
2525import java .util .LinkedHashMap ;
2626import java .util .List ;
2727import java .util .Map ;
2828import java .util .Set ;
29+ import java .util .stream .Collectors ;
2930
3031import org .apache .commons .lang3 .StringUtils ;
3132
3233import org .springframework .http .HttpHeaders ;
3334import org .springframework .http .HttpMethod ;
35+ import org .springframework .util .CollectionUtils ;
3436
3537/**
3638 * The type Abstract router function visitor.
@@ -46,50 +48,63 @@ public class AbstractRouterFunctionVisitor {
4648 /**
4749 * The Nested or paths.
4850 */
49- protected List <String > nestedOrPaths = new ArrayList <>();
51+ protected List <String > orPaths = new ArrayList <>();
5052
5153 /**
5254 * The Nested and paths.
5355 */
54- protected List <String > nestedAndPaths = new ArrayList <>();
56+ protected Map < Integer , List <String >> nestedPaths = new LinkedHashMap <>();
5557
5658 /**
57- * The Nested accept headers .
59+ * The Is or .
5860 */
59- protected List < String > nestedAcceptHeaders = new ArrayList <>() ;
61+ protected boolean isOr ;
6062
6163 /**
62- * The Nested content type headers .
64+ * The Router function data .
6365 */
64- protected List <String > nestedContentTypeHeaders = new ArrayList <>() ;
66+ protected List <RouterFunctionData > currentRouterFunctionDatas ;
6567
6668 /**
67- * The Is or .
69+ * The Attributes .
6870 */
69- protected boolean isOr ;
71+ protected Map < String , Object > attributes = new LinkedHashMap <>() ;
7072
7173 /**
72- * The Is nested .
74+ * The Level .
7375 */
74- protected boolean isNested ;
76+ private int level ;
7577
7678 /**
77- * The Router function data .
79+ * The Methods .
7880 */
79- protected RouterFunctionData routerFunctionData ;
81+ private Set < HttpMethod > methods ;
8082
8183 /**
82- * The Attributes .
84+ * The Consumes .
8385 */
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 <>();
8597
8698 /**
8799 * Method.
88100 *
89101 * @param methods the methods
90102 */
91103 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 ));
93108 }
94109
95110 /**
@@ -98,12 +113,26 @@ public void method(Set<HttpMethod> methods) {
98113 * @param pattern the pattern
99114 */
100115 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+ }
103129 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+ }
107136 }
108137
109138 /**
@@ -113,14 +142,12 @@ else if (isNested)
113142 * @param value the value
114143 */
115144 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 );
122149 else
123- routerFunctionData .addHeaders (name + "=" + value );
150+ currentRouterFunctionDatas . forEach ( routerFunctionData -> routerFunctionData .addHeaders (name + "=" + value ) );
124151 }
125152
126153 /**
@@ -139,7 +166,10 @@ public List<RouterFunctionData> getRouterFunctionDatas() {
139166 * @param value the value
140167 */
141168 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 ));
143173 }
144174
145175 /**
@@ -200,7 +230,7 @@ public void or() {
200230 * End or.
201231 */
202232 public void endOr () {
203- // Not yet needed
233+ this . isOr = false ;
204234 }
205235
206236 /**
@@ -217,96 +247,90 @@ public void endNegate() {
217247 // Not yet needed
218248 }
219249
250+ /**
251+ * Attributes.
252+ *
253+ * @param map the map
254+ */
255+ public void attributes (Map <String , Object > map ) {
256+ this .attributes = map ;
257+ }
258+
220259 /**
221260 * Compute nested.
222261 */
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 --;
248265 }
249266
250267 /**
251- * Calculate content type.
252- *
253- * @param value the value
268+ * Common start nested.
254269 */
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 <>();
270282 }
271283
272284 /**
273- * Calculate accept .
285+ * Calculate header .
274286 *
275287 * @param value the value
288+ * @param headers the headers
289+ * @param header the header
276290 */
277- private void calculateAccept (String value ) {
291+ private void calculateHeader (String value , List < String > headers , String header ) {
278292 if (value .contains ("," )) {
279293 String [] mediaTypes = value .substring (1 , value .length () - 1 ).split (", " );
280294 for (String mediaType : mediaTypes )
281- if (routerFunctionData != null )
282- routerFunctionData . addProduces (mediaType );
295+ if (CollectionUtils . isEmpty ( currentRouterFunctionDatas ) )
296+ headers . add (mediaType );
283297 else
284- nestedAcceptHeaders . addAll ( Arrays . asList ( mediaTypes ));
298+ currentRouterFunctionDatas . forEach ( routerFunctionData -> addHeader ( mediaType , header , routerFunctionData ));
285299 }
286300 else {
287- if (routerFunctionData != null )
288- routerFunctionData . addProduces (value );
301+ if (CollectionUtils . isEmpty ( currentRouterFunctionDatas ) )
302+ headers . add (value );
289303 else
290- nestedAcceptHeaders . add ( value );
304+ currentRouterFunctionDatas . forEach ( routerFunctionData -> addHeader ( value , header , routerFunctionData ) );
291305 }
292306 }
293307
294308 /**
295- * Route.
309+ * Create router function data.
310+ *
311+ * @param path the path
296312 */
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 );
301321 }
302322
303323 /**
304- * Attributes .
324+ * Add header .
305325 *
306- * @param map the map
326+ * @param mediaType the media type
327+ * @param header the header
328+ * @param routerFunctionData the router function data
307329 */
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 );
310335 }
311-
312336}
0 commit comments