Skip to content

Commit b738aa5

Browse files
committed
ACC-2100 split RelationRequestHandler into XToOneRelationRequestHandler and XToManyRelationRequestHandler
1 parent 0994fd5 commit b738aa5

File tree

3 files changed

+203
-108
lines changed

3 files changed

+203
-108
lines changed

contentgrid-appserver-rest/src/main/java/com/contentgrid/appserver/rest/property/handler/RelationRequestHandler.java renamed to contentgrid-appserver-rest/src/main/java/com/contentgrid/appserver/rest/property/handler/XToManyRelationRequestHandler.java

Lines changed: 32 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,12 @@
66
import com.contentgrid.appserver.application.model.Application;
77
import com.contentgrid.appserver.application.model.Entity;
88
import com.contentgrid.appserver.application.model.relations.ManyToManyRelation;
9-
import com.contentgrid.appserver.application.model.relations.ManyToOneRelation;
109
import com.contentgrid.appserver.application.model.relations.OneToManyRelation;
11-
import com.contentgrid.appserver.application.model.relations.OneToOneRelation;
1210
import com.contentgrid.appserver.application.model.relations.Relation;
1311
import com.contentgrid.appserver.application.model.values.PathSegmentName;
1412
import com.contentgrid.appserver.domain.DatamodelApi;
1513
import com.contentgrid.appserver.query.engine.api.data.EntityId;
1614
import com.contentgrid.appserver.query.engine.api.data.XToManyRelationData;
17-
import com.contentgrid.appserver.query.engine.api.data.XToOneRelationData;
1815
import com.contentgrid.appserver.query.engine.api.exception.ConstraintViolationException;
1916
import com.contentgrid.appserver.query.engine.api.exception.EntityNotFoundException;
2017
import com.contentgrid.appserver.rest.EntityRestController;
@@ -24,52 +21,33 @@
2421
import java.util.Map;
2522
import java.util.Optional;
2623
import java.util.UUID;
24+
import lombok.NonNull;
2725
import org.springframework.beans.factory.annotation.Autowired;
28-
import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
2926
import org.springframework.http.HttpMethod;
3027
import org.springframework.http.HttpStatus;
3128
import org.springframework.http.ResponseEntity;
3229
import org.springframework.stereotype.Component;
3330
import org.springframework.web.server.ResponseStatusException;
3431

3532
@Component
36-
public class RelationRequestHandler extends AbstractPropertyItemRequestHandler<List<URI>, Relation> {
33+
public class XToManyRelationRequestHandler extends AbstractPropertyItemRequestHandler<List<URI>, Relation> {
3734

38-
private static final HttpMethod[] SINGLE_TARGET_PROPERTY_METHODS = {HttpMethod.GET, HttpMethod.HEAD, HttpMethod.PUT, HttpMethod.DELETE};
39-
private static final HttpMethod[] MULTI_TARGET_PROPERTY_METHODS = {HttpMethod.GET, HttpMethod.HEAD, HttpMethod.POST, HttpMethod.DELETE};
40-
private static final HttpMethod[] MULTI_TARGET_PROPERTY_ITEM_METHODS = {HttpMethod.GET, HttpMethod.HEAD, HttpMethod.DELETE};
41-
42-
private static HttpMethod[] supportedPropertyMethods(Relation relation) {
43-
if (relation instanceof OneToManyRelation || relation instanceof ManyToManyRelation) {
44-
return MULTI_TARGET_PROPERTY_METHODS;
45-
} else {
46-
return SINGLE_TARGET_PROPERTY_METHODS;
47-
}
48-
}
49-
50-
private static ResponseEntity<Object> propertyItemUnsupportedMethodResponse(Relation relation) {
51-
if (relation instanceof OneToManyRelation || relation instanceof ManyToManyRelation) {
52-
// *-to-many relation
53-
return ResponseEntity.status(HttpStatus.METHOD_NOT_ALLOWED)
54-
.allow(MULTI_TARGET_PROPERTY_ITEM_METHODS)
55-
.build();
56-
} else {
57-
// *-to-one relation
58-
return ResponseEntity.notFound().build();
59-
}
60-
}
35+
private static final HttpMethod[] SUPPORTED_PROPERTY_METHODS = {HttpMethod.GET, HttpMethod.HEAD, HttpMethod.POST, HttpMethod.DELETE};
36+
private static final HttpMethod[] SUPPORTED_PROPERTY_ITEM_METHODS = {HttpMethod.GET, HttpMethod.HEAD, HttpMethod.DELETE};
6137

38+
@NonNull
6239
private final DatamodelApi datamodelApi;
6340

6441
@Autowired
65-
public RelationRequestHandler(DatamodelApi datamodelApi) {
42+
public XToManyRelationRequestHandler(@NonNull DatamodelApi datamodelApi) {
6643
super(new UriListHttpServletRequestConverter());
6744
this.datamodelApi = datamodelApi;
6845
}
6946

7047
@Override
7148
protected Optional<Relation> findProperty(Application application, Entity entity, PathSegmentName propertyName) {
72-
return application.getRelationForPath(entity.getPathSegment(), propertyName);
49+
return application.getRelationForPath(entity.getPathSegment(), propertyName)
50+
.filter(relation -> relation instanceof OneToManyRelation || relation instanceof ManyToManyRelation);
7351
}
7452

7553
@Override
@@ -81,31 +59,11 @@ protected ResponseEntity<Object> getProperty(
8159
) {
8260
var targetPathSegment = property.getTargetEndPoint().getEntity().getPathSegment();
8361
try {
84-
URI redirectUrl;
85-
switch (property) {
86-
case OneToOneRelation oneToOneRelation -> {
87-
var targetId = datamodelApi.findRelationTarget(application, oneToOneRelation, instanceId)
88-
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Target of %s not found".formatted(property.getSourceEndPoint().getName())));
89-
redirectUrl = WebMvcLinkBuilder.linkTo(methodOn(EntityRestController.class).getEntity(application, targetPathSegment, targetId)).toUri();
90-
}
91-
case ManyToOneRelation manyToOneRelation -> {
92-
var targetId = datamodelApi.findRelationTarget(application, manyToOneRelation, instanceId)
93-
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Target of %s not found".formatted(property.getSourceEndPoint().getName())));
94-
redirectUrl = linkTo(methodOn(EntityRestController.class).getEntity(application, targetPathSegment, targetId)).toUri();
95-
}
96-
case OneToManyRelation oneToManyRelation -> {
97-
datamodelApi.findById(application, oneToManyRelation.getSourceEndPoint().getEntity(), instanceId)
98-
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Entity with id %s not found".formatted(instanceId)));
99-
redirectUrl = linkTo(methodOn(EntityRestController.class).listEntity(application, targetPathSegment, 0,
100-
Map.of(property.getTargetEndPoint().getName().getValue(), instanceId.toString()))).toUri(); // TODO: use RelationSearchFilter
101-
}
102-
case ManyToManyRelation manyToManyRelation -> {
103-
datamodelApi.findById(application, manyToManyRelation.getSourceEndPoint().getEntity(), instanceId)
104-
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Entity with id %s not found".formatted(instanceId)));
105-
redirectUrl = linkTo(methodOn(EntityRestController.class).listEntity(application, targetPathSegment, 0,
106-
Map.of(property.getTargetEndPoint().getName().getValue(), instanceId.toString()))).toUri(); // TODO: use RelationSearchFilter
107-
}
108-
}
62+
datamodelApi.findById(application, property.getSourceEndPoint().getEntity(), instanceId)
63+
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Entity with id %s not found".formatted(instanceId)));
64+
var redirectUrl = linkTo(methodOn(EntityRestController.class).listEntity(application, targetPathSegment, 0,
65+
Map.of(property.getTargetEndPoint().getName().getValue(), instanceId.toString()))).toUri(); // TODO: use RelationSearchFilter
66+
10967
return ResponseEntity.status(HttpStatus.FOUND).location(redirectUrl).build();
11068
} catch (EntityNotFoundException e) {
11169
throw new ResponseStatusException(HttpStatus.NOT_FOUND, e.getMessage(), e);
@@ -142,13 +100,6 @@ protected ResponseEntity<Object> postProperty(
142100
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "No entity url provided.");
143101
}
144102
var targetPathSegment = property.getTargetEndPoint().getEntity().getPathSegment();
145-
146-
if (!(property instanceof OneToManyRelation || property instanceof ManyToManyRelation)) {
147-
return ResponseEntity.status(HttpStatus.METHOD_NOT_ALLOWED)
148-
.allow(SINGLE_TARGET_PROPERTY_METHODS)
149-
.build();
150-
}
151-
152103
var dataBuilder = XToManyRelationData.builder()
153104
.entity(property.getSourceEndPoint().getEntity().getName())
154105
.name(property.getSourceEndPoint().getName());
@@ -180,46 +131,21 @@ protected ResponseEntity<Object> putProperty(
180131
Relation property,
181132
List<URI> body
182133
) {
183-
if (body.isEmpty()) {
184-
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "No entity url provided.");
185-
}
186-
if (body.size() > 1) {
187-
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Multiple targets not supported.");
188-
}
189-
var targetPathSegment = property.getTargetEndPoint().getEntity().getPathSegment();
190-
191-
if (property instanceof OneToManyRelation || property instanceof ManyToManyRelation) {
192-
return ResponseEntity.status(HttpStatus.METHOD_NOT_ALLOWED)
193-
.allow(MULTI_TARGET_PROPERTY_METHODS)
194-
.build();
195-
}
196-
var element = body.getFirst();
197-
198-
var pathSegment = parseEntityPathSegment(element);
199-
if (!targetPathSegment.equals(pathSegment)) {
200-
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Invalid target entity. Expected %s, got %s.".formatted(targetPathSegment, pathSegment));
201-
}
202-
var targetId = parseEntityId(element);
203-
var data = XToOneRelationData.builder()
204-
.entity(property.getSourceEndPoint().getEntity().getName())
205-
.name(property.getSourceEndPoint().getName())
206-
.ref(targetId)
134+
return ResponseEntity.status(HttpStatus.METHOD_NOT_ALLOWED)
135+
.allow(SUPPORTED_PROPERTY_METHODS)
207136
.build();
208-
try {
209-
datamodelApi.setRelation(application, data, instanceId);
210-
} catch (EntityNotFoundException e) {
211-
throw new ResponseStatusException(HttpStatus.NOT_FOUND, e.getMessage(), e);
212-
} catch (ConstraintViolationException e) {
213-
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, e.getMessage(), e);
214-
}
215-
return ResponseEntity.noContent().build();
216137
}
217138

218139
@Override
219-
protected ResponseEntity<Object> patchProperty(Application application, Entity entity, EntityId instanceId,
220-
Relation property, List<URI> body) {
140+
protected ResponseEntity<Object> patchProperty(
141+
Application application,
142+
Entity entity,
143+
EntityId instanceId,
144+
Relation property,
145+
List<URI> body
146+
) {
221147
return ResponseEntity.status(HttpStatus.METHOD_NOT_ALLOWED)
222-
.allow(supportedPropertyMethods(property))
148+
.allow(SUPPORTED_PROPERTY_METHODS)
223149
.build();
224150
}
225151

@@ -248,10 +174,6 @@ protected ResponseEntity<Object> getPropertyItem(
248174
Relation property,
249175
EntityId itemId
250176
) {
251-
if (!(property instanceof OneToManyRelation || property instanceof ManyToManyRelation)) {
252-
return ResponseEntity.notFound().build();
253-
}
254-
255177
if (datamodelApi.hasRelationTarget(application, property, instanceId, itemId)) {
256178
var uri = linkTo(methodOn(EntityRestController.class).getEntity(application, property.getTargetEndPoint().getEntity().getPathSegment(), itemId)).toUri();
257179
return ResponseEntity.status(HttpStatus.FOUND).location(uri).build();
@@ -269,7 +191,9 @@ protected ResponseEntity<Object> postPropertyItem(
269191
EntityId itemId,
270192
List<URI> body
271193
) {
272-
return propertyItemUnsupportedMethodResponse(property);
194+
return ResponseEntity.status(HttpStatus.METHOD_NOT_ALLOWED)
195+
.allow(SUPPORTED_PROPERTY_ITEM_METHODS)
196+
.build();
273197
}
274198

275199
@Override
@@ -281,7 +205,9 @@ protected ResponseEntity<Object> putPropertyItem(
281205
EntityId itemId,
282206
List<URI> body
283207
) {
284-
return propertyItemUnsupportedMethodResponse(property);
208+
return ResponseEntity.status(HttpStatus.METHOD_NOT_ALLOWED)
209+
.allow(SUPPORTED_PROPERTY_ITEM_METHODS)
210+
.build();
285211
}
286212

287213
@Override
@@ -293,7 +219,9 @@ protected ResponseEntity<Object> patchPropertyItem(
293219
EntityId itemId,
294220
List<URI> body
295221
) {
296-
return propertyItemUnsupportedMethodResponse(property);
222+
return ResponseEntity.status(HttpStatus.METHOD_NOT_ALLOWED)
223+
.allow(SUPPORTED_PROPERTY_ITEM_METHODS)
224+
.build();
297225
}
298226

299227
@Override
@@ -304,10 +232,6 @@ protected ResponseEntity<Object> deletePropertyItem(
304232
Relation property,
305233
EntityId itemId
306234
) {
307-
if (!(property instanceof OneToManyRelation || property instanceof ManyToManyRelation)) {
308-
return ResponseEntity.notFound().build();
309-
}
310-
311235
try {
312236
datamodelApi.removeRelationItem(application, property, instanceId, itemId);
313237
} catch (EntityNotFoundException e) {

0 commit comments

Comments
 (0)