forked from quarkusio/quarkus
-
Notifications
You must be signed in to change notification settings - Fork 0
/
GetMethodImplementor.java
139 lines (120 loc) · 5.64 KB
/
GetMethodImplementor.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
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.ws.rs.core.Response;
import io.quarkus.gizmo.BranchResult;
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 GetMethodImplementor extends StandardMethodImplementor {
private static final String METHOD_NAME = "get";
private static final String RESOURCE_METHOD_NAME = "get";
private static final String EXCEPTION_MESSAGE = "Failed to get an entity";
private static final String REL = "self";
public GetMethodImplementor(boolean isResteasyClassic, boolean isReactivePanache) {
super(isResteasyClassic, isReactivePanache);
}
/**
* Generate JAX-RS GET method.
*
* The RESTEasy Classic version exposes {@link RestDataResource#get(Object)}.
* and the generated code looks more or less like this:
*
* <pre>
* {@code
* @GET
* @Produces({"application/json"})
* @Path("{id}")
* @LinkResource(
* rel = "self",
* entityClassName = "com.example.Entity"
* )
* public Response get(@PathParam("id") ID id) {
* try {
* Entity entity = restDataResource.get(id);
* if (entity != null) {
* return entity;
* } else {
* return Response.status(404).build();
* }
* } catch (Throwable t) {
* throw new RestDataPanacheException(t);
* }
* }
* }
* </pre>
*
* The RESTEasy Reactive version exposes {@link io.quarkus.rest.data.panache.ReactiveRestDataResource#delete(Object)}
* and the generated code looks more or less like this:
*
* <pre>
* {@code
* @GET
* @Produces({"application/json"})
* @Path("{id}")
* @LinkResource(
* rel = "self",
* entityClassName = "com.example.Entity"
* )
* public Uni<Response> get(@PathParam("id") ID id) {
* try {
* return restDataResource.get(id).map(entity -> entity == null ? Response.status(404).build() : Response.ok(entity).build());
* } catch (Throwable 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.getIdType());
// Add method annotations
addPathAnnotation(methodCreator, appendToPath(resourceProperties.getPath(RESOURCE_METHOD_NAME), "{id}"));
addGetAnnotation(methodCreator);
addProducesJsonAnnotation(methodCreator, resourceProperties);
addPathParamAnnotation(methodCreator.getParameterAnnotations(0), "id");
addLinksAnnotation(methodCreator, resourceMetadata.getEntityType(), REL);
ResultHandle resource = methodCreator.readInstanceField(resourceField, methodCreator.getThis());
ResultHandle id = 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, id);
// Return response
BranchResult wasNotFound = tryBlock.ifNull(entity);
wasNotFound.trueBranch().returnValue(responseImplementor.notFound(wasNotFound.trueBranch()));
wasNotFound.falseBranch().returnValue(responseImplementor.ok(wasNotFound.falseBranch(), entity));
tryBlock.close();
} else {
ResultHandle uniEntity = methodCreator.invokeVirtualMethod(
ofMethod(resourceMetadata.getResourceClass(), RESOURCE_METHOD_NAME, Uni.class, Object.class),
resource, id);
methodCreator.returnValue(UniImplementor.map(methodCreator, uniEntity, EXCEPTION_MESSAGE,
(body, entity) -> {
BranchResult entityWasNotFound = body.ifNull(entity);
entityWasNotFound.trueBranch()
.returnValue(responseImplementor.notFound(entityWasNotFound.trueBranch()));
entityWasNotFound.falseBranch()
.returnValue(responseImplementor.ok(entityWasNotFound.falseBranch(), entity));
}));
}
methodCreator.close();
}
@Override
protected String getResourceMethodName() {
return RESOURCE_METHOD_NAME;
}
}