29
29
import java .util .stream .Collectors ;
30
30
import java .util .stream .Stream ;
31
31
32
+ import com .fasterxml .jackson .databind .ObjectMapper ;
32
33
import io .swagger .v3 .oas .models .OpenAPI ;
33
34
import org .springdoc .api .AbstractOpenApiResource ;
34
35
import org .springdoc .core .RepositoryRestResourceProvider ;
35
36
import org .springdoc .core .fn .RouterOperation ;
37
+ import org .springdoc .data .rest .core .ControllerType ;
36
38
import org .springdoc .data .rest .core .DataRestRepository ;
37
39
import org .springdoc .data .rest .core .DataRestRouterOperationBuilder ;
38
40
41
+ import org .springframework .data .mapping .PersistentEntity ;
42
+ import org .springframework .data .mapping .PersistentProperty ;
43
+ import org .springframework .data .mapping .SimpleAssociationHandler ;
44
+ import org .springframework .data .mapping .context .PersistentEntities ;
39
45
import org .springframework .data .repository .support .Repositories ;
40
46
import org .springframework .data .rest .core .mapping .MethodResourceMapping ;
41
47
import org .springframework .data .rest .core .mapping .ResourceMappings ;
45
51
import org .springframework .data .rest .webmvc .ProfileController ;
46
52
import org .springframework .data .rest .webmvc .RepositoryRestHandlerMapping ;
47
53
import org .springframework .data .rest .webmvc .alps .AlpsController ;
54
+ import org .springframework .data .rest .webmvc .json .JacksonMetadata ;
48
55
import org .springframework .data .rest .webmvc .mapping .Associations ;
49
56
import org .springframework .data .rest .webmvc .support .DelegatingHandlerMapping ;
50
57
import org .springframework .web .method .HandlerMethod ;
@@ -102,6 +109,16 @@ public class SpringRepositoryRestResourceProvider implements RepositoryRestResou
102
109
*/
103
110
private DataRestRouterOperationBuilder dataRestRouterOperationBuilder ;
104
111
112
+ /**
113
+ * The Persistent entities.
114
+ */
115
+ private PersistentEntities persistentEntities ;
116
+
117
+ /**
118
+ * The Mapper.
119
+ */
120
+ private ObjectMapper mapper ;
121
+
105
122
/**
106
123
* Instantiates a new Spring repository rest resource provider.
107
124
*
@@ -110,14 +127,17 @@ public class SpringRepositoryRestResourceProvider implements RepositoryRestResou
110
127
* @param associations the associations
111
128
* @param delegatingHandlerMapping the delegating handler mapping
112
129
* @param dataRestRouterOperationBuilder the data rest router operation builder
130
+ * @param persistentEntities the persistent entities
131
+ * @param mapper the mapper
113
132
*/
114
- public SpringRepositoryRestResourceProvider (ResourceMappings mappings , Repositories repositories , Associations associations ,
115
- DelegatingHandlerMapping delegatingHandlerMapping , DataRestRouterOperationBuilder dataRestRouterOperationBuilder ) {
133
+ public SpringRepositoryRestResourceProvider (ResourceMappings mappings , Repositories repositories , Associations associations , DelegatingHandlerMapping delegatingHandlerMapping , DataRestRouterOperationBuilder dataRestRouterOperationBuilder , PersistentEntities persistentEntities , ObjectMapper mapper ) {
116
134
this .mappings = mappings ;
117
135
this .repositories = repositories ;
118
136
this .associations = associations ;
119
137
this .delegatingHandlerMapping = delegatingHandlerMapping ;
120
138
this .dataRestRouterOperationBuilder = dataRestRouterOperationBuilder ;
139
+ this .persistentEntities = persistentEntities ;
140
+ this .mapper = mapper ;
121
141
}
122
142
123
143
public List <RouterOperation > getRouterOperations (OpenAPI openAPI ) {
@@ -127,18 +147,38 @@ public List<RouterOperation> getRouterOperations(OpenAPI openAPI) {
127
147
Class <?> repository = repositories .getRequiredRepositoryInformation (domainType ).getRepositoryInterface ();
128
148
DataRestRepository dataRestRepository = new DataRestRepository (domainType , repository );
129
149
ResourceMetadata resourceMetadata = mappings .getMetadataFor (domainType );
150
+ final PersistentEntity <?, ?> entity = persistentEntities .getRequiredPersistentEntity (domainType );
151
+ final JacksonMetadata jackson = new JacksonMetadata (mapper , domainType );
152
+
130
153
if (resourceMetadata .isExported ()) {
131
154
for (HandlerMapping handlerMapping : handlerMappingList ) {
132
155
if (handlerMapping instanceof RepositoryRestHandlerMapping ) {
133
156
RepositoryRestHandlerMapping repositoryRestHandlerMapping = (RepositoryRestHandlerMapping ) handlerMapping ;
134
157
Map <RequestMappingInfo , HandlerMethod > handlerMethodMap = repositoryRestHandlerMapping .getHandlerMethods ();
158
+ // Entity controllers lookup first
135
159
Map <RequestMappingInfo , HandlerMethod > handlerMethodMapFiltered = handlerMethodMap .entrySet ().stream ()
136
160
.filter (requestMappingInfoHandlerMethodEntry -> REPOSITORY_ENTITY_CONTROLLER .equals (requestMappingInfoHandlerMethodEntry
137
- .getValue ().getBeanType ().getName ()) || REPOSITORY_PROPERTY_CONTROLLER .equals (requestMappingInfoHandlerMethodEntry
138
161
.getValue ().getBeanType ().getName ()))
139
162
.filter (controller -> !AbstractOpenApiResource .isHiddenRestControllers (controller .getValue ().getBeanType ()))
140
163
.collect (Collectors .toMap (Map .Entry ::getKey , Map .Entry ::getValue , (a1 , a2 ) -> a1 ));
164
+ dataRestRepository .setControllerType (ControllerType .ENTITY );
141
165
findControllers (routerOperationList , handlerMethodMapFiltered , resourceMetadata , dataRestRepository , openAPI );
166
+
167
+ Map <RequestMappingInfo , HandlerMethod > handlerMethodMapFilteredMethodMap = handlerMethodMap .entrySet ().stream ()
168
+ .filter (requestMappingInfoHandlerMethodEntry -> REPOSITORY_PROPERTY_CONTROLLER .equals (requestMappingInfoHandlerMethodEntry
169
+ .getValue ().getBeanType ().getName ()))
170
+ .filter (controller -> !AbstractOpenApiResource .isHiddenRestControllers (controller .getValue ().getBeanType ()))
171
+ .collect (Collectors .toMap (Map .Entry ::getKey , Map .Entry ::getValue , (a1 , a2 ) -> a1 ));
172
+
173
+ entity .doWithAssociations ((SimpleAssociationHandler ) association -> {
174
+ PersistentProperty <?> property = association .getInverse ();
175
+ if (jackson .isExported (property ) && associations .isLinkableAssociation (property )) {
176
+ ResourceMetadata targetTypeMetadata = associations .getMetadataFor (property .getActualType ());
177
+ dataRestRepository .setRelationName (targetTypeMetadata .getItemResourceRel ().toString ());
178
+ dataRestRepository .setControllerType (ControllerType .PROPERTY );
179
+ findControllers (routerOperationList , handlerMethodMapFilteredMethodMap , resourceMetadata , dataRestRepository , openAPI );
180
+ }
181
+ });
142
182
}
143
183
else if (handlerMapping instanceof BasePathAwareHandlerMapping ) {
144
184
BasePathAwareHandlerMapping beanBasePathAwareHandlerMapping = (BasePathAwareHandlerMapping ) handlerMapping ;
@@ -148,7 +188,7 @@ else if (handlerMapping instanceof BasePathAwareHandlerMapping) {
148
188
.getValue ().getBeanType ().getName ()))
149
189
.filter (controller -> !AbstractOpenApiResource .isHiddenRestControllers (controller .getValue ().getBeanType ()))
150
190
.collect (Collectors .toMap (Map .Entry ::getKey , Map .Entry ::getValue , (a1 , a2 ) -> a1 ));
151
-
191
+ dataRestRepository . setControllerType ( ControllerType . SCHEMA );
152
192
findControllers (routerOperationList , handlerMethodMapFiltered , resourceMetadata , dataRestRepository , openAPI );
153
193
handlerMethodMapFiltered = handlerMethodMap .entrySet ().stream ()
154
194
.filter (requestMappingInfoHandlerMethodEntry -> ProfileController .class .equals (requestMappingInfoHandlerMethodEntry
0 commit comments