Skip to content

Commit ac134c0

Browse files
committed
Make ApiClient more pluggable for Java
- Rename ApiInvoker to ApiClient - Make ApiClient pluggable by allowing setting the ApiClient field of API classes - Introduce a Configuration class, containing the default ApiClient (which is also customizable) - Move basePath from API class to ApiClient - Change static methods in ApiClient to instance level
1 parent 1657f2e commit ac134c0

File tree

4 files changed

+95
-70
lines changed

4 files changed

+95
-70
lines changed

modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/JavaClientCodegen.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,13 @@ public JavaClientCodegen() {
5151
additionalProperties.put("artifactVersion", artifactVersion);
5252

5353
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
54-
supportingFiles.add(new SupportingFile("apiInvoker.mustache",
55-
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiInvoker.java"));
56-
supportingFiles.add(new SupportingFile("JsonUtil.mustache",
54+
supportingFiles.add(new SupportingFile("ApiClient.mustache",
55+
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiClient.java"));
56+
supportingFiles.add(new SupportingFile("Configuration.mustache",
57+
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "Configuration.java"));
58+
supportingFiles.add(new SupportingFile("JsonUtil.mustache",
5759
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "JsonUtil.java"));
58-
supportingFiles.add(new SupportingFile("apiException.mustache",
60+
supportingFiles.add(new SupportingFile("apiException.mustache",
5961
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiException.java"));
6062

6163
languageSpecificPrimitives = new HashSet<String>(

modules/swagger-codegen/src/main/resources/Java/apiInvoker.mustache renamed to modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache

Lines changed: 56 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -29,65 +29,82 @@ import java.net.URLEncoder;
2929
import java.io.IOException;
3030
import java.io.UnsupportedEncodingException;
3131

32+
import java.text.DateFormat;
3233
import java.text.SimpleDateFormat;
3334
import java.text.ParseException;
3435

35-
public class ApiInvoker {
36-
private static ApiInvoker INSTANCE = new ApiInvoker();
36+
public class ApiClient {
3737
private Map<String, Client> hostMap = new HashMap<String, Client>();
3838
private Map<String, String> defaultHeaderMap = new HashMap<String, String>();
3939
private boolean isDebug = false;
40+
private String basePath = "{{basePath}}";
4041
41-
/**
42-
* ISO 8601 date time format.
43-
* @see https://en.wikipedia.org/wiki/ISO_8601
44-
*/
45-
public static final SimpleDateFormat DATE_TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
42+
private DateFormat dateFormat;
43+
private DateFormat datetimeFormat;
4644
47-
/**
48-
* ISO 8601 date format.
49-
* @see https://en.wikipedia.org/wiki/ISO_8601
50-
*/
51-
public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
45+
public ApiClient() {
46+
// Use ISO 8601 format for date and datetime.
47+
// See https://en.wikipedia.org/wiki/ISO_8601
48+
this.dateFormat = new SimpleDateFormat("yyyy-MM-dd");
49+
this.datetimeFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
5250
53-
static {
5451
// Use UTC as the default time zone.
55-
DATE_TIME_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
56-
DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
52+
this.dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
53+
this.datetimeFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
5754
5855
// Set default User-Agent.
5956
setUserAgent("Java-Swagger");
6057
}
6158

62-
public static void setUserAgent(String userAgent) {
63-
INSTANCE.addDefaultHeader("User-Agent", userAgent);
59+
public String getBasePath() {
60+
return basePath;
6461
}
6562

66-
public static Date parseDateTime(String str) {
63+
public ApiClient setBasePath(String basePath) {
64+
this.basePath = basePath;
65+
return this;
66+
}
67+
68+
public ApiClient setUserAgent(String userAgent) {
69+
addDefaultHeader("User-Agent", userAgent);
70+
return this;
71+
}
72+
73+
public ApiClient addDefaultHeader(String key, String value) {
74+
defaultHeaderMap.put(key, value);
75+
return this;
76+
}
77+
78+
public ApiClient enableDebug() {
79+
isDebug = true;
80+
return this;
81+
}
82+
83+
public Date parseDateTime(String str) {
6784
try {
68-
return DATE_TIME_FORMAT.parse(str);
85+
return datetimeFormat.parse(str);
6986
} catch (java.text.ParseException e) {
7087
throw new RuntimeException(e);
7188
}
7289
}
7390

74-
public static Date parseDate(String str) {
91+
public Date parseDate(String str) {
7592
try {
76-
return DATE_FORMAT.parse(str);
93+
return dateFormat.parse(str);
7794
} catch (java.text.ParseException e) {
7895
throw new RuntimeException(e);
7996
}
8097
}
8198

82-
public static String formatDateTime(Date datetime) {
83-
return DATE_TIME_FORMAT.format(datetime);
99+
public String formatDateTime(Date datetime) {
100+
return datetimeFormat.format(datetime);
84101
}
85102

86-
public static String formatDate(Date date) {
87-
return DATE_FORMAT.format(date);
103+
public String formatDate(Date date) {
104+
return dateFormat.format(date);
88105
}
89106

90-
public static String parameterToString(Object param) {
107+
public String parameterToString(Object param) {
91108
if (param == null) {
92109
return "";
93110
} else if (param instanceof Date) {
@@ -105,17 +122,6 @@ public class ApiInvoker {
105122
return String.valueOf(param);
106123
}
107124
}
108-
public void enableDebug() {
109-
isDebug = true;
110-
}
111-
112-
public static ApiInvoker getInstance() {
113-
return INSTANCE;
114-
}
115-
116-
public void addDefaultHeader(String key, String value) {
117-
defaultHeaderMap.put(key, value);
118-
}
119125

120126
public String escapeString(String str) {
121127
try{
@@ -126,7 +132,7 @@ public class ApiInvoker {
126132
}
127133
}
128134

129-
public static Object deserialize(String json, String containerType, Class cls) throws ApiException {
135+
public Object deserialize(String json, String containerType, Class cls) throws ApiException {
130136
if(null != containerType) {
131137
containerType = containerType.toLowerCase();
132138
}
@@ -151,7 +157,7 @@ public class ApiInvoker {
151157
}
152158
}
153159

154-
public static String serialize(Object obj) throws ApiException {
160+
public String serialize(Object obj) throws ApiException {
155161
try {
156162
if (obj != null)
157163
return JsonUtil.getJsonMapper().writeValueAsString(obj);
@@ -163,8 +169,8 @@ public class ApiInvoker {
163169
}
164170
}
165171

166-
public String invokeAPI(String host, String path, String method, Map<String, String> queryParams, Object body, Map<String, String> headerParams, Map<String, String> formParams, String contentType) throws ApiException {
167-
Client client = getClient(host);
172+
public String invokeAPI(String path, String method, Map<String, String> queryParams, Object body, Map<String, String> headerParams, Map<String, String> formParams, String contentType) throws ApiException {
173+
Client client = getClient();
168174
169175
StringBuilder b = new StringBuilder();
170176
@@ -180,7 +186,7 @@ public class ApiInvoker {
180186
}
181187
String querystring = b.toString();
182188

183-
Builder builder = client.resource(host + path + querystring).accept("application/json");
189+
Builder builder = client.resource(basePath + path + querystring).accept("application/json");
184190
for(String key : headerParams.keySet()) {
185191
builder = builder.header(key, headerParams.get(key));
186192
}
@@ -236,6 +242,7 @@ public class ApiInvoker {
236242
else {
237243
throw new ApiException(500, "unknown method type " + method);
238244
}
245+
239246
if(response.getClientResponseStatus() == ClientResponse.Status.NO_CONTENT) {
240247
return null;
241248
}
@@ -267,8 +274,8 @@ public class ApiInvoker {
267274
StringBuilder formParamBuilder = new StringBuilder();
268275
269276
for (Entry<String, String> param : formParams.entrySet()) {
270-
String keyStr = ApiInvoker.parameterToString(param.getKey());
271-
String valueStr = ApiInvoker.parameterToString(param.getValue());
277+
String keyStr = parameterToString(param.getKey());
278+
String valueStr = parameterToString(param.getValue());
272279
273280
try {
274281
formParamBuilder.append(URLEncoder.encode(keyStr, "utf8"))
@@ -287,14 +294,13 @@ public class ApiInvoker {
287294
return encodedFormParams;
288295
}
289296

290-
291-
private Client getClient(String host) {
292-
if(!hostMap.containsKey(host)) {
297+
private Client getClient() {
298+
if(!hostMap.containsKey(basePath)) {
293299
Client client = Client.create();
294300
if(isDebug)
295301
client.addFilter(new LoggingFilter());
296-
hostMap.put(host, client);
302+
hostMap.put(basePath, client);
297303
}
298-
return hostMap.get(host);
304+
return hostMap.get(basePath);
299305
}
300-
}
306+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package {{invokerPackage}};
2+
3+
public class Configuration {
4+
private static ApiClient defaultApiClient = new ApiClient();
5+
6+
public static ApiClient getDefaultApiClient() {
7+
return defaultApiClient;
8+
}
9+
10+
public static void setDefaultApiClient(ApiClient apiClient) {
11+
defaultApiClient = apiClient;
12+
}
13+
}

modules/swagger-codegen/src/main/resources/Java/api.mustache

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package {{package}};
22

33
import {{invokerPackage}}.ApiException;
4-
import {{invokerPackage}}.ApiInvoker;
4+
import {{invokerPackage}}.ApiClient;
5+
import {{invokerPackage}}.Configuration;
56

67
import {{modelPackage}}.*;
78

@@ -21,19 +22,22 @@ import java.util.HashMap;
2122

2223
{{#operations}}
2324
public class {{classname}} {
24-
String basePath = "{{basePath}}";
25-
ApiInvoker apiInvoker = ApiInvoker.getInstance();
25+
private ApiClient apiClient;
2626
27-
public ApiInvoker getInvoker() {
28-
return apiInvoker;
27+
public {{classname}}() {
28+
this(Configuration.getDefaultApiClient());
2929
}
3030

31-
public void setBasePath(String basePath) {
32-
this.basePath = basePath;
31+
public {{classname}}(ApiClient apiClient) {
32+
this.apiClient = apiClient;
3333
}
3434

35-
public String getBasePath() {
36-
return basePath;
35+
public ApiClient getApiClient() {
36+
return apiClient;
37+
}
38+
39+
public void setApiClient(ApiClient apiClient) {
40+
this.apiClient = apiClient;
3741
}
3842

3943
{{#operation}}
@@ -54,17 +58,17 @@ public class {{classname}} {
5458

5559
// create path and map variables
5660
String path = "{{path}}".replaceAll("\\{format\\}","json"){{#pathParams}}
57-
.replaceAll("\\{" + "{{paramName}}" + "\\}", apiInvoker.escapeString({{{paramName}}}.toString())){{/pathParams}};
61+
.replaceAll("\\{" + "{{paramName}}" + "\\}", apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}};
5862

5963
// query params
6064
Map<String, String> queryParams = new HashMap<String, String>();
6165
Map<String, String> headerParams = new HashMap<String, String>();
6266
Map<String, String> formParams = new HashMap<String, String>();
6367

6468
{{#queryParams}}if ({{paramName}} != null)
65-
queryParams.put("{{baseName}}", ApiInvoker.parameterToString({{paramName}}));
69+
queryParams.put("{{baseName}}", apiClient.parameterToString({{paramName}}));
6670
{{/queryParams}}
67-
{{#headerParams}}headerParams.put("{{baseName}}", ApiInvoker.parameterToString({{paramName}}));
71+
{{#headerParams}}headerParams.put("{{baseName}}", apiClient.parameterToString({{paramName}}));
6872
{{/headerParams}}
6973
String[] contentTypes = {
7074
{{#consumes}}"{{mediaType}}"{{#hasMore}},{{/hasMore}}{{/consumes}}
@@ -77,7 +81,7 @@ public class {{classname}} {
7781
FormDataMultiPart mp = new FormDataMultiPart();
7882
{{#formParams}}{{#notFile}}
7983
hasFields = true;
80-
mp.field("{{baseName}}", ApiInvoker.parameterToString({{paramName}}), MediaType.MULTIPART_FORM_DATA_TYPE);
84+
mp.field("{{baseName}}", apiClient.parameterToString({{paramName}}), MediaType.MULTIPART_FORM_DATA_TYPE);
8185
{{/notFile}}{{#isFile}}
8286
hasFields = true;
8387
mp.field("{{baseName}}", file.getName());
@@ -87,14 +91,14 @@ public class {{classname}} {
8791
postBody = mp;
8892
}
8993
else {
90-
{{#formParams}}{{#notFile}}formParams.put("{{baseName}}", ApiInvoker.parameterToString({{paramName}}));{{/notFile}}
94+
{{#formParams}}{{#notFile}}formParams.put("{{baseName}}", apiClient.parameterToString({{paramName}}));{{/notFile}}
9195
{{/formParams}}
9296
}
9397

9498
try {
95-
String response = apiInvoker.invokeAPI(basePath, path, "{{httpMethod}}", queryParams, postBody, headerParams, formParams, contentType);
99+
String response = apiClient.invokeAPI(path, "{{httpMethod}}", queryParams, postBody, headerParams, formParams, contentType);
96100
if(response != null){
97-
return {{#returnType}}({{{returnType}}}) ApiInvoker.deserialize(response, "{{returnContainer}}", {{returnBaseType}}.class){{/returnType}};
101+
return {{#returnType}}({{{returnType}}}) apiClient.deserialize(response, "{{returnContainer}}", {{returnBaseType}}.class){{/returnType}};
98102
}
99103
else {
100104
return {{#returnType}}null{{/returnType}};

0 commit comments

Comments
 (0)