Add a new library template to Java client: okhttp-gson

which uses OkHttp as HTTP library and Gson as JSON processing library
This commit is contained in:
xhh 2015-08-31 18:42:09 +08:00
parent 8114c416b9
commit 3c84847adb
13 changed files with 1311 additions and 13 deletions

View File

@ -0,0 +1,4 @@
{
"library": "okhttp-gson",
"artifactId": "swagger-petstore-okhttp-gson"
}

View File

@ -0,0 +1,31 @@
#!/bin/sh
SCRIPT="$0"
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"
if [ ! -f "$executable" ]
then
mvn clean package
fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l java -c bin/java-petstore-okhttp-gson.json -o samples/client/petstore/java/okhttp-gson"
java $JAVA_OPTS -jar $executable $ags

View File

@ -83,6 +83,7 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
supportedLibraries.put("<default>", "HTTP client: Jersey client 1.18. JSON processing: Jackson 2.4.2");
supportedLibraries.put("jersey2", "HTTP client: Jersey client 2.6");
supportedLibraries.put("okhttp-gson", "HTTP client: OkHttp 2.4.0. JSON processing: Gson 2.3.1");
cliOptions.add(buildLibraryCliOption(supportedLibraries));
}
@ -159,7 +160,15 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java"));
supportingFiles.add(new SupportingFile("Pair.mustache", invokerFolder, "Pair.java"));
supportingFiles.add(new SupportingFile("StringUtil.mustache", invokerFolder, "StringUtil.java"));
supportingFiles.add(new SupportingFile("TypeRef.mustache", invokerFolder, "TypeRef.java"));
// library-specific files
if ("okhttp-gson".equals(getLibrary())) {
// the "okhttp-gson" library template requires "ApiCallback.mustache"
// and does not require "TypeRef.mustache"
supportingFiles.add(new SupportingFile("ApiCallback.mustache", invokerFolder, "ApiCallback.java"));
} else {
supportingFiles.add(new SupportingFile("TypeRef.mustache", invokerFolder, "TypeRef.java"));
}
final String authFolder = (sourceFolder + File.separator + invokerPackage + ".auth").replace(".", File.separator);
supportingFiles.add(new SupportingFile("auth/Authentication.mustache", authFolder, "Authentication.java"));

View File

@ -39,4 +39,13 @@ public class StringUtil {
}
return out.toString();
}
/**
* Convert the given object to string with each line indented by 4 spaces
* (except the first line).
*/
public static String toIndentedString(Object o) {
if (o == null) return "null";
return o.toString().replace("\n", "\n ");
}
}

View File

@ -6,20 +6,45 @@ import java.util.List;
{{>generatedAnnotation}}
public class ApiException extends Exception {
private int code = 0;
private String message = null;
private Map<String, List<String>> responseHeaders = null;
private String responseBody = null;
public ApiException() {}
public ApiException(int code, String message) {
public ApiException(Throwable throwable) {
super(throwable);
}
public ApiException(String message) {
super(message);
}
public ApiException(String message, Throwable throwable, int code, Map<String, List<String>> responseHeaders, String responseBody) {
super(message, throwable);
this.code = code;
this.responseHeaders = responseHeaders;
this.responseBody = responseBody;
}
public ApiException(String message, int code, Map<String, List<String>> responseHeaders, String responseBody) {
this(message, (Throwable) null, code, responseHeaders, responseBody);
}
public ApiException(String message, Throwable throwable, int code, Map<String, List<String>> responseHeaders) {
this(message, throwable, code, responseHeaders, null);
}
public ApiException(int code, Map<String, List<String>> responseHeaders, String responseBody) {
this((String) null, (Throwable) null, code, responseHeaders, responseBody);
}
public ApiException(int code, String message) {
super(message);
this.code = code;
this.message = message;
}
public ApiException(int code, String message, Map<String, List<String>> responseHeaders, String responseBody) {
this.code = code;
this.message = message;
this(code, message);
this.responseHeaders = responseHeaders;
this.responseBody = responseBody;
}
@ -28,10 +53,6 @@ public class ApiException extends Exception {
return code;
}
public String getMessage() {
return message;
}
/**
* Get the HTTP response headers.
*/

View File

@ -0,0 +1,22 @@
package {{invokerPackage}};
import java.io.IOException;
/**
* Callback for asynchronous API call.
*
* @param <T> The return type
*/
public interface ApiCallback<T> {
/**
* This is called when the API call fails.
*/
void onFailure(ApiException e);
/**
* This is called when the API call succeeded.
*
* @param result The result deserialized from response
*/
void onSuccess(T result);
}

View File

@ -0,0 +1,762 @@
package {{invokerPackage}};
import com.squareup.okhttp.Call;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.FormEncodingBuilder;
import com.squareup.okhttp.MultipartBuilder;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.Headers;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Date;
import java.util.TimeZone;
import java.util.regex.Pattern;
import java.net.URLEncoder;
import java.net.URLConnection;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import {{invokerPackage}}.auth.Authentication;
import {{invokerPackage}}.auth.HttpBasicAuth;
import {{invokerPackage}}.auth.ApiKeyAuth;
import {{invokerPackage}}.auth.OAuth;
public class ApiClient {
private String basePath = "{{basePath}}";
private boolean lenientOnJson = false;
private boolean debugging = false;
private Map<String, String> defaultHeaderMap = new HashMap<String, String>();
private Map<String, Authentication> authentications;
private String dateFormat;
private DateFormat dateFormatter;
private int dateLength;
private String datetimeFormat;
private DateFormat datetimeFormatter;
private OkHttpClient httpClient;
private JSON json;
public ApiClient() {
httpClient = new OkHttpClient();
json = new JSON(this);
// Use ISO 8601 format for date and datetime.
// See https://en.wikipedia.org/wiki/ISO_8601
setDateFormat("yyyy-MM-dd");
setDatetimeFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
// Set default User-Agent.
setUserAgent("Java-Swagger");
// Setup authentications (key: authentication name, value: authentication).
authentications = new HashMap<String, Authentication>();{{#authMethods}}{{#isBasic}}
authentications.put("{{name}}", new HttpBasicAuth());{{/isBasic}}{{#isApiKey}}
authentications.put("{{name}}", new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}"));{{/isApiKey}}{{#isOAuth}}
authentications.put("{{name}}", new OAuth());{{/isOAuth}}{{/authMethods}}
// Prevent the authentications from being modified.
authentications = Collections.unmodifiableMap(authentications);
}
public String getBasePath() {
return basePath;
}
public ApiClient setBasePath(String basePath) {
this.basePath = basePath;
return this;
}
public OkHttpClient getHttpClient() {
return httpClient;
}
public ApiClient setHttpClient(OkHttpClient httpClient) {
this.httpClient = httpClient;
return this;
}
public JSON getJSON() {
return json;
}
public ApiClient setJSON(JSON json) {
this.json = json;
return this;
}
public String getDateFormat() {
return dateFormat;
}
public ApiClient setDateFormat(String dateFormat) {
this.dateFormat = dateFormat;
this.dateFormatter = new SimpleDateFormat(dateFormat);
// Use UTC as the default time zone.
this.dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
this.dateLength = this.dateFormatter.format(new Date()).length();
return this;
}
public String getDatetimeFormat() {
return datetimeFormat;
}
public ApiClient setDatetimeFormat(String datetimeFormat) {
this.datetimeFormat = datetimeFormat;
this.datetimeFormatter = new SimpleDateFormat(datetimeFormat);
// Note: The datetime formatter uses the system's default time zone.
return this;
}
/**
* Parse the given date string into Date object.
* The default <code>dateFormat</code> supports these ISO 8601 date formats:
* 2015-08-16
* 2015-8-16
*/
public Date parseDate(String str) {
if (str == null)
return null;
try {
return dateFormatter.parse(str);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
/**
* Parse the given date-time string into Date object.
* The default <code>datetimeFormat</code> supports these ISO 8601 datetime formats:
* 2015-08-16T08:20:05Z
* 2015-8-16T8:20:05Z
* 2015-08-16T08:20:05+00:00
* 2015-08-16T08:20:05+0000
* 2015-08-16T08:20:05.376Z
* 2015-08-16T08:20:05.376+00:00
* 2015-08-16T08:20:05.376+00
* Note: The 3-digit milli-seconds is optional. Time zone is required and can be in one of
* these formats:
* Z (same with +0000)
* +08:00 (same with +0800)
* -02 (same with -0200)
* -0200
* @see https://en.wikipedia.org/wiki/ISO_8601
*/
public Date parseDatetime(String str) {
if (str == null)
return null;
if ("yyyy-MM-dd'T'HH:mm:ss.SSSZ".equals(datetimeFormat)) {
/*
* When the default datetime format is used, process the given string
* to support various formats defined by ISO 8601.
*/
// normalize time zone
// trailing "Z": 2015-08-16T08:20:05Z => 2015-08-16T08:20:05+0000
str = str.replaceAll("[zZ]\\z", "+0000");
// remove colon: 2015-08-16T08:20:05+00:00 => 2015-08-16T08:20:05+0000
str = str.replaceAll("([+-]\\d{2}):(\\d{2})\\z", "$1$2");
// expand time zone: 2015-08-16T08:20:05+00 => 2015-08-16T08:20:05+0000
str = str.replaceAll("([+-]\\d{2})\\z", "$100");
// add milliseconds when missing
// 2015-08-16T08:20:05+0000 => 2015-08-16T08:20:05.000+0000
str = str.replaceAll("(:\\d{1,2})([+-]\\d{4})\\z", "$1.000$2");
}
try {
return datetimeFormatter.parse(str);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
public Date parseDateOrDatetime(String str) {
if (str == null)
return null;
else if (str.length() <= dateLength)
return parseDate(str);
else
return parseDatetime(str);
}
/**
* Format the given Date object into string.
*/
public String formatDate(Date date) {
return dateFormatter.format(date);
}
/**
* Format the given Date object into string.
*/
public String formatDatetime(Date date) {
return datetimeFormatter.format(date);
}
/**
* Get authentications (key: authentication name, value: authentication).
*/
public Map<String, Authentication> getAuthentications() {
return authentications;
}
/**
* Get authentication for the given name.
*
* @param authName The authentication name
* @return The authentication, null if not found
*/
public Authentication getAuthentication(String authName) {
return authentications.get(authName);
}
/**
* Helper method to set username for the first HTTP basic authentication.
*/
public void setUsername(String username) {
for (Authentication auth : authentications.values()) {
if (auth instanceof HttpBasicAuth) {
((HttpBasicAuth) auth).setUsername(username);
return;
}
}
throw new RuntimeException("No HTTP basic authentication configured!");
}
/**
* Helper method to set password for the first HTTP basic authentication.
*/
public void setPassword(String password) {
for (Authentication auth : authentications.values()) {
if (auth instanceof HttpBasicAuth) {
((HttpBasicAuth) auth).setPassword(password);
return;
}
}
throw new RuntimeException("No HTTP basic authentication configured!");
}
/**
* Helper method to set API key value for the first API key authentication.
*/
public void setApiKey(String apiKey) {
for (Authentication auth : authentications.values()) {
if (auth instanceof ApiKeyAuth) {
((ApiKeyAuth) auth).setApiKey(apiKey);
return;
}
}
throw new RuntimeException("No API key authentication configured!");
}
/**
* Helper method to set API key prefix for the first API key authentication.
*/
public void setApiKeyPrefix(String apiKeyPrefix) {
for (Authentication auth : authentications.values()) {
if (auth instanceof ApiKeyAuth) {
((ApiKeyAuth) auth).setApiKeyPrefix(apiKeyPrefix);
return;
}
}
throw new RuntimeException("No API key authentication configured!");
}
/**
* Set the User-Agent header's value (by adding to the default header map).
*/
public ApiClient setUserAgent(String userAgent) {
addDefaultHeader("User-Agent", userAgent);
return this;
}
/**
* Add a default header.
*
* @param key The header's key
* @param value The header's value
*/
public ApiClient addDefaultHeader(String key, String value) {
defaultHeaderMap.put(key, value);
return this;
}
/**
* @see https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/stream/JsonReader.html#setLenient(boolean)
*/
public boolean isLenientOnJson() {
return lenientOnJson;
}
public ApiClient setLenientOnJson(boolean lenient) {
this.lenientOnJson = lenient;
return this;
}
/**
* Check that whether debugging is enabled for this API client.
*/
public boolean isDebugging() {
return debugging;
}
/**
* Enable/disable debugging for this API client.
*
* @param debugging To enable (true) or disable (false) debugging
*/
public ApiClient setDebugging(boolean debugging) {
this.debugging = debugging;
return this;
}
/**
* Format the given parameter object into string.
*/
public String parameterToString(Object param) {
if (param == null) {
return "";
} else if (param instanceof Date) {
return formatDatetime((Date) param);
} else if (param instanceof Collection) {
StringBuilder b = new StringBuilder();
for (Object o : (Collection)param) {
if (b.length() > 0) {
b.append(",");
}
b.append(String.valueOf(o));
}
return b.toString();
} else {
return String.valueOf(param);
}
}
/*
Format to {@code Pair} objects.
*/
public List<Pair> parameterToPairs(String collectionFormat, String name, Object value){
List<Pair> params = new ArrayList<Pair>();
// preconditions
if (name == null || name.isEmpty() || value == null) return params;
Collection valueCollection = null;
if (value instanceof Collection) {
valueCollection = (Collection) value;
} else {
params.add(new Pair(name, parameterToString(value)));
return params;
}
if (valueCollection.isEmpty()){
return params;
}
// get the collection format
collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv
// create the params based on the collection format
if (collectionFormat.equals("multi")) {
for (Object item : valueCollection) {
params.add(new Pair(name, parameterToString(item)));
}
return params;
}
String delimiter = ",";
if (collectionFormat.equals("csv")) {
delimiter = ",";
} else if (collectionFormat.equals("ssv")) {
delimiter = " ";
} else if (collectionFormat.equals("tsv")) {
delimiter = "\t";
} else if (collectionFormat.equals("pipes")) {
delimiter = "|";
}
StringBuilder sb = new StringBuilder() ;
for (Object item : valueCollection) {
sb.append(delimiter);
sb.append(parameterToString(item));
}
params.add(new Pair(name, sb.substring(1)));
return params;
}
/**
* Select the Accept header's value from the given accepts array:
* if JSON exists in the given array, use it;
* otherwise use all of them (joining into a string)
*
* @param accepts The accepts array to select from
* @return The Accept header to use. If the given array is empty,
* null will be returned (not to set the Accept header explicitly).
*/
public String selectHeaderAccept(String[] accepts) {
if (accepts.length == 0) return null;
if (StringUtil.containsIgnoreCase(accepts, "application/json")) return "application/json";
return StringUtil.join(accepts, ",");
}
/**
* Select the Content-Type header's value from the given array:
* if JSON exists in the given array, use it;
* otherwise use the first one of the array.
*
* @param contentTypes The Content-Type array to select from
* @return The Content-Type header to use. If the given array is empty,
* JSON will be used.
*/
public String selectHeaderContentType(String[] contentTypes) {
if (contentTypes.length == 0) return "application/json";
if (StringUtil.containsIgnoreCase(contentTypes, "application/json")) return "application/json";
return contentTypes[0];
}
/**
* Escape the given string to be used as URL query value.
*/
public String escapeString(String str) {
try {
return URLEncoder.encode(str, "utf8").replaceAll("\\+", "%20");
} catch (UnsupportedEncodingException e) {
return str;
}
}
/**
* Deserialize response body to Java object, according the Content-Type
* response header.
*
* @param response HTTP response
* @param returnType The type of the Java object
* @return The deserialized Java object
*/
public <T> T deserialize(Response response, Type returnType) throws ApiException {
if (response == null || returnType == null)
return null;
String respBody;
try {
if (response.body() != null)
respBody = response.body().string();
else
respBody = null;
} catch (IOException e) {
throw new ApiException(e);
}
if (respBody == null || "".equals(respBody))
return null;
String contentType = response.headers().get("Content-Type");
if (contentType == null) {
// ensuring a default content type
contentType = "application/json";
}
if (contentType.startsWith("application/json")) {
return json.deserialize(respBody, returnType);
} else {
throw new ApiException(
"Content type \"" + contentType + "\" is not supported",
response.code(),
response.headers().toMultimap(),
respBody);
}
}
/**
* Serialize the given Java object into request body string, according to the
* request Content-Type.
*
* @param obj The Java object
* @param contentType The request Content-Type
* @return The serialized string
*/
public String serialize(Object obj, String contentType) throws ApiException {
if (contentType.startsWith("application/json")) {
if (obj != null)
return json.serialize(obj);
else
return null;
} else {
throw new ApiException("Content type \"" + contentType + "\" is not supported");
}
}
/**
* @see #execute(Call, Type)
*/
public <T> T execute(Call call) throws ApiException {
return execute(call, null);
}
/**
* Execute HTTP call and deserialize the HTTP response body into the given return type.
*
* @param returnType The return type used to deserialize HTTP response body
* @param <T> The return type corresponding to (same with) returnType
* @return The Java object deserialized from response body. Returns null if returnType is null.
*/
public <T> T execute(Call call, Type returnType) throws ApiException {
try {
Response response = call.execute();
return handleResponse(response, returnType);
} catch (IOException e) {
throw new ApiException(e);
}
}
/**
* #see executeAsync(Call, Type, ApiCallback)
*/
public <T> void executeAsync(Call call, ApiCallback<T> callback) throws ApiException {
executeAsync(call, null, callback);
}
/**
* Execute HTTP call asynchronously.
*
* @see #execute(Call, Type)
* @param The callback to be executed when the API call finishes
*/
public <T> void executeAsync(Call call, final Type returnType, final ApiCallback<T> callback) {
call.enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
callback.onFailure(new ApiException(e));
}
@Override
public void onResponse(Response response) throws IOException {
T result;
try {
result = (T) handleResponse(response, returnType);
} catch (ApiException e) {
callback.onFailure(e);
return;
}
callback.onSuccess(result);
}
});
}
public <T> T handleResponse(Response response, Type returnType) throws ApiException {
if (response.isSuccessful()) {
if (returnType == null || response.code() == 204) {
// returning null if the returnType is not defined,
// or the status code is 204 (No Content)
return null;
} else {
return deserialize(response, returnType);
}
} else {
String respBody = null;
if (response.body() != null) {
try {
respBody = response.body().string();
} catch (IOException e) {
throw new ApiException(response.message(), e, response.code(), response.headers().toMultimap());
}
}
throw new ApiException(response.message(), response.code(), response.headers().toMultimap(), respBody);
}
}
/**
* Build HTTP call with the given options.
*
* @param path The sub-path of the HTTP URL
* @param method The request method, one of "GET", "HEAD", "POST", "PUT", "PATCH" and "DELETE"
* @param queryParams The query parameters
* @param body The request body object
* @param headerParams The header parameters
* @param formParams The form parameters
* @param authNames The authentications to apply
* @return The HTTP call
*/
public Call buildCall(String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String[] authNames) throws ApiException {
updateParamsForAuth(authNames, queryParams, headerParams);
final String url = buildUrl(path, queryParams);
final Request.Builder reqBuilder = new Request.Builder().url(url);
processHeaderParams(headerParams, reqBuilder);
String contentType = (String) headerParams.get("Content-Type");
// ensuring a default content type
if (contentType == null) contentType = "application/json";
RequestBody reqBody;
if ("GET".equals(method) || "HEAD".equals(method)) {
reqBody = null;
} else if ("application/x-www-form-urlencoded".equals(contentType)) {
reqBody = buildRequestBodyFormEncoding(formParams);
} else if ("multipart/form-data".equals(contentType)) {
reqBody = buildRequestBodyMultipart(formParams);
} else if (body == null) {
if ("DELETE".equals(method)) {
// allow calling DELETE without sending a request body
reqBody = null;
} else {
// use an empty request body (for POST, PUT and PATCH)
reqBody = RequestBody.create(MediaType.parse(contentType), "");
}
} else {
reqBody = RequestBody.create(MediaType.parse(contentType), serialize(body, contentType));
}
Request request;
if ("GET".equals(method)) {
request = reqBuilder.get().build();
} else if ("HEAD".equals(method)) {
request = reqBuilder.head().build();
} else if ("POST".equals(method)) {
request = reqBuilder.post(reqBody).build();
} else if ("PUT".equals(method)) {
request = reqBuilder.put(reqBody).build();
} else if ("PATCH".equals(method)) {
request = reqBuilder.patch(reqBody).build();
} else if ("DELETE".equals(method)) {
if (reqBody == null) {
// calling DELETE without sending a request body
request = reqBuilder.delete().build();
} else {
request = reqBuilder.delete(reqBody).build();
}
} else {
throw new ApiException("unknown method type: " + method);
}
return httpClient.newCall(request);
}
/**
* Build full URL by concatenating base path, the given sub path and query parameters.
*
* @param path The sub path
* @param queryParams The query parameters
* @return The full URL
*/
public String buildUrl(String path, List<Pair> queryParams) {
StringBuilder query = new StringBuilder();
if (queryParams != null) {
for (Pair param : queryParams) {
if (param.getValue() != null) {
if (query.toString().length() == 0)
query.append("?");
else
query.append("&");
String value = parameterToString(param.getValue());
query.append(escapeString(param.getName())).append("=").append(escapeString(value));
}
}
}
return basePath + path + query.toString();
}
/**
* Set header parameters to the request builder, including default headers.
*/
public void processHeaderParams(Map<String, String> headerParams, Request.Builder reqBuilder) {
for (Entry<String, String> param : headerParams.entrySet()) {
reqBuilder.header(param.getKey(), parameterToString(param.getValue()));
}
for (Entry<String, String> header : defaultHeaderMap.entrySet()) {
if (!headerParams.containsKey(header.getKey())) {
reqBuilder.header(header.getKey(), parameterToString(header.getValue()));
}
}
}
/**
* Update query and header parameters based on authentication settings.
*
* @param authNames The authentications to apply
*/
public void updateParamsForAuth(String[] authNames, List<Pair> queryParams, Map<String, String> headerParams) {
for (String authName : authNames) {
Authentication auth = authentications.get(authName);
if (auth == null) throw new RuntimeException("Authentication undefined: " + authName);
auth.applyToParams(queryParams, headerParams);
}
}
/**
* Build a form-encoding request body with the given form parameters.
*/
public RequestBody buildRequestBodyFormEncoding(Map<String, Object> formParams) {
FormEncodingBuilder formBuilder = new FormEncodingBuilder();
for (Entry<String, Object> param : formParams.entrySet()) {
formBuilder.add(param.getKey(), parameterToString(param.getValue()));
}
return formBuilder.build();
}
/**
* Build a multipart (file uploading) request body with the given form parameters,
* which could contain text fields and file fields.
*/
public RequestBody buildRequestBodyMultipart(Map<String, Object> formParams) {
MultipartBuilder mpBuilder = new MultipartBuilder().type(MultipartBuilder.FORM);
for (Entry<String, Object> param : formParams.entrySet()) {
if (param.getValue() instanceof File) {
File file = (File) param.getValue();
Headers partHeaders = Headers.of("Content-Disposition", "form-data; name=\"" + param.getKey() + "\"; filename=\"" + file.getName() + "\"");
MediaType mediaType = MediaType.parse(guessContentTypeFromFile(file));
mpBuilder.addPart(partHeaders, RequestBody.create(mediaType, file));
} else {
Headers partHeaders = Headers.of("Content-Disposition", "form-data; name=\"" + param.getKey() + "\"");
mpBuilder.addPart(partHeaders, RequestBody.create(null, parameterToString(param.getValue())));
}
}
return mpBuilder.build();
}
/**
* Guess Content-Type header from the given file (defaults to "application/octet-stream").
*
* @param file The given file
* @return The Content-Type guessed
*/
public String guessContentTypeFromFile(File file) {
String contentType = URLConnection.guessContentTypeFromName(file.getName());
if (contentType == null) {
return "application/octet-stream";
} else {
return contentType;
}
}
}

View File

@ -0,0 +1,102 @@
package {{invokerPackage}};
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.stream.JsonReader;
import java.io.StringReader;
import java.lang.reflect.Type;
import java.util.Date;
public class JSON {
private ApiClient apiClient;
private Gson gson;
public JSON(ApiClient apiClient) {
this.apiClient = apiClient;
gson = new GsonBuilder()
.serializeNulls()
.registerTypeAdapter(Date.class, new DateAdapter(apiClient))
.create();
}
public Gson getGson() {
return gson;
}
public void setGson(Gson gson) {
this.gson = gson;
}
/**
* Serialize the given Java object into JSON string.
*/
public String serialize(Object obj) {
return gson.toJson(obj);
}
/**
* Deserialize the given JSON string to Java object.
*
* @param body The JSON string
* @param returnType The type to deserialize inot
* @return The deserialized Java object
*/
public <T> T deserialize(String body, Type returnType) {
try {
if (apiClient.isLenientOnJson()) {
JsonReader jsonReader = new JsonReader(new StringReader(body));
// see https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/stream/JsonReader.html#setLenient(boolean)
jsonReader.setLenient(true);
return gson.fromJson(jsonReader, returnType);
} else {
return gson.fromJson(body, returnType);
}
} catch (JsonParseException e) {
// Fallback processing when failed to parse JSON form response body:
// return the response body string directly for the String return type;
// parse response body into date or datetime for the Date return type.
if (returnType.equals(String.class))
return (T) body;
else if (returnType.equals(Date.class))
return (T) apiClient.parseDateOrDatetime(body);
else throw(e);
}
}
}
class DateAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
private final ApiClient apiClient;
public DateAdapter(ApiClient apiClient) {
super();
this.apiClient = apiClient;
}
@Override
public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
if (src == null) {
return JsonNull.INSTANCE;
} else {
return new JsonPrimitive(apiClient.formatDatetime(src));
}
}
@Override
public Date deserialize(JsonElement json, Type date, JsonDeserializationContext context) throws JsonParseException {
String str = json.getAsJsonPrimitive().getAsString();
try {
return apiClient.parseDateOrDatetime(str);
} catch (RuntimeException e) {
throw new JsonParseException(e);
}
}
}

View File

@ -0,0 +1,116 @@
package {{package}};
import {{invokerPackage}}.ApiCallback;
import {{invokerPackage}}.ApiClient;
import {{invokerPackage}}.ApiException;
import {{invokerPackage}}.Configuration;
import {{invokerPackage}}.Pair;
import {{modelPackage}}.*;
import com.google.gson.reflect.TypeToken;
import com.squareup.okhttp.Call;
import java.lang.reflect.Type;
import java.util.*;
{{#imports}}import {{import}};
{{/imports}}
import java.io.File;
import java.util.Map;
import java.util.HashMap;
{{#operations}}
public class {{classname}} {
private ApiClient {{localVariablePrefix}}apiClient;
public {{classname}}() {
this(Configuration.getDefaultApiClient());
}
public {{classname}}(ApiClient apiClient) {
this.{{localVariablePrefix}}apiClient = apiClient;
}
public ApiClient getApiClient() {
return {{localVariablePrefix}}apiClient;
}
public void setApiClient(ApiClient apiClient) {
this.{{localVariablePrefix}}apiClient = apiClient;
}
{{#operation}}
/* Build call for {{nickname}} */
private Call {{nickname}}Call({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {
Object {{localVariablePrefix}}postBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
{{#allParams}}{{#required}}
// verify the required parameter '{{paramName}}' is set
if ({{paramName}} == null) {
throw new ApiException("Missing the required parameter '{{paramName}}' when calling {{nickname}}(Async)");
}
{{/required}}{{/allParams}}
// create path and map variables
String {{localVariablePrefix}}path = "{{path}}".replaceAll("\\{format\\}","json"){{#pathParams}}
.replaceAll("\\{" + "{{baseName}}" + "\\}", {{localVariablePrefix}}apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}};
List<Pair> {{localVariablePrefix}}queryParams = new ArrayList<Pair>();{{#queryParams}}
if ({{paramName}} != null)
{{localVariablePrefix}}queryParams.addAll({{localVariablePrefix}}apiClient.parameterToPairs("{{#collectionFormat}}{{{collectionFormat}}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}));{{/queryParams}}
Map<String, String> {{localVariablePrefix}}headerParams = new HashMap<String, String>();{{#headerParams}}
if ({{paramName}} != null)
{{localVariablePrefix}}headerParams.put("{{baseName}}", {{localVariablePrefix}}apiClient.parameterToString({{paramName}}));{{/headerParams}}
Map<String, Object> {{localVariablePrefix}}formParams = new HashMap<String, Object>();{{#formParams}}
if ({{paramName}} != null)
{{localVariablePrefix}}formParams.put("{{baseName}}", {{paramName}});{{/formParams}}
final String[] {{localVariablePrefix}}accepts = {
{{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}}
};
final String {{localVariablePrefix}}accept = {{localVariablePrefix}}apiClient.selectHeaderAccept({{localVariablePrefix}}accepts);
if ({{localVariablePrefix}}accept != null) {{localVariablePrefix}}headerParams.put("Accept", {{localVariablePrefix}}accept);
final String[] {{localVariablePrefix}}contentTypes = {
{{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}
};
final String {{localVariablePrefix}}contentType = {{localVariablePrefix}}apiClient.selectHeaderContentType({{localVariablePrefix}}contentTypes);
{{localVariablePrefix}}headerParams.put("Content-Type", {{localVariablePrefix}}contentType);
String[] {{localVariablePrefix}}authNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
return {{localVariablePrefix}}apiClient.buildCall({{localVariablePrefix}}path, "{{httpMethod}}", {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}authNames);
}
/**
* {{summary}}
* {{notes}}{{#allParams}}
* @param {{paramName}} {{description}}{{/allParams}}{{#returnType}}
* @return {{{returnType}}}{{/returnType}}
*/
public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{nickname}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {
Call {{localVariablePrefix}}call = {{nickname}}Call({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{#returnType}}Type {{localVariablePrefix}}returnType = new TypeToken<{{{returnType}}}>(){}.getType();
return {{localVariablePrefix}}apiClient.execute({{localVariablePrefix}}call, {{localVariablePrefix}}returnType);{{/returnType}}{{^returnType}}{{localVariablePrefix}}apiClient.execute({{localVariablePrefix}}call);{{/returnType}}
}
/**
* {{summary}} (asynchronously)
* {{notes}}{{#allParams}}
* @param {{paramName}} {{description}}{{/allParams}}
* @param callback The callback to be executed when the API call finishes
* @return The request call
*/
public Call {{nickname}}Async({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}ApiCallback<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{localVariablePrefix}}callback) throws ApiException {
Call {{localVariablePrefix}}call = {{nickname}}Call({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{#returnType}}Type {{localVariablePrefix}}returnType = new TypeToken<{{{returnType}}}>(){}.getType();
{{localVariablePrefix}}apiClient.executeAsync({{localVariablePrefix}}call, {{localVariablePrefix}}returnType, {{localVariablePrefix}}callback);{{/returnType}}{{^returnType}}{{localVariablePrefix}}apiClient.executeAsync({{localVariablePrefix}}call, {{localVariablePrefix}}callback);{{/returnType}}
return {{localVariablePrefix}}call;
}
{{/operation}}
}
{{/operations}}

View File

@ -0,0 +1,17 @@
public enum {{datatypeWithEnum}} {
{{#allowableValues}}{{#enumVars}}@SerializedName("{{value}}")
{{name}}("{{value}}"){{^-last}},
{{/-last}}{{#-last}};{{/-last}}{{/enumVars}}{{/allowableValues}}
private String value;
StatusEnum(String value) {
this.value = value;
}
@Override
public String toString() {
return value;
}
}

View File

@ -0,0 +1,58 @@
package {{package}};
import {{invokerPackage}}.StringUtil;
{{#imports}}import {{import}};
{{/imports}}
import com.google.gson.annotations.SerializedName;
{{#serializableModel}}
import java.io.Serializable;{{/serializableModel}}
import io.swagger.annotations.*;
{{#models}}
{{#model}}{{#description}}
/**
* {{description}}
**/{{/description}}
@ApiModel(description = "{{{description}}}")
public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#serializableModel}}implements Serializable{{/serializableModel}} {
{{#vars}}{{#isEnum}}
{{>libraries/okhttp-gson/enumClass}}{{/isEnum}}{{#items.isEnum}}{{#items}}
{{>libraries/okhttp-gson/enumClass}}{{/items}}{{/items.isEnum}}
@SerializedName("{{baseName}}")
private {{{datatypeWithEnum}}} {{name}} = {{{defaultValue}}};
{{/vars}}
{{#vars}}
/**{{#description}}
* {{{description}}}{{/description}}{{#minimum}}
* minimum: {{minimum}}{{/minimum}}{{#maximum}}
* maximum: {{maximum}}{{/maximum}}
**/
@ApiModelProperty({{#required}}required = {{required}}, {{/required}}value = "{{{description}}}")
public {{{datatypeWithEnum}}} {{getter}}() {
return {{name}};
}
public void {{setter}}({{{datatypeWithEnum}}} {{name}}) {
this.{{name}} = {{name}};
}
{{/vars}}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class {{classname}} {\n");
{{#parent}}sb.append(" ").append(StringUtil.toIndentedString(super.toString())).append("\n");{{/parent}}
{{#vars}}sb.append(" {{name}}: ").append(StringUtil.toIndentedString({{name}})).append("\n");
{{/vars}}sb.append("}");
return sb.toString();
}
}
{{/model}}
{{/models}}

View File

@ -0,0 +1,146 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>{{groupId}}</groupId>
<artifactId>{{artifactId}}</artifactId>
<packaging>jar</packaging>
<name>{{artifactId}}</name>
<version>{{artifactVersion}}</version>
<scm>
<connection>scm:git:git@github.com:swagger-api/swagger-mustache.git</connection>
<developerConnection>scm:git:git@github.com:swagger-api/swagger-codegen.git</developerConnection>
<url>https://github.com/swagger-api/swagger-codegen</url>
</scm>
<prerequisites>
<maven>2.2.0</maven>
</prerequisites>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
<configuration>
<systemProperties>
<property>
<name>loggerPath</name>
<value>conf/log4j.properties</value>
</property>
</systemProperties>
<argLine>-Xms512m -Xmx1500m</argLine>
<parallel>methods</parallel>
<forkMode>pertest</forkMode>
</configuration>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<!-- attach test jar -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
<configuration>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add_sources</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>src/main/java</source>
</sources>
</configuration>
</execution>
<execution>
<id>add_test_sources</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/test/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger-annotations-version}</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp</groupId>
<artifactId>okhttp</artifactId>
<version>${okhttp-version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson-version}</version>
</dependency>
<dependency>
<groupId>com.brsanthu</groupId>
<artifactId>migbase64</artifactId>
<version>2.2</version>
</dependency>
<!-- test dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<swagger-annotations-version>1.5.0</swagger-annotations-version>
<okhttp-version>2.4.0</okhttp-version>
<gson-version>2.3.1</gson-version>
<maven-plugin-version>1.0.0</maven-plugin-version>
<junit-version>4.8.1</junit-version>
</properties>
</project>

View File

@ -1,5 +1,6 @@
package {{package}};
import {{invokerPackage}}.StringUtil;
{{#imports}}import {{import}};
{{/imports}}
@ -45,9 +46,9 @@ public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#seriali
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class {{classname}} {\n");
{{#parent}}sb.append(" " + super.toString()).append("\n");{{/parent}}
{{#vars}}sb.append(" {{name}}: ").append({{name}}).append("\n");
{{/vars}}sb.append("}\n");
{{#parent}}sb.append(" ").append(StringUtil.toIndentedString(super.toString())).append("\n");{{/parent}}
{{#vars}}sb.append(" {{name}}: ").append(StringUtil.toIndentedString({{name}})).append("\n");
{{/vars}}sb.append("}");
return sb.toString();
}
}