forked from loafle/openapi-generator-original
Merge branch 'master' into issue-1357
This commit is contained in:
@@ -1,8 +1,13 @@
|
||||
package {{invokerPackage}};
|
||||
|
||||
import com.fasterxml.jackson.annotation.*;
|
||||
import com.fasterxml.jackson.databind.*;
|
||||
import com.fasterxml.jackson.datatype.joda.*;
|
||||
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
|
||||
|
||||
import com.sun.jersey.api.client.Client;
|
||||
import com.sun.jersey.api.client.ClientResponse;
|
||||
import com.sun.jersey.api.client.config.ClientConfig;
|
||||
import com.sun.jersey.api.client.GenericType;
|
||||
import com.sun.jersey.api.client.config.DefaultClientConfig;
|
||||
import com.sun.jersey.api.client.filter.LoggingFilter;
|
||||
import com.sun.jersey.api.client.WebResource.Builder;
|
||||
@@ -25,14 +30,11 @@ import java.util.TimeZone;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.DataInputStream;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.text.ParseException;
|
||||
|
||||
import {{invokerPackage}}.auth.Authentication;
|
||||
import {{invokerPackage}}.auth.HttpBasicAuth;
|
||||
@@ -45,7 +47,7 @@ public class ApiClient {
|
||||
private Map<String, String> defaultHeaderMap = new HashMap<String, String>();
|
||||
private boolean debugging = false;
|
||||
private String basePath = "{{basePath}}";
|
||||
private JSON json = new JSON();
|
||||
private ObjectMapper mapper;
|
||||
|
||||
private Map<String, Authentication> authentications;
|
||||
|
||||
@@ -55,6 +57,14 @@ public class ApiClient {
|
||||
private DateFormat dateFormat;
|
||||
|
||||
public ApiClient() {
|
||||
mapper = new ObjectMapper();
|
||||
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||
mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
|
||||
mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
|
||||
mapper.registerModule(new JodaModule());
|
||||
|
||||
// Use RFC3339 format for date and datetime.
|
||||
// See http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14
|
||||
this.dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
|
||||
@@ -62,7 +72,7 @@ public class ApiClient {
|
||||
// Use UTC as the default time zone.
|
||||
this.dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
|
||||
this.json.setDateFormat((DateFormat) dateFormat.clone());
|
||||
this.mapper.setDateFormat((DateFormat) dateFormat.clone());
|
||||
|
||||
// Set default User-Agent.
|
||||
setUserAgent("Java-Swagger");
|
||||
@@ -76,13 +86,6 @@ public class ApiClient {
|
||||
authentications = Collections.unmodifiableMap(authentications);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the JSON instance to do JSON serialization and deserialization.
|
||||
*/
|
||||
public JSON getJSON() {
|
||||
return json;
|
||||
}
|
||||
|
||||
public String getBasePath() {
|
||||
return basePath;
|
||||
}
|
||||
@@ -237,7 +240,7 @@ public class ApiClient {
|
||||
public ApiClient setDateFormat(DateFormat dateFormat) {
|
||||
this.dateFormat = dateFormat;
|
||||
// also set the date format for model (de)serialization with Date properties
|
||||
this.json.setDateFormat((DateFormat) dateFormat.clone());
|
||||
this.mapper.setDateFormat((DateFormat) dateFormat.clone());
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -269,7 +272,7 @@ public class ApiClient {
|
||||
return formatDate((Date) param);
|
||||
} else if (param instanceof Collection) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
for(Object o : (Collection)param) {
|
||||
for(Object o : (Collection<?>)param) {
|
||||
if(b.length() > 0) {
|
||||
b.append(",");
|
||||
}
|
||||
@@ -290,9 +293,9 @@ public class ApiClient {
|
||||
// preconditions
|
||||
if (name == null || name.isEmpty() || value == null) return params;
|
||||
|
||||
Collection valueCollection = null;
|
||||
if (value instanceof Collection) {
|
||||
valueCollection = (Collection) value;
|
||||
Collection<?> valueCollection = null;
|
||||
if (value instanceof Collection<?>) {
|
||||
valueCollection = (Collection<?>) value;
|
||||
} else {
|
||||
params.add(new Pair(name, parameterToString(value)));
|
||||
return params;
|
||||
@@ -337,6 +340,17 @@ public class ApiClient {
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given MIME is a JSON MIME.
|
||||
* JSON MIME examples:
|
||||
* application/json
|
||||
* application/json; charset=UTF8
|
||||
* APPLICATION/JSON
|
||||
*/
|
||||
public boolean isJsonMime(String mime) {
|
||||
return mime != null && mime.matches("(?i)application\\/json(;.*)?");
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the Accept header's value from the given accepts array:
|
||||
* if JSON exists in the given array, use it;
|
||||
@@ -347,8 +361,14 @@ public class ApiClient {
|
||||
* 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";
|
||||
if (accepts.length == 0) {
|
||||
return null;
|
||||
}
|
||||
for (String accept : accepts) {
|
||||
if (isJsonMime(accept)) {
|
||||
return accept;
|
||||
}
|
||||
}
|
||||
return StringUtil.join(accepts, ",");
|
||||
}
|
||||
|
||||
@@ -362,8 +382,14 @@ public class ApiClient {
|
||||
* 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";
|
||||
if (contentTypes.length == 0) {
|
||||
return "application/json";
|
||||
}
|
||||
for (String contentType : contentTypes) {
|
||||
if (isJsonMime(contentType)) {
|
||||
return contentType;
|
||||
}
|
||||
}
|
||||
return contentTypes[0];
|
||||
}
|
||||
|
||||
@@ -382,49 +408,30 @@ public class ApiClient {
|
||||
* Serialize the given Java object into string according the given
|
||||
* Content-Type (only JSON is supported for now).
|
||||
*/
|
||||
public String serialize(Object obj, String contentType) throws ApiException {
|
||||
if (contentType.startsWith("application/json")) {
|
||||
return json.serialize(obj);
|
||||
public Object serialize(Object obj, String contentType, Map<String, Object> formParams) throws ApiException {
|
||||
if (contentType.startsWith("multipart/form-data")) {
|
||||
FormDataMultiPart mp = new FormDataMultiPart();
|
||||
for (Entry<String, Object> param: formParams.entrySet()) {
|
||||
if (param.getValue() instanceof File) {
|
||||
File file = (File) param.getValue();
|
||||
mp.bodyPart(new FileDataBodyPart(param.getKey(), file, MediaType.MULTIPART_FORM_DATA_TYPE));
|
||||
} else {
|
||||
mp.field(param.getKey(), parameterToString(param.getValue()), MediaType.MULTIPART_FORM_DATA_TYPE);
|
||||
}
|
||||
}
|
||||
return mp;
|
||||
} else if (contentType.startsWith("application/x-www-form-urlencoded")) {
|
||||
return this.getXWWWFormUrlencodedParams(formParams);
|
||||
} else {
|
||||
throw new ApiException(400, "can not serialize object into Content-Type: " + contentType);
|
||||
// We let Jersey attempt to serialize the body
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize response body to Java object according to the Content-Type.
|
||||
*/
|
||||
public <T> T deserialize(ClientResponse response, TypeRef returnType) throws ApiException {
|
||||
String contentType = null;
|
||||
List<String> contentTypes = response.getHeaders().get("Content-Type");
|
||||
if (contentTypes != null && !contentTypes.isEmpty())
|
||||
contentType = contentTypes.get(0);
|
||||
if (contentType == null)
|
||||
throw new ApiException(500, "missing Content-Type in response");
|
||||
private ClientResponse getAPIResponse(String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String accept, String contentType, String[] authNames) throws ApiException {
|
||||
|
||||
String body;
|
||||
if (response.hasEntity())
|
||||
body = (String) response.getEntity(String.class);
|
||||
else
|
||||
body = "";
|
||||
|
||||
if (contentType.startsWith("application/json")) {
|
||||
return json.deserialize(body, returnType);
|
||||
} else if (returnType.getType().equals(String.class)) {
|
||||
// Expecting string, return the raw response body.
|
||||
return (T) body;
|
||||
} else {
|
||||
throw new ApiException(
|
||||
500,
|
||||
"Content type \"" + contentType + "\" is not supported for type: "
|
||||
+ returnType.getType()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private ClientResponse getAPIResponse(String path, String method, List<Pair> queryParams, Object body, byte[] binaryBody, Map<String, String> headerParams, Map<String, Object> formParams, String accept, String contentType, String[] authNames) throws ApiException {
|
||||
|
||||
if (body != null && binaryBody != null){
|
||||
throw new ApiException(500, "either body or binaryBody must be null");
|
||||
if (body != null && !formParams.isEmpty()){
|
||||
throw new ApiException(500, "Cannot have body and form params");
|
||||
}
|
||||
|
||||
updateParamsForAuth(authNames, queryParams, headerParams);
|
||||
@@ -461,61 +468,16 @@ public class ApiClient {
|
||||
}
|
||||
}
|
||||
|
||||
String encodedFormParams = null;
|
||||
if (contentType.startsWith("multipart/form-data")) {
|
||||
FormDataMultiPart mp = new FormDataMultiPart();
|
||||
for (Entry<String, Object> param: formParams.entrySet()) {
|
||||
if (param.getValue() instanceof File) {
|
||||
File file = (File) param.getValue();
|
||||
mp.bodyPart(new FileDataBodyPart(param.getKey(), file, MediaType.MULTIPART_FORM_DATA_TYPE));
|
||||
} else {
|
||||
mp.field(param.getKey(), parameterToString(param.getValue()), MediaType.MULTIPART_FORM_DATA_TYPE);
|
||||
}
|
||||
}
|
||||
body = mp;
|
||||
} else if (contentType.startsWith("application/x-www-form-urlencoded")) {
|
||||
encodedFormParams = this.getXWWWFormUrlencodedParams(formParams);
|
||||
}
|
||||
|
||||
ClientResponse response = null;
|
||||
|
||||
if ("GET".equals(method)) {
|
||||
response = (ClientResponse) builder.get(ClientResponse.class);
|
||||
} else if ("POST".equals(method)) {
|
||||
if (encodedFormParams != null) {
|
||||
response = builder.type(contentType).post(ClientResponse.class, encodedFormParams);
|
||||
} else if (body == null) {
|
||||
if(binaryBody == null)
|
||||
response = builder.post(ClientResponse.class, null);
|
||||
else
|
||||
response = builder.type(contentType).post(ClientResponse.class, binaryBody);
|
||||
} else if (body instanceof FormDataMultiPart) {
|
||||
response = builder.type(contentType).post(ClientResponse.class, body);
|
||||
} else {
|
||||
response = builder.type(contentType).post(ClientResponse.class, serialize(body, contentType));
|
||||
}
|
||||
response = builder.type(contentType).post(ClientResponse.class, serialize(body, contentType, formParams));
|
||||
} else if ("PUT".equals(method)) {
|
||||
if (encodedFormParams != null) {
|
||||
response = builder.type(contentType).put(ClientResponse.class, encodedFormParams);
|
||||
} else if(body == null) {
|
||||
if(binaryBody == null)
|
||||
response = builder.put(ClientResponse.class, null);
|
||||
else
|
||||
response = builder.type(contentType).put(ClientResponse.class, binaryBody);
|
||||
} else {
|
||||
response = builder.type(contentType).put(ClientResponse.class, serialize(body, contentType));
|
||||
}
|
||||
response = builder.type(contentType).put(ClientResponse.class, serialize(body, contentType, formParams));
|
||||
} else if ("DELETE".equals(method)) {
|
||||
if (encodedFormParams != null) {
|
||||
response = builder.type(contentType).delete(ClientResponse.class, encodedFormParams);
|
||||
} else if(body == null) {
|
||||
if(binaryBody == null)
|
||||
response = builder.delete(ClientResponse.class);
|
||||
else
|
||||
response = builder.type(contentType).delete(ClientResponse.class, binaryBody);
|
||||
} else {
|
||||
response = builder.type(contentType).delete(ClientResponse.class, serialize(body, contentType));
|
||||
}
|
||||
response = builder.type(contentType).delete(ClientResponse.class, serialize(body, contentType, formParams));
|
||||
} else {
|
||||
throw new ApiException(500, "unknown method type " + method);
|
||||
}
|
||||
@@ -529,7 +491,6 @@ public class ApiClient {
|
||||
* @param method The request method, one of "GET", "POST", "PUT", and "DELETE"
|
||||
* @param queryParams The query parameters
|
||||
* @param body The request body object - if it is not binary, otherwise null
|
||||
* @param binaryBody The request body object - if it is binary, otherwise null
|
||||
* @param headerParams The header parameters
|
||||
* @param formParams The form parameters
|
||||
* @param accept The request's Accept header
|
||||
@@ -537,9 +498,9 @@ public class ApiClient {
|
||||
* @param authNames The authentications to apply
|
||||
* @return The response body in type of string
|
||||
*/
|
||||
public <T> T invokeAPI(String path, String method, List<Pair> queryParams, Object body, byte[] binaryBody, Map<String, String> headerParams, Map<String, Object> formParams, String accept, String contentType, String[] authNames, TypeRef returnType) throws ApiException {
|
||||
public <T> T invokeAPI(String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String accept, String contentType, String[] authNames, GenericType<T> returnType) throws ApiException {
|
||||
|
||||
ClientResponse response = getAPIResponse(path, method, queryParams, body, binaryBody, headerParams, formParams, accept, contentType, authNames);
|
||||
ClientResponse response = getAPIResponse(path, method, queryParams, body, headerParams, formParams, accept, contentType, authNames);
|
||||
|
||||
statusCode = response.getStatusInfo().getStatusCode();
|
||||
responseHeaders = response.getHeaders();
|
||||
@@ -550,13 +511,13 @@ public class ApiClient {
|
||||
if (returnType == null)
|
||||
return null;
|
||||
else
|
||||
return deserialize(response, returnType);
|
||||
return response.getEntity(returnType);
|
||||
} else {
|
||||
String message = "error";
|
||||
String respBody = null;
|
||||
if (response.hasEntity()) {
|
||||
try {
|
||||
respBody = String.valueOf(response.getEntity(String.class));
|
||||
respBody = response.getEntity(String.class);
|
||||
message = respBody;
|
||||
} catch (RuntimeException e) {
|
||||
// e.printStackTrace();
|
||||
@@ -569,58 +530,6 @@ public class ApiClient {
|
||||
respBody);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Invoke API by sending HTTP request with the given options - return binary result
|
||||
*
|
||||
* @param path The sub-path of the HTTP URL
|
||||
* @param method The request method, one of "GET", "POST", "PUT", and "DELETE"
|
||||
* @param queryParams The query parameters
|
||||
* @param body The request body object - if it is not binary, otherwise null
|
||||
* @param binaryBody The request body object - if it is binary, otherwise null
|
||||
* @param headerParams The header parameters
|
||||
* @param formParams The form parameters
|
||||
* @param accept The request's Accept header
|
||||
* @param contentType The request's Content-Type header
|
||||
* @param authNames The authentications to apply
|
||||
* @return The response body in type of string
|
||||
*/
|
||||
public byte[] invokeBinaryAPI(String path, String method, List<Pair> queryParams, Object body, byte[] binaryBody, Map<String, String> headerParams, Map<String, Object> formParams, String accept, String contentType, String[]authNames) throws ApiException {
|
||||
|
||||
ClientResponse response = getAPIResponse(path, method, queryParams, body, binaryBody, headerParams, formParams, accept, contentType, authNames);
|
||||
|
||||
if(response.getStatusInfo() == ClientResponse.Status.NO_CONTENT) {
|
||||
return null;
|
||||
}
|
||||
else if(response.getStatusInfo().getFamily() == Family.SUCCESSFUL) {
|
||||
if(response.hasEntity()) {
|
||||
DataInputStream stream = new DataInputStream(response.getEntityInputStream());
|
||||
byte[] data = new byte[response.getLength()];
|
||||
try {
|
||||
stream.readFully(data);
|
||||
} catch (IOException ex) {
|
||||
throw new ApiException(500, "Error obtaining binary response data");
|
||||
}
|
||||
return data;
|
||||
}
|
||||
else {
|
||||
return new byte[0];
|
||||
}
|
||||
}
|
||||
else {
|
||||
String message = "error";
|
||||
if(response.hasEntity()) {
|
||||
try{
|
||||
message = String.valueOf(response.getEntity(String.class));
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
// e.printStackTrace();
|
||||
}
|
||||
}
|
||||
throw new ApiException(
|
||||
response.getStatusInfo().getStatusCode(),
|
||||
message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update query and header parameters based on authentication settings.
|
||||
@@ -642,7 +551,6 @@ public class ApiClient {
|
||||
StringBuilder formParamBuilder = new StringBuilder();
|
||||
|
||||
for (Entry<String, Object> param : formParams.entrySet()) {
|
||||
String keyStr = param.getKey();
|
||||
String valueStr = parameterToString(param.getValue());
|
||||
try {
|
||||
formParamBuilder.append(URLEncoder.encode(param.getKey(), "utf8"))
|
||||
@@ -667,7 +575,11 @@ public class ApiClient {
|
||||
*/
|
||||
private Client getClient() {
|
||||
if(!hostMap.containsKey(basePath)) {
|
||||
Client client = Client.create();
|
||||
// Add the JSON serialization support to Jersey
|
||||
JacksonJsonProvider jsonProvider = new JacksonJsonProvider(mapper);
|
||||
DefaultClientConfig conf = new DefaultClientConfig();
|
||||
conf.getSingletons().add(jsonProvider);
|
||||
Client client = Client.create(conf);
|
||||
if (debugging)
|
||||
client.addFilter(new LoggingFilter());
|
||||
hostMap.put(basePath, client);
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
package {{invokerPackage}};
|
||||
|
||||
import com.fasterxml.jackson.annotation.*;
|
||||
import com.fasterxml.jackson.databind.*;
|
||||
import com.fasterxml.jackson.datatype.joda.*;
|
||||
|
||||
import java.text.DateFormat;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
public class JSON {
|
||||
private ObjectMapper mapper;
|
||||
|
||||
public JSON() {
|
||||
mapper = new ObjectMapper();
|
||||
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||
mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
|
||||
mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
|
||||
mapper.registerModule(new JodaModule());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the date format for JSON (de)serialization with Date properties.
|
||||
*/
|
||||
public void setDateFormat(DateFormat dateFormat) {
|
||||
mapper.setDateFormat(dateFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the given Java object into JSON string.
|
||||
*/
|
||||
public String serialize(Object obj) throws ApiException {
|
||||
try {
|
||||
if (obj != null)
|
||||
return mapper.writeValueAsString(obj);
|
||||
else
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
throw new ApiException(400, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, TypeRef returnType) throws ApiException {
|
||||
JavaType javaType = mapper.constructType(returnType.getType());
|
||||
try {
|
||||
return mapper.readValue(body, javaType);
|
||||
} catch (IOException e) {
|
||||
if (returnType.getType().equals(String.class))
|
||||
return (T) body;
|
||||
else
|
||||
throw new ApiException(500, e.getMessage(), null, body);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package {{invokerPackage}};
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
public class TypeRef<T> {
|
||||
private final Type type;
|
||||
|
||||
public TypeRef() {
|
||||
this.type = getGenericType(getClass());
|
||||
}
|
||||
|
||||
private static Type getGenericType(Class<?> klass) {
|
||||
Type superclass = klass.getGenericSuperclass();
|
||||
if (superclass instanceof Class) {
|
||||
throw new RuntimeException("No type parameter provided");
|
||||
}
|
||||
ParameterizedType parameterized = (ParameterizedType) superclass;
|
||||
return parameterized.getActualTypeArguments()[0];
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
package {{package}};
|
||||
|
||||
import com.sun.jersey.api.client.GenericType;
|
||||
|
||||
import {{invokerPackage}}.ApiException;
|
||||
import {{invokerPackage}}.ApiClient;
|
||||
import {{invokerPackage}}.Configuration;
|
||||
import {{invokerPackage}}.Pair;
|
||||
import {{invokerPackage}}.TypeRef;
|
||||
|
||||
{{#imports}}import {{import}};
|
||||
{{/imports}}
|
||||
@@ -42,8 +43,7 @@ public class {{classname}} {
|
||||
{{/allParams}} * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}
|
||||
*/
|
||||
public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {
|
||||
Object {{localVariablePrefix}}postBody = {{#bodyParam}}{{^isBinary}}{{paramName}}{{/isBinary}}{{#isBinary}}null{{/isBinary}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
|
||||
byte[] {{localVariablePrefix}}postBinaryBody = {{#bodyParam}}{{#isBinary}}{{paramName}}{{/isBinary}}{{^isBinary}}null{{/isBinary}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
|
||||
Object {{localVariablePrefix}}postBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
|
||||
{{#allParams}}{{#required}}
|
||||
// verify the required parameter '{{paramName}}' is set
|
||||
if ({{paramName}} == null) {
|
||||
@@ -83,22 +83,12 @@ public class {{classname}} {
|
||||
|
||||
String[] {{localVariablePrefix}}authNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
|
||||
|
||||
{{#isResponseBinary}}
|
||||
byte[] {{localVariablePrefix}}response = null;
|
||||
{{localVariablePrefix}}response = {{localVariablePrefix}}apiClient.invokeBinaryAPI({{localVariablePrefix}}path, "{{httpMethod}}", {{localVariablePrefix}}queryParams,{{localVariablePrefix}} postBody, {{localVariablePrefix}}postBinaryBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}accept, {{localVariablePrefix}}contentType, {{localVariablePrefix}}authNames);
|
||||
return {{localVariablePrefix}}response;
|
||||
{{/isResponseBinary}}
|
||||
|
||||
{{^isResponseBinary}}
|
||||
{{#returnType}}
|
||||
TypeRef {{localVariablePrefix}}returnType = new TypeRef<{{{returnType}}}>() {};
|
||||
return {{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}path, "{{httpMethod}}", {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}postBinaryBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}accept, {{localVariablePrefix}}contentType, {{localVariablePrefix}}authNames, {{localVariablePrefix}}returnType);
|
||||
GenericType<{{{returnType}}}> {{localVariablePrefix}}returnType = new GenericType<{{{returnType}}}>() {};
|
||||
return {{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}path, "{{httpMethod}}", {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}accept, {{localVariablePrefix}}contentType, {{localVariablePrefix}}authNames, {{localVariablePrefix}}returnType);
|
||||
{{/returnType}}{{^returnType}}
|
||||
{{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}path, "{{httpMethod}}", {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}postBinaryBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}accept, {{localVariablePrefix}}contentType, {{localVariablePrefix}}authNames, null);
|
||||
{{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}path, "{{httpMethod}}", {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}accept, {{localVariablePrefix}}contentType, {{localVariablePrefix}}authNames, null);
|
||||
{{/returnType}}
|
||||
{{/isResponseBinary}}
|
||||
|
||||
|
||||
}
|
||||
{{/operation}}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
package {{invokerPackage}};
|
||||
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import feign.Feign;
|
||||
import feign.jackson.JacksonDecoder;
|
||||
import feign.jackson.JacksonEncoder;
|
||||
import feign.slf4j.Slf4jLogger;
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
public class ApiClient {
|
||||
public interface Api {}
|
||||
|
||||
private ObjectMapper objectMapper;
|
||||
private String basePath = "{{basePath}}";
|
||||
|
||||
public ApiClient() {
|
||||
objectMapper = createObjectMapper();
|
||||
}
|
||||
|
||||
public String getBasePath() {
|
||||
return basePath;
|
||||
}
|
||||
|
||||
public ApiClient setBasePath(String basePath) {
|
||||
this.basePath = basePath;
|
||||
return this;
|
||||
}
|
||||
|
||||
private ObjectMapper createObjectMapper() {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
|
||||
objectMapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
|
||||
return objectMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a feign client for given API interface.
|
||||
*
|
||||
* Usage:
|
||||
* ApiClient apiClient = new ApiClient();
|
||||
* apiClient.setBasePath("http://localhost:8080");
|
||||
* XYZApi api = apiClient.buildClient(XYZApi.class);
|
||||
* XYZResponse response = api.someMethod(...);
|
||||
*/
|
||||
public <T extends Api> T buildClient(Class<T> clientClass) {
|
||||
return Feign.builder()
|
||||
.encoder(new FormAwareEncoder(new JacksonEncoder(objectMapper)))
|
||||
.decoder(new JacksonDecoder(objectMapper))
|
||||
// enable for basic auth:
|
||||
// .requestInterceptor(new feign.auth.BasicAuthRequestInterceptor(username, password))
|
||||
.logger(new Slf4jLogger())
|
||||
.target(clientClass, basePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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];
|
||||
}
|
||||
}
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
package {{invokerPackage}};
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URLEncoder;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.*;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import feign.codec.EncodeException;
|
||||
import feign.codec.Encoder;
|
||||
import feign.RequestTemplate;
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
public class FormAwareEncoder implements Encoder {
|
||||
public static final String UTF_8 = "utf-8";
|
||||
private static final String LINE_FEED = "\r\n";
|
||||
private static final String TWO_DASH = "--";
|
||||
private static final String BOUNDARY = "----------------314159265358979323846";
|
||||
|
||||
private byte[] lineFeedBytes;
|
||||
private byte[] boundaryBytes;
|
||||
private byte[] twoDashBytes;
|
||||
private byte[] atBytes;
|
||||
private byte[] eqBytes;
|
||||
|
||||
private final Encoder delegate;
|
||||
private final DateFormat dateFormat;
|
||||
|
||||
public FormAwareEncoder(Encoder delegate) {
|
||||
this.delegate = delegate;
|
||||
// Use RFC3339 format for date and datetime.
|
||||
// See http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14
|
||||
this.dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
|
||||
|
||||
// Use UTC as the default time zone.
|
||||
this.dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
try {
|
||||
this.lineFeedBytes = LINE_FEED.getBytes(UTF_8);
|
||||
this.boundaryBytes = BOUNDARY.getBytes(UTF_8);
|
||||
this.twoDashBytes = TWO_DASH.getBytes(UTF_8);
|
||||
this.atBytes = "&".getBytes(UTF_8);
|
||||
this.eqBytes = "=".getBytes(UTF_8);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException {
|
||||
if (object instanceof Map) {
|
||||
try {
|
||||
encodeFormParams(template, (Map<String, Object>) object);
|
||||
} catch (IOException e) {
|
||||
throw new EncodeException("Failed to create request", e);
|
||||
}
|
||||
} else {
|
||||
delegate.encode(object, bodyType, template);
|
||||
}
|
||||
}
|
||||
|
||||
private void encodeFormParams(RequestTemplate template, Map<String, Object> formParams) throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
|
||||
boolean isMultiPart = isMultiPart(formParams);
|
||||
boolean isFirstField = true;
|
||||
for (Map.Entry<String, Object> param : formParams.entrySet()) {
|
||||
String keyStr = param.getKey();
|
||||
if (param.getValue() instanceof File) {
|
||||
addFilePart(baos, keyStr, (File) param.getValue());
|
||||
} else {
|
||||
String valueStr = parameterToString(param.getValue());
|
||||
if (isMultiPart) {
|
||||
addMultiPartFormField(baos, keyStr, valueStr);
|
||||
} else {
|
||||
addEncodedFormField(baos, keyStr, valueStr, isFirstField);
|
||||
isFirstField = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isMultiPart) {
|
||||
baos.write(lineFeedBytes);
|
||||
baos.write(twoDashBytes);
|
||||
baos.write(boundaryBytes);
|
||||
baos.write(twoDashBytes);
|
||||
baos.write(lineFeedBytes);
|
||||
}
|
||||
|
||||
String contentType = isMultiPart ? "multipart/form-data; boundary=" + BOUNDARY : "application/x-www-form-urlencoded";
|
||||
template.header("Content-type");
|
||||
template.header("Content-type", contentType);
|
||||
template.header("MIME-Version", "1.0");
|
||||
template.body(baos.toByteArray(), Charset.forName(UTF_8));
|
||||
}
|
||||
|
||||
/*
|
||||
* Currently only supports text files
|
||||
*/
|
||||
private void addFilePart(ByteArrayOutputStream baos, String fieldName, File uploadFile) throws IOException {
|
||||
String fileName = uploadFile.getName();
|
||||
baos.write(twoDashBytes);
|
||||
baos.write(boundaryBytes);
|
||||
baos.write(lineFeedBytes);
|
||||
|
||||
String contentDisposition = "Content-Disposition: form-data; name=\"" + fieldName
|
||||
+ "\"; filename=\"" + fileName + "\"";
|
||||
baos.write(contentDisposition.getBytes(UTF_8));
|
||||
baos.write(lineFeedBytes);
|
||||
String contentType = "Content-Type: " + URLConnection.guessContentTypeFromName(fileName);
|
||||
baos.write(contentType.getBytes(UTF_8));
|
||||
baos.write(lineFeedBytes);
|
||||
baos.write(lineFeedBytes);
|
||||
|
||||
BufferedReader reader = new BufferedReader(new FileReader(uploadFile));
|
||||
InputStream input = new FileInputStream(uploadFile);
|
||||
byte[] bytes = new byte[4096];
|
||||
int len = bytes.length;
|
||||
while ((len = input.read(bytes)) != -1) {
|
||||
baos.write(bytes, 0, len);
|
||||
baos.write(lineFeedBytes);
|
||||
}
|
||||
|
||||
baos.write(lineFeedBytes);
|
||||
}
|
||||
|
||||
private void addEncodedFormField(ByteArrayOutputStream baos, String name, String value, boolean isFirstField) throws IOException {
|
||||
if (!isFirstField) {
|
||||
baos.write(atBytes);
|
||||
}
|
||||
|
||||
String encodedName = URLEncoder.encode(name, UTF_8);
|
||||
String encodedValue = URLEncoder.encode(value, UTF_8);
|
||||
baos.write(encodedName.getBytes(UTF_8));
|
||||
baos.write("=".getBytes(UTF_8));
|
||||
baos.write(encodedValue.getBytes(UTF_8));
|
||||
}
|
||||
|
||||
private void addMultiPartFormField(ByteArrayOutputStream baos, String name, String value) throws IOException {
|
||||
baos.write(twoDashBytes);
|
||||
baos.write(boundaryBytes);
|
||||
baos.write(lineFeedBytes);
|
||||
|
||||
String contentDisposition = "Content-Disposition: form-data; name=\"" + name + "\"";
|
||||
String contentType = "Content-Type: text/plain; charset=utf-8";
|
||||
|
||||
baos.write(contentDisposition.getBytes(UTF_8));
|
||||
baos.write(lineFeedBytes);
|
||||
baos.write(contentType.getBytes(UTF_8));
|
||||
baos.write(lineFeedBytes);
|
||||
baos.write(lineFeedBytes);
|
||||
baos.write(value.getBytes(UTF_8));
|
||||
baos.write(lineFeedBytes);
|
||||
}
|
||||
|
||||
private boolean isMultiPart(Map<String, Object> formParams) {
|
||||
boolean isMultiPart = false;
|
||||
for (Map.Entry<String, Object> entry : formParams.entrySet()) {
|
||||
if (entry.getValue() instanceof File) {
|
||||
isMultiPart = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isMultiPart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the given parameter object into string.
|
||||
*/
|
||||
public String parameterToString(Object param) {
|
||||
if (param == null) {
|
||||
return "";
|
||||
} else if (param instanceof Date) {
|
||||
return formatDate((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 the given Date object into string.
|
||||
*/
|
||||
public String formatDate(Date date) {
|
||||
return dateFormat.format(date);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package {{package}};
|
||||
|
||||
import {{invokerPackage}}.ApiClient;
|
||||
|
||||
{{#imports}}import {{import}};
|
||||
{{/imports}}
|
||||
|
||||
{{^fullJavaUtil}}import java.util.*;
|
||||
{{/fullJavaUtil}}
|
||||
import feign.*;
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
public interface {{classname}} extends ApiClient.Api {
|
||||
|
||||
{{#operations}}{{#operation}}
|
||||
/**
|
||||
* {{summary}}
|
||||
* {{notes}}
|
||||
{{#allParams}} * @param {{paramName}} {{description}}
|
||||
{{/allParams}} * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}
|
||||
*/
|
||||
@RequestLine("{{httpMethod}} {{{path}}}{{#hasQueryParams}}?{{/hasQueryParams}}{{#queryParams}}{{paramName}}={{=<% %>=}}{<%paramName%>}<%={{ }}=%>{{#hasMore}}&{{/hasMore}}{{/queryParams}}")
|
||||
@Headers({
|
||||
"Content-type: {{vendorExtensions.x-contentType}}",
|
||||
"Accepts: {{vendorExtensions.x-accepts}}",{{#headerParams}}
|
||||
"{{paramName}}: {{=<% %>=}}{<%paramName%>}<%={{ }}=%>"{{#hasMore}},
|
||||
{{/hasMore}}{{/headerParams}}
|
||||
})
|
||||
{{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{nickname}}({{#allParams}}{{^isBodyParam}}@Param("{{paramName}}") {{/isBodyParam}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
}
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
group = '{{groupId}}'
|
||||
version = '{{artifactVersion}}'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:1.2.2'
|
||||
classpath 'com.github.dcendents:android-maven-plugin:1.2'
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
|
||||
if(hasProperty('target') && target == 'android') {
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'com.github.dcendents.android-maven'
|
||||
|
||||
android {
|
||||
compileSdkVersion 22
|
||||
buildToolsVersion '22.0.0'
|
||||
defaultConfig {
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 22
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
}
|
||||
|
||||
// Rename the aar correctly
|
||||
libraryVariants.all { variant ->
|
||||
variant.outputs.each { output ->
|
||||
def outputFile = output.outputFile
|
||||
if (outputFile != null && outputFile.name.endsWith('.aar')) {
|
||||
def fileName = "${project.name}-${variant.baseName}-${version}.aar"
|
||||
output.outputFile = new File(outputFile.parent, fileName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
provided 'javax.annotation:jsr250-api:1.0'
|
||||
}
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
android.libraryVariants.all { variant ->
|
||||
def task = project.tasks.create "jar${variant.name.capitalize()}", Jar
|
||||
task.description = "Create jar artifact for ${variant.name}"
|
||||
task.dependsOn variant.javaCompile
|
||||
task.from variant.javaCompile.destinationDir
|
||||
task.destinationDir = project.file("${project.buildDir}/outputs/jar")
|
||||
task.archiveName = "${project.name}-${variant.baseName}-${version}.jar"
|
||||
artifacts.add('archives', task);
|
||||
}
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar) {
|
||||
from android.sourceSets.main.java.srcDirs
|
||||
classifier = 'sources'
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives sourcesJar
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'maven'
|
||||
|
||||
sourceCompatibility = JavaVersion.VERSION_1_7
|
||||
targetCompatibility = JavaVersion.VERSION_1_7
|
||||
|
||||
install {
|
||||
repositories.mavenInstaller {
|
||||
pom.artifactId = '{{artifactId}}'
|
||||
}
|
||||
}
|
||||
|
||||
task execute(type:JavaExec) {
|
||||
main = System.getProperty('mainClass')
|
||||
classpath = sourceSets.main.runtimeClasspath
|
||||
}
|
||||
}
|
||||
|
||||
ext {
|
||||
swagger_annotations_version = "1.5.0"
|
||||
jackson_version = "2.6.3"
|
||||
feign_version = "8.1.1"
|
||||
jodatime_version = "2.5"
|
||||
junit_version = "4.12"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile "io.swagger:swagger-annotations:$swagger_annotations_version"
|
||||
compile "com.netflix.feign:feign-core:$feign_version"
|
||||
compile "com.netflix.feign:feign-jackson:$feign_version"
|
||||
compile "com.netflix.feign:feign-slf4j:$feign_version"
|
||||
compile "com.fasterxml.jackson.core:jackson-core:$jackson_version"
|
||||
compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version"
|
||||
compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version"
|
||||
compile "com.fasterxml.jackson.datatype:jackson-datatype-joda:2.1.5"
|
||||
compile "joda-time:joda-time:$jodatime_version"
|
||||
compile "com.brsanthu:migbase64:2.2"
|
||||
testCompile "junit:junit:$junit_version"
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
<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>
|
||||
|
||||
<!-- HTTP client: Netflix Feign -->
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-core</artifactId>
|
||||
<version>${feign-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-jackson</artifactId>
|
||||
<version>${feign-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-slf4j</artifactId>
|
||||
<version>${feign-version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- JSON processing: jackson -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<version>${jackson-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
<version>${jackson-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-joda</artifactId>
|
||||
<version>2.1.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>${jodatime-version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Base64 encoding that works in both JVM and Android -->
|
||||
<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>
|
||||
<feign-version>8.1.1</feign-version>
|
||||
<jackson-version>2.6.3</jackson-version>
|
||||
<jodatime-version>2.5</jodatime-version>
|
||||
<junit-version>4.12</junit-version>
|
||||
<maven-plugin-version>1.0.0</maven-plugin-version>
|
||||
</properties>
|
||||
</project>
|
||||
+61
-67
@@ -6,6 +6,7 @@ import javax.ws.rs.client.Entity;
|
||||
import javax.ws.rs.client.Invocation;
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import javax.ws.rs.core.Form;
|
||||
import javax.ws.rs.core.GenericType;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
@@ -29,13 +30,11 @@ import java.util.TimeZone;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.text.ParseException;
|
||||
|
||||
import {{invokerPackage}}.auth.Authentication;
|
||||
import {{invokerPackage}}.auth.HttpBasicAuth;
|
||||
@@ -344,6 +343,17 @@ public class ApiClient {
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given MIME is a JSON MIME.
|
||||
* JSON MIME examples:
|
||||
* application/json
|
||||
* application/json; charset=UTF8
|
||||
* APPLICATION/JSON
|
||||
*/
|
||||
public boolean isJsonMime(String mime) {
|
||||
return mime != null && mime.matches("(?i)application\\/json(;.*)?");
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the Accept header's value from the given accepts array:
|
||||
* if JSON exists in the given array, use it;
|
||||
@@ -354,8 +364,14 @@ public class ApiClient {
|
||||
* 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";
|
||||
if (accepts.length == 0) {
|
||||
return null;
|
||||
}
|
||||
for (String accept : accepts) {
|
||||
if (isJsonMime(accept)) {
|
||||
return accept;
|
||||
}
|
||||
}
|
||||
return StringUtil.join(accepts, ",");
|
||||
}
|
||||
|
||||
@@ -369,8 +385,14 @@ public class ApiClient {
|
||||
* 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";
|
||||
if (contentTypes.length == 0) {
|
||||
return "application/json";
|
||||
}
|
||||
for (String contentType : contentTypes) {
|
||||
if (isJsonMime(contentType)) {
|
||||
return contentType;
|
||||
}
|
||||
}
|
||||
return contentTypes[0];
|
||||
}
|
||||
|
||||
@@ -389,18 +411,39 @@ public class ApiClient {
|
||||
* Serialize the given Java object into string entity according the given
|
||||
* Content-Type (only JSON is supported for now).
|
||||
*/
|
||||
public Entity<String> serialize(Object obj, String contentType) throws ApiException {
|
||||
if (contentType.startsWith("application/json")) {
|
||||
return Entity.json(json.serialize(obj));
|
||||
public Entity<?> serialize(Object obj, Map<String, Object> formParams, String contentType) throws ApiException {
|
||||
Entity<?> entity = null;
|
||||
if (contentType.startsWith("multipart/form-data")) {
|
||||
MultiPart multiPart = new MultiPart();
|
||||
for (Entry<String, Object> param: formParams.entrySet()) {
|
||||
if (param.getValue() instanceof File) {
|
||||
File file = (File) param.getValue();
|
||||
FormDataContentDisposition contentDisp = FormDataContentDisposition.name(param.getKey())
|
||||
.fileName(file.getName()).size(file.length()).build();
|
||||
multiPart.bodyPart(new FormDataBodyPart(contentDisp, file, MediaType.APPLICATION_OCTET_STREAM_TYPE));
|
||||
} else {
|
||||
FormDataContentDisposition contentDisp = FormDataContentDisposition.name(param.getKey()).build();
|
||||
multiPart.bodyPart(new FormDataBodyPart(contentDisp, parameterToString(param.getValue())));
|
||||
}
|
||||
}
|
||||
entity = Entity.entity(multiPart, MediaType.MULTIPART_FORM_DATA_TYPE);
|
||||
} else if (contentType.startsWith("application/x-www-form-urlencoded")) {
|
||||
Form form = new Form();
|
||||
for (Entry<String, Object> param: formParams.entrySet()) {
|
||||
form.param(param.getKey(), parameterToString(param.getValue()));
|
||||
}
|
||||
entity = Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE);
|
||||
} else {
|
||||
throw new ApiException(400, "can not serialize object into Content-Type: " + contentType);
|
||||
// We let jersey handle the serialization
|
||||
entity = Entity.entity(obj, contentType);
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize response body to Java object according to the Content-Type.
|
||||
*/
|
||||
public <T> T deserialize(Response response, TypeRef returnType) throws ApiException {
|
||||
public <T> T deserialize(Response response, GenericType<T> returnType) throws ApiException {
|
||||
String contentType = null;
|
||||
List<Object> contentTypes = response.getHeaders().get("Content-Type");
|
||||
if (contentTypes != null && !contentTypes.isEmpty())
|
||||
@@ -408,24 +451,7 @@ public class ApiClient {
|
||||
if (contentType == null)
|
||||
throw new ApiException(500, "missing Content-Type in response");
|
||||
|
||||
String body;
|
||||
if (response.hasEntity())
|
||||
body = (String) response.readEntity(String.class);
|
||||
else
|
||||
body = "";
|
||||
|
||||
if (contentType.startsWith("application/json")) {
|
||||
return json.deserialize(body, returnType);
|
||||
} else if (returnType.getType().equals(String.class)) {
|
||||
// Expecting string, return the raw response body.
|
||||
return (T) body;
|
||||
} else {
|
||||
throw new ApiException(
|
||||
500,
|
||||
"Content type \"" + contentType + "\" is not supported for type: "
|
||||
+ returnType.getType()
|
||||
);
|
||||
}
|
||||
return response.readEntity(returnType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -443,7 +469,7 @@ public class ApiClient {
|
||||
* @param returnType The return type into which to deserialize the response
|
||||
* @return The response body in type of string
|
||||
*/
|
||||
public <T> T invokeAPI(String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String accept, String contentType, String[] authNames, TypeRef returnType) throws ApiException {
|
||||
public <T> T invokeAPI(String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String accept, String contentType, String[] authNames, GenericType<T> returnType) throws ApiException {
|
||||
updateParamsForAuth(authNames, queryParams, headerParams);
|
||||
|
||||
WebTarget target = client.target(this.basePath).path(path);
|
||||
@@ -474,50 +500,16 @@ public class ApiClient {
|
||||
}
|
||||
}
|
||||
|
||||
Entity<?> formEntity = null;
|
||||
|
||||
if (contentType.startsWith("multipart/form-data")) {
|
||||
MultiPart multiPart = new MultiPart();
|
||||
for (Entry<String, Object> param: formParams.entrySet()) {
|
||||
if (param.getValue() instanceof File) {
|
||||
File file = (File) param.getValue();
|
||||
FormDataContentDisposition contentDisp = FormDataContentDisposition.name(param.getKey())
|
||||
.fileName(file.getName()).size(file.length()).build();
|
||||
multiPart.bodyPart(new FormDataBodyPart(contentDisp, file, MediaType.APPLICATION_OCTET_STREAM_TYPE));
|
||||
} else {
|
||||
FormDataContentDisposition contentDisp = FormDataContentDisposition.name(param.getKey()).build();
|
||||
multiPart.bodyPart(new FormDataBodyPart(contentDisp, parameterToString(param.getValue())));
|
||||
}
|
||||
}
|
||||
formEntity = Entity.entity(multiPart, MediaType.MULTIPART_FORM_DATA_TYPE);
|
||||
} else if (contentType.startsWith("application/x-www-form-urlencoded")) {
|
||||
Form form = new Form();
|
||||
for (Entry<String, Object> param: formParams.entrySet()) {
|
||||
form.param(param.getKey(), parameterToString(param.getValue()));
|
||||
}
|
||||
formEntity = Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE);
|
||||
}
|
||||
Entity<?> entity = serialize(body, formParams, contentType);
|
||||
|
||||
Response response = null;
|
||||
|
||||
if ("GET".equals(method)) {
|
||||
response = invocationBuilder.get();
|
||||
} else if ("POST".equals(method)) {
|
||||
if (formEntity != null) {
|
||||
response = invocationBuilder.post(formEntity);
|
||||
} else if (body == null) {
|
||||
response = invocationBuilder.post(null);
|
||||
} else {
|
||||
response = invocationBuilder.post(serialize(body, contentType));
|
||||
}
|
||||
response = invocationBuilder.post(entity);
|
||||
} else if ("PUT".equals(method)) {
|
||||
if (formEntity != null) {
|
||||
response = invocationBuilder.put(formEntity);
|
||||
} else if (body == null) {
|
||||
response = invocationBuilder.put(null);
|
||||
} else {
|
||||
response = invocationBuilder.put(serialize(body, contentType));
|
||||
}
|
||||
response = invocationBuilder.put(entity);
|
||||
} else if ("DELETE".equals(method)) {
|
||||
response = invocationBuilder.delete();
|
||||
} else {
|
||||
@@ -556,6 +548,8 @@ public class ApiClient {
|
||||
private void buildClient() {
|
||||
final ClientConfig clientConfig = new ClientConfig();
|
||||
clientConfig.register(MultiPartFeature.class);
|
||||
clientConfig.register(json);
|
||||
clientConfig.register(org.glassfish.jersey.jackson.JacksonFeature.class);
|
||||
if (debugging) {
|
||||
clientConfig.register(LoggingFilter.class);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package {{invokerPackage}};
|
||||
|
||||
import com.fasterxml.jackson.annotation.*;
|
||||
import com.fasterxml.jackson.databind.*;
|
||||
import com.fasterxml.jackson.datatype.joda.*;
|
||||
|
||||
import java.text.DateFormat;
|
||||
|
||||
import javax.ws.rs.ext.ContextResolver;
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
public class JSON implements ContextResolver<ObjectMapper> {
|
||||
private ObjectMapper mapper;
|
||||
|
||||
public JSON() {
|
||||
mapper = new ObjectMapper();
|
||||
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||
mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
|
||||
mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
|
||||
mapper.registerModule(new JodaModule());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the date format for JSON (de)serialization with Date properties.
|
||||
*/
|
||||
public void setDateFormat(DateFormat dateFormat) {
|
||||
mapper.setDateFormat(dateFormat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMapper getContext(Class<?> type) {
|
||||
return mapper;
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,8 @@ import {{invokerPackage}}.ApiException;
|
||||
import {{invokerPackage}}.ApiClient;
|
||||
import {{invokerPackage}}.Configuration;
|
||||
import {{invokerPackage}}.Pair;
|
||||
import {{invokerPackage}}.TypeRef;
|
||||
|
||||
import javax.ws.rs.core.GenericType;
|
||||
|
||||
{{#imports}}import {{import}};
|
||||
{{/imports}}
|
||||
@@ -83,7 +84,7 @@ public class {{classname}} {
|
||||
String[] {{localVariablePrefix}}authNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
|
||||
|
||||
{{#returnType}}
|
||||
TypeRef {{localVariablePrefix}}returnType = new TypeRef<{{{returnType}}}>() {};
|
||||
GenericType<{{{returnType}}}> {{localVariablePrefix}}returnType = new GenericType<{{{returnType}}}>() {};
|
||||
return {{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}path, "{{httpMethod}}", {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}accept, {{localVariablePrefix}}contentType, {{localVariablePrefix}}authNames, {{localVariablePrefix}}returnType);
|
||||
{{/returnType}}{{^returnType}}
|
||||
{{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}path, "{{httpMethod}}", {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}accept, {{localVariablePrefix}}contentType, {{localVariablePrefix}}authNames, null);
|
||||
|
||||
@@ -124,7 +124,12 @@
|
||||
<artifactId>jersey-media-multipart</artifactId>
|
||||
<version>${jersey-version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.media</groupId>
|
||||
<artifactId>jersey-media-json-jackson</artifactId>
|
||||
<version>2.22.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- JSON processing: jackson -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
|
||||
+32
-7
@@ -549,6 +549,17 @@ public class ApiClient {
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given MIME is a JSON MIME.
|
||||
* JSON MIME examples:
|
||||
* application/json
|
||||
* application/json; charset=UTF8
|
||||
* APPLICATION/JSON
|
||||
*/
|
||||
public boolean isJsonMime(String mime) {
|
||||
return mime != null && mime.matches("(?i)application\\/json(;.*)?");
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the Accept header's value from the given accepts array:
|
||||
* if JSON exists in the given array, use it;
|
||||
@@ -559,8 +570,14 @@ public class ApiClient {
|
||||
* 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";
|
||||
if (accepts.length == 0) {
|
||||
return null;
|
||||
}
|
||||
for (String accept : accepts) {
|
||||
if (isJsonMime(accept)) {
|
||||
return accept;
|
||||
}
|
||||
}
|
||||
return StringUtil.join(accepts, ",");
|
||||
}
|
||||
|
||||
@@ -574,8 +591,14 @@ public class ApiClient {
|
||||
* 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";
|
||||
if (contentTypes.length == 0) {
|
||||
return "application/json";
|
||||
}
|
||||
for (String contentType : contentTypes) {
|
||||
if (isJsonMime(contentType)) {
|
||||
return contentType;
|
||||
}
|
||||
}
|
||||
return contentTypes[0];
|
||||
}
|
||||
|
||||
@@ -626,7 +649,7 @@ public class ApiClient {
|
||||
// ensuring a default content type
|
||||
contentType = "application/json";
|
||||
}
|
||||
if (contentType.startsWith("application/json")) {
|
||||
if (isJsonMime(contentType)) {
|
||||
return json.deserialize(respBody, returnType);
|
||||
} else if (returnType.equals(String.class)) {
|
||||
// Expecting string, return the raw response body.
|
||||
@@ -650,7 +673,7 @@ public class ApiClient {
|
||||
* @throws ApiException If fail to serialize the given object
|
||||
*/
|
||||
public String serialize(Object obj, String contentType) throws ApiException {
|
||||
if (contentType.startsWith("application/json")) {
|
||||
if (isJsonMime(contentType)) {
|
||||
if (obj != null)
|
||||
return json.serialize(obj);
|
||||
else
|
||||
@@ -822,7 +845,9 @@ public class ApiClient {
|
||||
|
||||
String contentType = (String) headerParams.get("Content-Type");
|
||||
// ensuring a default content type
|
||||
if (contentType == null) contentType = "application/json";
|
||||
if (contentType == null) {
|
||||
contentType = "application/json";
|
||||
}
|
||||
|
||||
RequestBody reqBody;
|
||||
if (!HttpMethod.permitsRequestBody(method)) {
|
||||
|
||||
@@ -137,6 +137,11 @@
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.jaxrs</groupId>
|
||||
<artifactId>jackson-jaxrs-json-provider</artifactId>
|
||||
<version>${jackson-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-joda</artifactId>
|
||||
|
||||
Reference in New Issue
Block a user