forked from quarkusio/quarkus
-
Notifications
You must be signed in to change notification settings - Fork 0
/
AddMethodImplementor.java
146 lines (129 loc) · 6.1 KB
/
AddMethodImplementor.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package io.quarkus.rest.data.panache.deployment.methods;
import static io.quarkus.gizmo.MethodDescriptor.ofMethod;
import static io.quarkus.rest.data.panache.deployment.utils.SignatureMethodCreator.ofType;
import javax.validation.Valid;
import javax.ws.rs.core.Response;
import io.quarkus.gizmo.ClassCreator;
import io.quarkus.gizmo.FieldDescriptor;
import io.quarkus.gizmo.MethodCreator;
import io.quarkus.gizmo.ResultHandle;
import io.quarkus.gizmo.TryBlock;
import io.quarkus.rest.data.panache.RestDataResource;
import io.quarkus.rest.data.panache.deployment.ResourceMetadata;
import io.quarkus.rest.data.panache.deployment.properties.ResourceProperties;
import io.quarkus.rest.data.panache.deployment.utils.SignatureMethodCreator;
import io.quarkus.rest.data.panache.deployment.utils.UniImplementor;
import io.smallrye.mutiny.Uni;
public final class AddMethodImplementor extends StandardMethodImplementor {
private static final String METHOD_NAME = "add";
private static final String RESOURCE_METHOD_NAME = "add";
private static final String EXCEPTION_MESSAGE = "Failed to add an entity";
private static final String REL = "add";
private final boolean withValidation;
public AddMethodImplementor(boolean withValidation, boolean isResteasyClassic, boolean isReactivePanache) {
super(isResteasyClassic, isReactivePanache);
this.withValidation = withValidation;
}
/**
* Generate JAX-RS POST method.
*
* The RESTEasy Classic version exposes {@link RestDataResource#add(Object)}.
* Generated code looks more or less like this:
*
* <pre>
* {@code
* @POST
* @Path("")
* @Consumes({"application/json"})
* @Produces({"application/json"})
* @LinkResource(
* rel = "add",
* entityClassName = "com.example.Entity"
* )
* public Response add(Entity entityToSave) {
* try {
* Entity entity = restDataResource.add(entityToSave);
* String location = new ResourceLinksProvider().getSelfLink(entity);
* if (location != null) {
* ResponseBuilder responseBuilder = Response.status(201);
* responseBuilder.entity(entity);
* responseBuilder.location(URI.create(location));
* return responseBuilder.build();
* } else {
* throw new RuntimeException("Could not extract a new entity URL")
* }
* } catch (Throwable t) {
* throw new RestDataPanacheException(t);
* }
* }
* }
* </pre>
*
* The RESTEasy Reactive version exposes {@link io.quarkus.rest.data.panache.ReactiveRestDataResource#add(Object)}
* and the generated code looks more or less like this:
*
* <pre>
* {@code
* @POST
* @Path("")
* @Consumes({"application/json"})
* @Produces({"application/json"})
* @LinkResource(
* rel = "add",
* entityClassName = "com.example.Entity"
* )
* public Uni<Response> add(Entity entityToSave) {
* return restDataResource.add(entityToSave).map(entity -> {
* String location = new ResourceLinksProvider().getSelfLink(entity);
* if (location != null) {
* ResponseBuilder responseBuilder = Response.status(201);
* responseBuilder.entity(entity);
* responseBuilder.location(URI.create(location));
* return responseBuilder.build();
* } else {
* throw new RuntimeException("Could not extract a new entity URL")
* }
* }).onFailure().invoke(t -> throw new RestDataPanacheException(t));
* }
* }
* </pre>
*/
@Override
protected void implementInternal(ClassCreator classCreator, ResourceMetadata resourceMetadata,
ResourceProperties resourceProperties, FieldDescriptor resourceField) {
MethodCreator methodCreator = SignatureMethodCreator.getMethodCreator(METHOD_NAME, classCreator,
isNotReactivePanache() ? ofType(Response.class) : ofType(Uni.class, resourceMetadata.getEntityType()),
resourceMetadata.getEntityType());
// Add method annotations
addPathAnnotation(methodCreator, resourceProperties.getPath(RESOURCE_METHOD_NAME));
addPostAnnotation(methodCreator);
addConsumesAnnotation(methodCreator, APPLICATION_JSON);
addProducesJsonAnnotation(methodCreator, resourceProperties);
addLinksAnnotation(methodCreator, resourceMetadata.getEntityType(), REL);
// Add parameter annotations
if (withValidation) {
methodCreator.getParameterAnnotations(0).addAnnotation(Valid.class);
}
ResultHandle resource = methodCreator.readInstanceField(resourceField, methodCreator.getThis());
ResultHandle entityToSave = methodCreator.getMethodParam(0);
if (isNotReactivePanache()) {
TryBlock tryBlock = implementTryBlock(methodCreator, EXCEPTION_MESSAGE);
ResultHandle entity = tryBlock.invokeVirtualMethod(
ofMethod(resourceMetadata.getResourceClass(), RESOURCE_METHOD_NAME, Object.class, Object.class),
resource, entityToSave);
tryBlock.returnValue(responseImplementor.created(tryBlock, entity));
tryBlock.close();
} else {
ResultHandle uniEntity = methodCreator.invokeVirtualMethod(
ofMethod(resourceMetadata.getResourceClass(), RESOURCE_METHOD_NAME, Uni.class, Object.class),
resource, entityToSave);
methodCreator.returnValue(UniImplementor.map(methodCreator, uniEntity, EXCEPTION_MESSAGE,
(body, item) -> body.returnValue(responseImplementor.created(body, item))));
}
methodCreator.close();
}
@Override
protected String getResourceMethodName() {
return RESOURCE_METHOD_NAME;
}
}