Skip to content

Commit 34913dc

Browse files
committed
Update client generation for 1.7 with async and call support
1 parent 42ebfdd commit 34913dc

File tree

12 files changed

+242
-64
lines changed

12 files changed

+242
-64
lines changed

http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,16 @@
1212
class ClientMethodWriter {
1313

1414
private static final KnownResponse KNOWN_RESPONSE = new KnownResponse();
15+
private static final String BODY_HANDLER = "java.net.http.HttpResponse.BodyHandler";
16+
private static final String COMPLETABLE_FUTURE = "java.util.concurrent.CompletableFuture";
17+
private static final String HTTP_CALL = "io.avaje.http.client.HttpCall";
1518

1619
private final MethodReader method;
1720
private final Append writer;
1821
private final WebMethod webMethod;
1922
private final ProcessingContext ctx;
2023
private final UType returnType;
24+
private MethodParam bodyHandlerParam;
2125

2226
ClientMethodWriter(MethodReader method, Append writer, ProcessingContext ctx) {
2327
this.method = method;
@@ -45,10 +49,20 @@ private void methodStart(Append writer) {
4549
}
4650
writer.append(param.getShortType()).append(" ");
4751
writer.append(param.getName());
52+
checkBodyHandler(param);
4853
}
4954
writer.append(") {").eol();
5055
}
5156

57+
/**
58+
* Assign a method parameter as *the* BodyHandler.
59+
*/
60+
private void checkBodyHandler(MethodParam param) {
61+
if (param.getRawType().startsWith(BODY_HANDLER)) {
62+
bodyHandlerParam = param;
63+
}
64+
}
65+
5266
void write() {
5367
methodStart(writer);
5468
writer.append(" ");
@@ -74,15 +88,60 @@ void write() {
7488
String known = KNOWN_RESPONSE.get(returnType.full());
7589
if (known != null) {
7690
writer.append(" %s", known).eol();
77-
} else if (isReturnList()) {
78-
writer.append(" .list(%s.class);", Util.shortName(returnType.param0())).eol();
7991
} else {
80-
writer.append(" .bean(%s.class);", Util.shortName(returnType.full())).eol();
92+
if (COMPLETABLE_FUTURE.equals(returnType.mainType())) {
93+
writeAsyncResponse();
94+
} else if (HTTP_CALL.equals(returnType.mainType())) {
95+
writeCallResponse();
96+
} else {
97+
writeSyncResponse();
98+
}
8199
}
82100
}
83101
writer.append(" }").eol().eol();
84102
}
85103

104+
private void writeSyncResponse() {
105+
writer.append(" ");
106+
String type0 = returnType.mainType();
107+
String type1 = returnType.param0();
108+
writeResponse(type0, type1);
109+
}
110+
111+
private void writeAsyncResponse() {
112+
writer.append(" .async()");
113+
String type0 = returnType.param0();
114+
String type1 = returnType.param1();
115+
writeResponse(type0, type1);
116+
}
117+
118+
private void writeCallResponse() {
119+
writer.append(" .call()");
120+
String type0 = returnType.param0();
121+
String type1 = returnType.param1();
122+
writeResponse(type0, type1);
123+
}
124+
125+
private void writeResponse(String type0, String type1) {
126+
if (isList(type0)) {
127+
writer.append(".list(%s.class);", Util.shortName(type1)).eol();
128+
} else if (isStream(type0)) {
129+
writer.append(".stream(%s.class);", Util.shortName(type1)).eol();
130+
} else if (isHttpResponse(type0)){
131+
writeWithHandler();
132+
} else {
133+
writer.append(".bean(%s.class);", Util.shortName(type0)).eol();
134+
}
135+
}
136+
137+
private void writeWithHandler() {
138+
if (bodyHandlerParam != null) {
139+
writer.append(".withHandler(%s);", bodyHandlerParam.getName()).eol();
140+
} else {
141+
writer.append(".withHandler(responseHandler);").eol(); // Better to barf here?
142+
}
143+
}
144+
86145
private void writeQueryParams(PathSegments pathSegments) {
87146
List<MethodParam> params = method.getParams();
88147
for (MethodParam param : params) {
@@ -144,8 +203,16 @@ private void writePaths(Set<PathSegments.Segment> segments) {
144203
}
145204
}
146205

147-
private boolean isReturnList() {
148-
return returnType.shortType().startsWith("List<");
206+
private boolean isList(String type0) {
207+
return type0.equals("java.util.List");
208+
}
209+
210+
private boolean isStream(String type0) {
211+
return type0.equals("java.util.stream.Stream");
212+
}
213+
214+
private boolean isHttpResponse(String type0) {
215+
return type0.equals("java.net.http.HttpResponse");
149216
}
150217

151218
}

http-generator-client/src/main/java/io/avaje/http/generator/client/KnownResponse.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ class KnownResponse {
1111
private final Map<String, String> map = new HashMap<>();
1212

1313
KnownResponse() {
14-
map.put("void", ".asDiscarding();");
15-
map.put("java.net.http.HttpResponse<java.lang.Void>", ".asDiscarding();");
14+
map.put("void", ".asVoid();");
15+
map.put("java.net.http.HttpResponse<java.lang.Void>", ".asVoid();");
1616
map.put("java.net.http.HttpResponse<java.lang.String>", ".asString();");
1717
map.put("java.lang.String", ".asString().body();");
1818
map.put("java.net.http.HttpResponse<java.io.InputStream>", ".asInputStream();");
@@ -21,6 +21,11 @@ class KnownResponse {
2121
map.put("java.util.Stream<java.lang.String>", ".asLines().body();");
2222
map.put("java.net.http.HttpResponse<byte[]>", ".asByteArray();");
2323
map.put("byte[]", ".asByteArray().body();");
24+
map.put("java.util.concurrent.CompletableFuture<java.lang.Void>", ".async().asVoid();");
25+
map.put("java.util.concurrent.CompletableFuture<java.net.http.HttpResponse<java.lang.Void>>", ".async().asVoid();");
26+
map.put("java.util.concurrent.CompletableFuture<java.net.http.HttpResponse<java.lang.String>>", ".async().asString();");
27+
map.put("io.avaje.http.client.HttpCall<java.net.http.HttpResponse<java.lang.Void>>", ".call().asVoid();");
28+
map.put("io.avaje.http.client.HttpCall<java.net.http.HttpResponse<java.lang.String>>", ".call().asString();");
2429
}
2530

2631
String get(String full) {

http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
package io.avaje.http.generator.core;
22

3-
import java.util.Collections;
4-
import java.util.LinkedHashSet;
5-
import java.util.List;
6-
import java.util.Set;
3+
import java.util.*;
74

85
public interface UType {
96

@@ -19,10 +16,24 @@ public interface UType {
1916
*/
2017
String shortType();
2118

19+
/**
20+
* Return the main type (outer most type).
21+
*/
22+
String mainType();
23+
2224
/**
2325
* Return the first generic parameter.
2426
*/
25-
String param0();
27+
default String param0() {
28+
return null;
29+
}
30+
31+
/**
32+
* Return the second generic parameter.
33+
*/
34+
default String param1() {
35+
return null;
36+
}
2637

2738
/**
2839
* Return the raw type.
@@ -42,8 +53,8 @@ public String shortType() {
4253
}
4354

4455
@Override
45-
public String param0() {
46-
return null;
56+
public String mainType() {
57+
return "java.lang.Void";
4758
}
4859

4960
@Override
@@ -57,6 +68,7 @@ public String full() {
5768
*/
5869
class Basic implements UType {
5970
final String rawType;
71+
6072
Basic(String rawType) {
6173
this.rawType = rawType;
6274
}
@@ -77,8 +89,8 @@ public String shortType() {
7789
}
7890

7991
@Override
80-
public String param0() {
81-
return null;
92+
public String mainType() {
93+
return rawType;
8294
}
8395
}
8496

@@ -87,12 +99,25 @@ public String param0() {
8799
*/
88100
class Generic implements UType {
89101
final String rawType;
90-
final String mainType;
91-
final List<String> params;
92-
Generic(String rawType, String mainType, List<String> params) {
93-
this.rawType = rawType;
94-
this.mainType = mainType;
95-
this.params = params;
102+
final List<String> allTypes;
103+
final String shortRawType;
104+
105+
Generic(String rawTypeInput) {
106+
this.rawType = rawTypeInput.replace(" ",""); // trim whitespace
107+
this.allTypes = Arrays.asList(rawType.split("[<|>|,]"));
108+
this.shortRawType = shortRawType(rawType, allTypes);
109+
}
110+
111+
private String shortRawType(String rawType, List<String> allTypes) {
112+
Map<String, String> typeMap = new LinkedHashMap<>();
113+
for (String val : allTypes) {
114+
typeMap.put(val, Util.shortName(val));
115+
}
116+
String shortRaw = rawType;
117+
for (Map.Entry<String, String> entry : typeMap.entrySet()) {
118+
shortRaw = shortRaw.replace(entry.getKey(), entry.getValue());
119+
}
120+
return shortRaw;
96121
}
97122

98123
@Override
@@ -103,27 +128,32 @@ public String full() {
103128
@Override
104129
public Set<String> importTypes() {
105130
Set<String> set = new LinkedHashSet<>();
106-
set.add(mainType);
107-
set.addAll(params);
131+
for (String type : allTypes) {
132+
if (!type.startsWith("java.lang.")) {
133+
set.add(type);
134+
}
135+
}
108136
return set;
109137
}
110138

111139
@Override
112140
public String shortType() {
113-
StringBuilder sb = new StringBuilder();
114-
sb.append(Util.shortName(mainType)).append("<");
115-
for (int i = 0; i < params.size(); i++) {
116-
if (i > 0) {
117-
sb.append(",");
118-
}
119-
sb.append(Util.shortName(params.get(i)));
120-
}
121-
return sb.append(">").toString();
141+
return shortRawType;
142+
}
143+
144+
@Override
145+
public String mainType() {
146+
return allTypes.isEmpty() ? null : allTypes.get(0);
122147
}
123148

124149
@Override
125150
public String param0() {
126-
return params.get(0);
151+
return allTypes.size() < 2 ? null : allTypes.get(1);
152+
}
153+
154+
@Override
155+
public String param1() {
156+
return allTypes.size() < 3 ? null : allTypes.get(2);
127157
}
128158
}
129159
}

http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@
88
import javax.lang.model.type.TypeKind;
99
import javax.lang.model.type.TypeMirror;
1010
import javax.lang.model.util.SimpleAnnotationValueVisitor8;
11-
import java.util.ArrayList;
12-
import java.util.Collections;
13-
import java.util.List;
11+
import java.util.*;
1412

1513
public class Util {
1614

@@ -22,22 +20,10 @@ public static UType parse(String rawType) {
2220
if (pos == -1) {
2321
return new UType.Basic(rawType);
2422
} else {
25-
String mainType = rawType.substring(0, pos);
26-
String genericParams = rawType.substring(pos + 1, rawType.length() - 1);
27-
List<String> params = parseGenericParams(genericParams);
28-
return new UType.Generic(rawType, mainType, params);
23+
return new UType.Generic(rawType);
2924
}
3025
}
3126

32-
private static List<String> parseGenericParams(String genericParams) {
33-
String[] vals = genericParams.split(",");
34-
List<String> result = new ArrayList<>(vals.length);
35-
for (String val : vals) {
36-
result.add(val.trim());
37-
}
38-
return result;
39-
}
40-
4127
/**
4228
* Return the type removing validation annotations etc.
4329
*/

http-generator-core/src/test/java/io/avaje/http/generator/core/UtilTest.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,36 @@ void parse_generic_twoParams() {
9797
assertThat(type.importTypes()).containsExactly("java.util.List", "org.example.Repo", "foo.Other");
9898
assertThat(type.shortType()).isEqualTo("List<Repo,Other>");
9999
}
100+
101+
@Test
102+
void parse_CompletableFutureHttpVoid() {
103+
UType type = Util.parse("java.util.concurrent.CompletableFuture<java.net.http.HttpResponse<java.lang.Void>>");
104+
105+
assertThat(type.importTypes()).containsExactly("java.util.concurrent.CompletableFuture", "java.net.http.HttpResponse");
106+
assertThat(type.shortType()).isEqualTo("CompletableFuture<HttpResponse<Void>>");
107+
}
108+
109+
@Test
110+
void parse_CompletableFutureBean() {
111+
UType type = Util.parse("java.util.concurrent.CompletableFuture<org.example.Repo>");
112+
113+
assertThat(type.importTypes()).containsExactly("java.util.concurrent.CompletableFuture", "org.example.Repo");
114+
assertThat(type.shortType()).isEqualTo("CompletableFuture<Repo>");
115+
}
116+
117+
@Test
118+
void parse_CompletableFutureListBean() {
119+
UType type = Util.parse("java.util.concurrent.CompletableFuture<java.util.List<org.example.Repo>>");
120+
121+
assertThat(type.importTypes()).containsExactly("java.util.concurrent.CompletableFuture", "java.util.List", "org.example.Repo");
122+
assertThat(type.shortType()).isEqualTo("CompletableFuture<List<Repo>>");
123+
}
124+
125+
@Test
126+
void parse_CompletableFutureStreamBean() {
127+
UType type = Util.parse("java.util.concurrent.CompletableFuture<java.util.Stream<org.example.Repo>>");
128+
129+
assertThat(type.importTypes()).containsExactly("java.util.concurrent.CompletableFuture", "java.util.Stream", "org.example.Repo");
130+
assertThat(type.shortType()).isEqualTo("CompletableFuture<Stream<Repo>>");
131+
}
100132
}

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
<module>http-generator-jex</module>
4040
<module>http-generator-helidon</module>
4141
<module>http-generator-client</module>
42-
<!-- <module>tests</module>-->
42+
<module>tests</module>
4343
</modules>
4444

4545
</project>

tests/test-client/pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
<dependency>
2626
<groupId>io.avaje</groupId>
2727
<artifactId>avaje-http-client</artifactId>
28-
<version>1.6</version>
28+
<version>1.7</version>
2929
</dependency>
3030

3131
<dependency>
@@ -37,7 +37,7 @@
3737
<dependency>
3838
<groupId>io.avaje</groupId>
3939
<artifactId>avaje-http-api</artifactId>
40-
<version>1.6-SNAPSHOT</version>
40+
<version>1.7-SNAPSHOT</version>
4141
</dependency>
4242

4343
<dependency>
@@ -93,7 +93,7 @@
9393
<path>
9494
<groupId>io.avaje</groupId>
9595
<artifactId>avaje-http-generator-client</artifactId>
96-
<version>1.6-SNAPSHOT</version>
96+
<version>1.7-SNAPSHOT</version>
9797
</path>
9898
</annotationProcessorPaths>
9999
</configuration>

0 commit comments

Comments
 (0)