27
27
import java .lang .reflect .Type ;
28
28
import java .lang .reflect .WildcardType ;
29
29
import java .util .Arrays ;
30
+ import java .util .Map ;
30
31
import java .util .Objects ;
31
32
import java .util .Set ;
32
33
34
+ import com .fasterxml .jackson .annotation .JsonAnyGetter ;
33
35
import io .swagger .v3 .oas .models .OpenAPI ;
34
36
import io .swagger .v3 .oas .models .Operation ;
35
37
import io .swagger .v3 .oas .models .media .Content ;
38
40
import org .springdoc .core .GenericResponseService ;
39
41
import org .springdoc .core .MethodAttributes ;
40
42
import org .springdoc .core .ReturnTypeParser ;
41
- import org .springdoc .data .rest .SpringRepositoryRestResourceProvider ;
42
43
43
44
import org .springframework .core .MethodParameter ;
44
45
import org .springframework .core .ResolvableType ;
45
46
import org .springframework .data .rest .core .mapping .MethodResourceMapping ;
46
47
import org .springframework .hateoas .CollectionModel ;
47
48
import org .springframework .hateoas .EntityModel ;
49
+ import org .springframework .hateoas .Link ;
48
50
import org .springframework .hateoas .PagedModel ;
49
51
import org .springframework .hateoas .RepresentationModel ;
50
52
import org .springframework .http .HttpEntity ;
@@ -123,11 +125,12 @@ public void buildSearchResponse(Operation operation, HandlerMethod handlerMethod
123
125
* @param operationPath the operation path
124
126
* @param domainType the domain type
125
127
* @param methodAttributes the method attributes
128
+ * @param dataRestRepository the data rest repository
126
129
*/
127
130
public void buildEntityResponse (Operation operation , HandlerMethod handlerMethod , OpenAPI openAPI , RequestMethod requestMethod ,
128
- String operationPath , Class <?> domainType , MethodAttributes methodAttributes ) {
131
+ String operationPath , Class <?> domainType , MethodAttributes methodAttributes , DataRestRepository dataRestRepository ) {
129
132
MethodParameter methodParameterReturn = handlerMethod .getReturnType ();
130
- Type returnType = getType (methodParameterReturn , domainType , requestMethod );
133
+ Type returnType = getType (methodParameterReturn , domainType , requestMethod , dataRestRepository );
131
134
ApiResponses apiResponses = new ApiResponses ();
132
135
ApiResponse apiResponse = new ApiResponse ();
133
136
Content content = genericResponseService .buildContent (openAPI .getComponents (), methodParameterReturn .getParameterAnnotations (), methodAttributes .getMethodProduces (), null , returnType );
@@ -204,34 +207,40 @@ else if (ClassUtils.isPrimitiveOrWrapper(methodResourceMapping.getReturnedDomain
204
207
* @param methodParameterReturn the method parameter return
205
208
* @param domainType the domain type
206
209
* @param requestMethod the request method
210
+ * @param dataRestRepository the data rest repository
207
211
* @return the type
208
212
*/
209
- private Type getType (MethodParameter methodParameterReturn , Class <?> domainType , RequestMethod requestMethod ) {
213
+ private Type getType (MethodParameter methodParameterReturn , Class <?> domainType , RequestMethod requestMethod , DataRestRepository dataRestRepository ) {
210
214
Type returnType = ReturnTypeParser .resolveType (methodParameterReturn .getGenericParameterType (), methodParameterReturn .getContainingClass ());
215
+ Class returnedEntityType = domainType ;
216
+
217
+ if (dataRestRepository !=null && ControllerType .PROPERTY .equals (dataRestRepository .getControllerType ()))
218
+ returnedEntityType = dataRestRepository .getPropertyType ();
219
+
211
220
if (returnType instanceof ParameterizedType ) {
212
221
ParameterizedType parameterizedType = (ParameterizedType ) returnType ;
213
222
if ((ResponseEntity .class .equals (parameterizedType .getRawType ()))) {
214
223
if (Object .class .equals (parameterizedType .getActualTypeArguments ()[0 ])) {
215
- return ResolvableType .forClassWithGenerics (ResponseEntity .class , domainType ).getType ();
224
+ return ResolvableType .forClassWithGenerics (ResponseEntity .class , returnedEntityType ).getType ();
216
225
}
217
226
else if (parameterizedType .getActualTypeArguments ()[0 ] instanceof ParameterizedType ) {
218
227
ParameterizedType parameterizedType1 = (ParameterizedType ) parameterizedType .getActualTypeArguments ()[0 ];
219
228
Class <?> rawType = ResolvableType .forType (parameterizedType1 .getRawType ()).getRawClass ();
220
229
if (rawType != null && rawType .isAssignableFrom (RepresentationModel .class )) {
221
- Class <?> type = findType (methodParameterReturn , requestMethod );
222
- return resolveGenericType (ResponseEntity .class , type , domainType );
230
+ Class <?> type = findType (requestMethod , dataRestRepository );
231
+ return resolveGenericType (ResponseEntity .class , type , returnedEntityType );
223
232
}
224
233
else if (EntityModel .class .equals (parameterizedType1 .getRawType ())) {
225
- return resolveGenericType (ResponseEntity .class , EntityModel .class , domainType );
234
+ return resolveGenericType (ResponseEntity .class , EntityModel .class , returnedEntityType );
226
235
}
227
236
}
228
237
else if (parameterizedType .getActualTypeArguments ()[0 ] instanceof WildcardType ) {
229
238
WildcardType wildcardType = (WildcardType ) parameterizedType .getActualTypeArguments ()[0 ];
230
239
if (wildcardType .getUpperBounds ()[0 ] instanceof ParameterizedType ) {
231
240
ParameterizedType wildcardTypeUpperBound = (ParameterizedType ) wildcardType .getUpperBounds ()[0 ];
232
241
if (RepresentationModel .class .equals (wildcardTypeUpperBound .getRawType ())) {
233
- Class <?> type = findType (methodParameterReturn , requestMethod );
234
- return resolveGenericType (ResponseEntity .class , type , domainType );
242
+ Class <?> type = findType (requestMethod , dataRestRepository );
243
+ return resolveGenericType (ResponseEntity .class , type , returnedEntityType );
235
244
}
236
245
}
237
246
}
@@ -240,12 +249,12 @@ else if ((HttpEntity.class.equals(parameterizedType.getRawType())
240
249
&& parameterizedType .getActualTypeArguments ()[0 ] instanceof ParameterizedType )) {
241
250
ParameterizedType wildcardTypeUpperBound = (ParameterizedType ) parameterizedType .getActualTypeArguments ()[0 ];
242
251
if (RepresentationModel .class .equals (wildcardTypeUpperBound .getRawType ())) {
243
- return resolveGenericType (HttpEntity .class , RepresentationModel .class , domainType );
252
+ return resolveGenericType (HttpEntity .class , RepresentationModel .class , returnedEntityType );
244
253
}
245
254
}
246
255
else if ((CollectionModel .class .equals (parameterizedType .getRawType ())
247
256
&& Object .class .equals (parameterizedType .getActualTypeArguments ()[0 ]))) {
248
- return ResolvableType .forClassWithGenerics (CollectionModel .class , domainType ).getType ();
257
+ return ResolvableType .forClassWithGenerics (CollectionModel .class , returnedEntityType ).getType ();
249
258
}
250
259
}
251
260
return returnType ;
@@ -254,14 +263,22 @@ else if ((CollectionModel.class.equals(parameterizedType.getRawType())
254
263
/**
255
264
* Find type class.
256
265
*
257
- * @param methodParameterReturn the method parameter return
258
266
* @param requestMethod the request method
267
+ * @param dataRestRepository the data rest repository
259
268
* @return the class
260
269
*/
261
- private Class findType (MethodParameter methodParameterReturn , RequestMethod requestMethod ) {
262
- if (SpringRepositoryRestResourceProvider . REPOSITORY_ENTITY_CONTROLLER .equals (methodParameterReturn . getContainingClass (). getCanonicalName ())
270
+ private Class findType (RequestMethod requestMethod , DataRestRepository dataRestRepository ) {
271
+ if (ControllerType . ENTITY .equals (dataRestRepository . getControllerType ())
263
272
&& Arrays .stream (requestMethodsEntityModel ).anyMatch (requestMethod ::equals ))
264
273
return EntityModel .class ;
274
+ else if (dataRestRepository !=null && ControllerType .PROPERTY .equals (dataRestRepository .getControllerType ())) {
275
+ if (dataRestRepository .isCollectionLike ())
276
+ return CollectionModel .class ;
277
+ else if (dataRestRepository .isMap ())
278
+ return MapModel .class ;
279
+ else
280
+ return EntityModel .class ;
281
+ }
265
282
else
266
283
return RepresentationModel .class ;
267
284
}
@@ -306,4 +323,37 @@ private void addResponse204(ApiResponses apiResponses) {
306
323
private void addResponse404 (ApiResponses apiResponses ) {
307
324
apiResponses .put (String .valueOf (HttpStatus .NOT_FOUND .value ()), new ApiResponse ().description (HttpStatus .NOT_FOUND .getReasonPhrase ()));
308
325
}
326
+
327
+ /**
328
+ * The type Map model.
329
+ * @author bnasslashen
330
+ */
331
+ private static class MapModel extends RepresentationModel <MapModel > {
332
+ /**
333
+ * The Content.
334
+ */
335
+ private Map <? extends Object , ? extends Object > content ;
336
+
337
+ /**
338
+ * Instantiates a new Map model.
339
+ *
340
+ * @param content the content
341
+ * @param links the links
342
+ */
343
+ public MapModel (Map <? extends Object , ? extends Object > content , Link ... links ) {
344
+ super (Arrays .asList (links ));
345
+ this .content = content ;
346
+ }
347
+
348
+ /**
349
+ * Gets content.
350
+ *
351
+ * @return the content
352
+ */
353
+ @ JsonAnyGetter
354
+ public Map <? extends Object , ? extends Object > getContent () {
355
+ return content ;
356
+ }
357
+ }
358
+
309
359
}
0 commit comments