Skip to content

Commit 0be57df

Browse files
jaxrs: options type can be generic variable
1 parent 1cd795e commit 0be57df

File tree

8 files changed

+46
-22
lines changed

8 files changed

+46
-22
lines changed

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/Settings.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ public class Settings {
5050
public String jaxrsNamespacingAnnotationElement; // default is "value"
5151
public String restResponseType = null;
5252
public String restOptionsType = null;
53+
public boolean restOptionsTypeIsGeneric;
5354
public TypeProcessor customTypeProcessor = null;
5455
public boolean sortDeclarations = false;
5556
public boolean sortTypeDeclarations = false;
@@ -154,7 +155,7 @@ public void validate() {
154155
}
155156
if (features.restOptionsType != null) {
156157
reportConfigurationChange(extensionName, "restOptionsType", features.restOptionsType);
157-
restOptionsType = features.restOptionsType;
158+
setRestOptionsType(features.restOptionsType);
158159
}
159160
if (features.overridesStringEnums) {
160161
defaultStringEnumsOverriddenByExtension = true;
@@ -250,6 +251,18 @@ public void setJaxrsNamespacingAnnotation(ClassLoader classLoader, String jaxrsN
250251
}
251252
}
252253

254+
public void setRestOptionsType(String restOptionsType) {
255+
if (restOptionsType != null) {
256+
if (restOptionsType.startsWith("<") && restOptionsType.endsWith(">")) {
257+
this.restOptionsType = restOptionsType.substring(1, restOptionsType.length() - 1);
258+
this.restOptionsTypeIsGeneric = true;
259+
} else {
260+
this.restOptionsType = restOptionsType;
261+
this.restOptionsTypeIsGeneric = false;
262+
}
263+
}
264+
}
265+
253266
public boolean areDefaultStringEnumsOverriddenByExtension() {
254267
return defaultStringEnumsOverriddenByExtension;
255268
}

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/compiler/ModelCompiler.java

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import java.lang.annotation.Annotation;
99
import java.lang.reflect.*;
1010
import java.util.*;
11-
import javax.ws.rs.core.Application;
1211

1312

1413
/**
@@ -54,12 +53,15 @@ public TsModel javaToTypeScript(Model model) {
5453
final TsType optionsType = settings.restOptionsType != null
5554
? new TsType.VerbatimType(settings.restOptionsType)
5655
: null;
56+
final TsType.GenericVariableType optionsGenericVariable = settings.restOptionsTypeIsGeneric
57+
? new TsType.GenericVariableType(settings.restOptionsType)
58+
: null;
5759

5860
if (settings.generateJaxrsApplicationInterface) {
59-
tsModel = createJaxrsInterfaces(symbolTable, tsModel, jaxrsApplication, responseSymbol, optionsType);
61+
tsModel = createJaxrsInterfaces(symbolTable, tsModel, jaxrsApplication, responseSymbol, optionsGenericVariable, optionsType);
6062
}
6163
if (settings.generateJaxrsApplicationClient) {
62-
tsModel = createJaxrsClients(symbolTable, tsModel, jaxrsApplication, responseSymbol, optionsType);
64+
tsModel = createJaxrsClients(symbolTable, tsModel, jaxrsApplication, responseSymbol, optionsGenericVariable, optionsType);
6365
}
6466
}
6567

@@ -315,20 +317,24 @@ private Symbol createJaxrsResponseType(SymbolTable symbolTable, TsModel tsModel)
315317
return responseSymbol;
316318
}
317319

318-
private TsModel createJaxrsInterfaces(SymbolTable symbolTable, TsModel tsModel, JaxrsApplicationModel jaxrsApplication, Symbol responseSymbol, TsType optionsType) {
320+
private TsModel createJaxrsInterfaces(SymbolTable symbolTable, TsModel tsModel, JaxrsApplicationModel jaxrsApplication,
321+
Symbol responseSymbol, TsType.GenericVariableType optionsGenericVariable, TsType optionsType) {
322+
final List<TsType.GenericVariableType> typeParameters = Utils.listFromNullable(optionsGenericVariable);
319323
final Map<Symbol, List<TsMethodModel>> groupedMethods = processJaxrsMethods(jaxrsApplication, symbolTable, null, responseSymbol, optionsType, false);
320324
for (Map.Entry<Symbol, List<TsMethodModel>> entry : groupedMethods.entrySet()) {
321-
final TsBeanModel interfaceModel = new TsBeanModel(null, TsBeanCategory.Service, false, entry.getKey(), null, null, null, null, null, null, entry.getValue(), null);
325+
final TsBeanModel interfaceModel = new TsBeanModel(null, TsBeanCategory.Service, false, entry.getKey(), typeParameters, null, null, null, null, null, entry.getValue(), null);
322326
tsModel.getBeans().add(interfaceModel);
323327
}
324328
return tsModel;
325329
}
326330

327-
private TsModel createJaxrsClients(SymbolTable symbolTable, TsModel tsModel, JaxrsApplicationModel jaxrsApplication, Symbol responseSymbol, TsType optionsType) {
331+
private TsModel createJaxrsClients(SymbolTable symbolTable, TsModel tsModel, JaxrsApplicationModel jaxrsApplication,
332+
Symbol responseSymbol, TsType.GenericVariableType optionsGenericVariable, TsType optionsType) {
328333
final Symbol httpClientSymbol = symbolTable.getSyntheticSymbol("HttpClient");
334+
final List<TsType.GenericVariableType> typeParameters = Utils.listFromNullable(optionsGenericVariable);
329335

330336
// HttpClient interface
331-
tsModel.getBeans().add(new TsBeanModel(null, TsBeanCategory.ServicePrerequisite, false, httpClientSymbol, null, null, null, null, null, null, Arrays.asList(
337+
tsModel.getBeans().add(new TsBeanModel(null, TsBeanCategory.ServicePrerequisite, false, httpClientSymbol, typeParameters, null, null, null, null, null, Arrays.asList(
332338
new TsMethodModel("request", new TsType.GenericReferenceType(responseSymbol, TsType.Any), Arrays.asList(
333339
new TsParameterModel("requestConfig", new TsType.ObjectType(
334340
new TsProperty("method", TsType.String),
@@ -341,8 +347,11 @@ private TsModel createJaxrsClients(SymbolTable symbolTable, TsModel tsModel, Jax
341347
), null));
342348

343349
// application client classes
350+
final TsType.ReferenceType httpClientType = optionsGenericVariable != null
351+
? new TsType.GenericReferenceType(httpClientSymbol, optionsGenericVariable)
352+
: new TsType.ReferenceType(httpClientSymbol);
344353
final TsConstructorModel constructor = new TsConstructorModel(
345-
Arrays.asList(new TsParameterModel(TsAccessibilityModifier.Protected, "httpClient", new TsType.ReferenceType(httpClientSymbol))),
354+
Arrays.asList(new TsParameterModel(TsAccessibilityModifier.Protected, "httpClient", httpClientType)),
346355
Collections.<TsStatement>emptyList(),
347356
null
348357
);
@@ -351,7 +360,7 @@ private TsModel createJaxrsClients(SymbolTable symbolTable, TsModel tsModel, Jax
351360
for (Map.Entry<Symbol, List<TsMethodModel>> entry : groupedMethods.entrySet()) {
352361
final Symbol symbol = settings.generateJaxrsApplicationInterface ? symbolTable.addSuffixToSymbol(entry.getKey(), "Client") : entry.getKey();
353362
final TsType interfaceType = settings.generateJaxrsApplicationInterface ? new TsType.ReferenceType(entry.getKey()) : null;
354-
final TsBeanModel clientModel = new TsBeanModel(null, TsBeanCategory.Service, true, symbol, null, null, null,
363+
final TsBeanModel clientModel = new TsBeanModel(null, TsBeanCategory.Service, true, symbol, typeParameters, null, null,
355364
Utils.listFromNullable(interfaceType), null, constructor, entry.getValue(), null);
356365
tsModel.getBeans().add(clientModel);
357366
}

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/ext/AxiosClientExtension.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public EmitterExtensionFeatures getFeatures() {
2020
features.generatesModuleCode = true;
2121
features.generatesJaxrsApplicationClient = true;
2222
features.restResponseType = "Axios.Promise<Axios.GenericAxiosResponse<R>>";
23-
features.restOptionsType = "Axios.AxiosRequestConfig";
23+
features.restOptionsType = "<O>";
2424
return features;
2525
}
2626

typescript-generator-core/src/main/resources/cz/habarta/typescript/generator/ext/AxiosClientExtension-client.template.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
/*export*/ class $$AxiosRestApplicationClient$$ extends $$RestApplicationClient$$ {
2+
/*export*/ class $$AxiosRestApplicationClient$$ extends $$RestApplicationClient$$<Axios.AxiosRequestConfig> {
33

44
constructor(baseURL: string, axiosInstance: Axios.AxiosInstance = axios.create()) {
55
axiosInstance.defaults.baseURL = baseURL;

typescript-generator-core/src/main/resources/cz/habarta/typescript/generator/ext/AxiosClientExtension-shared.template.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ declare module "axios" {
88
}
99
}
1010

11-
class AxiosHttpClient implements HttpClient {
11+
class AxiosHttpClient implements HttpClient<Axios.AxiosRequestConfig> {
1212

1313
constructor(private axios: Axios.AxiosInstance) {
1414
}

typescript-generator-core/src/test/java/cz/habarta/typescript/generator/ext/AxiosClientExtensionTest.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,22 @@ public void test() {
2424
settings.jaxrsNamespacing = JaxrsNamespacing.perResource;
2525
settings.extensions.add(new AxiosClientExtension());
2626
final String output = new TypeScriptGenerator(settings).generateTypeScript(Input.from(JaxrsApplicationTest.OrganizationApplication.class));
27+
System.out.println(output);
2728
final String errorMessage = "Unexpected output: " + output;
2829

2930
Assert.assertTrue(errorMessage, output.contains("interface Organization"));
3031
Assert.assertTrue(errorMessage, output.contains("interface Address"));
3132
Assert.assertTrue(errorMessage, output.contains("interface Person"));
3233
Assert.assertTrue(errorMessage, output.contains("interface HttpClient"));
3334

34-
Assert.assertTrue(errorMessage, output.contains("class OrganizationsResourceClient"));
35-
Assert.assertTrue(errorMessage, output.contains("class PersonResourceClient"));
35+
Assert.assertTrue(errorMessage, output.contains("class OrganizationsResourceClient<O>"));
36+
Assert.assertTrue(errorMessage, output.contains("class PersonResourceClient<O>"));
3637
Assert.assertTrue(errorMessage, output.contains("type RestResponse<R> = Axios.Promise<Axios.GenericAxiosResponse<R>>"));
3738

38-
Assert.assertTrue(errorMessage, output.contains("class AxiosHttpClient implements HttpClient"));
39+
Assert.assertTrue(errorMessage, output.contains("class AxiosHttpClient implements HttpClient<Axios.AxiosRequestConfig>"));
3940
Assert.assertTrue(errorMessage, output.contains("request(requestConfig: { method: string; url: string; queryParams?: any; data?: any; options?: Axios.AxiosRequestConfig; }): RestResponse<any>"));
40-
Assert.assertTrue(errorMessage, output.contains("class AxiosOrganizationsResourceClient extends OrganizationsResourceClient"));
41-
Assert.assertTrue(errorMessage, output.contains("class AxiosPersonResourceClient extends PersonResourceClient"));
41+
Assert.assertTrue(errorMessage, output.contains("class AxiosOrganizationsResourceClient extends OrganizationsResourceClient<Axios.AxiosRequestConfig>"));
42+
Assert.assertTrue(errorMessage, output.contains("class AxiosPersonResourceClient extends PersonResourceClient<Axios.AxiosRequestConfig>"));
4243
Assert.assertTrue(errorMessage, output.contains("constructor(baseURL: string, axiosInstance: Axios.AxiosInstance = axios.create())"));
4344
}
4445

typescript-generator-gradle-plugin/src/main/java/cz/habarta/typescript/generator/gradle/GenerateTask.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ public void generate() throws Exception {
117117
settings.jaxrsNamespacing = jaxrsNamespacing;
118118
settings.setJaxrsNamespacingAnnotation(classLoader, jaxrsNamespacingAnnotation);
119119
settings.restResponseType = restResponseType;
120-
settings.restOptionsType = restOptionsType;
120+
settings.setRestOptionsType(restOptionsType);
121121
settings.loadCustomTypeProcessor(classLoader, customTypeProcessor);
122122
settings.sortDeclarations = sortDeclarations;
123123
settings.sortTypeDeclarations = sortTypeDeclarations;

typescript-generator-maven-plugin/src/main/java/cz/habarta/typescript/generator/maven/GenerateMojo.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,8 +280,8 @@ public class GenerateMojo extends AbstractMojo {
280280

281281
/**
282282
* Specifies HTTP response type in JAXRS application.
283-
* Default value is <code>Promise&amp;R></code> which means data object returned asynchronously.
284-
* Useful for example when underlying HTTP response object (like <code>XMLHttpRequest</code> or <code>AxiosPromise</code>)
283+
* Default value is <code>Promise&lt;R></code> which means data object returned asynchronously.
284+
* This parameter is useful for example when underlying HTTP response object (like <code>XMLHttpRequest</code> or <code>AxiosPromise</code>)
285285
* is returned instead of actual response data.
286286
*/
287287
@Parameter
@@ -291,6 +291,7 @@ public class GenerateMojo extends AbstractMojo {
291291
* Specifies HTTP request options type in JAXRS application.
292292
* By default no <code>options</code> parameter is generated.
293293
* Useful when passing additional parameters to underlying HTTP request method (like jQuery ajax settings or <code>AxiosRequestConfig</code>).
294+
* Can be specific (for example <code>AxiosRequestConfig</code>) or generic (for example <code>&ltO></code>).
294295
*/
295296
@Parameter
296297
private String restOptionsType;
@@ -444,7 +445,7 @@ public void execute() {
444445
settings.jaxrsNamespacing = jaxrsNamespacing;
445446
settings.setJaxrsNamespacingAnnotation(classLoader, jaxrsNamespacingAnnotation);
446447
settings.restResponseType = restResponseType;
447-
settings.restOptionsType = restOptionsType;
448+
settings.setRestOptionsType(restOptionsType);
448449
settings.loadCustomTypeProcessor(classLoader, customTypeProcessor);
449450
settings.sortDeclarations = sortDeclarations;
450451
settings.sortTypeDeclarations = sortTypeDeclarations;

0 commit comments

Comments
 (0)